一、指针和数组
1.虽然数组和指针关系密切,但数组绝不是指针。
代码举例:
#includeint main() { int a; int *p = &a; printf("请输入一个整数:"); scanf("%d",&a); printf("a = %dn",a); printf("请重新输入一个整数:"); scanf("%d",p); printf("a = %dn",a); return 0; }
运行结果:
2.数组名其实是数组第一个元素的地址!
代码举例1:
#includeint main() { char str[128]; printf("请输入内容:"); scanf("%s",str); printf("str 的地址是:%pn",str); printf("str 的地址是:%pn",&str[0]); return 0; }
运行结果:
代码举例2:
#includeint main() { char a[] = "LoveC"; int b[5] = {1, 2, 3, 4, 5}; float c[5] = {1.1, 2.2, 3.3, 4.4, 5.5}; double d[5] = {1.1, 2.2, 3.3, 4.4, 5.5}; printf("a[0] -> %p, a[1] -> %p, a[2] -> %pn", &a[0], &a[1], &a[2]); printf("b[0] -> %p, b[1] -> %p, b[2] -> %pn", &b[0], &b[1], &b[2]); printf("c[0] -> %p, c[1] -> %p, c[2] -> %pn", &c[0], &c[1], &c[2]); printf("d[0] -> %p, d[1] -> %p, d[2] -> %pn", &d[0], &d[1], &d[2]); return 0; }
运行结果:
3.指向数组的指针
char *p;
p = a; // 语句1
p = &a[0]; // 语句2
4.指针的运算
- 当指针指向数组元素的时候,可以对指针变量进行加减运算,这样做的意义相当于指向距离指针所在位置向前或向后第n个元素。
- 当指针指向数组元素的时候,可以对指针变量进行加减运算,这样做的意义相当于指向距离指针所在位置向前或向后第n个元素。
代码举例:
#includeint main() { char a[] = "LoveC"; char *p = a; printf("*p = %c, *(p+1) = %c, *(p+2) = %cn", *p, *(p+1), *(p+2)); return 0; }
运行结果:
- 对比标准的下标法访问数组元素,这种使用指针进行间接访问的方法叫做指针法。
- 注意:p+1并不是简单地将地址加1,而是指向数组的下一个元素。
代码举例:
#includeint main() { int b[5] = {1, 2, 3, 4, 5}; int *p = b; printf("*p = %d, *(p+1) = %d, *(p+2) = %dn", *p, *(p+1), *(p+2)); return 0; }
运行结果:
二、指针数组和数组指针
1.指针和数组的区别
数组名只是一个地址,而指针是一个左值。
注:C语言的术语lvalue 指用于识别或定位一个存储位置的标识符。(注意:左值同时还必须是可改变的)
代码举例:
#includeint main() { char str[]="I love C!"; char *target=str; int count = 0; while(*target++ !=' ') { count++; } printf("总共有%d个字符!n",count); return 0; }
运行结果:
2.指针数组和数组指针
结论:指针数组是一个数组,每个数组元素存放一个指针变量。
代码举例:
#includeint main() { char *p1[5] = { "让编程改变世界", "Just do it", "一切皆有可能", "永不止步", "One more thing" }; int i; for(i = 0; i < 5; i++) { printf("%sn",p1[i]); } return 0; }
运行结果:
结论:数组指针是一个指针,它指向的是一个数组。
代码举例:
#includeint main() { int temp[5] = {1, 2, 3, 4, 5}; int (*p2)[5] = &temp; int i; for(i = 0; i < 5;i++) { printf("%dn", *(*p2 + i)); } return 0; }
运行结果:
三、指针和二维数组
1. *(array + 1)== array[1]
代码举例:
#includeint main() { int array[4][5] = {0}; int i, j, k = 0; for(i = 0;i < 4;i++) { for(j = 0;j <5;j++) { array[i][j] = k++; } } printf("*(array + 1): %pn",*(array + 1)); printf("array[1]: %pn",array[1]); printf("&array[1][0]: %pn",&array[1][0]); printf("**(array + 1): %dn",**(array + 1)); return 0; }
运行结果:
2. *(*(array + 1)+ 3 ) == &array[1][3]
添加两行代码即可证明:
printf("*(*(array + 1) + 3): %dn",*(*(array + 1) + 3));
printf("array[1][3]: %dn",array[1][3]);
运行结果:
3.结论
- *(array + i)== array[ i ]
- *(*(array+i)+j) == array[ i ][ j ]
- *(*(*(array+i)+j)+k) == array[ i ][ j ][ k ]
4.数组指针和二维数组
初始化二维数组是可以偷懒的:int array[2][3]={{0,1,2},{3,4,5}};
可以写成int array[][3]={{0,1,2},{3,4,5}};
定义一个数组指针是这样的:int(*p)[3];
那么如何解释这条语句:int(*p)[3]=array;
代码举例:
#includeint main() { int array[2][3] = {{0, 1, 2}, {3, 4, 5}}; int (*p)[3] = array; printf("**(p + 1): %dn", **(p + 1)); printf("**(array + 1): %dn", **(array + 1)); printf("array[1][0]: %dn", array[1][0]); printf("*(*(p + 1) + 2): %dn", *(*(p + 1) + 2)); printf("*(*(array + 1) + 2): %dn", *(*(array + 1) + 2)); printf("array[1][2]: %dn", array[1][2]); return 0; }
运行结果:



