数组与指针
程序1
指向数组元素的指针
// 27-1指向数组元素的指针.c #include <stdio.h> main() { //定义一维数组 int a[10] = {1,2,3,4,5,6,7,8,9,10}; int *p; //定义一个整型指针 p = &a[0]; //取数组a[0]元素的内存地址 如果: p = &a[10] p++ 系统发生报错 *p = 20; // 20 赋值给 a[0] printf("%d\n",a[0]); //输出数组第一个元素 p++; //移动一个指向数组元素的指针,可让他指向下一个元素 *p = 30; printf("%d\n", a[1]); }
注意:
※指针++并不是指针指向的内容++,而是指针本身++,相当于指针向前移动一个位置。
※指针每次++,并不是移动一个字节,它移动的字节数刚好为指针类型所占的字节数。每次移动多少字节,同学们也可以用sizeof函数自己测出来。
如:
double *pd;
pd++; /*pd一次移动了8字节*/
※指针一般在指向数组元素时才使用加减法,指向二维数组时还经常用到乘法
※指针的比较也就是比较两个指针是否指向同一位置,在指向数组元素的指针中经常用来测试两个指针是否指向同一数组元素。
内存计算
定义double arr[1000];将占用8*1000=8000=8K的内存,可用sizeof(arr)自己试试。
定义一个指针变量,要消耗4个字节的内存。
指针数组
格式:
int *a[10]; //相当于定义了十个元素都是指针类型
定义变量时,虽然各运算符意义不同,但同样符合C语言的运算符优先级。
在这里a先与[10]结合,表示a是个数组,再与int*结合,表示数组的每个元素都是int*型,也就是int型指针。
程序2
指针数组
// 27-2指针数组.c #include <stdio.h> main() { int a, b; int *pa[10]; //定义指针数组 pa[3] = &a; //取变量a的地址 pa[6] = &b; //取变量b的地址 a = 40; b = 50; printf("pa[3] = %d ,pa[6] = %d \n", *pa[3], *pa[6]); //输出值 }
指向数组的指针
格式:
int (*a)[10];
a先与*结合,表示a是个指针,再与[10]结合,表示它指向有10个元素的数组,再与int结合,表示这个数组是int型。
程序3
指向数组的指针
// 27-3指向数组的指针.c // #include <stdio.h> main() { int a[10] = {1,2,3,4,5}; int(*pa)[10]; //pa 是个指向有10个元素数组的指针 pa = &a; printf("%d\n", (*pa)[2]); //星号取值 }
切割记忆法:
*a: a先与*结合,不管两旁有什么东西,表示a只是“1个”指针,指向什么,以后再说。
a[10]: a先与[10]结合,表示a有“10个”元素,这10个元素是什么类型,以后再说。
数组名与指针
程序4
数组名与指针
// 27-4数组名与指针.c #include <stdio.h> main() { int a[10] = {10,1,2,3,4,5}; int *pa = a; // 数组a是一个指针 //*(pa+0) = *pa 指向数组第一个元素。数组名可直接当指针使用,*(a+0) = *a 指向数组第一个元素 printf("%d,%d,%d\n",*(pa+0),*(a+0),*a); printf("%d\n", *(pa + 3)); }
※数组名实际上是个只读指针,[n]运算早就被C语言的设计者设计好,在电脑中取a[n]的值相当于*(a+n)
*(a+n)与*a+n区别:
※数组名与指针的差别是:数组名是只读的,而指针可以改写。
假设a是数组名,p是指针,p++就可以,a++就不行。
※因为a[0]等价于*(a+0)等价于*a,所以&a[0]与 a意义相同。因此p=&a[0]和p=a效果一样。
++的分解
假如p是一个赋了值的char型指针,如果遇到如下表达式
char a=*p++;
可分解为:
char a=*p;
p=p+1;
第二种情况:
char a=*++p;
可分解为
p=p+1;
char a=*p;
第三种情况:
char a=(*p)++;
可分解为
char a=*p;
(*p)=(*p)+1;
第四种情况:
char a=++(*p);
可分解为
(*p) = (*p) +1;
char a=(*p);
图表总结
用指针输出一个数组中的全部元素
// 27-5用指针输出一个数组中的全部元素.c。 #include <stdio.h> main() { //定义一个普通的整形数组 int a[6] = { 0,1,2,3,4,5 }; //指向数组元素的指针输出 int *pa; printf("\"指向数组元素的指针:\"\n"); for (int i = 0; i < 6; i++) { pa = &a[i]; printf("%d ", *pa); } printf("\n\n"); //指针数组输出 int *pa1[10]; printf("\"指针数组:\"\n"); for (int i = 0; i < 6; i++) { pa1[i] = &a[i]; printf("%d ", *pa1[i]); } printf("\n\n"); //指向数组的指针输出 int(*pa2)[6]; printf("\"指向数组的指针:\"\n"); pa2 = &a; for (int i = 0; i < 6; i++) { printf("%d ", (*pa2)[i]); } printf("\n\n"); //数组名与指针输出 int *pa3 = a; printf("\"数组名与指针输出:\"\n"); for (int i = 0; i < 6; i++) { printf("%d ", *(pa3++)); } }