前言
看前须知:
编译器为 vs2022
电脑为 64位
故:指针大小为 8字节
一维数组
整形数组
int main(void)
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16
printf("%d\n", sizeof(a+0));//8 指针
printf("%d\n", sizeof(*a));//4 元素
printf("%d\n", sizeof(a+1));//8 指针
printf("%d\n", sizeof(a[1]));//4 元素
printf("%d\n", sizeof(&a));//8 指针
printf("%d\n", sizeof(*&a));//16 整个数组大小 int(*P)[4] = &a
printf("%d\n", sizeof(&a+1));//8 指针,其地址是4后面空间的地址
printf("%d\n", sizeof(&a[0]));//8
printf("%d\n", sizeof(&a[0]+1));//8
return 0;
}
解析
- sizeof( ) 括号内单独放数组名,表示整个数组,故大小为 4(int) * 4(元素个数)=16
- 数组名(a)没单独放在sizeof的括号里,则数组名表示首元素的地址,a+0 相当于指针+整数 ,类型为指针,为8字节
- *a 同上,这里a为首元素的地址,解引用为首元素 1 ,1是int类型,4字节
- a+1同第二个解释
- a[1] <==> *(a + 1)
- &a 表示取出整个数组的地址,为指针,8字节
- *&a 为整个数组,16字节
- &a + 1 ,&a表示取出整个数组的地址,&a+1为指针+整数,+1表示跳过整个数组,如图
字符数组
1
int main(void)
{
char arr[] = { 'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//6
printf("%d\n", sizeof(arr + 0));//8
printf("%d\n", sizeof(*arr));//1
printf("%d\n", sizeof(arr[1]));//1
printf("%d\n", sizeof(&arr));//8
printf("%d\n", sizeof(&arr + 1));//8 +1跳整个数组
printf("%d\n", sizeof(&arr[0] + 1));//8
printf("%d", sizeof(arr[0]+1));//4
return 0;
}
解释:
1 - 7:与整型数组的解释差不多
8. 一个表达式具有两种属性:值属性,类型属性
sizeof() 的括号内部仅体现表达式的类型属性,即不进行运算,仅推测其结果的类型
所以:arr[0]+1,arr[0]属于char,1属于int,若计算则须整型提升为int类型,可推测表达式结果为int类型,为4字节
2
int main(void)
{
char arr[] = { 'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));//随机 strlen需要传地址 int my_strlen(const char* str)
printf("%d\n", strlen(arr+0));//随机
printf("%d\n", strlen(*arr));//err *arr = a,把a的ASCII码值传过去 97 不是个合法的地址
printf("%d\n", strlen(arr[1]));//err 不是地址为错误
printf("%d\n", strlen(&arr));//随机 char (*)[6] = &arr即使传过去的是数组的地址,对于strlen依然当作为数组首元素的地址
printf("%d\n", strlen(&arr+1));//随机 与上一个随机值差6
printf("%d\n", strlen(&arr[0]+1));//随机 与上上个差1
return 0;
}
解释:
strlen函数 int strlen (const char* p) 需要传地址过去 ,从传过去的地址开始往后直达遇到 \0 (0)
对于 char arr[] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’}; 数组只存有 该6个元素 无\0,故其会一直数到数组之外 直到遇到 \0 (0)
而由于不知道数组外存储的是什么,故无法得出准确值
3. a的ASKCII码值为97 为十六进制的61
3
char arr[] = “abcdef”; 数组有 7个元素 如下
char arr[] = "abcdef"; // 相当于 [a b c d e f \0]
printf("%d\n", sizeof(arr));//7
printf("%d\n", sizeof(arr + 0));//8
printf("%d\n", sizeof(*arr));//1
printf("%d\n", sizeof(arr[1]));//1
printf("%d\n", sizeof(&arr));//8
printf("%d\n", sizeof(&arr + 1));//8 +1跳一个数组 7字节
printf("%d\n", sizeof(&arr[0] + 1));//8 - 指向b
printf("%d", sizeof(arr[0] + 1));//4
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr + 0));//6
printf("%d\n", strlen(*arr));//err *arr = a,把a的ASCII码值传过去 97 不是个合法的地址
printf("%d\n", strlen(arr[1]));//err
printf("%d\n", strlen(&arr));//6 char (*)[6] = &arr即使传过去的是数组的地址,对于strlen依然认为是数组首元素的地址
printf("%d\n", strlen(&arr + 1));//随机
printf("%d\n", strlen(&arr[0] + 1));//5
4
char* p = "abcdef";
printf("%d\n", sizeof(p));//8 指针
printf("%d\n", sizeof(p + 1));//8 指针
printf("%d\n", sizeof(*p));//1 *p = a 为char类型 1字节
printf("%d\n", sizeof(p[0]));//1 p[0] <==> *(p+0)---------------------------$
printf("%d\n", sizeof(&p));//8 二级指针
printf("%d\n", sizeof(&p + 1));//8 二级指针 指向p后面
printf("%d\n", sizeof(&p[0]+1));//8 b的地址
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p + 1));//5
printf("%d\n", strlen(*p));//err
printf("%d\n", strlen(p[0]));//err
printf("%d\n", strlen(&p));//随机
printf("%d\n", strlen(&p + 1));//随机 与上面的随机值的关系无从得知,p的地址不知道是什么
//可能P的地址中有0 ,导致函数停止
printf("%d\n", strlen(&p[0] + 1));//5
解释
注:char *p = “abcdef”; 可看作 char arr[] = “abcdef”; char *p = arr;
p[0] < == > *(p+0) < == > 0[p]