sizeof终极解惑
★深入解析sizeof操作符★
3. 不适用场合 sizeof 操作符不能用于不完全类型定义,例如数组必须有确定的维数,结构体有完整的 成员列表定义。 例: extern int arr[]; struct s; sizeof(arr); // Error sizeof(s); // Error 4. 一般用法 1) 2) 3) 4) 5) 6) 7) cout<<sizeof(int); // 4 double d; cout<<sizeof(d); // 8 char str[]=”0123456789”; cout<<sizeof(str); // 11(注意字符串的结束字符’\0’) char str[100]=”0123456789”; cout<<sizeof(str); // 100 char *p=”0123456789”; cout<<sizeof(p); // 4(p 的类型是字符指针) char *p=(char *)malloc(100); cout<<sizeof(p); // 4(同上) string str(“0123456789”); cout<<sizeof(str.c_str()); // 4(同上)
★深入解析 sizeof 操作符★
更新日期:08/20/2010 1. 描述 sizeof 操作符以字节形式给出了其操作数的存储空间,操作数的存储空间有操作数的类 型决定。操作数可以是变量、类型(需加括号)或表达式。 2. 使用场合 1) 2) 动态分配内存时,计算需要分配的内存空间大小 由于不同平台相同类型的所占的字节数不同,可以使用 sizeof 代替常量计算
6. 高级用法之——struct 的空间计算 总体上遵循三个原则(即内存对齐原则) : (1) 结构体变量的起始地址是占用空间最大的成员(的类型)所占字节数的整倍数 (2) 整体空间是占用空间最大的成员(的类型)所占字节数的整倍数 (3) 内存按结构成员的先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小 必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。 注意: 数组按照单个变量一个一个的摆放, 而不是看成整体。 如果成员中有自定义的类、 结构体,也要注意数组问题。 看下面的例子:(默认对齐方式下) struct s1 { char a; double b; int c; char d; }; struct s2 { char a; char b; int c; double d; }; cout<<sizeof(s1)<<endl; // 24 cout<<sizeof(s2)<<endl; // 16 同样是两个 char 类型,一个 int 类型,一个 double 类型,但是因为对齐问题,导致他们 的大小不同。计算结构体大小可以采用元素摆放法,我举例子说明一下:首先,CPU 判断 结构体的对界,根据上一节的结论,s1 和 s2 的对界都取最大的元素类型,也就是 double 类 型的对界 8。然后开始摆放每个元素。 对于 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 的倍数。 这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看 下面的例子:
sizeof深入理解(vcbase)
sizeof深入理解(vcbase)∙ 1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。
该类型保证能容纳实现所建立的最大对象的字节大小。
∙ 2.sizeof是算符,strlen是函数。
∙ 3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。
sizeof还可以用函数做参数,比如:∙short f();∙printf("%d\n", sizeof(f()));输出的结果是sizeof(short),即2。
∙ 4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
∙ 5.大部分编译程序在编译的时候就把sizeof计算过了是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因∙char str[20]="0123456789";∙int a=strlen(str); //a=10;∙int b=sizeof(str); //而b=20;∙ 6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
∙7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。
这是因为sizeof是个操作符不是个函数。
∙8.当适用了于一个结构类型时或变量, sizeof 返回实际的大小,当适用一静态地空间数组, sizeof 归还全部数组的尺寸。
sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸∙9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:∙fun(char [8])∙fun(char [])都等价于 fun(char *) 在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的大小,需要这样做:进入函数后用memcpy 拷贝出来,长度由另一个形参传进去fun(unsiged char *p1, int len){unsigned char* buf = new unsigned char[len+1]memcpy(buf, p1, len);}有关内容见: C++ PRIMER?∙10.计算结构变量的大小就必须讨论数据对齐问题。
详细解析sizeof()
一、sizeof的概念sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。
它并不是函数。
sizeof操作符以字节形式给出了其操作数的存储大小。
操作数可以是一个表达式或括在括号内的类型名。
操作数的存储大小由操作数的类型决定。
二、sizeof的使用方法1、用于数据类型sizeof使用形式:sizeof(type)数据类型必须用括号括住。
如sizeof(int)。
2、用于变量sizeof使用形式:sizeof(var_name)或sizeof var_name变量名可以不用括号括住。
如sizeof (var_name),sizeof var_name等都是正确形式。
带括号的用法更普遍,大多数程序员采用这种形式。
注意:sizeof操作符不能用于函数类型,不完全类型或位字段。
不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。
如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式。
三、sizeof的结果sizeof操作符的结果类型是size_t,它在头文件中typedef为unsignedint类型。
该类型保证能容纳实现所建立的最大对象的字节大小。
1、若操作数具有类型char、unsigned char或signed char,其结果等于1。
ANSI C正式规定字符类型为1字节。
2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long 、float、double、long double类型的sizeof 在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、2、4、4、4、8、10。
C 中的sizeof 关键字详解
10、不要让 double 干扰你的位域 、
在结构体和类中, 可以使用位域来规定某个成员所能占用的空间, 所以使用位域能在一 定程度上节省结构体占用的空间。不过考虑下面的代码: struct s1 { int i: 8; int j: 4; double b; int a:3; }; struct s2 { int i; int j; double b; int a; }; struct s3 { int i; int j; int a; double b; }; struct s4 { int i: 8;
可以看到,有 double 存在会干涉到位域(sizeof 的算法参考上一节) ,所以使用位域的 的时候,最好把 float 类型和 double 类型放在程序的开始或者最后。
1
cout<<sizeof(s1)<<endl; // 8 cout<<sizeof(s2)<<endl; // 8 cout<<sizeof(s3)<<endl; // 9 cout<<sizeof(s4)<<endl; // 16; s1 和 s2 大小虽然都是 8,但是 s1 的对齐方式是 1,s2 是 8(double) ,所以在 s3 和 s4 中才有这样的差异。 所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体 里的元素。
sizeof用法 c语言
sizeof用法 c语言在C语言中,sizeof是一个非常有用的运算符,它可以用于获取数据类型或对象的大小,以字节为单位。
这对于内存管理、动态分配和大小调整等方面非常重要。
本文将介绍sizeof在C语言中的用法。
一、基本概念sizeof运算符返回一个类型或对象所占的字节大小。
它只能用于数据类型(如int、float、char等)或对象(如数组、结构体等)。
sizeof的结果是一个整数,表示所求对象的大小(以字节为单位)。
二、用法示例1.获取数据类型的大小可以使用sizeof运算符来获取常见数据类型的大小,例如:```cinti=10;printf("%lu\n",sizeof(i));//输出4,表示int类型占4个字节```2.获取数组的大小可以通过sizeof运算符获取数组的大小,例如:```cintarr[5]={1,2,3,4,5};printf("%lu\n",sizeof(arr));//输出20,表示arr数组占20个字节(4个字节的指针+5个元素的*3个字节+一个结尾标志)```3.获取结构体的大小可以为一个结构体分配内存,并使用sizeof运算符获取其大小。
例如:```cstructMyStruct{inti;charc;};structMyStructs;printf("%lu\n",sizeof(s));//输出8,表示MyStruct结构体占8个字节(包括成员变量i和c所占的字节)```三、注意事项sizeof运算符返回的是对象或类型在内存中的大小,而不是其在磁盘上的大小。
它不考虑对齐和填充字节。
此外,sizeof的结果是编译时常量,可以在代码中直接使用。
四、应用场景sizeof运算符在C语言中应用非常广泛,例如:1.动态内存分配:在使用malloc()或calloc()函数分配内存时,可以使用sizeof运算符确定分配的大小。
sizeof使用方法
sizeof使用方法嘿,朋友们!今天咱就来好好唠唠 sizeof 这个家伙的使用方法。
你说 sizeof 像不像一把神奇的尺子呀?它能帮我们准确地量出各种数据类型所占的空间大小呢!比如说,你想知道一个整数在内存中占了多大地方,sizeof 就能告诉你答案。
就好比你去买衣服,你得知道自己的尺码吧?不然怎么能买到合身的呢?sizeof 就像是那个帮你量尺寸的店员,能让你清楚知道每个数据类型的“身材”。
那怎么用这把“尺子”呢?很简单啦!就把你想要量的东西放在sizeof 后面就行。
比如说 sizeof(int),它就会告诉你整数类型所占的字节数。
这可太有用啦!为啥呢?你想想啊,有时候我们写程序,得考虑内存的使用情况吧。
如果不清楚每个数据类型占多少空间,那不是容易出乱子嘛。
举个例子哈,你要存储很多数据,如果不知道它们各自占多大空间,可能就会导致内存不够用,程序就崩溃啦!这就好像你要装很多东西到一个箱子里,你总得知道每个东西大概占多大地方,才能合理安排空间,对吧?而且 sizeof 可不光能量基本数据类型哦,它对结构体、数组这些也都管用呢!就像它能量出一个人的身高、体重,也能量出一群人的总体情况一样。
比如说,你有个结构体,里面包含了各种不同类型的数据。
那sizeof 就能告诉你整个结构体所占的空间大小。
这就好比你要知道一个团队的整体规模, sizeof 就能帮你做到。
还有数组呢,它能准确地告诉你这个数组所占的总字节数。
这就像你知道一箱子苹果有多少个,每个苹果多大,就能算出这箱苹果占了多大空间一样。
总之啊,sizeof 就像是我们编程世界里的一个小助手,默默地帮我们把各种数据的“身材”量得清清楚楚。
有了它,我们就能更好地管理内存,让程序跑得更顺畅。
所以啊,朋友们,可别小看了 sizeof 哦!它虽然看起来不起眼,但在关键时刻,可是能发挥大作用的呢!好好利用它,让我们的编程之路更加顺畅吧!。
数组结束符sizeof
数组结束符sizeof数组是一种在编程中经常使用的数据结构,它由一系列相同类型的元素组成。
在C语言中,数组的大小通常通过数组的元素个数乘以每个元素占用的字节数来确定。
而在计算数组的大小时,sizeof运算符则是一个非常有用的工具。
sizeof运算符是C语言中的一个关键字,用于计算某个类型的对象所占用的字节数。
在使用sizeof运算符时,可以用它来计算数组的大小。
在C语言中,数组的大小是由数组的元素个数乘以每个元素所占用的字节数得到的。
在计算数组的大小时,sizeof运算符的使用方法是在sizeof后面加上数组名,并用括号括起来。
例如,如果有一个int类型的数组arr,那么可以使用sizeof(arr)来计算数组arr的大小。
sizeof运算符的返回值的类型是size_t,这是一种无符号整数类型。
它的大小足够大,可以表示任何对象的大小。
在实际编程中,可以使用%zu格式化字符来输出size_t类型的值。
需要注意的是,sizeof运算符计算的是整个数组所占用的内存空间的大小,并不仅仅是数组元素的个数。
在计算数组的大小时,sizeof运算符会将数组的元素个数乘以每个元素所占用的字节数,并返回结果。
使用sizeof运算符计算数组的大小具有以下几个优点:1. 精确:sizeof运算符能够准确地计算数组的大小,不会出现计算错误的情况。
这对于编写安全可靠的程序非常重要。
2. 灵活:sizeof运算符可以用于任何类型的数组,无论是基本类型还是自定义类型。
不同类型的数组可以使用同样的方式来计算大小。
3. 方便:sizeof运算符的使用非常简单,只需要在sizeof后面加上数组名,并用括号括起来即可。
不需要复杂的计算过程和额外的代码。
除了计算数组的大小之外,sizeof运算符还可以用于计算其他类型的对象的大小。
例如,可以使用sizeof运算符来计算结构体、联合体、指针等类型的对象所占用的字节数。
需要注意的是,在使用sizeof运算符计算指针类型的对象时,sizeof运算符实际上计算的是指针本身所占用的字节数,而不是指针指向的对象所占用的字节数。
sizeof用法 c语言 -回复
sizeof用法c语言-回复关于C语言中sizeof的用法在C语言中,sizeof是一个用来获取变量或数据类型的大小的关键字。
它可以用于任何数据类型,包括基本数据类型、结构体、数组等。
sizeof的使用方法非常简单,只需要在sizeof后面加上要获取大小的变量或数据类型即可。
例如,sizeof(int)就可以用来获取int类型的大小。
那么,为了更好地理解和掌握sizeof的用法,我们将逐步回答以下问题:1. sizeof的作用是什么?2. sizeof的用法有哪些?3. sizeof和strlen的区别是什么?4. sizeof的注意事项有哪些?5. 实例演示:如何在不知道数组长度的情况下获取数组大小?1. sizeof的作用是什么?sizeof用于获取变量或数据类型在内存中所占的字节数,它可以用来在编程过程中动态计算数据的大小。
2. sizeof的用法有哪些?sizeof可以用于获取变量或数据类型的大小。
它有两种常见的用法:- sizeof(变量):用于获取指定变量在内存中所占用的字节数。
- sizeof(数据类型):用于获取指定数据类型在内存中所占用的字节数。
例如,sizeof(int)将返回整型int在内存中所占用的字节数。
3. sizeof和strlen的区别是什么?sizeof和strlen都可以用来获取字符串的长度,但它们之间有一些区别:- sizeof用于获取字符串变量在内存中所占用的字节数,而不是字符串的实际长度。
即sizeof返回的是字符串所占用的空间大小,包括字符串中的字符和结尾的空字符'\0'。
- strlen用于获取字符串的实际长度,即字符串中的字符数量,不包括结尾的空字符'\0'。
strlen返回的是size_t类型的值。
4. sizeof的注意事项有哪些?- sizeof返回的是size_t类型的无符号整数。
- sizeof可以用于计算任何数据类型的大小,包括基本数据类型、结构体、指针等。
ARM内存边界对齐以及sizeof问题
不得不说,确实有那幺些质量较差的程序可能需要你部分自然对齐,部
分一字节对齐,此时
2.typedefstructpack{
}__attribute__((packed))
可利用__attribute__属性
当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
ARM内存边界对齐以及sizeof问题
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四
个字节来对齐的。看以下结构体
typedefstructpack{
chara;
intb;
shortc;
}pack;
对于Pack结构体,默认情况下在arm/386平台下(别的平台没试
过)sizeof(pack)=12,求解过程如下:
பைடு நூலகம்sizeof(char)=1;
下一个intb,由于是四个字节,要求b的开始地址从32的整数倍开始,
故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结
构体扩充为
chara;
chardump(3);
intb;
看shortc,现在c的前面有8个字节,c是两个字节,c的开始地址是从
#pramapack(1)
后,sizeof(pack)=142=7
而在arm下同样的操作sizeof(pack)=1421=8,即虽然b根a之间不要
填充但总的长度必须要是4的整数倍.
在arm下要使结构体按指定字节对齐,可行的方法
1.在makefile里加-fpack-struct选项,这样的话对所有的结构按一字节
16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,
C++中的sizeof 关键字详解
1、什么是sizeof首先看一下sizeof在msdn上的定义:The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t.看到return这个字眼,是不是想到了函数?错了,sizeof不是一个函数,你见过给一个函数传参数,而不加括号的吗?sizeof可以,所以sizeof不是函数。
网上有人说sizeof是一元操作符,但是我并不这么认为,因为sizeof更像一个特殊的宏,它是在编译阶段求值的。
举个例子:cout<<sizeof(int)<<endl; // 32位机上int长度为4cout<<sizeof(1==2)<<endl; // == 操作符返回bool类型,相当于cout<<sizeof(bool)<<endl;在编译阶段已经被翻译为:cout<<4<<endl;cout<<1<<endl;这里有个陷阱,看下面的程序:int a = 0;cout<<sizeof(a=3)<<endl;cout<<a<<endl;输出为什么是4,0而不是期望中的4,3???就在于sizeof在编译阶段处理的特性。
由于sizeof不能被编译成机器码,所以sizeof作用范围内,也就是()里面的内容也不能被编译,而是被替换成类型。
=操作符返回左操作数的类型,所以a=3相当于int,而代码也被替换为:int a = 0;cout<<4<<endl;cout<<a<<endl;所以,sizeof是不可能支持链式表达式的,这也是和一元操作符不一样的地方。
sizeof知识
Sizeof1. 定义:sizeof是何方神圣sizeof乃C/C++中的一个操作符(operator)是也,简单的说其作用就是返回一个对象或者类型所占的内存字节数。
MSDN上的解释为:The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types).This keyword returns a value of type size_t.其返回值类型为size_t,在头文件stddef.h中定义。
这是一个依赖于编译系统的值,一般定义为typedef unsigned int size_t;世上编译器林林总总,但作为一个规范,它们都会保证char、signed char和unsignedchar的sizeof值为1,毕竟char是我们编程能用的最小数据类型。
2. 语法:sizeof有三种语法形式,如下:1) sizeof( object ); // sizeof( 对象);2) sizeof( type_name ); // sizeof( 类型);3) sizeof object; // sizeof 对象;所以,int i;sizeof( i ); // oksizeof i; // oksizeof( int ); // oksizeof int; // error既然写法3可以用写法1代替,为求形式统一以及减少我们大脑的负担,第3种写法,忘掉它吧!实际上,sizeof计算对象的大小也是转换成对对象类型的计算,也就是说,同种类型的不同对象其sizeof值都是一致的。
这里,对象可以进一步延伸至表达式,即sizeof 可以对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。
如:sizeof( 2 );// 2的类型为int,所以等价于sizeof( int );sizeof( 2 + 3.14 ); // 3.14的类型为double,2也会被提升成double类型,所以等价于sizeof( double );sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用,我们来看一个完整的例子:char foo(){printf("foo() has been called.\n");return 'a';}int main(){size_t sz = sizeof( foo() ); // foo() 的返回值类型为char,所以sz = sizeof( char ),foo()并不会被调用printf("sizeof( foo() ) = %d\n", sz);}C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算sizeof值,即下面这些写法都是错误的:sizeof( foo );// errorvoid foo2() { }sizeof( foo2() );// errorstruct S{unsigned int f1 : 1;unsigned int f2 : 5;unsigned int f3 : 12;};sizeof( S.f1 );// error3. sizeof的常量性sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用,如:char ary[ sizeof( int ) * 10 ]; // ok最新的C99标准规定sizeof也可以在运行时刻进行计算,如下面的程序在Dev-C++中可以正确执行:int n;n = 10; // n动态赋值char ary[n]; // C99也支持数组的动态定义printf("%d\n", sizeof(ary)); // ok. 输出10但在没有完全实现C99标准的编译器中就行不通了,上面的代码在VC6中就通不过编译。
C语言--sizeof总结
C语⾔--sizeof总结sizeof的语法1:sizeof是C语⾔的关键字,⽤来计算变量、常量或数据类型在当前系统中占⽤内存的字节数。
…2:sizeof不是函数,产⽣这样的疑问是因为sizeof的书写确实有点像函数。
在程序中,sizeof有两种写法:1)⽤于数据类型:sizeof(数据类型)2)⽤于变量名:sizeof(变量名);sizeof变置名 //不建议这样使⽤代码⽰例:#include<stdio.h>int main() {int i;char str[20];printf("sizeof(i) is %d\n", sizeof(i));printf("sizeof i is %d\n", sizeof i);printf("sizeof int is %d\n", sizeof(int));//printf("sizeof int is %d\n", sizeof int);错误写法printf("sizeof(str) is %d\n", sizeof(str));printf("sizeof str is %d\n", sizeof str);printf("sizeof str is %d\n", sizeof (char[20]));//printf("sizeof str is %d\n", sizeof char[20]);错误写法printf("sizeof(365) is %d\n", sizeof(365));printf("sizeof(i love you) is %d\n", sizeof("i love you"));}结果:注:最后⼀个字符串之所以是11,是因为在C语⾔中字符串后边会默认添加⼀个结束符,也就是'\0'sizeof与strlensizeof是运算符,⽤来计算变量、常量或数据类型在当前系统中占⽤内存的字节数strlen是函数,⽤于计算字符串的实际长度代码⽰例:char ch[20];strcpy(ch, "i love you");printf("sizeof(ch) is %d\n", sizeof(ch));//地址长度20,不变printf("strlen(ch) is %d\n", strlen(ch));//字符串的实际长度,也就是i love you的长度,为10结构体内存对齐⾸先看⼀个例⼦:struct S{char a;int b;char c;};我们先来计算⼀下这个结构体的⼤⼩,如果不存在内存对齐这个问题,按理说这个结构体应该占(1+4+1)6个字节;然⽽事实上它占了12个字节,为什么?我们需要解决下⾯⼏个问题。
sizeof详解
sizeof详解sizeof是C和C++中的一个运算符,用于获取数据类型或变量所占用的字节数。
它的作用是在编译时确定数据类型或变量的大小,以便在程序中进行内存分配和操作。
在C和C++中,使用sizeof运算符可以得到不同数据类型的大小。
sizeof运算符的语法格式为:sizeof(type) 或者sizeof expression。
其中,type是数据类型,expression是数据类型或者变量的表达式。
sizeof运算符返回一个size_t类型的值,表示操作数所占用的字节数。
sizeof运算符的结果与编译器和平台有关,不同的编译器和平台可能有不同的实现。
通常,sizeof(char)的结果是1,即字符类型占用1个字节。
sizeof(int)的结果通常是4或者8,即整型类型占用4个或者8个字节,具体取决于编译器和平台的位数。
sizeof运算符可以用于计算数组的大小。
例如,对于一个整型数组int arr[10],可以使用sizeof(arr)来获取该数组占用的总字节数,即sizeof(int) * 10。
sizeof运算符还可以用于计算结构体、联合体和类的大小。
例如,对于一个结构体struct Person,可以使用sizeof(Person)来获取该结构体占用的总字节数,其中包括结构体内部的所有成员变量的大小。
在C++中,使用sizeof运算符还可以获取对象的大小。
例如,对于一个类的对象obj,可以使用sizeof(obj)来获取该对象占用的总字节数,其中包括对象内部的所有成员变量的大小。
需要注意的是,sizeof运算符只能用于静态类型,即在编译时已知的类型。
对于动态类型,如指针和引用,sizeof运算符只能返回它们本身的大小,而不是指向的对象的大小。
在使用sizeof运算符时,要注意避免出现歧义。
例如,对于一个指针,sizeof运算符返回的是指针本身的大小,而不是指针指向的对象的大小。
如果想要获取指针指向的对象的大小,可以通过解引用指针再使用sizeof运算符来实现。
详解C++sizeof(上)
详解C++sizeof(上)sizeof是C/C++中的⼀个操作符(operator),其作⽤是返回⼀个对象或者类型所占的内存字节数,使⽤频繁,有必须对其有个全⾯的了解。
1.sizeof的基本语法sizeof有三种语法形式。
(1)sizeof(object); //sizeof(对象);(2)sizeof(type_name); //sizeof(类型);(3)sizeof object; //sizeof对象;第三种语法结构虽然简约,但并不常见,为简单统⼀,建议使⽤第⼀和第⼆种写法。
int i;sizeof( i ); // oksizeof i; // oksizeof( int ); // oksizeof int; // error2.sizeof计算基本类型与表⽰式sizeof计算对象的⼤⼩实际上是转换成对象类型进⾏计算,也就是说,同种类型的不同对象其sizeof值都是⼀致的。
这⾥,对象可以进⼀步延伸⾄表达式,即sizeof可以对⼀个表达式求值,编译器根据表达式的最终结果类型来确定⼤⼩,sizeof是编译时进⾏运算,与运⾏时⽆关,不会对表达式进⾏计算。
考察如下代码:#include <iostream>using namespace std;int main(int argc,char* argv[]){cout<<"sizeof(char)="<<sizeof(char)<<endl;cout<<"sizeof(short)="<<sizeof(short int)<<endl;cout<<"sizeof(int)="<<sizeof(int)<<endl;cout<<"sizeof(long)="<<sizeof(long int)<<endl;cout<<"sizeof(long long)="<<sizeof(long int int)<<endl;cout<<"sizeof(float)="<<sizeof(float)<<endl;cout<<"sizeof(double)="<<sizeof(double)<<endl;int i=8;cout<<"i="<<i<<endl;cout<<"sizeof(i)="<<sizeof(i)<<endl;cout<<"sizeof(i)="<<sizeof(i=5)<<endl;cout<<"i="<<i<<endl;}在64bits的Windows下运⾏结果如下:sizeof(char)=1sizeof(short)=2sizeof(int)=4sizeof(long)=4sizeof(long long)=4sizeof(float)=4sizeof(double)=8i=8sizeof(i)=4sizeof(i)=4i=8观察以上程序需要注意两点。
c语言sizeof的返回值类型
c语言sizeof的返回值类型C语言中的sizeof关键字是一个用来获取数据类型或变量字节大小的运算符。
它的返回值类型是一个无符号整数,通常用size_t表示,其实质是一个unsigned int类型。
sizeof操作符可以用于获取各种数据类型的字节大小,包括基本数据类型(如int、float、double等)、自定义数据类型(如结构体、联合体等)以及指针类型。
在C语言中,每种数据类型都占用一定的内存空间,而sizeof可以帮助我们准确地获取到这个大小。
在使用sizeof时,可以使用两种形式。
一种是sizeof(类型),用来获取指定类型的字节大小;另一种是sizeof(变量),用来获取指定变量的字节大小。
例如,sizeof(int)可以获取int类型的字节大小,sizeof(float)可以获取float类型的字节大小,sizeof(struct Student)可以获取自定义结构体Student的字节大小。
需要注意的是,sizeof操作符并不会真正地计算变量或类型的字节大小,它在编译时就会被替换成一个常量。
这意味着sizeof操作符的计算结果是在编译时确定的,并不会因为程序运行时的实际数据而变化。
sizeof操作符的返回值类型是一个无符号整数,这是为了确保能够表示所有可能的字节大小。
无符号整数与有符号整数的区别在于,无符号整数只能表示非负数,而有符号整数可以表示正负数。
由于sizeof操作符获取的是字节大小,因此它的返回值类型必须是无符号整数,以确保能够表示所有可能的字节大小。
在实际编程中,sizeof操作符经常与其他运算符一起使用,例如在动态内存分配中,可以使用sizeof操作符来计算需要分配的内存空间大小。
另外,sizeof操作符还可以用来帮助判断数据类型的字节对齐方式,以及在处理网络通信或文件IO时,计算数据的字节大小。
需要注意的是,sizeof操作符不能直接用于获取动态分配的内存空间的大小。
sizeof 参数
sizeof 参数sizeof 参数是在编程中常用的一个关键字,用于获取数据类型或变量的大小。
在不同的编程语言中,sizeof 参数的用法和具体实现可能会有所差异,下面将以C语言为例,详细介绍sizeof 参数的用法和相关注意事项。
一、sizeof 参数的基本概念sizeof 是C语言中的一个运算符,用于计算数据类型或变量在内存中所占的字节数。
sizeof 参数可以是数据类型、变量、表达式或者函数名。
sizeof 参数的结果是一个整数值,表示所计算的数据类型或变量在内存中所占的字节数。
1. 计算数据类型的大小sizeof 参数可以直接跟数据类型名,用于计算该数据类型在内存中所占的字节数。
例如,sizeof(int) 用于计算整型数据在内存中所占的字节数,sizeof(float) 用于计算单精度浮点数在内存中所占的字节数。
2. 计算变量的大小sizeof 参数可以跟变量名,用于计算该变量在内存中所占的字节数。
例如,int a; sizeof(a) 用于计算整型变量a在内存中所占的字节数。
3. 计算表达式的大小sizeof 参数可以跟表达式,用于计算该表达式的结果在内存中所占的字节数。
例如,sizeof(a + b) 用于计算整型变量a和b相加的结果所占的字节数。
4. 计算函数名的大小sizeof 参数可以跟函数名,用于计算该函数所占的字节数。
注意,函数名在sizeof 参数中并不会被真正执行,只是用于计算函数的大小。
例如,sizeof(main) 用于计算主函数main所占的字节数。
三、sizeof 参数的注意事项1. sizeof 参数返回的是一个整数值,单位是字节。
不同的数据类型在内存中所占的字节数可能不同,需要根据具体的编程语言和编译器来确定。
2. sizeof 参数只能计算静态类型的大小,不能计算动态类型的大小。
例如,对于指针变量sizeof(p),返回的是指针本身的大小,而不是指针所指向的对象的大小。
c语言sizeof有关的计算
c语言sizeof有关的计算sizeof是C语言中的一个操作符,用于计算数据类型或变量在内存中所占的字节数。
它可以用来获取不同数据类型的大小,包括基本数据类型(如整型、浮点型)、数组、结构体等。
我们来看一下sizeof的基本用法。
在C语言中,使用sizeof操作符时,可以将其作用于数据类型或变量。
当作用于数据类型时,sizeof返回该数据类型在内存中所占的字节数。
例如,sizeof(int)将返回整型在内存中所占的字节数,通常是4个字节。
当作用于变量时,sizeof返回该变量所占的字节数。
sizeof的使用非常灵活,可以用于任何数据类型。
在C语言中,有以下几种常见的数据类型:1. 基本数据类型:包括整型、浮点型、字符型等。
sizeof可以用来计算这些基本数据类型的字节数。
例如,sizeof(int)返回4,sizeof(float)返回4,sizeof(char)返回1。
2. 指针类型:指针变量在内存中所占的字节数与机器的位数有关。
在32位机器上,sizeof指针变量通常是4个字节,在64位机器上通常是8个字节。
例如,sizeof(int*)返回4或8,取决于机器的位数。
3. 数组类型:数组在内存中是连续存储的一块数据区域。
使用sizeof可以计算数组所占的字节数。
例如,对于int nums[10]来说,sizeof(nums)返回40,因为int类型占4个字节,数组长度为10,所以总共占40个字节。
4. 结构体类型:结构体是由多个不同类型的成员变量组成的复合数据类型。
使用sizeof可以计算结构体所占的字节数。
例如,对于struct Person来说,sizeof(struct Person)返回16,因为结构体中有一个int类型的成员变量(占4个字节)和一个char类型的成员变量(占1个字节),总共占5个字节,但是由于对齐规则的存在,结构体的大小通常是成员变量中最大类型的整数倍,所以结构体的大小是16个字节。
sizeof的返回类型
sizeof的返回类型摘要:一、sizeof 的定义与作用二、sizeof 的返回类型1.整型数据类型2.浮点型数据类型3.字符型数据类型4.指针类型5.数组类型6.结构体类型7.联合体类型三、sizeof 与类型转换四、sizeof 与对象的大小五、sizeof 的局限性正文:sizeof 是一个在编程中常用的运算符,用于计算数据类型或对象的大小。
它的返回类型是一个整型数值,表示该数据类型或对象在内存中所占的字节数。
sizeof 运算符主要应用于C/C++等编程语言中。
sizeof 的返回类型取决于所计算的数据类型。
对于整型数据类型,如int、short、long 等,sizeof 返回的是该数据类型所占用的字节数。
对于浮点型数据类型,如float、double 等,sizeof 返回的是该数据类型所占用的字节数。
对于字符型数据类型,如char,sizeof 返回的是该数据类型所占用的字节数。
此外,sizeof 还可以用于计算指针类型、数组类型、结构体类型和联合体类型的大小。
指针类型的大小取决于所指向的数据类型,数组类型的大小取决于数组中元素的数量和元素类型的大小,结构体类型的大小取决于结构体中成员变量的大小,联合体类型的大小取决于联合体中成员变量的大小。
需要注意的是,sizeof 运算符不能用于类型转换。
例如,不能通过sizeof(int) 来判断一个变量是否为整型。
此外,sizeof 运算符只能计算对象在内存中的大小,不能反映对象在实际运行中的表现。
例如,一个字符串在内存中可能占用多个字节,但在显示时可能只显示其中的一部分。
总之,sizeof 是一个非常有用的运算符,可以帮助程序员了解数据类型和对象在内存中的大小。
然而,sizeof 也有一定的局限性,不能反映对象在实际运行中的表现和类型转换。
sizeof用法以及编程中常见问题
数组的sizeof
? 数组的sizeof值等于数组所占用的内存字节 数
? 数组元素的个数
char a1[] = abc;
int c1 = sizeof( a1 ) / sizeof( char ); // 总长 度/单个元素的长度
int c2 = sizeof( a1 ) / sizeof(总a长1[0]
struct S3 {
char c1; S1 s; char c2; };
sizeof(S3)?
? S1的最宽简单成员的类型为 int,S3在考虑最宽简 单类型成员时是将 S1“打散”看的,所以 S3的最 宽简单类型为 int,这样,通过 S3定义的变量,其 存储空间首地址需要被 4整除,整个sizeof(S3) 的 值也应该被 4整除。 c1的偏移量为 0,s的偏移量呢这时 s是一个整体, 它作为结构体变量也满足前面三个准则,所以其 大小为8,偏移量为 4,c1与s之间便需要3个填充 字节,而c2与s之间就不需要了,所以 c2的偏移量 为12,算上 c2的大小为 13,13是不能被 4整除的, 这样末尾还得补上 3个填充字节。最后得到 sizeof(S3) 的值为16。
函数返回类型的大小,函数并不会被调用 sizeof( foo() ) //这里foo的返回值不能为空,
否则非法
指针变量的sizeof
? 指针记录了另一个对象的地址。既然是来 存放地址的,那么它当然等于计算机内部 地址总线的宽度。所以在32位计算机中, 一个指针变量的返回值必定是4(注意结果 是以字节为单位)。
? 这里函数参数a3已不再是数组类型,而是 蜕变成指针,相当于char* a3。数组是“传 址”的,调用者只需将实参的地址传递过 去,所以a3自然为指针类型(char*),c3 的值也就为4。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
sizeof,终极无惑(上)sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着"辛苦我一个,幸福千万人"的伟大思想,我决定将其尽可能详细的总结一下。
但当我总结的时候才发现,这个问题既可以简单,又可以复杂,所以本文有的地方并不适合初学者,甚至都没有必要大作文章。
但如果你想"知其然,更知其所以然"的话,那么这篇文章对你或许有所帮助。
菜鸟我对C++的掌握尚未深入,其中不乏错误,欢迎各位扔砖砸蛋。
1. 定义sizeof是何方神圣?sizeof乃C/C++中的一个操作符(operator)是也,简单的说其作用就是返回一个对象或者类型所占的内存字节数。
MSDN上的解释为:The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types).This keyword returns a value of type size_t.其返回值类型为size_t,在头文件stddef.h中定义。
这是一个依赖于编译系统的值,一般定义为:typedef unsigned int size_t;世上编译器林林总总,但作为一个规范,它们都会保证char、signed char和unsigned char 的sizeof值为1,毕竟char是我们编程能用的最小数据类型。
2. 语法sizeof有三种语法形式,如下:1) sizeof( object ); // sizeof( 对象);2) sizeof( type_name ); // sizeof( 类型);3) sizeof object; // sizeof 对象;所以,int i;sizeof( i ); // oksizeof i; // oksizeof( int ); // oksizeof int; // error既然写法3可以用写法1代替,为求形式统一以及减少我们大脑的负担,第3种写法,忘掉它吧!实际上,sizeof计算对象的大小也是转换成对对象类型的计算,也就是说,同种类型的不同对象其sizeof值都是一致的。
这里,对象可以进一步延伸至表达式,即sizeof可以对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。
如:sizeof( 2 ); // 2的类型为int,所以等价于sizeof( int );sizeof( 2 + 3.14 ); // 3.14的类型为double,2也会被提升成double类型,所以等价于sizeof( double );sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用,我们来看一个完整的例子:char foo(){printf("foo() has been called./n");return 'a';}int main(){size_t sz = sizeof( foo() ); // foo() 的返回值类型为char,所以sz = sizeof( char ),foo()并不会被调用printf("sizeof( foo() ) = %d/n", sz);}C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算sizeof 值,即下面这些写法都是错误的:sizeof( foo ); // errorvoid foo2() { }sizeof( foo2() ); // errorstruct S{unsigned int f1 : 1;unsigned int f2 : 5;unsigned int f3 : 12;};sizeof( S.f1 ); // error3. sizeof的常量性sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用,如:char ary[ sizeof( int ) * 10 ]; // ok最新的C99标准规定sizeof也可以在运行时刻进行计算,如下面的程序在Dev-C++中可以正确执行:int n;n = 10; // n动态赋值char ary[n]; // C99也支持数组的动态定义printf("%d/n", sizeof(ary)); // ok. 输出10但在没有完全实现C99标准的编译器中就行不通了,上面的代码在VC6中就通不过编译。
所以我们最好还是认为sizeof是在编译期执行的,这样不会带来错误,让程序的可移植性强些。
4. 基本数据类型的sizeof这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型,由于它们都是和系统相关的,所以在不同的系统下取值可能不同,这务必引起我们的注意,尽量不要在这方面给自己程序的移植造成麻烦。
一般的,在32位编译环境中,sizeof(int)的取值为4。
5. 指针变量的sizeof学过数据结构的你应该知道指针是一个很重要的概念,它记录了另一个对象的地址。
既然是来存放地址的,那么它当然等于计算机内部地址总线的宽度。
所以在32位计算机中,一个指针变量的返回值必定是4(注意结果是以字节为单位),可以预计,在将来的64位系统中指针变量的sizeof结果为8。
char* pc = "abc";int* pi;string* ps;char** ppc = &pc;void (*pf)(); // 函数指针sizeof( pc ); // 结果为4sizeof( pi ); // 结果为4sizeof( ps ); // 结果为4sizeof( ppc ); // 结果为4sizeof( pf ); // 结果为4指针变量的sizeof值与指针所指的对象没有任何关系,正是由于所有的指针变量所占内存大小相等,所以MFC消息处理函数使用两个参数WPARAM、LPARAM就能传递各种复杂的消息结构(使用指向结构体的指针)。
6. 数组的sizeof数组的sizeof值等于数组所占用的内存字节数,如:char a1[] = "abc";int a2[3];sizeof( a1 ); // 结果为4,字符串末尾还存在一个NULL终止符sizeof( a2 ); // 结果为3*4=12(依赖于int)一些朋友刚开始时把sizeof当作了求数组元素的个数,现在,你应该知道这是不对的,那么应该怎么求数组元素的个数呢?Easy,通常有下面两种写法:int c1 = sizeof( a1 ) / sizeof( char ); // 总长度/单个元素的长度int c2 = sizeof( a1 ) / sizeof( a1[0] ); // 总长度/第一个元素的长度写到这里,提一问,下面的c3,c4值应该是多少呢?void foo3(char a3[3]){int c3 = sizeof( a3 ); // c3 == ?}void foo4(char a4[]){int c4 = sizeof( a4 ); // c4 == ?}也许当你试图回答c4的值时已经意识到c3答错了,是的,c3!=3。
这里函数参数a3已不再是数组类型,而是蜕变成指针,相当于char* a3,为什么?仔细想想就不难明白,我们调用函数foo1时,程序会在栈上分配一个大小为3的数组吗?不会!数组是"传址"的,调用者只需将实参的地址传递过去,所以a3自然为指针类型(char*),c3的值也就为4。
7. 结构体的sizeof这是初学者问得最多的一个问题,所以这里有必要多费点笔墨。
让我们先看一个结构体:struct S1{char c;int i;};问sizeof(s1)等于多少?聪明的你开始思考了,char占1个字节,int占4个字节,那么加起来就应该是5。
是这样吗?你在你机器上试过了吗?也许你是对的,但很可能你是错的!VC6中按默认设置得到的结果为8。
Why?为什么受伤的总是我?请不要沮丧,我们来好好琢磨一下sizeof的定义——sizeof的结果等于对象或者类型所占的内存字节数,好吧,那就让我们来看看S1的内存分配情况:S1 s1 = { 'a', 0xFFFFFFFF };定义上面的变量后,加上断点,运行程序,观察s1所在的内存,你发现了什么?以我的VC6.0为例,s1的地址为0x0012FF78,其数据内容如下:0012FF78: 61 CC CC CC FF FF FF FF发现了什么?怎么中间夹杂了3个字节的CC?看看MSDN上的说明:When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.原来如此,这就是传说中的字节对齐啊!一个重要的话题出现了。
为什么需要字节对齐?计算机组成原理教导我们这样有助于加快计算机的取数速度,否则就得多花指令周期了。
为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。
这样,两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了。
让我们交换一下S1中char与int的位置:struct S2{int i;char c;};看看sizeof(S2)的结果为多少,怎么还是8?再看看内存,原来成员c后面仍然有3个填充字节,这又是为什么啊?别着急,下面总结规律。
字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
对于上面的准则,有几点需要说明:1) 前面不是说结构体成员的地址是其大小的整数倍,怎么又说到偏移量了呢?因为有了第1点存在,所以我们就可以只考虑成员的偏移量,这样思考起来简单。