通过程序解读sizeof
2015-03-29 16:45
134 查看
<pre name="code" class="cpp">#include <iostream> #include <string> using namespace std; void foo3(char *c1) { int c3 = sizeof( c1 ); // c3 == cout<< c3 << endl; } void foo4(int *c2) { int c4 = sizeof( c2 ); // c4 == cout<< c4 << endl; } //字节对齐的细节和编译器实现相关,但一般而言,满足三个准则: //1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; //2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节; //3) 结构体的总大小为结构体最宽基本(内置)类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节. struct student { int num; // 占4个字节 char name[20]; // 占20个字节 char sex; // 占4个字节(结构体为每个成员分配空间时,根据最宽基本类型成员大小的整数倍进行分配,这里指的是int/float) double age; // 占4字节 float score; // 占4字节 char addr[30]; // 占32字节(分配的空间必须为最宽基本类型成员大小的整数倍) }; struct S1 { char a; // 4字节 int i; // 4字节 }; // 嵌套的结构体 struct S2 { char a; // 4字节 int i; // 4字节 student t; // 占68字节,最宽基本类型成员为int/float型,4字节(注意,这里最大成员不是t,因为它不属于内置类型;具体计算S2时,student要按S2中的最近倍数来算) }; // 空结构体 struct S3{}; // 共用体成员共用一个空间,所以其为最宽基本类型成员的大小 union U { int i; char a; }; int main() { /* 1. int count=0; int m=779; while(m) { count++; m=m&(m-1); } //printf("%d\n",count); cout<< count << endl; return 0; */ // sizeof的用法 //(1)数组1 int p1[10]; int *p2[10]; int (*p3)[10]; cout<< "int p1[10] sizeof(p1):" << sizeof(p1) << endl; cout<< "int *p2[10] sizeof(p2):" << sizeof(p2) << endl; cout<< "int (*p3)[10] sizeof(p3):" << sizeof(p3) << endl; cout<< "----------------------------"<< endl; //(2)内置类型 char a1; int a2; float a3; double a4; long a5; long double a6; string a7; string a8="abc"; // string类型变量本质上属于指针 cout<< "char: " << sizeof(a1) << endl; cout<< "int: " << sizeof(a2) << endl; cout<< "float: " << sizeof(a3) << endl; cout<< "double: " << sizeof(a4) << endl; cout<< "long: " << sizeof(a5) << endl; cout<< "long double: " << sizeof(a6) << endl; cout<< "string: " << sizeof(a7) << endl; cout<< "string a8=\"abc\": " << sizeof(a8) << endl; cout<< "----------------------------"<< endl; //(3)指针:所有的指针(包括结构体)均占4字节(一个int型大小)。 char *b1; int *b2; float *b3; double *b4; long *b5; long double *b6; cout<< "char*: " << sizeof(b1) << endl; cout<< "int*: " << sizeof(b2) << endl; cout<< "float*: " << sizeof(b3) << endl; cout<< "double*: " << sizeof(b4) << endl; cout<< "long*: " << sizeof(b5) << endl; cout<< "long double*:" << sizeof(b6) << endl; cout<< "----------------------------"<< endl; //(4)数组2 char c1[]="abcd"; int c2[4]; cout<< "char c1[]=\"abcd\": " << sizeof(c1) << endl; cout<< "int c2[4]: " << sizeof(c2) << endl; //数组名做形参:本质就是指针 cout<< "foo3(char *c1): "; foo3(c1); cout<< "foo3(int *c2): "; foo4(c2); cout<< "----------------------------"<< endl; // (5)结构体 S1 s1; S1 *s2; S2 s3; S3 s4; student student1; student *student2; cout<< "S1 s1: " << sizeof(s1) << endl; cout<< "S1 *s2: " << sizeof(s2) << endl; cout<< "student student1: " << sizeof(student1) << endl; cout<< "student *student2: " << sizeof(student2) << endl; cout<< "S2 s3: " << sizeof(s3) << endl; cout<< "S3 s4: " << sizeof(s4) << endl; cout<< "----------------------------"<< endl; // 共用体 U u; cout<< "U u: " << sizeof(u) << endl; system("pause"); return 0; }
<div id="art_demo">本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节</div><p>在C语言中我们操作字符串肯定用到的是指针或者数组,这样相对来说对字符串的处理还是比较麻烦的,好在C++中提供了 string 类型的支持,让我们在处理字符串时方便了许多。</p><p><strong><span style="COLOR: #ff0000">首先,我写了一段测试代码,如下所示:</span></strong></p><pre name="code" class="cpp">#include <iostream>using namespace std;int main(void){string str_test1;string str_test2 = "Hello World";int value1, value2, value3;value1 = sizeof(str_test1);value2 = sizeof(str_test2);value3 = sizeof(string);cout<<"str_test1占 "<<value1<<" 个字节"<<endl;cout<<"str_test2占 "<<value2<<" 个字节"<<endl;cout<<"string占 "<<value3<<" 个字节"<<endl;system("pause");return 0;}首先,我用G++编译运行,得到的结果如下图所示:
结果都是4字节;<p>这说明string占4个字节。之后,我用VS2012编译运行,得到的结果如下图所示:结果都是28字节。</p><p>奇怪,这里string竟然占28个字节。这里,我们注意观察,还会发现一个问题,不管有没有对string类型的变量赋值,或者是赋什么值,得到的结果是一样的。</p><p><strong>下面,来解释上述问题:</strong>string的实现在各库中可能有所不同,但是在同一库中相同一点是,无论你的string里放多长的字符串,它的sizeof()都是固定的,字符串所占的空间是从堆中动态分配的,与sizeof()无关。 sizeof(string)=4可能是最典型的实现之一,不过也有sizeof()为12、32字节的库实现。通常,我们所用到的 string 类型一般都会是这样实现:</p><p><pre name="code" class="cpp">class{char *_Ptr; //指向字符串的指针int _Len; //字符串的长度........};所以,我们一般接触到的string类型所占字节数为 8+。
相关文章推荐
- C#实现通过程序自动抓取远程Web网页信息
- 多队列网卡简介以及Linux通过网卡发送数据包源码解读
- 如何通过程序取得Excel中条件格式的结果
- Solution—程序编译通过但运行提示:找不到程序集:[random].dll或依赖项
- 我看小程序系列文章:1 不一样的角度 解读微信小程序
- Android之通过ActivityLifecycleCallbacks判断程序是否运行在后台
- 编写多线程程序,模拟多个人通过一个山洞。这个山洞每次只能通过一个人,每个人通过山洞的时间为2秒(sleep)。随机生成10个人,都要通过此山洞,用随机值对应的字符串表示人名,打印输出每次通过山洞的人名
- android程序中 通过包名判断手机上是否已安装app
- 参数被修饰成final,意味着该参数不能在方法体中被修改,一旦修改了方法体中的final参数,程序将无法通过编译。
- linux通过端口号查找程序执行路径
- 实验七4编写程序,输入一批学生的成绩,遇0或负数则输入结束,要求统计并输出优秀(大于85)、通过(60~84)和不及格(小于60)的学生人数。
- Delphi让你的程序通过XP防火墙
- Linux程序宕掉后如何通过gdb查看出错信息
- 通过一个详细的例子解读错误提示
- 【Python学习系列四】Python程序通过hadoop-streaming提交到Hadoop集群执行MapReduce
- 通过反射来判断某个程序集中是否有实现该接口的类
- c#通过app.manifest使程序以管理员身份运行
- C#(ASP.NET) 下载数据 C#实现通过程序自动抓取远程Web网页信息
- web程序通过dbcp连接池处理自动重新连接数据库问题(通过连接池dbcp处理方案)
- 编写一个程序,可以通过次程序完成一个表的创建操作,输入表的名称,各个列的名称及类型,输入完成后直接通过JDBC创建指定的表。