sizeof的另外一种实现方法 -- 指针偏移

sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。

sizeof操作符以字节形式给出了其操作数的存储大小,存储大小由操作数的类型决定,操作数可以是一个表达式或括在括号内的类型名。操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。sizeof的优先级为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式。

sizeof操作符的主要用途:计算类型存储空间大小。

详细官方解释可以参考wiki


The sizeof operator  -- C99 standard (ISO IEC9899)

Constraints

The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that
designates a bit-field member.


Semantics

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer.Ifthe type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

When applied to an operand that has type char, unsigned char,or signed char, (or a qualified version thereof) the result is 1. When applied to an operand that has array type, the result is the total number of bytes in the array. When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.


The value of the result is implementation-defined, and its type (an unsigned integer type) is size_t,defined in <stddef.h> (and other headers).


这里我们用编译器固有特性,从软件角度实现sizeof_shift函数,用于计算不同类型的存储大小。

关键代码如下:

#define sizeof_shift(type) ((type)((type *)0 + 1))


原理:type类型的指针NULL加上一个type类型的偏移获取到第二个偏移的位置,此时这个位置的值正好就是type类型的字节数。

实现代码:

#include <stdio.h>

#define sizeof_shift(type) ((type)((type *)0 + 1))

int main()
{
        printf("                   sizeof(int)/sizeof_shit(int): %d/%d\r\n", sizeof(int), sizeof_shift(int));
        printf("      sizeof(short int)/sizeof_shift(short int): %d/%d\r\n", sizeof(short int), sizeof_shift(short int));
        printf("sizeof(unsigned int)/sizeof_shift(unsigned int): %d/%d\r\n", sizeof(unsigned int), sizeof_shift(unsigned int));
        printf("                sizeof(char)/sizeof_shift(char): %d/%d\r\n", sizeof(char), sizeof_shift(char));
        return 0;
}

在gcc (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)环境下:


实验结果表明与gcc操作符给出的结果一致。

网上最近有很多讨论总线位宽的问题,希望通过软件代码来获取。如果仅仅是软件方法是很难知道的,因为硬件被编译器给屏蔽了。


唯有一个比较合理的方法,通过OS或者BSP来获取硬件细节,如果有这样的系统API支持,那么获取总线宽度等硬件细节也就比较合理了。这里打个不恰当的比方,如果软件通过I2C发送命令给IC slave,但是总线频率是多少,其实上层应用软件并不知道,只有通过BSP提供的接口,查询I2C寄存器或者BSP内部初始化数据才能获取硬件细节。但是这些对于大部分应用软件来说都不是那么重要。


推荐:深入理解sizeof

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值