当前位置:首页 >> 信息与通信 >>

c语言详解sizeof


c 语言详解 sizeof
原文地址:http://blog.sina.com.cn/s/blog_5da08c340100bmwu.html

一、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 的结果(以下结果都是在 Linux v2.6 gcc v4 获取) sizeof 操作符的结果类型是 size_t 它在头文件中定义为: typedef unsigned int size_t; 该类型保证能容纳实现所建立的最大对象的字节大小. 1、ANSI C 正式规定字符类型为 1 字节。 sizeof(char) = 1; sizeof(unsigned char) = 1; sizeof(signed char) = 1; 2、其他类型在 ANSI C 中没有具体规定,大小依赖于实现。

sizeof(int) = 4; sizeof(unsigned int) = 4; sizeof(short int) = 2; sizeof(unsigned short) = 2; sizeof(long int) = 4; sizeof(unsigned long) = 4; sizeof(float) = 4; sizeof(double) = 8; sizeof(long double) = 12; 3、当操作数是指针时,sizeof 依赖于编译器。
Microsoft C/C++7.0 中,near 类指针字节数为 2,far、huge 类指针字节数为 4。 一般 Unix/Linux 的指针字节数为 4。 例如: char *p; //Linux 中 sizeof(p) = 4; 4、当操作数具有数组类型时,其结果是数组的总字节数。 例如: char a[5]; int b[5]; sizeof(a) = 5; sizeof(b) = 20; 5、当操作数是具体的字符串或者数值时,会根据具体的类型进行相应转化。 例如: sizeof(8) = 4; //自动转化为 int 类型 sizeof(8.8) = 8; //自动转化为 double 类型,注意,不是 float 类型 sizeof("ab") = 3 //自动转化为数组类型, //长度是 4,不是 3,因为加上了最后的'\n'符 //有资料说,会自动转化为指针类型(Linux 为 4) //可能和操作系统与编译器有关系 6、当操作数是联合类型时,sizeof 是其最大字节成员的字节数。 当操作数是结构类型时,sizeof 是其成员类型的总字节数,包括补充字节在内。 还是让我们拿例子来说话: union u{ //对 union 来说 char c; double d; }u; sizeof(u) = max(sizeof(c),sizeof(d)) = sizeof(1,8) = 8; struct a{ //对 struct 来说 char b; double x; }a; 在 Linux 上: sizeof(a) = 12;

而一般 sizeof(char) + sizeof(double) = 9; 这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。 但如果全对齐的话,sizeof(a) = 16, 这是因为 b 被放到偏移量为 0 的地址,占 1 个字节; 在存放 x 时,double 类型长度为 8,需要放到能被 8 整除的偏移量上,这时候需要补 7 个空字 节, 达到 8 个,这时候偏移量为 8,放上 x 后长度为 16。 在此例中,所有的结构成员都要放在被 4 整除的地址(Linux 的存放方式),这里补 3 个字节, 所以为 12。 7、当操作数是函数中的数组形参或函数类型的形参: sizeof 给出其指针的大小,Linux 中值为 4。 四、sizeof 与其他操作符的关系 sizeof 的优先级为 2 级,比/、%等 3 级运算符优先级高。 它可以与其他操作符一起组成表达式: 例如: int i = 10; i * sizeof(int); 五、sizeof 的主要用途 1、主要用途是与存储分配和 I/O 系统那样的例程进行通信。 例如: void size_t *malloc(size_t fread(void size); size, size_t nmemb, FILE * stream); *ptr, size_t

2、另一个的主要用途是计算数组中元素的个数。 例如: void *memset(void *s, int c, sizeof(s));



C 语言中 sizeof 与 strlen 区别 2
1. 以字符串形式出现的,编译器都会为该字符串自动添加一个 0 作为结束符,如在代码中 写 "abc", 那 么 编 译 器 帮 你 存 储 的 是 "abc\0". 2. 字 符 串 直 接 量 作 为 字 符 指 针 的 初 始 值 "hello"是一个字符串直接量,编译器将其作为 const char*处理,与之相关联的内存空 间位于内存的只读部分,即允许编译器重用指向等价字符串直接量的引用以优化内存使 用 , 即使程序 中使用了字符串直接量 500 次,编译器在内存中也只是创建了一个实例。例 如 : char *ptr = “ hello ” ; 等 价 于 const char *ptr = “ hello ” ; 字符串直接量"hello"关联的是只读内存,如果试图修改将出错,例如 ptr[1] = ‘a’; 是 会 引 起 错 误 的 。 3. 字 符 串 直 接 量 作 为 基 于 栈 的 字 符 数 组 的 初 始 值 由于基于栈的变量不可能引用其他地方存储的内存,编译器会负责将字符串直接量复制 到 基 于 栈 的 数 组 内 存 中 。 例 如 : char stackArray[] = “ hello ” ; 做 如 下 修 改 : stackArray[1] = ‘ a ’ ; 是 真 确 的 。 4. 字 符 数 组 与 字 符 指 针 字 符 数 组 的 形 式 如 下 , 会 将 字 符 直 接 量 拷 贝 到 栈 上 : char str[] = "abc"; // 实 际 的 数 据 存 储 : a b c \0, 也 就 是 增 加 了 一 个 终 结 符 \0 char str[3] = {'a','b','c'}; // 实 际 的 数 据 存 储 : a b c, 并 没 有 在 最 后 添 加 终 结 符 char str[10] = {'a','b','c'}; // 实 际 的 数 据 存 储 : a b c \0 \0 \0 \0 \0 \0 \0 字 符 指 针 的 形 式 如 下 : char *str = “ abc”; // 实 际 的 数 据 存 储: a b c \0, 也 就 是 增 加了 一 个终 结 符 \0 5. 类 型 的 决 定 1). 数 组 的 类 型 是 由 该 数 组 所 存 放 元 素 的 类 型 以 及 数 组 本 身 的 大 小 决 定 的 如 char s1[3]和 char s2[4],s1 的类型就是 char[3],s2 的类型就是 char[4],也就是说尽管 s1 和 s2 都 是 字 符 数 组 , 但 两 者 的 类 型 却 是 不 同 的 。 2). 字 符 串 常 量 的 类 型 可 以 理 解 为 相 应 字 符 常 量 数 组 的 类 型 如"abcdef"的类型就可以看成是 const char[7],也就是说实际的数据存储为"abcdef\0"。 3). 函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型 如对于 void func(char sa[100],int ia[20],char *p),则 sa 的类型为 char*,ia 的类型为 int*,p 的 类 型 为 char* 。 对 于 sizeof 与 strlen: 1. sizeof 操作符的结果类型是 size_t,它在头文件中 typedef 为 unsigned int 类型。该类型 保 证 能 容 纳 实 现 所 建 立 的 最 大 对 象 的 字 节 大 小 。 2. sizeof 是 算 符 , strlen 是 函 数 。 3. sizeof 可以用类型做参数,strlen 只能用 char*做参数,且必须是以''\0''结尾的。 4. 数 组 做 sizeof 的 参 数 不 退 化 , 传 递 给 strlen 就 退 化 为 指 针 了 。 5. 大部分编译程序在编译的时候就把 sizeof 计算过了,是类型或是变量的长度这就是 sizeof(x) 可 以 用 来 定 义 数 组 维 数 的 原 因 。 char str[20]="0123456789"; // str 是 编 译 期 大 小 已 经 固 定 的 数 组

int a=strlen(str); // a=10; //strlen() 在 运 行 起 确 定 , 计 算 的 是 实 际 长 度 int b=sizeof(str); // 而 b=20; //sizeof()在编译期确定,str 的类型是 int[20], 计算的是占据内 存 的 大 小 6. strlen 的结果要在运行的时候才能计算出来,是用来计算字符串的实际长度,不是类 型 占 内 存 的 大 小 。 7. sizeof 后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为 sizeof 是个 操 作 符 不 是 个 函 数 。 char c; sizeof 8. 当 当 适 sizeof sizeof c; // 变 量 名 可 以 不 加 括 适 用 于 一 个 结 构 类 型 或 变 量 , sizeof 返 回 实 际 的 大 小 用 一 静 态 地 空 间 数 组 , sizeof 归 还 全 部 数 组 的 尺 寸 操作符不能返回动态地被分派了的数组或外部的数组的尺 、 strlen 计 算 字 符 数 组 、 字 符 指 针 空 弧 , 。 寸 间

char str[] = "abc"; 实际的数据存储: a b c \0,也就是增加了一个终结符\0 其类型为 char[4] VS: sizeof(str)=4 strlen(str) = 3 GCC: sizeof(str)=4 strlen(str) = 3 char str[] = {'a','b','c'}; 实际的数据存储: a b c,并没有在最后添加终结符 其类型为 char[3] VS: sizeof(str)=3 strlen(str) = 15 GCC: sizeof(str)=3 strlen(str) = 6 Linux-c sizeof(str1)=3 strlen(str1)=18 char str[5] = {'a','b','c','d','e'}; 实际的数据存储: a b c d e ,并没有在最后添加终结符 其类型为 char[5] VS: sizeof(str)=5 strlen(str) = 19 GCC: sizeof(str)=5 strlen(str) = 8 char str[5] = {'a','b','c','d'}; 实际的数据存储: a b c d \0(默认填充字符\0) 其类型为 char[5] sizeof(str)=5 strlen(str) GCC: sizeof(str)=5 strlen(str) = = VS: 4 4

char *pstr = "abcde"; 实际的数据存储: a b c d e \0 pstr 的类型为 char* sizeof(pstr) = 4 ( 指针 的 数 据 存 储 空 间 , 4 个 字 节 ) , strlen(pstr) = 5 总 结 一 下 : 1). sizeof 的结果是类型的大小,区分类型之后,sizeof 的结果也就命了,sizeof 的结果是在编 译 期 决 定 的 , 计 算 的 占 据 的 内 存 大 小 。 srelen 的结果是在运行期间决定,计算的是实际长度,strlen 只能以 char*作参数,以\0 作为 结 束 符 , 以 上 的 例 子 中 , 红 色 部 分 的 strlen 计 算 是 错 误 的 , 因 为在 str 的 数据 存储中 并没 有 一 个\0 字符, 所以 strlen 的 结果看似 有点 异常 。 2). 注 意 在 计 算 sizeof 的 时 候 : char str[] = "abc"; 类 型 为 char[4], sizeof(str) = 4*sizeof(char) = 4. 3). sizeof(express),其 中的 express 在 编译过 程中 是不会 被编 译的, 而是 被替代 类型。 例 如 : int a = 1; sizeof(a=2); 此时的 express 为 a=2, 在编译过程中被替换为 sizeof(int),所以在执行完之后,a 仍然是等于 1. 4). 对 函 数 使 用 sizeof , 在 编 译 阶 段 会 被 替 换 为 函 数 的 返 回 值 的 类 型 取 代

例 如 : int f(){return 0;} sizeof(f()); 的 结 果 为 void f(){} sizeof(f());编译过程中会出现错误,替换之后的 sizoeof(void)编译无法通过.

4.

c 语言中有关 void,sizeof,结构体的一些问题

void[1]: void 是 C 语言中的空类型,void 的用途有二。 1、对函数返回的限定; 如果函数没有返回值, 则默认返回整数类型, 而不是 void 类型。 c++ 有很严格的类型,不允许函数不加类型声明,而编译器则不这么认为 检查这一点在 VC6.0 中可以验证。所以在编写代码的时候,每个函 数都应该加上返回类型。 2、对函数参数的限定; 在 c++中,函数参数为 void 意味着不接受参数,但是在 c 语言中可 以给无参数的函数传递任意类型的参数,这点在 turbo c 中可以验 证。 指针的大小和机器的位数有关,在 32 位机器上任何类型指针的大小 都是 4 字节,在 64 位机器上为 8。所以指针大小和类型无关。 void*就是空类型指针,所谓空类型指针就是通用指针类型。它有以 下特点。1、按照 ASC 码标准 void 指针不能做算术操作,因为不确 定其指向数据类型大小; 2、c++允许将任何类型的指针赋给 void*,但是不允许 void 指针 赋值给其它类型。必须显示的强制转换。

其它类型指针相互之间是否也可以强制装换? 强制转换后编译能通过,大部分情况下运行也是没有问题的,但是根 据参考文献[4]的说法是容易出问题的, 因为某些 CPU 对某些数据类 型有对其限制,这样在做指针强制转换的时候就容易出现问题。 其实,其它类型指针之间的转换完全可以通过使用 void*类型来避 免。

sizeof[2]: 前面说在同一台机器上指针大小是固定的,通过 sizeof 测试 int*,char*,bool*,double*都出结果都是 4(32 位机器测试)。 今天在程序中 memset 一个 T*类型的指针,发现没有初始化成功, 原来在 memset 的第三个参数中填的是 sizeof(T*类型的指针)。特 此总结了一下 sizeof 的一些问题。 1、char* s="0123456789"; sizeof(s)=4,s 是一个指针。 sizeof(*s)=1,*s 是第一个元素。 strlen(s)=10,s 是字符串首地址。 2、char s[]="0123456789"; sizeof(s)=11,s 是字符串数组,包括'\0'。 sizeof(*s)=1,*s 是第一个元素。 strlen(s)=10,s 是字符串首地址。

3、char s[20]="0123456789"; sizeof(s)=20,s 是在内存中静态分配的大小。 sizeof(*s)=1,*s 是第一个元素。 strlen(s)=10,s 是字符串首地址。

结构体[3]: 结构体在字节对齐的时候有三个原则, 有了这三个原则就很容易的可 以计算出任意一个结构体的 sizeof 大小了。 1、结构体变量的首地址能够被其最宽基本类型的成员大小所整除; 2、结构体每个成员相对于结构体首地址的偏移量(offset)都是成员 大小的整数倍,如有需要编译器会在成员之间加上填充字节 (internal adding); 3、结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有 需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

参 [1]







: 、

http://blog.sina.com.cn/s/blog_625cce080100kip3.html [2] [3] http://blog.csdn.net/Linux_Gao/article/details/2612885 、 http://shansun123.iteye.com/blog/398601 、

[4] http://blog.csdn.net/Linux_Gao/article/details/2612885




相关文章:
解析C语言中的sizeof
解析C 语言中的 sizeof 一,sizeof 的概念 sizeofC 语言的一种单目操作符,如 C 语言的其他操作符++,--等.它 并不是函数.sizeof 操作符以字节形式给出...
详细解析C语言Sizeof关键字_(程序员笔试常见问题)
详细解析C语言Sizeof关键字_(程序员笔试常见问题)_IT/计算机_专业资料。程序员笔试常见Sizeof关键字问题sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也...
C语言学习(sizeof())总结
C语言学习(sizeof())总结 这是我学习C语言的一点小心得,分享给大家这是我学习C语言的一点小心得,分享给大家隐藏>> C 语言学习总结 关仁杰 #include<stdio.h...
C++中的sizeof 关键字详解
c语言详解sizeof 9页 1下载券 解析C语言的SIZEOF 5页 1下载券 初学C积累解析...sizeof 可以,所以 sizeof 不是函数。网上有人说 sizeof 是一 元操作符,但是我...
C语言选择题+解析
("%c%c%c%c\n",a,b,c,d); ) 解析:C语言中利用sizeof()函数判断数据类型长度,在VC6.0平台中,整 则输出结果是( A) 12 34 C) 1234 ) B) 12 D)...
c语言中struct 的长度详解
c语言中struct 的长度详解_计算机软件及应用_IT/计算机_专业资料。struct中内存长度sizeof论struct 的长度 2009-12-16 23:14 什么是对齐,以及为什么要对齐: 现代计...
C语言字符的长度计算strlen和sizeof
C语言字符的长度计算strlen和sizeof_数学_自然科学_专业资料。C 语言字符的长度计算 strlen 和 sizeof。 #include<stdio.h>//输出 wang Zhao.注意中间要有空格的...
C语言基本细节剖析
C语言基本细节剖析_IT/计算机_专业资料。运算符入门: 注意:算数运算符(加减...("c:\t%d\n",sizeof(c)); printf("d:\t%d\n",sizeof(d)); printf(...
辨析C语言中的strlen和sizeof函数
辨析C语言中的strlen和sizeof函数_IT/计算机_专业资料。辨析 C 语言中的 strlen...(s),sizeof(s)); } 这题的运行结果为 5,15 解析: 字符数组 s 中的字符...
C语言详解
C 语言详解 - 枚举类型 http://www.cnblogs.com/JCSU/articles/1299051.html...sizeof(spring)); // 4 bytes /* Weekday */ printf("sizeof Weekday is:...
更多相关标签: