#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16
printf("%d\n", sizeof(a + 0));//4,a已经隐式转换为指针int*
printf("%d\n", sizeof(*a)); //4,a已经隐式转换为int*再解引用得到int
printf("%d\n", sizeof(a+1));//4,a已经隐式转换为指针int*再+1还是int*
printf("%d\n", sizeof(a[1]));//4,a[1]= *(a+1)还是指针int*
printf("%d\n", sizeof(&a));//4,&a是一个数组指针int(*)[4]
printf("%d\n", sizeof(*&a));//16,&a是数组指针,再次解引用从这个地址开始取int(*)[4]类型对应的的字节
printf("%d\n", sizeof(&a+1));//4,数组指针+1还是指针
printf("%d\n", sizeof(&a[0]));//4,得到int*
printf("%d\n", sizeof(&a[0]+1));//4,指针+1还是int*
return 0;
}
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6,arr是字符数组
printf("%d\n", sizeof(arr+0));//4,得到一个char*
printf("%d\n", sizeof(*arr));//1,得到一个char
printf("%d\n", sizeof(arr[1]));//1,得到一个char
printf("%d\n", sizeof(&arr));//4,得到一个数组指针char(*)[6]
printf("%d\n", sizeof(&arr+1));//4,数组指针+1还是指针
printf("%d\n", sizeof(&arr[0]+1));//4,&arr[0]得到一个char*,+1还是指针
printf("%d\n", strlen(arr));//针对一个不是字符串的字符数组进行strlen操作,未定义行为
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));//*arr得到的是'a'=>97,strlen就把97当成了一个地址,计算机上对应的97的地址,大概率无法访问。
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));
return 0;
}
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7,sizeof是求内存的大小,要包含\0
printf("%d\n", sizeof(arr+0));//4,arr + 0 => char*
printf("%d\n", sizeof(*arr));//1,*arr => char
printf("%d\n", sizeof(arr[1]));//1,arr[1] = * (arr + 1) => char
printf("%d\n", sizeof(&arr));//4,&arr=>char(*)[7]
printf("%d\n", sizeof(&arr+1));//4,指针+1还是指针
printf("%d\n", sizeof(&arr[0]+1));//4,&arr[0] => char*, + 1还是char*
printf("%d\n", strlen(arr));//6,计算字符串长度。不算\0
printf("%d\n", strlen(arr+0));//6
printf("%d\n", strlen(*arr));//ub,*arr得到char,char和char*类型不匹配,按理说是要编译失败的
printf("%d\n", strlen(arr[1]));//ub,理由同上
printf("%d\n", strlen(&arr));//6,&arr=>char(*)[7],和char*类型不匹配,按理说是要编译失败的
//&arr碰巧和arr得到的地址值是相同的值。这个结果能算对,纯属巧合
printf("%d\n", strlen(&arr+1));//ub,&arr+1跳过了整个数组,访问数组后面的空间,非法内存
printf("%d\n", strlen(&arr[0]+1));//5,&arr[0] => char* , char* + 1跳过一个char
return 0;
}
int main()
{
char* p = "abcdef";
printf("%d\n", sizeof(p));//4,p=>char*
printf("%d\n", sizeof(p+1));//4,p+1还是char*
printf("%d\n", sizeof(*p));//1,*p=char
printf("%d\n", sizeof(p[0]));//1,p[0]=*(p+0)=>char
printf("%d\n", sizeof(&p));//4,p=>char*,&p=>char**
printf("%d\n", sizeof(&p+1));//4,&p + 1还是char**
printf("%d\n", sizeof(&p[0]+1));//4,&p[0]=>char*,+1还是char*
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p+1));//5,从p+1的位置往后找5个元素得到\0;
printf("%d\n", strlen(*p));//ub,*p=>char,和char*类型不匹配
printf("%d\n", strlen(p[0]));//ub,同上
printf("%d\n", strlen(&p));//ub,&p=>char**
printf("%d\n", strlen(&p+1));//ub
printf("%d\n", strlen(&p[0]+1));//5,&p[0]=>p+1
return 0;
}
int main()
{
int a[3][4] = { 0 };//所谓二维数组,本质是一个一维数组,里面的每个元素又是一个一维数组
printf("%d\n", sizeof(a));//48,12个元素,每个元素4个字节
printf("%d\n", sizeof(a[0][0]));//4
printf("%d\n", sizeof(a[0]));//16,a[0]=>int[4]
printf("%d\n", sizeof(a[0]+1));//4,a[0]=>int[4]再+1,就隐式转换成指针int*
printf("%d\n", sizeof(*(a[0]+1)));//4,int*解引用得到int,*(a[0]+1)=>a[0][1]
printf("%d\n", sizeof(&a[0]+1));//4,a[0]=int[4],&a[0]=>int(*)[4],再+1还是指针
printf("%d\n", sizeof(*(&a[0]+1)));//16,上面解引用得到int[4]
printf("%d\n", sizeof(*a));//16,*a=>*(a+0)=>a[0],得到int[4]
printf("%d\n", sizeof(a[3]));//16,sizeof是一个运算符,特点是编译期求值
//“数组下标越界未定义行为”前提条件是内存访问越界,这是程序运行时的行为
return 0;
}
关于 sizeof 和 strlen 的各种情况
最新推荐文章于 2021-02-06 13:58:01 发布