`
rocky2com
  • 浏览: 38420 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

sizeof 笔记(转自http://student.csdn.net/space.php?uid=43658&do=blog&id=8677)

 
阅读更多

大家是否发现sizeof好多什么很烦人。。老是弄错的时候。实在没办法了。。对它做下总结吧。。希望以后少出错。。

1 sizeof 是什么?

sizeof()不是函数,不是宏。它是一个关键字。一个运算符。

2 sizeof用来干什么?

sizeof()他可以获得一中数据类型(内置类型或自定义类型)或一个变量所占字节的大小。结果为一个十进制数。

3 sizeof()和strlen()的区别。

现在我们知道sizeof是一个运算符了。那strlen是什么呢?我们去MSDN上看下:

Code:
  1. size_tstrlen(constchar*string);
  2. size_twcslen(constwchar_t*string);

这是MSDN的结果。也就是说strlen()是一个函数,返回类型为size_t。参数为const char *.好。我们明白了,下面我们看几个例子来区分一下吧:

第一个例子:

Code:
  1. char*p="123456";
  2. cout<<sizeof(p)<<endl;//结果为4
  3. cout<<sizeof(*p)<<endl;//结果为1
  4. cout<<strlen(p)<<endl;//结果为6

首相记住一句话,所有指针(包括void*)所占的大小均为4个字节。故第一个结果为4。这点到令我想起了类。我们知道在一个类未定义完成之前我们是无法用它来定义对象的。然而我们可以用它来定义指针成员。为什么呢?因为当我们用一个类型来定义对象时。我们在编译时必须知道这个类型的大下,该为此对象非配多大的空间。而此时我们的类并没有定义完整,编译器是无法得知类的大小的。故也就无法为该类的对象分配空间。故就干脆禁止定义类对象。而指针就不同了。因为任何类型的指针大小均为4.故编译器一看到指针直接分配4个字节就对了。。呵呵。。

程序的第二行结果为1,因为指针p中存放的是字符串的首地址。即字符串第一个字符的地址。*p也就是字符串第一个字符。类型为char故结果为1.

第三行strlen是用来求字符串的长度,不含结束符"/0";故结果为6

第二个例子:

Code:
  1. chara[100]="123456";
  2. cout<<sizeof(a)<<endl;//结果为100
  3. cout<<strlen(a)<<endl;//结果为6

第一行:结果为100.是因为在我们定义字符数组时,下标标出了100,此时编译器就会为我们分配100*sizeof(char)的内存空间。

第二行:结果类似第一个例子,是对该数组求长度。

第三个例子:

Code:
  1. chara[]="123456";
  2. cout<<sizeof(a)<<endl;//结果为7
  3. cout<<strlen(a)<<endl;//j结果为6

第一行:结果为7,是因为编译器在为数组分配空间时,看到数组a中没有标下标,故就根据后面字符串的长度来为该数组分配空间。而后面字符串的长度为7(包括结束符"/0"),故结果为7;

第四个例子:

Code:
  1. inta[100]={1,2,3};
  2. cout<<sizeof(a)<<endl;//结果为400
  3. cout<<strlen(a)<<endl;//错误

第一行:由于a是int行数组,故结果为100*sizeof(int).

第二行之所以错误是因为我们的strlen是个函数,它的参数是const char*。

4 sizeof的怪用

sizeof可以做数组的下标使用,作用类似于我们C++中的const。类似C中的define。呵呵。不知道吧。。我们看个例子:

Code:
  1. inta[sizeof(int)]={1,3,4,5};

编译下,成功了。。呵呵。。若是我们改成下面这样:

Code:
  1. inta[sizeof(int)]={1,3,4,5,6,7};

错误:too many initializers

为什么会成功呢?因为sizeof在编译的时候就被计算过了。。呵呵

5 牵涉到特殊字符时候的sizeof计算

这里的特殊字符指那些类似 '/n','/t','//','/0'的东西。记住遇到这些东西的时候,把它当做1计算就对了。。如:

Code:
  1. chara[]="b/n";
  2. cout<<sizeof(a)<<endl;//结果为3

6 牵涉到函数的sizeof

这里有两种含义,一种是对函数求sizeof。

这就怪了,我刚才还说sizeof仅对数据类型或变量求值的。呵呵。。其实这并没有违背我刚刚才的话。我们看下面例子:

Code:
  1. doublef();
  2. cout<<sizeof(f())<<endl;//结果为8

我们定义了一个函数f(),然后对它进行sizeof.还得出了结果。其实这里sizeof是对函数的返回类型进行了求值。因为f()的返回类型为double类型。故结果为8.

第二种函数,对函数里面的变量求值。

啊?函数里面的变量和其他的变量不一样?呵呵。一样的。不过有些变量传进来之后会改变身份的。。我们看下面例子:

Code:
  1. #include<iostream>
  2. usingnamespacestd;
  3. voidf(chara[]);
  4. intmain()
  5. {
  6. chara[]="123456";
  7. f(a);
  8. return0;
  9. }
  10. voidf(chara[])
  11. {
  12. cout<<sizeof(a)<<endl;//结果为4
  13. return0;
  14. }

结果为什么成4了呢。不该是7吗?这是因为a传进函数之后就退化成一个指针了。

7 牵涉到结构体的sizeof

这里就要考虑的东西多了,牵涉到结构体对齐,数据对齐问题了。很是烦人。

但是我们可以不然编译器进行结构体对齐:

我们使用这个#pragma pack(n)。n为指定的对齐数。当n==1时。这时候结构体便不再老老实实的输出实际的字节长度了。如:

Code:
  1. #include<iostream>
  2. usingnamespacestd;
  3. #pragmapack(1)
  4. structstu
  5. {
  6. charc;
  7. inta;
  8. };
  9. intmain()
  10. {
  11. cout<<sizeof(stu)<<endl;
  12. return0;
  13. }

输出结果为5.当我们去掉:#pragma pack(1)后,结果为8。

如果我们改下n的值为2.此时运行结果为6.

n的值为3 时。哇!!编译器给出警告了。。说n的值只能是 1, 2 ,4, 8 ,16.

n的值为4时,结果为8.

n的值为8时,结果为8

n的值为16时。结果为8.

由此我们可以总结出一下几点:

①: 编译器是根据 #pragma pack(n) 中n的值和当前对象进行比较进行字节对齐的。

②:当 :#pragma pack(n) 中n的值大于等于结构体中最大长度变量时。n值将不再起作用。此时编译器将根据最大长度值和当前变量进行字节对齐。

③ 当我们的n值为1时。将不进行任何的补齐。输出实际的变量大小之和。

我们用的win32操作系统默认的应该是8字节对齐的即n== 8;所以我们平时考虑字节对齐时只需跟句最大变量进行对齐即可:

这里的规则大家可以参考资料:

http://space.itpub.net/14805538/viewspace-483697

http://www.diybl.com/course/3_program/c++/cppjs/20090403/163712.html

这些都是google出来的。大家若是想了解更对的东西不妨也google一下吧。

另外除了结构体对齐的原因需要考虑外,千万别忘了有些变量是不再sizeof的计算范围之内的。如:

静态变量。enum。union。

Code:
  1. #include<iostream>
  2. usingnamespacestd;
  3. #pragmapack(16)
  4. structstu
  5. {
  6. charc;
  7. staticlongdoublea;
  8. uniont
  9. {
  10. inta;
  11. intb;
  12. };
  13. enumweekday{Monday};
  14. };
  15. intmain()
  16. {
  17. cout<<sizeof(stu)<<endl;//结果为1
  18. return0;
  19. }

8 牵涉到类的sizeof

这个就更麻烦了。。不但要考虑到结构体对齐问题,还要考虑虚函数,虚继承等等。在类里除了结构体中提到的那些不占空间外,普通函数也是不占空间的。至于这里的sizeof就不再总结了。太多了。大家可以google下。呵呵。。

9 其他的sizeof

有关标准库的sizeof你试过吗?如是没有的话,不妨可以去了解下哦。。呵呵。。

Code:
  1. cout<<sizeof(string)<<endl;
  2. cout<<sizeof(vector<int>)<<endl;
  3. cout<<sizeof(vector<string>)<<endl;
  4. cout<<sizeof(list<int>)<<endl;
  5. cout<<sizeof(deque<int>)<<endl;
  6. stringstr[]={"hello","world","nihao"};
  7. cout<<sizeof(str)/sizeof(string)<<endl;
  8. string*pstr=newstring[2];
  9. cout<<sizeof(pstr)<<endl;

若是有时间的话,上面的这些还是运行下看下结果呗。。呵呵。。了解一下。。

分享到:
评论

相关推荐

    QP移植到正点原子STM32.zip

    QF_poolInit(LedEvtPoolSto,sizeof(LedEvtPoolSto),sizeof(LedEvtPoolSto[0])); RedLed_Start(uiPrio++, l_redQueueSto, Q_DIM(l_redQueueSto), 0, 0); //建立活动对象 BlueLed_Start(uiPrio++, l_blueQueueSto, Q_...

    校园信息管理系统之容器法

    long Student::returnsort(){return id;} void Student::show() { cout*************************"; cout编号:"&lt;&lt;id; cout姓名:"; cout性别:"; cout家庭地址:"; cout出生日期:"&lt;&lt;date.year&lt;&lt;"-"&lt;&lt;date.month...

    pcf8563_i2c1_r8_ruoge_ov2640通过给RTC驱动增加设备节点读取秒钟成功+直接读取I2C1获取秒钟值20160626_2201.7z

    http://blog.csdn.net/21cnbao/article/details/7919055 在Android源码树中添加userspace I2C读写工具(i2c-util) 本文使用的开发板是:杭州若格科技有限公司的全志R8。CPU:CPUARM Cortex-A8 更多芯片资料请参见...

    CHtmlView访问文件内部资源与innerHTML

    CHtmlView访问文件内部资源与innerHTML演示代码例子...... 1、访问文件内部资源 void CInerHTMLView::OnRes() ...while (file-&gt;Read(buf, sizeof(buf)) &gt; 0) s += buf; delete file; } ... }

    全志A80平台固定以太网的MAC地址ethernet_a80_merrii_20151203_1607.7z

    http://blog.csdn.net/memechashang/article/details/23999857 http://yobin.sinaapp.com/topic/2780/android%E7%9A%84deviceid%E7%9A%84%E6%B7%BB%E5%8A%A0 Android的DeviceID的添加 找了好久,可以看见文件:/...

    MFC打开文件和文件夹

    // ZeroMemory(&ofn,sizeof(ofn)); // ofn.lStructSize = sizeof(ofn); // ofn.lpstrFile = szFile; // ofn.lpstrFile[0] = TEXT('/0'); // ofn.nMaxFile = sizeof(szFile); // ofn.lpstrFilter = TEXT("all/0*...

    vscode提交leetcode-leetcode:最后...leetcode练习

    我的leetcode练习笔记 结构 代码在根路径中,每个cpp文件都是一个问题的解决方案 有关特定问题的解决方案的一些说明在目录中。 我使用的工具 我使用扩展来测试和调试本地并提交我确定我的解决方案有效。 通常我会先...

    纯C语言读写24BMP文件,32位BMP转24位BMP

    纯C语言读写24BMP文件,32位BMP转24位BMP;...详情参见:https://blog.csdn.net/libizhide/article/details/104144513 下载后请修改错误:main.c中55行pic=(PIC *)malloc(1);改为pic=(PIC *)malloc(sizeof(PIC)*1);

    Delphi获取Windows物理及虚拟内存信息.rar

     MemInfo.dwLength:=sizeof(MEMORYSTATUS);  //用sizeof(MEMORYSTATUS)填充dwLength成员  GlobalMemoryStatus(MemInfo);  //获取内存信息  Edit1.Text:=IntToStr(MemInfo.dwMemoryLoad) '%';  //内存使用...

    stackC语言代码

    stack源代码//顺序栈基本运算算法 #include &lt;stdio.h&gt; #include &lt;malloc.h&gt; #define MaxSize 2 typedef char ElemType; typedef struct ... s=(SqStack *)malloc(sizeof(SqStack)); s-&gt;top=-1; }

    测定JVM中对象占用内存—SizeOf

    原项目下载地址:http://sourceforge.net/projects/sizeof/ 使用说明: 1、将SizeOf.jar放到Eclipse工程路径下,添加到classpath中; 2、运行前添加VM参数:-javaagent:lib/SizeOf.jar 运行即可(将jar放在lib路径下)...

    javacv-platform-1.3.3-src

    OpenJDK http://openjdk.java.net/install/ or Sun JDK http://www.oracle.com/technetwork/java/javase/downloads/ or IBM JDK http://www.ibm.com/developerworks/java/jdk/ Further, although not always ...

    java SizeOf 对象的大小

    NULL 博文链接:https://spice.iteye.com/blog/1104340

    iServer tcp 模拟服务器

    memset(&m_gThreadSocket,0,sizeof(m_gThreadSocket)); ////m_gThreadSocket.hThread = NULL; ////m_gThreadSocket.hEventSocket = NULL; ////m_gThreadSocket.hEventKill = NULL; ////m_gThreadSocket....

    delphi隐藏窗体在windows任务栏,在右下角,单独集成单元文件,比控件好用

    cbSize := SizeOf; //TNotifyIconData Wnd := Classes.AllocateHWnd(WndProc); uID := 1; uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP; uCallBackMessage := WM_NotifyIcon; hIcon := Application.Icon....

    标准windows sdk模板

    wc.cbSize = sizeof(WNDCLASSEX); // 注册窗口结构体的大小 wc.style = 0; // 窗口的样式 wc.lpfnWndProc = WndProc; // 指向窗口处理过程的函数指针 wc.cbClsExtra = 0; // 指定紧跟在窗口类结构后的附加字节数...

    更换exe图标_IDo_图标_换图标_

    for i := 0 to ih.count - 1 do begin Src.Position := oldentry; hinst := BeginUpdateResource(PChar(destexe) False); Src.Read(id SizeOf(ICONINFORMATION)); ic.width := id.width; ic.height := id.height; ...

    手机防盗软件实现(源码)

    http://blog.csdn.net/xiaoxiao108/archive/2011/05/01/6381414.aspx 前段时间母亲手机遭贼了,以防万一,如果自己手机丢了,肯定会更郁闷,记得很多手机有防盗功能,如果更换了sim卡就会,手机就会自动把新的 sim...

    KMP算法c语言实现

    #include &lt;stdlib.h&gt; #include&lt;stdio.h&gt; #include &lt;string.h&gt; typedef struct { int length;...本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xiweihang/archive/2009/08/23/4474864.aspx

Global site tag (gtag.js) - Google Analytics