一、sizeof与strlen的对比
sizeof | strlen |
sizeof是单目操作符 | strlen是库函数,使用需要包含头文件string.h |
sizeof计算操作数所占用的内存,单位是字节 | strlen是求字符串长度,统计的是\0之前字符的个数 |
不关注内存中存放什么数据 | 关注内存总是否有\0,如果没有就会持续 往后找,甚至越界 |
sizeof不挑类型 | 指针针对字符串 |
strlen是指针且针对字符串,strlen 原型是size_t strlen(const char *str);
数组名:数组名一般表示数组首元素地址但有两个例外;
1.siziof(数组名):数组名表示整个数组,计算的是整个数组的大小,单位字节。
2.&数组名:数组名表示整个数组,取出的是整个数组的地址。
指针的大小:指针在x86环境下大小为4,在x64环境下为8,单位字节。
一维数组:
int main()
{
int a[] = { 1, 2, 3, 4 };//arr数组中有四个元素每个元素都是int类型(占四个字节)
printf("%zd\n", sizeof(a));//sizeof(a)取出的是整个数组的大小16
printf("%zd\n", sizeof(a+0));//a+0中的a数组名表示数组首元素地址,地址即指针,指针大小4/8
printf("%zd\n", sizeof(*a));//数组首元素地址解引用,表示数组首元素,4
printf("%zd\n", sizeof(a+1));//第二个元素的地址,4/8
printf("%zd\n", sizeof(a[1]));//第二个元素,4
printf("%zd\n", sizeof(&a));//整个数组的地址,地址即指针4/8
printf("%zd\n", sizeof(&a + 1));//地址,4/8
printf("%zd\n", sizeof(&a[0]));//取出数组首元素地址,4/8
printf("%zd\n", sizeof(&a[0] + 1));//数组第二个元素的地址4/8
return 0;
}
字符数组:
代码1:
char arr[] = { 'a','b', 'c', 'd', 'e', 'f' };
printf("%zd\n", sizeof(arr));//整个数组的大小6
printf("%zd\n", sizeof(arr + 0));//指针4/8
printf("%zd\n", sizeof(*arr));//数组首元素,
printf("%zd\n", sizeof(arr + 1));//第二个元素的地址,4/8
printf("%zd\n", sizeof(arr[1]));//第二个元素,1
printf("%zd\n", sizeof(&arr));//整个数组的地址,地址即指针4/8
printf("%zd\n", sizeof(&arr + 1));//地址,4/8
printf("%zd\n", sizeof(&arr[0] + 1));//数组第二个元素的地址4/8
代码2:
char arr[] = { 'a','b', 'c', 'd', 'e', 'f' };printf("%d\n", strlen(arr));//随机
printf("%d\n", strlen(arr+0));//随机
//printf("%d\n", strlen(*arr));//err报错
printf("%d\n", strlen(arr+1));//随机
printf("%d\n", strlen(&arr));//取出整个数组的地址,但还是从首元素地址开始,随机
代码3:
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//计算整个数组的大小,7(abcdef\0)
printf("%d\n", sizeof(arr+0));//arr数组首元素地址,arr+0还是首元素地址,地址即指针 ,4/8
printf("%d\n", sizeof(*arr));//arr数组首元素地址,*解引用后为a,等同arr[0],第一个元素,1
printf("%d\n", sizeof(arr[1]));//数组第二个元素,1
printf("%d\n", sizeof(&arr));//整个数组的地址类型为int (*)[7],4/8
printf("%d\n", sizeof(&arr+1));//跳过整个arr地址,指向f后的地址,指针,4/8
printf("%d\n", sizeof(&arr[0]+1));//取出第一个元素的地址后+1,即指向第二个元素的地址,指针,4/8
代码4:
char arr[] = "abcdef";
printf("%d\n", strlen(arr));//数组名,数组首元素地址,6
printf("%d\n", strlen(arr+0));//数组首元素地址,6
// printf("%d\n", strlen(*arr));//数组首元素地址解引用,数组首元素a,a的ascll值为97,报错arr
// printf("%d\n", strlen(arr[1]));//第二个元素,b,98,arr
printf("%d\n", strlen(&arr));//取出整个数组的地址,但还是从首元素地址a的地址开始,6
printf("%d\n", strlen(&arr+1));//跳过整个数组的地址,随机
printf("%d\n", strlen(&arr[0]+1));//取出第一个元素的地址+1,指向第二个元素,5
代码5:
char* p = "abcdef";
printf("%zd\n", sizeof(p));//p中存放字符串首元素地址的指针,4/8
printf("%zd\n", sizeof(p + 1));//'b'的地址,指针,4/8
printf("%zd\n", sizeof(*p));//首元素a,1
printf("%zd\n", sizeof(p[0]));//首元素,1
printf("%zd\n", sizeof(&p));//&p是二级指针,char**类型,4/8
printf("%zd\n", sizeof(&p + 1));//4/8
printf("%zd\n", sizeof(&p[0] + 1));//取字符串首元素地址+1,'b'的地址,4/8
代码6:
char* p = "abcdef";
printf("%zd\n", strlen(p));//p中存放字符串首元素地址,6
printf("%zd\n", strlen(p+1));//'b'的地址,5
// printf("%zd", strlen(*p));//首元素a,ascll 97,arr
// printf("%zd\n", strlen(p[0]));//同*p,arr
printf("%zd\n", strlen(&p));//二级指针,p的地址,随机
printf("%zd\n", strlen(&p+1));//随机
printf("%zd\n", strlen(&p[0]+1));//取首元素地址+1,同p+1,5
二维数组:
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//计算整个数组的大小,48
printf("%d\n", sizeof(a[0][0]));//4
printf("%d\n", sizeof(a[0]));//a[0]是第一行,一维数组的数组名,sizeof(数组名)计算一维数组的大小,16
printf("%d\n", sizeof(a[0]+1));//重点,a[0]一维数组数组名,表示a[0][0]的地址,指针,4/8
printf("%d\n", sizeof(*a[0]+1));//第二行第二个元素,4
printf("%d\n", sizeof(a+1));//a[0][1]的地址,4/8
printf("%d\n", sizeof(*(a+1)));//*(a+1)等同于a[1],是第二行数组名,计算的是第二行的大小,16
printf("%d\n", sizeof(&a[0]+1));//取一维数组a[0]的地址,+1即第二行数组a[1]的地址,4/8
printf("%d\n", sizeof(*(&a[0]+1)));//重点,访问第二行,计算第二行的大小,16
printf("%d\n", sizeof(*a));//第一行的地址,*a就是第一行等同a[0],16
printf("%d\n", sizeof(a[3]));//重点,sizeof只计算类型,不参与真实计算,故不存在越界,计算第四行的大小,16