指针就是地址。 指针的类型决定了指针操作时该指针指向地址变化的规律。 int arr[10], *p; p=arr; 此时把数组的地址赋给了指针p,指针p就指向了数组的首地址。 现在假设数组的首地址值是3452,则指针p的值必然是3452。 那么 p 1 表示指针移动指向了数组的下一个元素, 那么p 1的值等于3452 1==3453?错误 这里的p 1不是简单的算术运算,它表示——指针移动了一个整型元素。一个整型变量占多少字节内存:2 个字节,所以指针移动一个整型元素后地址值应为3452 2,即指针p的值为3454。 字符型指针: char aa[10], *p; p=aa; 同样假设数组的首地址为3452,那么p 1 的值可以这样考虑,指针移动一个字符的地址,而一个字符占一个字节的内存,所以p 1的值就为3452 1=3453。 数组名代表了数组的起始地址,如 char arr[5][6]; 那么数组名 arr就是这个二维数组的首地址。这样的写法:char arr[5][6], *p; p=arr;是错误的, 二维数组名是一个二级指针,是地址的地址 char arr[5][6]; char **p; p=arr;这样写同样是错误的 例1: int arr[4][5]; int *p; p=arr[0];//正确
arr[0]是int一维数组,arr[0]这个一维数组的各元素才是基本的int数据类型 下面的写法: char arr[4][5]={"abc","def","ghi","jkl","mno"}; char *p=arr[0]; for(i=0;i<20;i ) printf("%c", *(p i) ); //仔细观察输出的值是怎样变化的
1、必须使这个指针指向与其对应的字符型数据类型; 2、指针每增加一个单位的地址值 。 printf()语句输出的结果为" abcdefghijklmno"
下面举一个整型指针的例子: int arr[3][3]={ {1,2,3},{4,5,6},{7,8,9}}; int *p=arr[0]; for(i=0;i<9;i ) printf("%d", *(p i)); // 逐个的输出数组元素 一个二维数组的指针它有哪些特点: 一个二维数组,它的每一个数组元素都是一个一维数组, 一个整型二维数组可以写为: int arr[3][3]; 即 {arr[0], arr[1], arr[2] } 指针 p指向arr[0], 指针 p 1 指向arr[1] ,指针 p 2指向arr[2], 也就是指针每移动一个单位的地址就指向下一个一维数组, 实际上移动一个一维数组的长度即3个整型量。 那么这个指针可定义为如下形式: int (* p) [3] ; // 定义了一个指向二维数组的指针,这个二维数组中的一维 数组有3个元素。 p=arr; // 把二维数组的地址赋给指针 p char arr[3][4]={"abc","def","ghi"}; *(p 0) //是数驵 a[0] 的首地址 printf("%s", *p); 输出字符串 “"abc" *(p 1) //数组a[1]的首地址 printf("%s", *(p 1)); 输出字符串 "def" *(p 2) //数组 a[2]的首地址 printf("%s",*(p 2)); 输出字符串 "ghi" 如果要用这个二维数组的指针逐个的输出字符可以写为: *(*(p 0) 0) //第一个字符 a *(*(p 0) 1) //第二个字符 b *(*(p 0) 2) //第三个字符 c *(*(p 0) 3) //第四个字符 d *(*(p 0) 4) //第五个字符 e .................. 依此类推
当指针指向结构时的情形。。。 一个结构数组,三个结构: struct student { int a;char *b; }stru[3]= { {1,"abc"}, {2,"def"}, {3,"ghi"} }; struct student *p=stru; p 0 //第一个结构的地址 p 1 //第二个结构的地址 p 2 //第三个结构的地址
====================================
定义一个二维数组: inta[3][4]; 表示二维数组有三行四列共12个元素,在内存中按行存放,每行四个元素 a是二维数组的首地址, &a[0][0]既可以看作数组0行0列的首地址,同样还可以看作是二维数组的首地址, a[0]是第0行的首地址,当然也是数组的首地址。 同理a[n]就是第n行的首址;&a[n][m]就是数组元素a[n][m]的地址。 把二维数组看成是由n行一维数组构成,将每行首地址传递给指针变量,行中的其余元素均可由指针来表示。 用地址法来表示数组各元素的地址。对元素a[1][2],&a[1][2]是其地址,a[1]+2也是其地址。 分析a[1]+1与a[1]+2的地址关系,它们地址的差并非整数1,而是一个数组元素的所占位置2,原因是每个数组元素占两个字节。 对0行首地址与1行首地址a与a+1来说,地址的差同样也并非整数1,是一行,四个元素占的字节数8。 由于数组元素在内存的连续存放。给指向整型变量的指针传递数组的首地址,则该指针指向二维数组。 int *ptr,a[3][4]; 若赋值:ptr=a;则用ptr++就能访问数组的各元素。 //用地址法输入输出二维数组各元素。 #include<stdio.h> main() { int a[3][4]; int i,j; for(i=0;i<3;i++) for(j=0;j<4;j++) scanf("%d",a[i]+j);/*地址法*/先输行,一行满了之后再输下一行 for(i=0;i<3;i++) { for(j=0;j<4;j++) printf("%4d",*(a[i]+j));/**(a[i]+是j地)址法所表示的数组元素*/ printf("\n"); } } 运行程序: 输入:1 2 3 4 5 6 7 8 9 10 11 12
输出: 1 2 3 4 5 6 7 8 9 10 11 12
//用指针法输入输出二维数组各元素。 //把二维数组看作是展开的一维数组 #include<stdio.h> main() { int a[3][4],*ptr; int i,j; ptr=a[0]; for(i=0;i<3;i++) for(j=0;j<4;j++) scanf("%d",ptr++);/*指针的表示方法*/ ptr=a[0]; //重新指向数组第0行 for(i=0;i<3;i++) { for(j=0;j<4;j++) printf("%4d",*ptr++); printf("\n"); } }
|