课堂案例有一个文章写,这片文章是把用到指针的单独提出来写一篇。
1. 指针数组,指向数组的指针 概念辨析
1.1指针数组是一个数组,里面的成员都是指针变量
1.1.1 指针开辟在栈上
void test05(){
int *arr[3];
int a=10;
int b=20;
int c=30;
arr[0]=&a;
arr[1]=&b;
arr[2]=&c;
for(int i=0;i<3;i++){
printf("%d\n",*(arr[i]));
}
}
1.1.2 指针开辟在堆上
//zhi指针数组 开辟在堆上
void test06(){
int **ptr=(int **)malloc(sizeof(int*)*3);
int a=10;
int b=20;
int c=30;
ptr[0]=&a;
ptr[1]=&b;
ptr[2]=&c;
for(int i=0;i<3;i++){
printf("%d\n",*(ptr[i]));
}
free(ptr);
ptr=NULL;
}
1.1.3 开辟在堆区的指针数组
这个例子中,我创建了一个二级指针,打算在堆区开辟一个有5个 int* 长度的指针数组。
//my test int数组
void allocfun(int ***arr){
int **temp=(int** )malloc(sizeof(int*)*5);
for(int i=0;i<5;i++){
temp[i]=(int*) malloc(sizeof(int));
*(temp[i])=100+i;
}
*arr=temp;
}
void outfun(int **arr333){
for(int i=0;i<5;i++){
printf("%d ",*(arr333[i]));
}
printf("\n");
}
void freefun(int ***arr2){
for(int i=0;i<5;i++){
if((*arr2)[i]!=NULL){
free((*arr2)[i]);
(*arr2)[i]=NULL;
}
}
if(*arr2!=NULL){
free(*arr2);
*arr2=NULL;
}
}
void test11(){
//我自己写的实验函数,分配堆区内存函数
int **ptr=NULL;
allocfun(&ptr);
outfun(ptr);
freefun(&ptr);
if(ptr!=NULL){
printf("只是形参复制了一份而已");
}
if(ptr==NULL){
printf("释放成功!!!");
}
}
1.2 指向数组的指针
一个int类型的指针,指向的是一个整数,当这个指针+1 时,它的步长就是4字节
一个char 类型的指针,指向的是一个字符,当这个指针+1 时,它的步长就是1字节
以此类推,一个指向数组的指针,它的步长是整个数组长度
一个指向自定义结构体的指针,它的步长就是整个结构体的字节长度
1.2.1 p指向一个整型 一维 数组。
指向数组的指针,语法格式是 &数组名。
void test02(){
int arr[5] = { 10,20,30,40,50 };
int(*p)[5] = &arr;//数组指针
printf("sizeof(p)= %d\n",sizeof(p));//4
printf("p的内存地址是 %d\n",p);//2686648 有警告
printf("*(*p) 是 %d\n",*(*p));//10
printf("(*p) [0] %d\n",(*p) [0]);//10
printf("(*p) [2]== %d\n",(*p) [2]);//30
printf("*(*p+2) == %d\n",*(*p+2));//30
printf("p+1后,内存地址是%d\n",p+1);//2686668
}
内存地址2686668和2686648正好差距20字节,是数组5个成员(每个4字节)的总和。
*p[0] 和( *p )[0] 结果是一样的,说明运算优先级是先跟 * 结合。
写错了!!*arr[10] 是指针数组, (*arr)[10] 是数组的指针完全不同
1.2.2 自定义类型的 数组的及其指向它的指针
MYARR1是一个自定义的,包涵5个整型的数组。
vo