2019/8/24 C语言回顾(6)
一、数组与指针
【1】一维数组与指针
一维数组内部关系
int a[3] = {1,2,3};
数组名:
1、可以代表整个数组
sizeof(a)代表整个数组的大小
2、数组的数组名是数组的首地址
注意:数组名是常量,不可以进行自加运算
a = &a[0]
a + 1 = &a[0] + 1 = &a[1]
*(a + 1) = *(&a[0] + 1) = *(&a[1]) = a[1];
结论:*(a + n) = a[n]
一维数组和指针
int *p = a;
p = a = &a[0]
p+1 = a + 1 = &a[1]
*(p+1) = a[1] = p[1]
结论:*(p + n) = a[n] = p[n]
【2】二维数组和指针
二位数组内部关系
int a[2][3] === int [3] a[2] //将二维数组的每一行看成一个元素
a === &a[0]
a + 1 == &a[0] + 1 == &a[1] //将a[1]可以看做一个一维数组的数组名
// a[1] ==== b
int b[3];
b = &b[0];
b + 1 = &b[1];
*(b + 1) = b[1];
//a[1][1]
*(a[1] + 1) = a[1][1]
*(*(a + 1) + 1) = a[1][1]
结论:*(*(a + i)+j) == a[i][j]
【3】二维数组和数组指针
int a[2][3] == int [3] a[2];
int [3] *p = a;//错误写法,编译器不认可
int (*p)[3] = a;
int (*)[3] , int [3]
p == a
p + 1 == a + 1
*(p + 1) == *(a+1) = a[1]
//将a[1]看做一个数组名
*(*(p+1) + 1) = a[1][1] = p[1][1]
结论:*(*(p + i) + j) = a[i][j] = p[i][j]
指针数组 数组指针
int *a[3] int (*p)[3]
【4】指针数组和二级指针
int *a[3]
int **p = a;
【5】指针数组指针
int a = 1,b = 2,c = 3;
int *p[3] = {&a,&b,&c};
int *(*q)[3] =&p; //为啥是&p
printf("%d\n",**(*q + 2));
int a,b,c;
int *p[3] = {&a,&b,&c};
int **q= p;
【6】数组指针数组
int a[3] = {1,2,3};
int b[3] = {4,5,6};
int c[3] = {7,8,9};
int (*x[3])[3]= {&a,&b,&c};//数组指针数组
printf("%d\n",*(*x[0] + 1));//打印2
二、字符型指针
char a;
char *p = &a;
char *str = "hello"; //本质是接收字符串首地址
注意:不可以通过*p的方式修改字符串内容,否则会出现段错误
因为是存放在rodata,只能读,不能写
三、void 空类型
1、函数的返回值
2、参数
3、void * 指针
void *型的指针可以接收任意类型的指针,但是在使用的时候需要强转为原来的数据类型
void a;//错误写法,void类型无法定义变量
void类型的大小为1个字节
四、const关键字
作用:将变量常量化 (不可修改的)
1、const int a;
int const a;
a不能跟在case后,本质还是变量
此时无法修改a的值,如果真要修改a的内容,可以通过指针的方式
2、const int *p; // int const *p;
此时不可以通过*p的方式修改内容,但是可以修改p的指向
3、int * const p;
此时可以通过*p的方式修改空间内容,但是无法修改指针p的指向
4、const int * const p;
无法修改任何内容