前言
相信很多老铁第一次接触C语言的时候,脑子里会莫名的把strlen和sizeof相混淆,这里就是来给大家区分一下 strlen 和 sizeof。
本篇文章所有代码链接:test_6_20 · hunter/C_NS - 码云 - 开源中国 (gitee.com)
strlen:
- 一个库函数(是C语言本身自带的函数)。
- 使用函数的时候需要引用头文件#include <stdio.h>。
- 作用是求字符串长度的函数,遇到\0就停止。
sizeof:
- 单目操作符、关键字
- 计算变量/类型/数组所占空间的大小。
- 单位是字节(byte)。
- sizeof是编译的时候确定大小的。
下面我们通过一些习题来带领着老铁深入了解。
首先我们这里要知道数组名是什么?
数组名的意义:
- sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
- 除此之外所有的数组名都表示首元素的地址。
PS:
- sizeof内部的数字是不进行真实的运算的,只是根据其类型计算其大小。
- 二维数组在运用时可以想象成一维数组 一行就是一个元素。
- 对于地址的大小,在32位机器上是4大小,在64位的机器是8字节大小。
- 字符串是在结尾处有'\0'结尾的,strlen是以'\0'为结束标志的,当遇到'\0'才会停止,没有遇到将会往后无限查找,直到在后面的未知空间找到'\0'然后停止。
- sizeof是不以'\0'为结束标志的(在编译的的时候会确定大小)反而会把其当成一个数组的元素加到其总和里面。
温馨提示:下面代码每一行都有解释,请各位自行观看。
sizeof
int main()
{
int a[] = { 1,2,3,4 };//4*4 = 16
printf("%d\n", sizeof(a));//16 sizeof(数组名)-计算的是数组总大小-单位是字节-16
printf("%d\n", sizeof(a + 0));//4/8 数组名这里表示收元素的值,a+8还是首元素地址,地址的大小就是4/8个字节
printf("%d\n", sizeof(*a));//4 数组名表示首元素地址,*a就是首元素,sizeof(*a)就是4
printf("%d\n", sizeof(a + 1));//4/8 数组名这里表示收元素的值,a+1第2个元素的地址,地址的大小就是4/8个字节
printf("%d\n", sizeof(a[1])); //4 第2个元素的大小
printf("%d\n", sizeof(&a));//4/8 &a取出的是数组的地址,但是数组的地址那也是地址,地址的大小就是4/8个字节
printf("%d\n", sizeof(*&a));//16 &a数组的地址,数组的地址解引用访问的数组,sizeof计算的就是数组的大小单位是字节
printf("%d\n", sizeof(&a + 1));//4/8 &a是数组的地址,&a+1虽然地址跳过整个数组,但还是地址,所以是4/8个字节
printf("%d\n", sizeof(&a[0]));//4/8 &a[0]是第一个元素的地址
printf("%d\n", sizeof(&a[0] + 1));//4/8 &a[0]+1 是第二个元素的地址
return 0;
}
int main()
{
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("%d\n", sizeof(arr) );//6 sizeof计算机的是数组大小,6*1 = 6字节
printf("%d\n", sizeof(arr + 0));//4/8 arr是首元素的地址,arr+8还是首元素的地址地址的大小是4/8字节
printf("%d\n", sizeof(*arr));//arr是首元素的地址,*arr就是首元素,首元素是字符大小是一个字节
printf("%d\n", sizeof(arr[1])); //1
printf("%d\n", sizeof(&arr)); //&arr虽然是数组的地址,但还是地址,地址大小是4 / 8个字节
printf("%d\n", sizeof(&arr + 1));//&arr+1是跳讨整个数组后的地址.地址大小是4/8个字节
return 0;
}
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7 sizeof(arr)计算的数组的大小,单位是字节:7
printf("%d\n", sizeof(arr + 0));//4/8 计算的是地址的大小-arr + 0是首元素的地址
printf("%d\n", sizeof(*arr));//1 *arr是首元素,sizeof(*arr)计算首元素的大小
printf("%d\n", sizeof(arr[1]));//1 arr[1]是第二个元素,sizeof(arr[1])计算的是第二个元素的大小
printf("%d\n", sizeof(&arr));//4/8 &arr虽然是数组的地址,但也是地址,所以是4/8个字节
printf("%d\n", sizeof(&arr + 1));//4/8 &arr+1是跳过整个数组后的地址,但也是地址
printf("%d\n", sizeof(&arr[0] + 1));//4/8 &arr[0]+1第二个元素的地址
return 0;
}
int main()
{
//二维数组
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]));//16 a[0]相当于第一行做为一维数组的数组名,
//sizeof(arr[e])把数组名单独放在sizeof()内,计算的是第一行的大小
printf("%d\n", sizeof(a[0] + 1));//4/8 - a[0]是第一行的数组名,数组名此时是首元素的地址,a[0]其实就是第一行第一个元素的地址
//所以a[0]+1就是第一行第二个元素的地址-地址大小是4/8个字节
printf("%d\n", sizeof(*(a[0] + 1)));//4 -*(a[0] + 1))是第一行第二个元素,大小是4个字节
printf("%d\n", sizeof(a + 1));//4/8 a是二维数组的数组名,没有sizeof(a),也没有&(a),所以a是首元素地址
//而把二维数组看成一维数组时,二维数组的首元素是他的第一行,a就是第一行(首元素)的地址
//a + 1就是第二行的地址
printf("%d\n", sizeof(*(a + 1)));//16 sizeof(a[1])计算第二行的大小,单位是字节
printf("%d\n", sizeof(&a[0] + 1));//4/8 第二行的地址
printf("%d\n", sizeof(*(&a[0] + 1)));//16 计算第二行的大小,单位是字节
printf("%d\n", sizeof(*a));//16 a是首元素地址-第一行的地址,*a就是第一行,sizeof(*a)就是计算第一行的大小
printf("%d\n", sizeof(a[3]));//16
//sizeof内部的数字是不进行真实的运算的,只是根据其类型计算其大小
}
strlen
int main()
{
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", strlen(arr));//随机值
printf("%d \n", strlen(arr + 0));//随机值
//printf( "%d\n", strlen(*arr)); //error
//printf("%d\n", strlen(arr[1]));//error
//error原因:arr是数组名一 > 是首元素地址—* arr一 > 首元素一 > 'a'—ASCIl— > 97,随机值strlen会把其当成地址进行查找一>非法访问
printf("%d\n", strlen(&arr));//随机值
printf("%d\n", strlen(&arr + 1));//随机值-6
printf("%d\n", strlen(&arr[0] + 1));//随机值-1
}
int main()
{
char arr[] = "abcdef";
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr + 0));//6
//printf("%d\n", strlen(*arr)); //error
//printf("%d\n",strlen(arr[1]));//error
//*arr是首元素地址,strlen("const, char*. str")char*接收的是地址,传进去就是'a'这个字符,'a'的ASCII对应的数字是97,就会造成非法访问。
printf("%d\n", strlen(&arr));//6 &arr - 数组的地址-数组指针 char(*p)[7] = &arr
printf("%d\n",strlen(&arr + 1));//随机值
printf("%d\n", strlen(&arr[0] + 1));//5
return 0;
}
PS:
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。形如:a
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。形如:b
int main()
{
char* p = "abcdef";
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p +1));//5
//printf("%d\n", strlen(*p));//error
//printf("%d\n", strlen(p[0]));//error
//*p是指针,存放的是a的地址,p是从初所开辟的空间来看的,而不是存放字符串的" abcdef”的所开辟的空间来看,
//而却的地址延存放' a'的地址,地址是16进制数字例如0x0O12=>大部分小端存放=>1200 strlen就是数到0
printf("%d\n", strlen(&p));//随机值
printf("%d\n", strlen(&p + 1));//随机值
printf("%d\n", strlen(&p[0] +1));//5
return 0;
}
结语:
希望本篇文章对各位了解C语言的strlen和sizeof有所帮助,对于别的知识点C语言的知识点的讲解,各位老铁可以看我别的文章,相信能对各位老铁了解C语言有帮助。各位老铁有什么问题欢迎在下方留言。感谢各位老铁的观看。