一维数组定义:
int arr[10];
int arr[]={1,2,3};
二维数组在内存也是连续存放;二维数组的首元素a[0]表示第一行的数组元素;
指针与数组的相关用算:
例1:
int a[] = { 1, 2, 3, 4 };
printf("%d\n",sizeof(a)); // 4*4=16
printf("%d\n", sizeof(a + 0)); // 4 首元素地址+0还是首元素地址,首元素的字节
printf("%d\n", sizeof(*a)); // 4 *a为首元素,
printf("%d\n", sizeof(a[1])); // 4 a[1]表示第二个元素
printf("%d\n",sizeof(&a)); // 4 注:&数组名时,数组名表示整个数组,取出的是数组的地址;地址都是4个字节
printf("%d\n", sizeof(*&a)); // 16 取出的是整个数组元素
printf("%d\n", sizeof(&a[0])); // 4 取出的是第一个元素的地址
printf("%d\n", sizeof(&a[0] + 1)); // 4 取出的是第二个元素的地址
重点:数组名表示整个数组有两种情况,其余情况都代表首元素:
(1):数组名单独放在sizeof内部时,相当于整个数组 ;
(2) :&数组名时,数组名表示整个数组;
例:sizeof(&a):表示数组的地址,而地址为4个字节,其意义体现在(&a+1)意味着跳过整个数组;而sizeof(&a+1)表示跳过整个数组指向数组之后,但其表示地址,值为4;
例2:
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", sizeof(arr));// 6 没有\0,共6个字节,表示整个数组,
printf("%d\n", sizeof(arr + 0)); // 4 表示第一个元素的地址
printf("%d\n", sizeof(*arr)); // 1 表示第一个元素
printf("%d\n", sizeof(arr[1])); // 1 表示第二个元素的值
printf("%d\n", sizeof(&arr));// 4 表示整个数组的地址
printf("%d\n", sizeof(&arr + 1)); // 4 表示跳过整个数组的地址
printf("%d\n", sizeof(&arr[0] + 1));// 4 表示第二个元素的地址
sizeof 求的是字节数,若有\0,则\0也算字节;
例3:
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", strlen(arr)); //随机值,没有\0,停不下
printf("%d\n", strlen(arr + 0)); //随机值,没有\0,停不下
printf("%d\n", strlen(*arr)); //错误,strlen函数参数为地址,不可为值
printf("%d\n", strlen(arr[1])); //错误,
printf("%d\n", strlen(&arr)); //随机值X,没有\0,停不下
printf("%d\n", strlen(&arr + 1)); //随机值X-6,没有\0,停不下,
printf("%d\n", strlen(&arr[0] + 1));//随机值X-1
strlen函数应传的是地址,不可为值;strlen求的是长度
例4:
char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); //7有\0,\0在sizeof计算时也为一个字节;
printf("%d\n", sizeof(arr + 0)); //4 arr + 0表示第一个元素的地址
printf("%d\n", sizeof(*arr)); //1 *arr表示第一个元素
printf("%d\n", sizeof(arr[1])); //1 arr[1]表示第二个元素,类型为char
printf("%d\n", sizeof(&arr)); //4 &arr表示整个数组的地址
printf("%d\n", sizeof(&arr + 1)); //4
printf("%d\n", sizeof(&arr[0] + 1)); //4 &arr[0] + 1表示第二个元素的地址
printf("%d\n", strlen(arr)); //6 有\0,求整个数组的长度
printf("%d\n", strlen(arr + 0)); //6
printf("%d\n", strlen(*arr)); //错误;
printf("%d\n", strlen(arr[1])); //错误;
printf("%d\n", strlen(&arr)); //6
printf("%d\n", strlen(&arr + 1)); //随机
printf("%d\n", strlen(&arr[0] + 1)); //5 &arr[0] + 1表示第二个元素的地址
例5:
char *p = "abcdef";
printf("%d\n", sizeof(p)); //4 有\0,p所指向字符串首元素,表示首元素的地址
printf("%d\n", sizeof(p + 1)); //4
printf("%d\n", sizeof(*p)); //1
printf("%d\n", sizeof(p[0])); //1
printf("%d\n", sizeof(&p)); //4
printf("%d\n", sizeof(&p + 1)); //4
printf("%d\n", sizeof(&p[0] + 1)); //4
printf("%d\n", strlen(p)); //6
printf("%d\n", strlen(p + 1)); //5
printf("%d\n", strlen(*p)); //错误
printf("%d\n", strlen(p[0])); //错误
printf("%d\n", strlen(&p)); //随机
printf("%d\n", strlen(&p + 1)); //随机
printf("%d\n", strlen(&p[0] + 1)); //5
解析:
printf(“%d\n”, strlen(&p)); //随机
printf(“%d\n”, strlen(&p + 1)); //随机
p指向a,p存放的是a的地址,p的类型为char*,&p取的是p的地址,&p取出的类型为char**,char* *pp二级指针,则strlen(&p)的值为随机,
strlen(&p + 1);&p+1表示跳到指针后面如图,(&p + 1)=1*sizeof(char*)即指针的类型;
例6:
int a[3][4] = { 0 };
printf("%d\n", sizeof(a)); //12*4=48 个字节
printf("%d\n", sizeof(a[0][0])); //4 int型,
printf("%d\n", sizeof(a[0])); //4*4=16 a[0]表示第一行的数组名,放在sizeof内部表示第一行数组的大小
printf("%d\n", sizeof(a[0] + 1)); //4 a[0]没有单独放在sizeof内部,则要降级变为第一行第一个元素的地址,再+1表示第一行第二个元素的地址;
printf("%d\n", sizeof(*(a[0] + 1))); //4 *(a[0] + 1))表示第一行第二个元素
printf("%d\n", sizeof(a + 1)); //4 a没有单独放在sizeof内部,则降级表示第一行的地址,再+1表示第二行的地址
printf("%d\n", sizeof(*(a + 1))); //16 *(a + 1))表示取出第二行的元素
printf("%d\n", sizeof(&a[0] + 1)); //4 a[0]表示第一行数组名,&a[0]表示取出第一行整个数组的地址,再+1表示第二行的地址
printf("%d\n", sizeof(*(&a[0] + 1))); //16 &a[0] + 1在sizeof中表示第二行的地址,再*表示第二行的元素
printf("%d\n", sizeof(*a)); //16 a没有单独放在sizeof中,表示第一行数组名,再解引用,表示第一行数组
printf("%d\n", sizeof(a[3])); //16 a[3]虽然越界,表示第四行数组名,在sizeof为第四行的元素,但由于sizeof内部不参与运算,不去取值,