操作内存时是否需要乘以sizeof(char)?
-
06-07-2019 - |
题
当使用malloc并进行类似的内存操作时,我可以依赖sizeof(char)总是1吗?
例如,我需要为 char
类型的N个元素分配内存。乘以 sizeof(char)
是必要的:
char* buffer = malloc( N * sizeof( char ) );
或者我可以依赖sizeof(char)始终为1并且只是跳过乘法
char* buffer = malloc( N );
我完全理解在编译期间会对 sizeof
进行评估,然后编译器甚至可以编译出乘法,因此性能损失最小,很可能为零。
我主要询问代码清晰度和可移植性。对于 char
类型,这个乘法是否必要?
解决方案
虽然没有必要,但我认为留下sizeof(char)是一种好习惯,因为它使代码更具可读性并避免使用幻数。此外,如果稍后需要更改代码,以便代替char将某些内容的大小拼接成该对象的指针,则更改代码比仅使用“1”更容易。
其他提示
根据定义,sizeof(char)总是等于1.一个字节是C中字符的大小,无论字节中的位数是多少(普通桌面CPU上有8位)。
一个字节不是8位的典型示例是 PDP-10 和其他旧的,类似迷你计算机的架构,具有9/36位字节。但是,我认为不是2 ^ N的字节变得非常罕见
另外,我认为这是更好的风格:
char* buf1;
double* buf2;
buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);
因为它适用于指针类型。
sizeof(char)
始终为1。
但是, sizeof(TCHAR)
可能会因您的编译器选项而异。
我认为它有点像反模式。它表明程序员并不完全知道他/她在做什么,这会立即将其余代码强加给人。
当然,它不是(引用维基百科)“无效”,但我发现它“远非最佳”。它不会在运行时花费任何成本,但它会使代码混乱不必要的垃圾,同时表明有人认为有必要。
另外,请注意表达式不会解析为函数调用: sizeof
不是函数。你没有调用一个函数传递它的神奇符号 char
。您正在将内置的一元前缀运算符 sizeof
应用于表达式,并且您的表达式在这种情况下是对 char
类型的强制转换,在C中将其写为<代码>(char)的代码>
完全有可能,并且强烈建议尽可能在其他表达式上使用 sizeof
,然后它将产生表达式值的大小:
char a;
printf("A char's size is %u\n", (unsigned int) sizeof a);
这将始终在所有符合要求的C实现上打印 1
。
我也非常同意David Cournapeau,并考虑在 malloc()
中重复名称类型 - 调用 是一种类型的反模式。
而不是
char *str;
str = malloc(N * sizeof (char));
许多人会编写分配N字符容量的字符串缓冲区,我会选择
char *str;
str = malloc(N * sizeof *str);
或者(仅限字符串)省略 sizeof
,如上所述,但这当然更通用,对任何类型的指针也一样。
没有必要。请参阅此处(例如)。
sizeof(char)
由C标准定义为始终 1 (字节)。请注意,因为 sizeof
返回多个字节,每个字节的位数无关紧要(实际上也是8)。
要记住的其他事情是编译器静态地知道sizeof(char)的值是1并且它也知道将数字乘以静态1意味着不需要进行乘法;编译器会优化它。对表现的担忧不应以这些理由加以考虑。
来自“新C标准”。经济和文化评论“。
- 统计:2.0%的sizeof来自
char
,1.5%来自unsigned char
。在1.2版本的书中的页面1033。 - 第1037页。 醇>
字符类型表示中的位数是 无关。根据定义的数量 字节类型为字节的字节数 之一。
编码指南有时候是开发人员 将一个字节关联为始终包含 八位。在主机上 字符类型是16位,这可以 导致错误的假设 将sizeof应用于字符类型 将返回值2。 这些问题在别处讨论过。
使用sizeof(char)可以使代码更具可读性和可移植性。
在x86上,我们都知道一个字符是1个字节。但明确地将其写下来有助于使你的意图更加清晰,这总是一件好事。
此外,如果您的代码被放置在字符不是1字节的其他平台上,该怎么办?如果一个字符只有4位而该怎么办?
同意,没有必要,但它不会减慢您的运行时间,并且在极少数情况下您需要将代码移植到不同的架构中才能获得回报。