char arr[10]; //10 char
char* arr[10]; //10 指针(char*)
Point* arr[10]; //10 指针(Point*)
int******** arr[10];
char* a = "Hello";
char* b = "World";
//方式1:
char* arr[2]= {a,b};
//方式2:
char* arr[2];
arr[0]=a;
arr[1]=b;
struct Point
{
int x;
int y;
}
Point p; //8字节 一个结构体
Point arr[10]; //8字节 * 10 结构体数组
Point* arrPoint[10]; //4字节 * 10 结构体指针数组
int arr[] = {1,2,3,4,5,6,7,8,9,0};
int* p =&arr[0]; //数组首个元素地址
int* p = arr; //数组首个元素地址 跟上面的表达方式是一样的 也可以说是简写形式
int* p =&arr; //什么情况? --编译失败 (int(*)[10] 类型 不可以转换为 int* 类型)
//我们使用显式声明类型来躲避编译器检查
int* x = (int*)&arr;
//我们编译后发现 此时的x 值和上面的p值是一样的
//那么区别是什么呢
//当我们使用&arr 获得的类型就是 int(*)[10] 类型 也就是数组指针类型
//定义数组指针的写法
int(*px)[5];//一维数组指针 px 这里就是当前指针的名字
char(*px)[3]; //px 就是指针的名字
int(*px)[2][2]; //二维数组指针 px 就是指针的名字
char(*px)[3][3][3]; //三维数组指针 px 就是指针的名字
//思考:
//int *p[5] 与 int(*p)[5] 有什么区别?
int(*px1)p[5]; //一维数组指针
char(*px2)[3];
int(*px3)[2][2]; //二维数组指针
char(*px4)[3][3][3]; //三维数组指针
printf("%d %d %d %d\n",sizeof(px1),sizeof(px2),sizeof(px3),sizeof(px4));
// 4 4 4 4
px1 = (int (*)[5])1;
px2 = (char (*)[3])2;
px3 = (int (*)[2][2])3;
px4 = (char (*)[3][3][3])4;
int(*px1)p[5]; //一维数组指针
char(*px2)[3];
int(*px3)[2][2]; //二维数组指针
char(*px4)[3][3][3]; //三维数组指针
px1 = (int (*)[5])1;
px2 = (char (*)[3])1;
px3 = (int (*)[2][2])1;
px4 = (char (*)[3][3][3])1;
px1++; //int(4) *5 +20 =21
px2++; //char(1) *3 +3 =4
px3++; //int(4) *2 *2 +16 =17
px4++; //char(1) *3 *3 *3 +9 =10
printf("%d %d %d %d \n",px1,px2,px3,px4);
//第一种:
int arr[] = {1,2,3,4,5,6,7,8,9,0}
int(*px)[10]=&arr
//*px 是啥类型? => int[10] 数组类型
//px[0] 等价于 *px 所以 *px 也等于 int[10]数组
printf("%d %d \n",(*px)[0],px[0][0]);
px++; //后 (*px)[0]就访问整个数组地址后的地址内的数据
//第二种:
int arr[3][3] = {
{1,2,3},
{4,5,6},
{7,8,9}
};
//此时的 px指针 指向的 {1,2,3}这个数组的首地址
int(*px)[3] = &arr[0];
// *px -> 此时就是数组{1,2,3}本身
//越过第一个数组 此时px指针指向 {4,5,6}的首地址
px++;
printf("%d %d \n",(*px)[0],px[0][0]);
//这里打印的就是 4 4
int arr[] = {1,2,3,4,5,6,7,8,9,0};
int(*px)[2][2] = (int(*)[2][2])arr;
//思考:
// *px 是什么类型
//int[2][2] 二维数组
//(*px)[1][1]的值是什么? px[0][1][1]的值是什么
//4