开心的一天来写一篇博客,看见好多人都写完出了sizeof和strlen的不同,那么我今天也来随波逐一下,来写一下对它两的理解。
祝各位每天都能开开心心
也许该懂sizeof与strlen的不同了
sizeof 在学习操作符的时候,我们学习了 sizeof , sizeof 计算变量所占内存内存空间大小的,单位是 字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。 sizeof 只关注占用内存空间的大小,不在乎内存中存放什么数据。
我们要知道 sizeof 与strlen不同的是sizeof是一个操作符,而strlen是一个库函数,那么我就举一个反例来证明为何说sizeof是一个操作符而不是一个库函数了。
反例如下:
#include <stdio.h> int main() { int i = 10; printf("%d\n", sizeof i); printf("%d\n", sizeof (int)); return 0; }
我们的代码可以很好的运行,而且仔细一看我写的代码中,sizeof的用法。这里我可以不用在sizeof旁加括号,而是在后面直接放一个整形变量a,但是代码还是可以运行的。
另外sizeof我把一个int 放进括号里面也是可以算得出一个值的,足以证明上面所说的sizeof只关注占用内存空间的大小,不在乎内存中存放什么数据。
从这两个例子就可以知道sizeof是一个操作符而不是一个库函数。
那strlen呢,为何它和sizeof如此相像?
srlen函数 统计的是从 strlen 函数的参数 str 中这个地址开始向后, \0 之前字符串中字符的个数。 strlen 函数会⼀直向后找 \0 字符,直到找到为止,所以当字符串中没有\0时可能存在越界查找。
需要注意:strlen是对字符串进行统计个数的,而sizeof操作符,是对操作数的所占内存空间进行计算。
那么我们可以从这里大概总结一下,它两的不同。
一、sizeof是操作符,而strlen是一个对字符串统计个数的库函数需要使用头文件 string.h
二、sizeof计算的是操作数所占内存空间的大小,strlen是对字符串个数的统计,不能将其他类型的数据传参给strlen否则报错且需要字符串中含\0 ,否则返回的数为随机数。
三、sizeof不关注内存中存在什么,只在乎空间大小,且sizeof()括号中不参与运算;strlen函数关注字符串中有没有\0.
也许我们该多看些代码例子好好了解他们的不同了呀
sizeof求没有\0,的字符串
char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(arr)); //6 sizeof括号接单独数组名计算整个数组空间的大小 printf("%d\n", sizeof(arr + 0)); //4或8 因为arr+0代表首元素地址,这里表示一个地址, // 地址的内存空间取决于机器为什么环境,32位机器为4个字节 // 64位为8个字节 printf("%d\n", sizeof(*arr)); //1 *arr为数组第一个元素‘a’,char类型占一个字节。 printf("%d\n", sizeof(arr[1])); //1 代表第二个元素'b'. printf("%d\n", sizeof(&arr)); //4或8 取的是整个数组的地址,本质还是地址 printf("%d\n", sizeof(&arr + 1)); //4或8 整个数组地址加1,则跳过数组大小即6个字节,指向 // 的还是一处未知的地址 printf("%d\n", sizeof(&arr[0] + 1)); //4或8 代表第二个元素的地址,本质还是地址
这里我是64位机器的环境 所以地址环境的大小都为8.
strlen函数求没有\0,的字符串
char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", strlen(arr)); //随机值x 首元素地址传入函数,则从地址一直往后数,直到 遇 到\0 没有则返回随机值 printf("%d\n", strlen(arr + 0)); / /随机值x 与上方一样,首元素地址即'a'的地址。 printf("%d\n", strlen(*arr)); //无法运行 *arr为一个字符,而strlen需要的是一个地址 printf("%d\n", strlen(arr[1])); //与上方相同 printf("%d\n", strlen(&arr)); //随机值 代表首元素地址,后面没有\0。 printf("%d\n", strlen(&arr + 1)); //随机值x-6 首元素往后跳6个字节,往后没有\0。 printf("%d\n", strlen(&arr[0] + 1)); //随机值x-1 第二个元素开始往后,没有\0。
sizeof和strlen对有\0的字符串进行计算
strlen
char a[] = "abcdefghij"; printf("%d\n", strlen(a)); //10 从首元素开始不断往后计算直到遇到\0(计算不包括\0) //printf("%d\n", strlen(a[0])); //报错 a[0]为字符类型,无法运行,
printf("%d\n", strlen(a+0)); //10 首元素地址 printf("%d\n", strlen(&a)); //10 首元素地址 printf("%d\n", strlen(&a+1)); //随机值 从首元素跳了11个字节,往后的地址,没有\0,随机值 printf("%d\n", strlen(&a[0])); //10 首元素地址 printf("%d\n", strlen(a+1)); //9 第二个元素地址往后计算,遇到\0结束
sizeof
char a[] = "abcdefghij"; printf("%d\n", sizeof(a)); //11 sizeof括号单独放数组名代表计算这个数组大小,包括\0。 printf("%d\n", sizeof(a[0])); //1 计算首元素大小 printf("%d\n", sizeof(a+0)); //4或8 首元素地址,本质计算地址大小 printf("%d\n", sizeof(&a)); //4或8 同上 printf("%d\n", sizeof(&a+1)); //4或8 这里地址已经指向首元素地址往后11个字节的地址,但 本质还是计算一个地址 printf("%d\n", sizeof( a + 1)); //4或8 第二个元素的地址 printf("%d\n", sizeof(&a[0])); //4或8 首元素大小
也许我也要知道sizeof对二级数组的计算
int arr[2][4] = { 0 }; printf("%d\n", sizeof(arr)); //32 sizeof括号单独放数组名,二维数组也一样,求整个数组大小 printf("%d\n", sizeof(arr[0] + 1)); //4或8 arr[0]代表第一行的元素,+1则表示第二行的首元素 地址这里是计算地址的大小 printf("%d\n", sizeof(arr[0])); //16 sizeof括号内单独放arr[0],则计算第一排元素的大小 printf("%d\n", sizeof(arr[0][0])); //4 首元素的大小 printf("%d\n", sizeof(*(arr[0] + 1))); //4 (arr[0] + 1)表示第二行的首元素地址加*后即计算第二行 的首元素大小 printf("%d\n", sizeof(arr + 1)); //4或8 第二个行首地址元素的地址 printf("%d\n", sizeof(*(arr + 1))); //16 第二行元素的大小 printf("%d\n", sizeof(&arr[0] + 1)); //4 第二个元素的地址的大小 printf("%d\n", sizeof(*(&arr[0] + 1))); //16 &arr[0] + 1 表示第二行的首元素地址,第二行的元素的大小 printf("%d\n", sizeof(*arr)); //16 计算第一行元素大小 printf("%d\n", sizeof(arr[4])); //16 计算第5行元素的小,尽管数组未定义第5行,但是 // sizeof的特点就是不参与运算所以这里也是可以计算出来的
好了这篇文章已到末尾。祝各位每天都能开开心心