文章目录
一、指针与一维数组
对指针浅显的认识
int a=0;int *p=&a;
*为解引用 拿到指针指向的内存里面的值
&为取地址 拿到元素所占内存的起始地址
指针玩的就是内存
指针就像拿钥匙套娃开门
*就像万能钥匙,p就像门牌号
*打开对应门牌号的门,进入里面
&拿到对应门牌号外面的门牌号,回到外面
有的门开了就能拿到东西,这就是一级指针
有的门开了里面还是一扇门,只能拿到门牌号,这就是多级指针
有的门开了,里面不只是一扇门,是一层楼,单用钥匙只能拿这层楼的起始门牌号,这就是数组指针
注意
一定要理解指针的类型、指针指向的类型
这对于 解引用和指针算术 很重要
指针加1是根据指针的类型来加
如:
int a[2] a的类型为int * 指向的类型为 int
int a[3][2] a的类型为int *[2] 指向的类型为 int *
1.1、int a[] = {1,2}; int *p = a
数组类似于指向位置固定的指针
即a除了不能 进行a++,其他用法和指针差不多
a的类型为int[2],p的类型为int *
a=数组的首地址
a = &a[0] = &a 只是地址相等 意义不一样
&a是一个数组指针 其类型为 int (*)[2];
a+1 相当于 a的地址+sizeof(int)*1
&a+1 相当于 a的地址 + sizeof(int [2])*1
int a[]={3,2,1};
int *p = a;
printf("p = %d\n",p);
printf("&a = %d\n",&a);
printf("a = %d\n",a);
printf("&a[0] = %d\n",&a[0]);
printf("&p = %d\n\n",&p);
printf("*p = %d\n",*p);
printf("a[0] = %d\n",a[0]);
1.2、 *(p+i) = p[i] = a[i] = *(a+i)
p+i = &p[i] = a+i = &a[i]
假设 p=200 则 p+n =200+n*size
size = p所指向的类型的大小
int a[]={1,2,3};
int *p = a;
printf("*(p+1) = %d\t",*(p+1));
printf("p[1] = %d\n",p[1]);
printf("*(a+1) = %d\t",*(a+1));
printf("a[1] = %d\n\n",a[1]);
printf("p = %d\n",p);
printf("p+1 = %d\n",p+1);
printf("&p[1] = %d\n",&p[1]);
printf("a+1 = %d\n",a+1);
printf("&a[1] = %d\n",&a[1]);
1.3、一维数组作为参数传入函数
数组作为参数传入函数时,函数只会生成一个指针来保存传入数组的首地址
即 fun(int a[ ]) = fun(int* a)
数组作为参数传入函数被修改后,main中也会被修改,
而一般变量传入则不会
void fun(int a[]){
a[0] = 6;
printf("f:sizeof(a) = %ld\n",sizeof(a));
printf("f:sizeof(int*) = %ld\n",sizeof(int*));
}
int main(){
int a[]={1,2,3,4,5};
int *p=a;
printf("m:sizeof(a) = %ld\n",sizeof(a));//5*4
fun(a);
printf("m:a[0] = %d\n",a[0]);//5*4
}
1.4、字符串
字符串必须以\0结束,计算字符串长度计算到 \0 为止
- sizeof
用于计算变量本身所占用的字节数,而不是变量指向的地址所占用的空间大小 - strlen
用于计算以 NULL (\0)结尾的字符串中字符的个数
/*
char name[] = “John” ---> name[4]=’\0’ ---> sizeof(name)=5
char name[20] = “John” ----> strlen(name) = 4 sizeof(name)=20
char a[] = “abc” 隐含\0
char b[] = {"abc"} 隐含\0
char c[] = {‘a’,’b’,’c’ }不隐含\0
*/
char a[]="hi";
char b[]={'h','i'};
char c[]={"hi"};
printf("strlen(a) = %d\n",strlen(a));
printf("strlen(b) = %d\n",strlen(b)); //可能统计垃圾数据
printf("strlen(c) = %d\n",strlen(c));
printf("sizeof(a) = %d\n",sizeof(a));
printf("sizeof(b) = %d\n",sizeof(b));
printf("sizeof(c) = %d\n",sizeof(c));
1.5、两种定义方式
char w[] = “hi” 被定义在栈区,可以被修改
char *w = “hi” 被定义在常量区,不能修改
二、指针与多维数组(整体思维)
2.1、int a[ ][3]={1,2,3,4,5,6}
int a[2][3]; int (* p)[3] = a;
不能写成int **p= a, 指针类型不同
a的类型int (* )[3]; a指向类型int [3] ;
*a的类型 int*; *a指向类型int;*a = a[0];
可将二维数组看做一维,只是里面元素还是一维数组
int a[][3]={1,2,3,4,5,6};
printf("sizeof(int* [3]) = %d\n",sizeof(int* [3]));
printf("sizeof(int [3]) = %d\n",sizeof(int [3]));
printf("sizeof(int) = %d\n",sizeof(int));
printf("a = %d\t",a);
printf("a+1 = %d\n",a+1);
printf("*a = %d\t",*a);
printf("*a+1 = %d\n",*a+1);
2.2、a[i][j] = *(a[i]+j) = *( *(a+i)+j)
/*
a是二维数组的名字,也是二维数组的首地址,将一维数组看做一个整体,那可将a看做一维数组
a的类型为int (*)[3] a中元素为 a[0] a[1]
a[0]是一维数组的名字,也是一维数组的首地址 a[0]的类型为int *
a[0]中元素为 a[0][0] a[0][1] a[0][2]
a = *a = a[0]= &a[0][0]
a+i = &a[i]; *(a+i) = a[i]
a[i][j] = *(a[i]+j) = *(*(a+i)+j)
*/
int a[2][3]={1,2,3,4,5,6};
printf("一维数组:\n");
printf("a = %d\n",a);
printf("*a = %d\n",*a);
printf("&a = %d\n",&a);
printf("a[0] = %d\n",a[0]);
printf("&a[0][0] = %d\n\n",&a[0][0]);
printf("二维数组:\n");
printf("a[1][2] = %d\n",a[1][2]);
printf("*((a[1])+2) = %d\n",*((a[1])+2));
printf("*(*(a+1)+2) = %d\n",*(*(a+1)+2));
2.3、int c[3][2][2]
int (* p)[2][2] = c;
假设 p=200 则 p+n =200+n* size
size = p所指向的类型的大小
p的类型 int(*) [2][2],指向类型 int [2][2]
*p的类型 int(*) [2],指向类型 int [2]
**p的类型 int(*); 指向类型int
int a[3][2][2]={0};
int (*p)[2][2] = a;
printf("sizeof(int [2][2]) = %d\n",sizeof(int [2][2]));
printf("sizeof(int [2]) = %d\n",sizeof(int [2]));
printf("sizeof(int) = %d\n",sizeof(int));
printf("p = %d\t",p);
printf("p+1 = %d\n",p+1);
printf("*p = %d\t",*p);
printf("*p+1 = %d\n",*p+1);
printf("**p = %d\t",**p);
printf("**p+1 = %d\n",**p+1);
2.4、c[i][j][k] = *( *( *(c+i)+j)+k)
c[i][j][k] = *((c[i][j]+k) = *(*(c[i]+j)+k)
//int a[3][2][2]={1,2,3,4,5,6,7,8,9,10,11,12};
int c[3][2][2]={{{1,2},{3,4}},
{{5,6},{7,8}},
{{9,10},{11,12}}};
printf("c[2][0][1] = %d\n",c[2][0][1]);
printf("*(*(*(c+2)+0)+1) = %d\n",*(*(*(c+2)+0)+1));
printf("*((c[2][0]+1) = %d\n",*((c[2][0]+1)));
printf("*(*(c[2]+0)+1) = %d\n\n",*(*(c[2]+0)+1));
2.5、多维数组作为参数传入函数
int c[3][2][2] ;
void fun(int (* c)[2][2]])
void fun(int ***c)
int a[2][3];
void fun(int (* a)[3]])
void fun(int **a)
void fun1(int ***p){
printf("p = %d\n",p);
printf("wrong:p+1 = %d\n\n",p+1);
}
void fun2(int (* p)[2][2]){
printf("p = %d\n",p);
printf("right:p+1 = %d\n",p+1);
}
int main(){
//int a[3][2][2]={1,2,3,4,5,6,7,8,9,10,11,12};
int c[3][2][2]={{{1,2},{3,4}},
{{5,6},{7,8}},
{{9,10},{11,12}}};
printf("c = %d\n",c);
printf("c+1 = %d\n\n",c+1);
fun1(c);
fun2(c);
}
能力有限,仅供参考
笔记是自己理解和总结的,根据一个印度老师的视频
原视频讲的通俗易懂,非常详细
封面是模拟程序在内存运行时的情况
封面和视频来源:https://www.bilibili.com/video/BV1bo4y1Z7xf?spm_id_from=333.999.0.0