指针与数组 总结
1.<指针数组>:
什么是指针数组,用来表示一个数组,用来存放指针的数组就叫指针数组,数组里面的员都是指针;
如: int *p[3]:,表示一个可以存三个 int 指针的 数组
赋值: int a1=1,a2=2,a3=3;
int *p[3]={&a1,&a2,&a3};
取值: int *a=p[0];
2.<数组的指针>
表示一个指针,这个指针的类型是数组,
定义:固定写法,一定要加括号,不然变量P先与[]结合,成数组了
如: int (*p)[3];
赋值: int arr[3]={1,2,3}; //arr表示一个数组,里面包含第一个元素的地址;arr=&arr[0]
p=&arr;//表示取数组的地址,p是一个数组的指针;
pinrtf("%d",(*p)[0]);//用数组指针,表示里面的值; //*p 等效于arr;
int *p1=arr; //定义一个指针,指向数组arr ,表示数组首元素的指针;
3.<数组元素指针>
什么是数组元素指针:表示一个指针,这个指针存得时数组的一个元素的地址
int arr[1]={1};
int *p=&arr[0]; //*p=arr;
printf("%d",*p); //*p 指向了数组arr第一个元素,*p=第一个元素的值;
4.<数组指针特点>
1).数组名表示第一个元素的地址,&数组名表示整个数组的地址,二者值相同,意义不同;
2).指针可以运算,但仅限于 加减运算,运算的实质就是地址运算,既地址的移动;
int arr[3]={1,2,3};
int *p=arr //等效于 *p=&arr[0]
int a=*p;
a=*(p+1);//等于 a=arr[1]; -----int *p1=&arr[1] , a=*p1; //P的值并没有改变
3).地址(+1)向高位移动,(-1)向低位移动,不同指针类型移动(+1或者-1)的字节数不同,//主要看当前环境定义指针的类型,是什么类型,移动几个字节;
char arr[3]={'a','b','c'};
char *p=arr; //char *p=&arr[0]
p+1 地址 比 p 高一个字节 //P+1 不赋值,P的地址不变
p=p+1; //表示p 指向了 &arr[1];
printf("%c",*p);//表示arr[0];
4).实际移动字节数,看指针类型,类型占多少字节,一位就移动多少个字节;
5).判断类型:去掉变量名,或者去掉*变量名 看是什么类型就是什么类型;
指针类型占8个字节;
6). 指针也可以以指针名移动数量 .p[1] 等效于 *(p+1);
指针名[移动数量],并且以这个指针地址位置开始位置为准-
向高地址或者低地址移动,指针类型*N的字节数
p[位置+1 -1 +n,-n]等效于 *(p+n,-n)
//指针不受限制,可以任意在内存中移动;
练习1:
//面试题目
int a[]={1,2,3,4,5};
int *p=(int *)(&a+1);
printf("%d,%d\n",*(a+1),*(p-1));
练习2:
//定义一个指针数组,并把它的值赋值给一个指针
int a,b,c;
a=10;
b=20;
c=30;
int *p[3]={&a,&b,&c};
int **p1=p;//定义一个二级指针指向了 指针数组p
printf("%p---%p\n",*(p1+1),p[1]); //输出得时指针数据里面的地址
练习3
char ch[]={'a','b','c','d','e'};
char *pch=ch;
for (int i=0; i<sizeof(ch);i++ ) {
//printf("%c\t",ch[i]);//第一个种方式
//printf("%c\t",*(pch+i));//第二种方式
printf("%c\t",pch[i]);//第三种方式
}
指针与二维数组
1.<二维指针数组>
什么是二维指针数据: 是一个数组,里面的每一个子数组存得元素类型都是指针
例如:
int *pa=&a; int *pb=&b; int *pc=&c;
int *pd=&b; int *pe=&e int *pf=&f;
定义二维指针数组
int *p[2][3]={{pa,pb,pc},{pd,pe,pf}};
int *p1=p[0][0];
2.<二维数组指针>
什么是二维数组指针: 是一个指针,只是指针类型是二维数组;
例如:
int arr[2][3]={{1,2,3},{4,5,6}}; //第二种写法:arr[2][3]={1,2,3,4,5,6};
int (*p)[2][3]=&arr; //是一个二维数组指针;
使用:
(*p)[0][0]==arr[0][0]==1;
|
|