sizeof和strleen的对比和练习
一.sizeof
-
sizeof是用于计算变量或类型所占内存内存空间⼤⼩的操作符,单位是字节。
注意:sizeof是操作符,不是库函数!!! -
sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据。
-
sizeof不进行计算。
-
sizeof返回值是size_t类型。
下面举一个例子:
int main()
{
int m = 2;
int n = 10;
printf("%zd\n", sizeof(n));
printf("%zd\n", sizeof n);
printf("%zd\n", sizeof(int));
printf("%zd\n", sizeof(m + n));
return 0;
}
运行截图如下:

二. strlen
-
strlen是用于计算字符串长度的库函数。使用时需要包含头文件string.h。
-
strlen是从给定地址开始,向后统计 ‘\0’ 之前字符串中字符的个数。由此可见,strlen是关注内存中所存放数据的。
-
strlen所统计的字符串中必须存在’\0’,否则会出现越界访问情况。
-
strlen返回值是size_t类型。
下面举一个例子:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = { "abcdefg" };
char arr2[] = { 'a','b','c','d','e','f','g','\0'};
char arr3[] = { 'a','b','c','d','e','f','g'};
printf("%zd\n", strlen(arr1));
printf("%zd\n", strlen(arr2));
printf("%zd\n", strlen(arr3));
return 0;
}
运行截图如下:

三.sizeof和strleen练习
做练习前,先补充一些知识:
数组名的含义:
-
sizeof(数组名),这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩。
-
&数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址。
-
除此之外所有的数组名都表⽰⾸元素的地址。
内存大小:
1.char占一个字节。
2.int占4个字节。
3.地址占4或8个字节。
下面举一个例子:
int main()
{
int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%zd\n", sizeof(a));//打印数组a的内存大小
printf("%p\n", a);//打印a的首元素的地址
printf("%p\n", a+1);//相比a多4
printf("%p\n", &a);//打印整个数组a的地址
printf("%p\n", &a+1);//相比&a多40
printf("%d\n", a[0]); //打印a的首元素
return 0;
}
运行截图如下:

- 一维数组
试题如下:
int main()
{
int a[] = { 1,2,3,4 };
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof(a + 0));
printf("%zd\n", sizeof(*a));
printf("%zd\n", sizeof(a + 1));
printf("%zd\n", sizeof(a[1]));
printf("%zd\n", sizeof(&a));
printf("%zd\n", sizeof(*&a));
printf("%zd\n", sizeof(&a + 1));
printf("%zd\n", sizeof(&a[0]));
printf("%zd\n", sizeof(&a[0] + 1));
return 0;
}
解析如下:
int main()
{
int a[] = { 1,2,3,4 };
printf("%zd\n", sizeof(a));//打印整个数组a的大小
printf("%zd\n", sizeof(a + 0));//a+0放在一起,a表示数组首元素地址,a+0打印数组首元素地址大小
printf("%zd\n", sizeof(*a));//a在这里表示数组首元素地址,相当于&a[0],*a就相当于a[0],打印第一个元素的内存大小
printf("%zd\n", sizeof(a + 1));//与a+0同理,a+1放在一起,a表示数组首元素地址,a+1打印数组第二个元素地址大小
printf("%zd\n", sizeof(a[1]));//与a[0]同理,打印数组第二个元素大小
printf("%zd\n", sizeof(&a));//打印整个数组a的地址大小
printf("%zd\n", sizeof(*&a));//a先与&结合,&a为整个数组a的地址,则*&a就是整个数组a,打印整个数组a的大小
printf("%zd\n", sizeof(&a + 1));//与&a同理,打印整个数组a后面的地址大小
printf("%zd\n", sizeof(&a[0])); //打印第一个元素的地址大小
printf("%zd\n", sizeof(&a[0] + 1));//与&a同理,打印第二个元素的地址大小
return 0;
}
运行截图如下:

- 字符数组
试题如下:
这里为了观看代码方便,所以arr重复定义了,
运行结果截图,我会分开放置.
#include<stdio.h>
#include<string.h>
int main()
{
//代码1:
char arr[] = { 'a','b','c','d','e','f' };
printf("%zd\n", sizeof(arr));
printf("%zd\n", sizeof(arr + 0));
printf("%zd\n", sizeof(*arr));
printf("%zd\n", sizeof(arr[1]));
printf("%zd\n", sizeof(&arr));
printf("%zd\n", sizeof(&arr + 1));
printf("%zd\n", sizeof(&arr[0] + 1));
printf("%zd\n", strlen(arr));
printf("%zd\n", strlen(arr + 0));
printf("%zd\n", strlen(*arr));
printf("%zd\n", strlen(arr[1]));
printf("%zd\n", strlen(&arr));
printf("%zd\n", strlen(&arr + 1));
printf("%zd\n", strlen(&arr[0] + 1));
//代码2:
char arr[] = "abcdef";
printf("%zd\n", sizeof(arr));
printf("%zd\n", sizeof(arr + 0));
printf("%zd\n", sizeof(*arr));
printf("%zd\n", sizeof(arr[1]));
printf("%zd\n", sizeof(&arr));
printf("%zd\n", sizeof(&arr + 1));
printf("%zd\n", sizeof(&arr[0] + 1));
printf("%zd\n", strlen(arr));
printf("%zd\n", strlen(arr + 0));
printf("%zd\n", strlen(*arr));
printf("%zd\n", strlen(arr[1]));
printf("%zd\n", strlen(&arr));
printf("%zd\n", strlen(&arr + 1));
printf("%zd\n", strlen(&arr[0] + 1));
//代码3:
char* p = "abcdef";
printf("%zd\n", sizeof(p));
printf("%zd\n", sizeof(p + 1));
printf("%zd\n", sizeof(*p));
printf("%zd\n", sizeof(p[0]));
printf("%zd\n", sizeof(&p));
printf("%zd\n", sizeof(&p + 1));
printf("%zd\n", sizeof(&p[0] + 1));
printf("%zd\n", strlen(p));
printf("%zd\n", strlen(p + 1));
printf("%zd\n", strlen(*p));
printf("%zd\n", strlen(p[0]));
printf("%zd\n", strlen(&p));
printf("%zd\n", strlen(&p + 1));
printf("%zd\n", strlen(&p[0] + 1));
return 0;
}
解析如下:
#include<stdio.h>
#include<string.h>
int main()
{
//代码1:
char arr[] = { 'a','b','c','d','e','f' };//没有'\0'
printf("%zd\n", sizeof(arr));//打印整个数组arr的内存大小——6
printf("%zd\n", sizeof(arr + 0));//arr+0放在一起,arr表示数组首元素地址,arr+0打印数组首元素地址大小——4或8
printf("%zd\n", sizeof(*arr));//arr在这里表示数组首元素地址,相当于&arr[0],*arr就相当于arr[0],打印第一个元素的内存大小——1
printf("%zd\n", sizeof(arr[1]));//与arr[0]同理,打印数组第二个元素大小——1
printf("%zd\n", sizeof(&arr));//打印整个数组arr的地址大小——4或8
printf("%zd\n", sizeof(&arr + 1));//与&arr同理,打印整个数组arr后面的地址大小——4或8
printf("%zd\n", sizeof(&arr[0] + 1));//相当于a+1,打印第二个元素的地址大小——4或8
printf("%zd\n", strlen(arr));//arr表示数组首元素地址,这里表示从数组首元素地址开始,向后统计元素个数,直到遇到'\0',但数组中没有'\0',故越界访问打印随机值
printf("%zd\n", strlen(arr + 0));//与arr同理,打印随机值
//printf("%zd\n", strlen(*arr));//*arr表第一个元素,这里把元素作为地址传给strlen,而strlen需要传指针,会打印错误(已注释)
//printf("%zd\n", strlen(arr[1]));//与*arr同理,会打印错误(已注释)
printf("%zd\n", strlen(&arr));//&arr表示整个数组的地址,这里仍表示从数组首元素地址开始,向后统计元素个数,直到遇到'\0',但数组中没有'\0',故越界访问打印随机值
printf("%zd\n", strlen(&arr + 1));//与&arr同理,&arr+1表示整个数组后面的地址,这里表示从整个数组后面的地址开始,向后统计元素个数,直到遇到'\0',故越界访问打印随机值
printf("%zd\n", strlen(&arr[0] + 1));//与arr+0同理,&arr[0]+1相当于arr+1,表示数组第二个元素的地址,即从第二个元素的地址开始,向后统计元素个数,直到遇到'\0',但数组中没有'\0',故越界访问打印随机值
//代码2:
char arr[] = "abcdef";//有'\0'
printf("%zd\n", sizeof(arr));//打印整个数组arr的内存大小(包括'\0',后面同理)——7
printf("%zd\n", sizeof(arr + 0));//arr+0放在一起,arr表示数组首元素地址,arr+0打印数组首元素地址大小——4或8
printf("%zd\n", sizeof(*arr));//arr在这里表示数组首元素地址,相当于&arr[0],*arr就相当于arr[0],打印第一个元素的内存大小——1
printf("%zd\n", sizeof(arr[1]));//与arr[0]同理,打印数组第二个元素大小——1
printf("%zd\n", sizeof(&arr));//打印整个数组arr的地址大小——4或8
printf("%zd\n", sizeof(&arr + 1));//与&arr同理,打印整个数组arr后面的地址大小——4或8
printf("%zd\n", sizeof(&arr[0] + 1));//相当于a+1,打印第二个元素的地址大小——4或8
printf("%zd\n", strlen(arr));//arr表示数组首元素地址,这里表示从数组首元素地址开始,向后统计元素个数,直到遇到'\0'(不包括'\0',后面同理)。——6
printf("%zd\n", strlen(arr + 0));//与arr同理,这里表示从数组首元素地址开始,向后统计元素个数,直到遇到'\0'。——6
//printf("%zd\n", strlen(*arr));//*arr表第一个元素,这里把元素作为地址传给strlen,而strlen需要传指针,会打印错误(已注释)
//printf("%zd\n", strlen(arr[1]));//与*arr同理,会打印错误(已注释)
printf("%zd\n", strlen(&arr));//&arr表示整个数组的地址,这里仍表示从数组首元素地址开始,向后统计元素个数,直到遇到'\0'。——6
printf("%zd\n", strlen(&arr + 1));//与&arr同理,&arr+1表示整个数组后面的地址,这里表示从整个数组后面的地址开始,向后统计元素个数,直到遇到'\0',越界访问打印随机值。
printf("%zd\n", strlen(&arr[0] + 1));//与arr+0同理,&arr[0]+1相当于arr+1,表示数组第二个元素的地址,即从第二个元素的地址开始,向后统计元素个数,直到遇到'\0'。——5
//代码3:
char* p = "abcdef";//相当于char* p[]={"abcdef"},但不等于
printf("%zd\n", sizeof(p));//p存放的是字符串的地址,打印地址大小——4或8
printf("%zd\n", sizeof(p + 1));//p是指针,存放的是地址,p+1存放的还是地址,是地址就是4或8
printf("%zd\n", sizeof(*p));//对指针解引用,打印字符串首元素内存大小。——1
printf("%zd\n", sizeof(p[0]));//表打印字符串内第一个元素大小——1
printf("%zd\n", sizeof(&p));//p是指针,对指针去地址还是指针,里面存放的仍然是地址,是地址就打印4或8.
printf("%zd\n", sizeof(&p + 1));//与&p同理,打印地址大小——4或8
printf("%zd\n", sizeof(&p[0] + 1));//p[0]表字符串内第一个元素,&p[0]就表示字符串内第一个元素的地址,&p[0] + 1表第二个元素的地址,打印地址大小——4或8
printf("%zd\n", strlen(p));//p字符串首元素地址,打印从字符串首元素到’\0’的元素个数——6
printf("%zd\n", strlen(p + 1));//p+1字符串第二个元素地址,打印从字符串第二个元素到’\0’的元素个数——5
//printf("%zd\n", strlen(*p));//*p表第一个元素,这里把元素作为地址传给strlen,而strlen需要传指针,会打印错误(已注释)
//printf("%zd\n", strlen(p[0]));//p[0]相当于*p,会打印错误(已注释)
printf("%zd\n", strlen(&p));//对整个字符串取地址,打印整个字符串元素个数——6
printf("%zd\n", strlen(&p + 1));//与&p同理,打印整个字符串之后元素大小——越界访问随机值
printf("%zd\n", strlen(&p[0] + 1));//与p+0同理,&p[0]+1相当于arr+1,表示数组第二个元素的地址,即从第二个元素的地址开始,向后统计元素个数,直到遇到'\0'。——5
return 0;
}
运行截图如下:
代码1:

代码2:

代码3:

- 二维数组
试题如下:
#include<stdio.h>
#include<string.h>
int main()
{
int a[3][4] = { 0 };
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof(a[0][0]));
printf("%zd\n", sizeof(a[0]));
printf("%zd\n", sizeof(a[0] + 1));
printf("%zd\n", sizeof(*(a[0] + 1)));
printf("%zd\n", sizeof(a + 1));
printf("%zd\n", sizeof(*(a + 1)));
printf("%zd\n", sizeof(&a[0] + 1));
printf("%zd\n", sizeof(*(&a[0] + 1)));
printf("%zd\n", sizeof(*a));
printf("%zd\n", sizeof(a[3]));
return 0;
}
解析如下:
#include<stdio.h>
#include<string.h>
int main()
{
int a[3][4] = { 0 };//3行4列
//0 0 0 0
//0 0 0 0
//0 0 0 0
printf("%zd\n", sizeof(a));//表示整个数组,打印整个数组内存大小——48
printf("%zd\n", sizeof(a[0][0]));//打印第一行第一列元素大小——4
printf("%zd\n", sizeof(a[0]));//a[0]表示第一行的元素,打印第一行内存大小——16
printf("%zd\n", sizeof(a[0] + 1));//a[0]+1表示第一行第二个元素的地址,打印地址大小——4或8
printf("%zd\n", sizeof(*(a[0] + 1)));//*(a[0] + 1)表示第一行第二个元素的元素,打印4
printf("%zd\n", sizeof(a + 1));//表示数组第二行元素地址,打印第二行地址大小——4或8
printf("%zd\n", sizeof(*(a + 1)));//表示数组第二行元素,打印第二行内存大小——16
printf("%zd\n", sizeof(&a[0] + 1));//相当于a+1,打印第二行地址大小——4或8
printf("%zd\n", sizeof(*(&a[0] + 1)));//相当于 *(a + 1),打印第二行内存大小——16
printf("%zd\n", sizeof(*a));//表示数组首元素,即第一行元素,打印第一行内存大小——16
printf("%zd\n", sizeof(a[3]));//越界访问,但仍能根据规律,打印16
return 0;
}
运行截图如下:

四.总结
-
sizeof是操作符,sizeof计算操作数所占内存的⼤⼩,单位是字节,不关注内存中存放什么数据.
-
strlen是库函数,使⽤需要包含头⽂件 string.h,srtlen是求字符串⻓度的,统计的是 \0 之前字符的个数,关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可能越界。
第一次写,如果有什么问题请见谅,我只是写下自己所学的部分。
当然,有问题的话也欢迎批评指正,谢谢!

635

被折叠的 条评论
为什么被折叠?



