strlen和sizeof
sizeof是在编译的时候就将结果计算出来了是类型所占空间的字节数,所以以数组名做参数时计算的是整个数组的大小。而strlen是在运行的时候才开始计算结果,这是计算的结果不再是类型所占内存的大小,数组名就退化为指针了。
strlen(): 函数 strlen是寻找从指定地址开始,到出现的第一个0之间的字符个数
sizeof()运算符
sizeofhttps://blog.csdn.net/weixin_41042404/article/details/86719441
在本文中有很多是从https://blog.csdn.net/weixin_41042404/article/details/86719441搬运的,感谢该文的作者,大家转载别忘了附上该文链接。
以下是一个C程序,注释是对应的知识介绍
#include<stdio.h>
#include<string>
#include <stdlib.h>
typedef long TLONG;
int f1() { return 0; };//定义函数
double f2() { return 0.0; }//定义函数
void f3() {}//定义函数
union u1//定义联合
{
double a;
int b;
};
union u2//定义联合
{
char a[13];
int b;
};
union u3//定义联合
{
char a[13];
char b;
};
struct s1//定义结构体
{
char a;
double b;
int c;
char d;
};
struct s2//定义结构体
{
char a;
char b;
int c;
double d;
};
int main()
{
char const *str1 = "123456";//定义字符串
char const str2[] = "123456";//定义字符串
char const str3[] = {1, 2, 3, 4, 5, 6};//定义字符数组
double* (*a)[3][6];//定义一个double*型数组指针
printf("sizeof(*str1)=%d,sizeof(str1)=%d,strlen(str1)=%d\n", sizeof(*str1),sizeof(str1), strlen(str1));//1 4 6,*str1是第一个是第一个字符,str1是一个指针,sizeof(指针)=4 strlen是统计str中0之前的字符数
printf("sizeof(str2)=%d,strlen(str2)=%d\n", sizeof(str2), strlen(str2));//7 6,sizeof(str2将\0加入计算,strlen只计算\0前的
printf("sizeof(str3)=%d,strlen(str3)=%d\n", sizeof(str3), strlen(str3));//6 不确定值,str3是一个数组,不是字符串,strlen检测不到\0会继续
printf("sizeof(int)=%d,sizeof(1==2)=%d\n", sizeof(int), sizeof(1 == 2));//1==2相当于bool型
printf("sizeof(unsigned int) == sizeof(int)值为%d\n", sizeof(unsigned int) == sizeof(int));//1,unsigned影响的只是最高位bit的意义,数据长度不会被改变的。
printf("自定义类型和原型比较=1%d\n", sizeof(long) == sizeof(TLONG));//1 自定义类型的sizeof取值等同于它的类型原形。
printf("sizeof 2=%d,sizeof(2)=%d\n", sizeof 2, sizeof(2));//正确
// printf("sizeof int=%d,sizeof(int)=%d\n", sizeof int, sizeof(int)); //结论:错误sizeof可以不加()不论sizeof要对谁取值,最好都加上()。
printf("sizeof(f1())=%d,sizeo(f2())=%d\n", sizeof(f1()), sizeof(f2()));//正确
//printf("sizeof(f3())=%d\n",sizeof(f3()));//错误 结论:对函数使用sizeof,在编译阶段会被函数返回值的类型取代,
printf("sizeof(int*)=%d,sizeo(char*)=%d,sizeo(double*)=%d\n",
sizeof(int*), sizeof(char*), sizeof(double*));//4 4 4结论:只要是指针,大小就是4。(64位机上要变成8也不一定)。
printf("sizeof(a)=%d,sizeof(*a)=%d,sizeof(**a)=%d,sizeof(***a)=%d,sizeof(****a)=%d\n",
sizeof(a), sizeof(*a), sizeof(**a), sizeof(***a), sizeof(****a));
/*既然a是执行double*[3][6]类型的指针,
*a就表示一个double*[3][6]的多维数组类型,
因此sizeof(*a)=3*6*sizeof(double*)=72。
同样的,**a表示一个double*[6]类型的数组,
所以sizeof(**a)=6*sizeof(double*)=24。
***a就表示其中的一个元素,也就是double*了,
所以sizeof(***a)=4。至于****a,就是一个double了,
所以sizeof(****a)=sizeof(double)=8。*/
printf("sizeof(u1)=%d,sizeof(u2)=%d,sizeof(u3)=%d\n",
sizeof(u1), sizeof(u2), sizeof(u3));
/*union的大小取决于它所有的成员中,占用空间最大的一个成员的大小。
所以对于u来说,大小就是最大的double类型成员a了,所以sizeof(u)=sizeof(double)=8。
但是对于u2和u3,最大的空间都是char[13]类型的数组,为什么u3的大小是13,而u2是16呢?
关键在于u2中的成员int b。由于int类型成员的存在,使u2的对齐方式变成4,也就是说,
u2的大小必须在4的对界上,所以占用的空间变成了16(最接近13的对界)。
*/
printf("sizeof(s1)=%d,sizeof(s2)=%d\n",
sizeof(s1), sizeof(s2));
/* 对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,
但是下一个元素d是double类型,要放到8的对界上,离1最接近的地址是8了,
所以d被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是4,
16可以满足,所以c放在了16,此时下一个空闲地址变成了20,下一个元素d需要对界1,
也正好落在对界上,所以d放在了20,结构体在地址21处结束。
由于s1的大小需要是8的倍数,所以21-23的空间被保留,s1的大小变成了24。
对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,
下一个元素的对界也是1,所以b摆放在1,下一个空闲地址变成了2;
下一个元素c的对界是4,所以取离2最近的地址4摆放c,下一个空闲地址变成了8,
下一个元素d的对界是8,所以d摆放在8,所有元素摆放完毕,结构体在15处结束,
占用总空间为16,正好是8的倍数。*/
system("pause");//作用就是让程序暂停一下。
return 0;
}
运行结果:
sizeof(*str1)=1,sizeof(str1)=4,strlen(str1)=6
sizeof(str2)=7,strlen(str2)=6
sizeof(str3)=6,strlen(str3)=22
sizeof(int)=4,sizeof(1==2)=1
sizeof(unsigned int) == sizeof(int)值为1
自定义类型和原型比较=11
sizeof 2=4,sizeof(2)=4
sizeof(f1())=4,sizeo(f2())=8
sizeof(int*)=4,sizeo(char*)=4,sizeo(double*)=4
sizeof(a)=4,sizeof(*a)=72,sizeof(**a)=24,sizeof(***a)=4,sizeof(****a)=8
sizeof(u1)=8,sizeof(u2)=16,sizeof(u3)=13
sizeof(s1)=24,sizeof(s2)=16
strlen(str3)=22之所以不确定是因为strlen需要检测到’\0’才会停下来,如果
char const str3[] = {1, 2, 3, 4, 5, 6,0}; strlen(str3)=6
如果不加const,那程序运行会出现问题。