(1)用字符数组存放一个字符串
#include
int main()
{
char string[] = "I Love China!";
printf("%s\n", string);
return 0;
}
(2)用字符指针指向一个字符串
#include
int main()
{
char* string = "I Love China!";
printf("%s\n", string);
return 0;
}
注意:
char* string = "I Love China!";
等价于
char* string; string = "I Love China!";
而不是
char* string; *string = "I Love China!";
例,字符串的复制:将字符数组a里面的字符串复制到字符数组b.
#include
int main()
{
char a[] = "I am a boy.", b[20];
int i;
for (i = 0; *(a + i) != '\0'; i++)
*(b + i) = *(a + i);
*(b + i) = '\0'; //当循环结束时,指针位置跳到i+1,正好是结束符的位置;
printf("string a is : %s\n", a);
printf("string b is : ");
for (i = 0; b[i] != '\0'; i++)
printf("%c", b[i]);
printf("\n");
return 0;
}
用指向字符数组的指针实现:
#include
int main()
{
char a[] = "I am a boy.", b[20], * p1, * p2;
p1 = a;
p2 = b;
for (; *p1 != '\0'; p1++, p2++)
*p2 = *p1;
*p2 = '\0';
printf("string a is: %s\n", a);
printf("string b is: %s\n", b);
return 0;
}
(1)实参形参都为字符数组
#include
void copy_string(char from[], char to[]);
int main()
{
char a[] = "I am a teacher.";
char b[] = "you are a student.";
printf("string a = %s\nstring b = %s\n", a, b);
printf("copy string a to string b: \n");
copy_string(a, b);
printf("\nstring a = %s\nstring b = %s\n", a, b);
return 0;
}
void copy_string(char from[], char to[])
{
int i = 0;
while (from[i] != '\0')
{
to[i] = from[i];
i++;
}
to[i] = '\0';
}
(2)实参为指针变量
#include
void copy_string(char from[], char to[]);
int main()
{
char a[] = "I am a teacher.";
char b[] = "you are a student.";
char* from = a, * to = b;
printf("string a = %s\nstring b = %s\n", a, b);
printf("copy string a to string b: \n");
copy_string(from, to);
printf("\nstring a = %s\nstring b = %s\n", a, b);
return 0;
}
(3)形参为指针变量
void copy_string(char* from, char* to)
{
for (; *from != '\0'; from++, to++)
*to = *from;
*to = '\0';
}
或者
void copy_string(char* from, char* to)
{
while ((*to = *from) != '\0')
{
to++;
from++;
}
}
(1)字符指针变量
char *a=″I love China!″;
等价于
char*a;a=″I love China!″;
而字符数组
char str[14] =″I love China!″;
不能等价于
char str[14];str[] =″I love China!″;
(2)字符数组的输入:
char str[10];scanf(″%s″,str);
但是字符指针变量
char *a;scanf(″%s″,a);
却是错误的,正确输入为:
char *a, str[10];a = str;scanf(″%s″,a);
用指针变量可以指向一个函数;函数在编译时被分配给一个入口地址这个函数的入口地址就称为函数的指针;函数名代表函数的入口地址;
一般定义形式:
数据类型 (*指针变量名)(函数参数表列)
例如这个简单的比较大小的函数
#include
int main()
{
int max(int, int);
int a, b, c;
scanf("%d,%d", &a, &b);
c = max(a, b);
printf("a=%d,b=%d,max=%d\n", a, b, c);
return 0;
}
int max(int x, int y)
{
int z;
if (x > y) z = x;
else z = y;
return z;
}
主函数里面可以使用函数指针变量:
#include
int main()
{
int max(int, int);
int (*p)(int, int);/*类型要跟被指向函数类型一致,
参数表列类型也要跟被指向函数一致,(*p)的括号不能省略*/
int a, b, c;
p = max;
scanf("%d,%d", &a, &b);
c = (*p)(a, b);
printf("a=%d,b=%d,max=%d\n", a, b, c);
return 0;
}
注意:
(1)* p两侧的括号不能省略,表示p先于 * 结合,是指针变量,然后再与后面的()结合,表示此指针变量指向函数。
(2)对指向函数的指针变量,像p+n、p++、p–等运算是没有意义的。
指向函数的指针作为参数,可以实现函数地址的传递,这样就能够在被调用的函数中使用实参函数。
例,有两个整数a和b,由用户输入1,2或3。输入1时,输出a和b中大者;输入2时,输出a和b中小者;输入3时,输出a和b之和。
#include
int main()
{
void fun(int, int, int (*p)(int, int));
int max(int, int);
int min(int, int);
int add(int, int);
int a = 34, b = -21, n;
scanf("%d",&n);
if (n == 1) fun(a, b, max);
else if (n == 2) fun(a, b, min);
else if (n == 3) fun(a, b, add);
return 0;
}
void fun(int x,int y,int(*p)(int, int))
{
int result;
result = (*p)(x, y);
printf("%d\n", result);
}
int max(int x, int y)
{
int z;
if (x > y) z = x;
else z = y;
return z;
}
int min(int x, int y)
{
int z;
if (x < y) z = x;
else z = y;
return z;
}
int add(int x, int y)
{
int z;
z = x + y;
return z;
}
第4行中,第三个参数是指向函数的指针,发生调用时,根据实参决定形参指针指向哪个函数,例如第11行中,函数调用
fun(a, b, min);
则
void fun(int, int, int (*p)(int, int))
中的形参(*p)指向函数min;
一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。
一般定义形式为:
类型名 *函数名(参数表列);
例如:
int *a(int x,int y);
注意:
*a两侧没有括号,在a的两侧分别为*运算符和()运算符。
而()优先级高于*,因此a先与()结合,这是函数形式。
前面有一个*,表示此函数是指针型函数,即函数值是指针。
例,有若干个学生的成绩(每个学生有4门 课程),要求在用户输入学生序号以 后,能输出该学生的全部成绩。
#include
int main()
{
float score[][4] = { {60,70,80,90},{56,89,67,88},{34,78,90,66} };
float* search(float(*p)[4], int n);
float* p1;
int i, k;
printf("enter the number of student: ");
scanf("%d", &k);
printf("The scores of No. %d are: \n", k);
p1 = search(score, k);
for (i = 0; i < 4; i++)
printf("%5.2f\t", *(p1 + i));
printf("\n");
return 0;
}
float* search(float(*p)[4], int n)
{
float* pt;
pt = *(p + n);
return pt;
}
例,对上例中的学生,找出其中有不及格课程的学生及其学生号
#include
int main()
{
float s[][4] = { {60,70,80,90},{56,89,67,88},{34,78,90,66} };
float* search(float(*pr)[4]);
float* p;
int i, j;
for (i = 0; i < 3; i++)
{
p = search(s + i);
if (p == *(s + i))
{
printf("No. %d scores;", i);
for (j = 0; j < 4; j++)
printf("%5.2f, ", *(p + j));
printf("\n");
}
}
return 0;
}
float* search(float(*p)[4])
{
int i;
float* pt;
pt = NULL;
for (i = 0; i < 4; i++)
if (*(*p + i) < 60) pt = *p;
return pt;
}
一个数组,若其元素均为指针类型数据,称为指针数组,即指针数组中的每一个元素都相当于一个指针变量。
一维指针数组的定义形式为: 类型名*数组名[数组长度];
例如:
int *p[4];
注意:
由于[]比* 优先级高,因此p先与[4]结合,形成p[4]形式,这是数组形式,它有4个元素。然后再与*结合,表示此数组是指针类型的,每个数组元素都是一个指针变量。
例如,下面这个程序
#include
#include
void sort(char* name[], int n);
void print(char* name[], int n);
int main()
{
char* name[] = { "Follow me", "BASIC",
"Great Wall", "FORTRAN", "Computer design" };
int n = 5;
sort(name, n);
print(name, n);
return 0;
}
void sort(char* name[],int n)
{
char* temp;
int i, j, k;
for (i = 0 ; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
if (strcmp(name[k],name[j]) > 0) k = j;
if(k!=i)
{
temp = name[i];
name[i] = name[k];
name[k] = temp;
}
}
}
void print(char* name[],int n)
{
int i;
for (i = 0; i < n; i++)
printf("%s\n", name[i]);
}
定义一个指向指针数据的指针变量:
char **p;
p的前面有两个* 号。*运算符的结合性是从右到左,因此**p相当于 * ( * p)。
如果没有最前面的 * ,那就是定义了一个指向字符数据的指针变量。
现在它前面又有一个*号,表示指针变量p是指向一个字符指针变量的。
*p就是p所指向的另一个指针变量。
#include
int main()
{
char* name[] = { "Follow me", "BASIC",
"Great Wall", "FORTRAN", "Computer design" };
char** p;
for(int i=0;i<5;i++)
{
p = name + i;
printf("%s\n", *p);
}
return 0;
}
1. #include<stdio.h>
2. int main()
3. {
4. int a[5] = { 1, 3, 5, 7, 9 };
5. int* num[5] = { &a[0], &a[1], &a[2], &a[3], &a[4] };
6. int** p,i;
7. p = num;
8. for(i=0;i<5;i++)
9. {
10. printf("%d\n", **p);
11. p++;
12. }
13. return 0;
14. }