C语言中的sizeof解析
1. 定义:
sizeof是C/C++中的一个操作符(operator),作用就是返回一个对象或者类型所占的内存字节数。返回
值类型为size_t,在头文件stddef.h中定义。这是一个依赖于编译系统的值,一
般定义为typedef unsigned int size_t;编译器林林总总,但作为一个规范,都会保证char、signed
char和unsigned char的sizeof值为1,毕竟char是编程能用的最小数据类型。
MSDN上的解释为:
The sizeof keyword gives the amount of storage, in bytes, associated with avariable or a
type (including aggregate types). This keyword returns a value of type
size_t.
2. 语法:
sizeof有三种语法形式,如下:
1) sizeof( object ); // sizeof( 对象 );
2) sizeof( type_name ); // sizeof( 类型 );
3) sizeof object; // sizeof 对象;
所以一下三种sizeof的使用都是对的
#include <stdio.h>
main()
{
int b;
printf("%d\n",sizeof b);
printf("%d\n",sizeof(b));
printf("%d\n",sizeof(int));
}
4. 基本数据类型的sizeof
这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型,由于它们都是和系
统相关的,所以在不同的系统下取值可能不同,这务必引起我们的注意,尽量不要在
这方面给自己程序的移植造成麻烦。一般的,在32位编译环境中,sizeof(int)的取值为4。
5. 指针变量的sizeof
等于计算机内部地址总线的宽度。所以在32位计算机中,一个指针变量的返回值必定是4(注意结果是以
字节为单位),可以预计,在将来的64位系统中指针变量的sizeof结果为8。
指针变量的sizeof值与指针所指的对象没有任何关系,正是由于所有的指针变量所占内存大小相等,所以
MFC消息处理函数使用两个参数WPARAM、LPARAM就能传递各种复杂的消息结构(使用
指向结构体的指针)。
6. 数组的sizeof
数组的sizeof值等于数组所占用的内存字节数,如:
char a1[] = "abc";
int a2[3];
sizeof( a1 ); // 结果为4,字符 末尾还存在一个NULL终止符
sizeof( a2 ); // 结果为3*4=12(依赖于int)
sizeof当作了求数组元素的个数是不对的,求数组元素的个数有下面两种写法:int c1 = sizeof( a1 )
/ sizeof( char ); // 总长度/单个元素的长度
int c2 = sizeof( a1 ) / sizeof( a1[0] ); // 总长度/第一个元素的长度.注意数组名做函数参数传递
时退化为指针。
7. 结构体的sizeof
struct S1
{
char c;
int i;
};
sizeof的结果等于对象或者类型所占的内存字节数,好吧,那就让我们来看看S1的内存分配情况:S1 s1
= { 'a', 0xFFFFFFFF };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值就增长了。
1.sizeof是运算符,跟加减乘除的性质其实是一样的,在编译的时候进行执行,而不是在运行时才执行。
那么如果编程中验证这一点呢?
#include<iostream>
using namespace std;
int main()
{
int i=1;
cout<<i<<endl;
sizeof(++i);
cout<<i<<endl;
return 1;
}
输入结果为 1
1
sizeof中的++i 的副作用并没有显示出来,原因只可能有一个,在编译的时候sizeof执行以后将++i 处理了,++i 的副作用因此被消除了。如果sizeof 是在运行时进行的话,则肯定要注意++i 。实际上sizeof的实现应该是用宏来做的,宏在编译时进行执行。具体实现可以参考下面。
2.sizeof('a')在C语言中的结果是4,在C++中结果是1,看过某篇文章说C中sizeof侧重于“数”,而C++中sizeof更侧重于“字符”。
3.文章中讲了两个用宏实现sizeof的经典应用
//适用于非数组 #define _sizeof(T) ((size_t)((T*)0 + 1)) //适用于数组 #define array_sizeof(T) ((size_t)(&T+1)-(size_t)(&T))
先举两个小例子说明两个宏的应用,对于第一个如 _sizeof(int); 的结果就是4;对于第二个先声明一个大小为4的数组int a[4];那么array_sizeof(a)结果为16.
对于非数组的宏定义,先是将0转换为T*类型的指针所指向的地址(此时地址为0)。然后对T类型的地址加1,相当于加上了T类型的大小(即得到了非数组T的大小)。前面的size_t只是将地址转化为int型的整数返回。
一个简单的例子:int* p; p=p+1; --------p是一个int*类型的指针, p+1在地址空间上相当于加上了4个字节。
对于数组的宏定义,类似于非数组的宏定义,为了方便理解,这里可以把数组T看成一个用户自定义的类型,&T表示数组类型的指针,对于数组类型指针加1相当于在地址上加上了该数组大小。由于是用户自定义的类型所以不能强制将0转化为数组类型的地址,只能用加1后的地址减去之前的地址,得到的差值就是数组本身所占的字节大小。
C语言中的sizeof解析的更多相关文章
- 转]解析C语言中的sizeof
解析C语言中的sizeof 一.sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++.--等.它并不是函数.sizeof操作符以字节形式给出 了其操作数的存储大小.操作数 ...
- c语言中的c语言中realloc()函数解析
c语言中realloc()函数解析 真是有点惭愧,这些内容本应该很早就掌握的,以前只是糊里糊涂的用,不知道在内存中具体是怎么回事,现在才弄清楚. realloc(void *__ptr, size_t ...
- C语言中的sizeof()
sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着"辛苦我一个,幸福千万人"的伟大思想,我决定将其尽可能详细的总结一下. 但当我总结的时候才发现,这个 ...
- C语言中的sizeof和strlen
1.sizeof是算符,strlen是函数: 2.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的: 3.大部分编译程序,在编译的时候就把sizeof计算 ...
- C语言中的sizeof函数总结
sizeof函数的结果: 变量:变量所占的字节数. ; printf( 数组:数组所占的字节数. ,,,,}; ] = {,,,,}; printf("size_arr1=%d\n" ...
- c语言中realloc()函数解析
一.基本特性 1. realloc()函数可以重用或扩展以前用malloc().calloc()及realloc()函数自身分配的内存. 2. realloc()函数需两个参数:一个是包含地址的指针( ...
- 对C语言中sizeof细节的三点分析
转自对C语言中sizeof细节的三点分析 1.sizeof是运算符,跟加减乘除的性质其实是一样的,在编译的时候进行执行,而不是在运行时才执行. 那么如果编程中验证这一点呢?ps:这是前两天朋友淘宝面试 ...
- C语言中.h和.c文件解析(很精彩)
C语言中.h和.c文件解析(很精彩) 简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析 ...
- C语言中.h和.c文件解析
整理自C语言中.h和.c文件解析(很精彩) Part.1(林锐<高质量C/C++编程>) 通过头文件来调用库功能.在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的 ...
随机推荐
- java基础复习+大数运算
String: Array: 下面分别是大数加法,加法,乘法,取模
- UCSC下载ENCODE数据
ENCODE数据库用于存放基因组原件,所有的测序数据(原始数据以及每一步处理后的数据以及最终的结果)都是开放下载的.假如说去官网下载的话会比较麻烦,这里可以通过UCSC的数据库下载(真的是神器啊)!下 ...
- 蚂蚁代理免费代理ip爬取(端口图片显示+token检查)
分析 蚂蚁代理的列表页大致是这样的: 端口字段使用了图片显示,并且在图片上还有各种干扰线,保存一个图片到本地用画图打开观察一下: 仔细观察蓝色的线其实是在黑色的数字下面的,其它的干扰线也是,所以这幅图 ...
- GCT学习总结
GCT的一个综合的考试性质,时间紧,题量大,这个时候需要我们快速.准确的答题,把自己的能力展现在其中,十一期间和同学们一起学习.讨论,大家都提高很大,各科谈一下自己的心得 数学: 数学相对来说还是不难 ...
- Programming In Scala笔记-第七章、Scala中的控制结构
所谓的内建控制结构是指编程语言中可以使用的一些代码控制语法,如Scala中的if, while, for, try, match, 以及函数调用等.需要注意的是,Scala几乎所有的内建控制结构都会返 ...
- [图论]最大流问题(Maximum flow)的定义
首先定义网络(network)N =(V,E), V表示顶点(Vertices)集合, E表示边(Edges)集合. s,t是V中的两个顶点,分别表示网络N中的源点(source)和汇点(sink). ...
- Swagger API接口管理
介绍 Swagger API框架,用于管理项目中API接口,属当前最流行的API接口管理工具. Swagger功能强大,UI界面漂亮,支持在线测试等! Swagger包 ...
- 【伯乐在线】HashMap的工作原理
本文由 ImportNew - 唐小娟 翻译自 Javarevisited.欢迎加入翻译小组.转载请见文末要求. HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道Ha ...
- Hazelcast集群原理分析
简介 hazelcast其中一个很重要的应用就是可以将多个应用服务器组成一个分布式环境的应用,形成一个cluster.这个cluster可以选举出一个master来对外工作.而cluster中的各台服 ...
- 19 Handler 总结
Handler 一, 回顾异步任务 AsyncTask 二, android 使用线程的规则 1,在主线程 不能做阻塞操作 2,在主线程之外的线程不能更新Ui 三, Handler的作用 1,在子线程 ...