C语言关键字浅析-sizeof

### C语言关键字浅析系列 ###

### ISO/ANSI C 关键字 ###

sizeof,本意为size of sth.,指某个事物的尺寸/长度

在C语言中,sizeof的用法与其名字也基本吻合,而且不同于其他常见的用于类型声明的或者作为限定词的关键字

类似于++和--,sizeof关键字是C语言的一个单目运算符

也就是说在某些计算上我们才会用到sizeof关键字

 

sizeof的作用是:

作为单目运算符,以字节形式给出其操作数的存储大小。

 

1、sizeof的格式和优先级

sizeof与操作数的格式一般要根据操作数的类型而定:

char ch;
sizeof(char);   /* 数据类型作为操作数必须加小括号 */
sizeof(ch);     /* 变量作为操作数,以下两种形式均可,即可以省略小括号 */
sizeof ch;      /* 但习惯上还是会都加上小括号,该行这种写法很少见,不过也是正确的 */

sizeof的对象是有限制的,不是所有的C语言的东西都能拿来sizeof一下,比如以下这些东西就不能拿来sizeof:

bool max(){return true;}   /* 定义一个函数 */
sizeof(max);               /* 非法操作,不能对函数sizeof */

int M;        /* M未知 */
float f[M];   /* 数组f长度未知 */
sizeof(f);    /* 这是一种不完全类型,即未知存储大小的数据类型,不完全类型不能被sizeof */
sizeof(void); /* 不完全类型,不能被sizeof。其他常见不完全类型还有:未知内容的结构或联合 */

/* 不能被sizeof的有:函数类型、不完全类型、位字段 */

既然sizeof是C的一个单目运算符,其必有自己的优先级,通常sizeof为2级优先级,与常见的几个单目运算符都是一级

比如* & ! ~ ++ --,2级比3级的高,3级的有/(除)、 %(求模)、 *(乘)

 

2、sizeof的结果

sizeof形式上看神似一个函数,但它并不是函数,不过它的运算结果需要一个称之为size_t的类型来存储

从其在头文件中的定义我们能看出它的本质:typedef unsigned int size_t;

所以其实我们能得到的结果是一个整数,意指字节形式表示的操作数的存储大小

在ISO/ANSI C标准中有这样的规定,规定char类型为1个字节长度,故以下类型的sizeof结果都是1:

sizeof(char);            /* 字符类型 */
sizeof(unsigned char);   /* 无符号字符类型 */
sizeof(signed char);     /* 有符号字符类型 */

字符类型是在标准中规定过的,所以一般各种机器平台里面的C的字符类型都是1,但其他类型由于标准中未规定,所以长度不一定统一

以目前的趋势——64位的系统为例:

/* 以下只是某个机器上的类型长度,具体数据根据系统和机器而定 */
sizeof(int) = 4;	sizeof(unsigned int) = 4;	sizeof(short) = 2;	sizeof(unsigned short) = 2;
sizeof(long int) = 4;	sizeof(unsigned long) = 4;	sizeof(long long) = 8;
sizeof(float) = 4;	sizeof(double) = 8;	 sizeof(long double) = 8;

/*
	指针类型比较特殊,其大小是依赖于编译器的,在Microsoft C/C++ 7.0中,near类指针是2byte,far和huge类指针是4byte
	在UNIX/Linux系统中指针通常为4byte,如下面这条伪代码
*/
char *p;
sizeof(p) = 4;

对确定的数组sizeof,得到的结果是数组的总大小,即等于数组长度乘以元素的存储大小:

char a[10];
sizeof(a) = 10;   /* char的长度是1byte,数组长度为10,结果为1*10=10 */
int b[10];
sizeof(b) = 40;   /* int的长度为4byte,数组长度为10,结果为4*10=40 */

对常量形式的操作数,会先按照常量的形式转化到相应类型,再sizeof:

sizeof(3) = 4;    /* 整数常量,默认是int */
sizeof(3.14) = 8; /* 浮点常量,默认是double */
sizeof("abcd");   /* 字符串常量,其类型根据系统而定,可能会是数组类型或者指针类型 */

对于结构和联合,其sizeof的计算方式类似,但又有区别:

union u
{
	char a;     /* sizeof(char) = 1 */
	int b;      /* sizeof(int) = 4 */
	double c;   /* sizeof(double) = 8 */
};
sizeof(u) = 8;   /* 对于联合,sizeof是计算联合的成员中存储空间最大的,此联合中double最大,故sizeof得到8 */

struct s
{
	char a;     /* sizeof(char) = 1 */
	int b;      /* sizeof(int) = 4 */
	double c;   /* sizeof(double) = 8 */
};
sizeof(s) = 13;  /* 对于结构,sizeof是计算所有成员的存储空间之和,即1+4+8=13,注意Linux中的C可能不是这个计算方式 */

/* 注意:对以上这种结构体进行sizeof运算,得到的结果可能不是13,而是16,这是因为有的系统自动优化将结构体的成员进行了对齐,比如使得char变量占用了4byte内存 */

3、sizeof的用途

相比类似的++和--,sizeof也许在初学C的时候几乎很少用,但这不妨碍它在其他地方发挥其用武之地

比如常见的计算数组中元素个数的函数:

void * memset(void * s, int c, sizeof(s));

再就是与存储分配和I/O系统那样的例程进行通信:

void *malloc(size_t size);

sizeof_t fread(void* ptr , size_t size , size_t nmemb , FILE* stream);

 

——参考《C Primer Plus第五版》

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值