c/c++中sizeof()问题以及sizeof()和strlen()的区别

来源:互联网 发布:mac airdrop文件在哪 编辑:程序博客网 时间:2024/05/05 12:00

参考了一些书籍和相关博客,将sizeof()和strlen()的问题整理如下。

参考博客:http://blog.csdn.net/van150/article/details/544454

        本人非计算机专业的学生,最近在找工作,笔试一些互联网公司的时候,发现很喜欢考sizeof(struct)的大小,经查阅资料,整理其资料如下:


问题1:本题考查应聘者对计算机底层机制的理解和设计程序的原则

struct product{char type[5];char *name;char ch;int id;union{char c;int i;}extra;};

我的计算:5*1+1+1+2+2=11Byte           因为刚学C语言的时候,老师说过int是16位的,所以很天真的认为sizeof(int)=2  这是错误的

比较迷惑的答案是:5*1+4+1+4+4=18B         后来知道sizeof(int)=4以为这是正确的,其实不是

正解是:24    这里面涉及到内存对齐的设计原则


1.int型的数据类型是16位的是最小存储空间,数据类型的对应的最小存储空间和编译器赋给类型的空间是不一样的,往往后者大于前者,eg:int 16位但是在VS2010的编译环境中,sizeof(int)=4Byte

cout<<sizeof(char)<<" "<<sizeof(signed int)<<" "<<sizeof(int)<<" "<<sizeof(float)<<" "<<sizeof(double)<<" "<<sizeof(long)<<" " <<sizeof(long double<<endl;

对应的分别是  1  4  4  4   8  4  8  bool:1   short:2  , Long,Float int sizeof都是4double8字节。知道这个知识点,就不会犯sizeof(int)=2这种错误。

2.在32位PC,VS2010编译环境下,任何一个指针的大小都是4Byte。

3.内存对齐原则:简单来说:就是对于一个结构体或者元素,它的首地址能被n(2,4,8)整除,才能获得最好的性能,同时考虑改结构体中最大内存的成员变量(2,4,8),以它为填充的基准。至于为什么计算机要采用字节对齐方式,因为这样访问效率会高很多,字节不对齐,访问效率低。



也就是说,type作为首地址,需要补充三个字节,使首地址占到8个字节,符合对齐原则。

同时ch也需要补充三个字节来确保字对齐原则。

另外有一点,共用体因为是共享一块内存,所以共用体的sizeof就其最大的那个变量内存就可以了。

所以这个题目的答案是24而不是16,因为对齐原则,增加了6个Byte。






如果你真明白了,就知道为什么下面这个题目,变量的位置摆放不同,得到的sizeof结果不同了。


sizeof(B)=12,sizeof(C)=8








如果这个明白了,基本的题应该问题不大,但是有些变态的题目,你可能不会。例如:在结构体前面定义了#pragma pack(n)

#pragma pack的基本用法为:#pragma pack( n ),n为字节对齐数,其取值为1、2、4、8、16,默认是8,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准,即是说,结构体成员的偏移量应该取二者的最小值,公式如下: offsetof( item ) = min( n, sizeof( item ) ) ;否则还是取默认的值。下面这个案例,sizeof(item)=5,即结构体成员中最大内存。

#pragma pack(n)struct product2{char type[5];char *name;char ch;  int id;union{char c;   int i;}extra;};
还是以这个例子为例:

如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准,但是这个时候16>5,所以采取的是默认的方式,字对齐为8字节。所以还是24Byte。

问题2:对于静态变量,sizeof的时候注意。

class A{public:int a;static int b;A();~A();};
sizeof(A)=4, 因为静态变量是放在全局数据区的,而sizeof计算栈中分配的大小,是不会计算在内的。

问题3:sizeof()和strlen()的区别

sizeof是一个单目操作符,而不是函数。作用是计算其操作数的存储空间。操作数可以是一个表达式或者一个类型。如sizeofint)。而strlen是一个函数,只能用char *做参数,且必须是以'\0'结尾的,计算有效字符串的字符数

Void main()

{

   char str[]="yanguoqi";

   char  str2[100]="yanguoqi";

   char *p = str;

   printf("sizeof(str) = %d\n", sizeof(str));    \\ 9个字节,字符串最后的结尾是’/0’

   printf("strlen(str) = %d\n", strlen(str));   \\  8个字节,这是有效字符的个数

   printf("sizeof(p) = %d\n", sizeof(p));       \\4个字节,p是一个指针变量

    printf("strlen(p) = %d\n", strlen(p)); \\8个字节,p为指针,指向字符串

   printf("sizeof(str2) = %d\n", sizeof(str2)); \\100个字节,内存预分配的大小

   printf("strlen(str2) = %d\n", strlen(str2)); \\8个字节,p为指针,指向字符串

}

Sizeof(指针)=4strlen(指针):求指针所指向内容的有效字符串的长度。


    第一次开博客,写技术日志,每周总结3个知识点吧,希望基础打牢固一点,将来可以走的更远,也希望各位前辈大牛,多提提建议,帮助小弟成长,在此谢谢各位了。


0 0
原创粉丝点击