当使用malloc并进行类似的内存操作时,我可以依赖sizeof(char)总是1吗?
例如,我需要为类型为char
的N个元素分配内存。乘以必要的sizeof( char )
:
char* buffer = malloc( N * sizeof( char ) );
或者我可以依赖sizeof(char)始终为1并且只是跳过乘法
char* buffer = malloc( N );
我完全理解在编译期间评估sizeof
,然后编译器甚至可以编译出乘法,因此性能损失将是最小的,很可能为零。
我主要询问代码清晰度和可移植性。对于char
类型,这个乘法是否必要?
答案 0 :(得分:27)
根据定义,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);
因为它适用于指针类型。
答案 1 :(得分:14)
sizeof(char)
总是1。
但是,sizeof(TCHAR)
可能会因您的编译器选项而异。
答案 2 :(得分:11)
我认为它有点anti-pattern。它表明程序员并不完全知道他/她在做什么,这会立即将其余的代码投射出来。
当然,它不是(引用维基百科)“无效”,但我发现它“远非最佳”。它不会在运行时花费任何成本,但它会使代码混乱不必要的垃圾,同时表明有人认为有必要。
另外,请注意表达式不会解析为函数调用: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()
中重复名称类型 - 对的调用是一种反模式。< / p>
而不是
char *str;
str = malloc(N * sizeof (char));
许多人会编写分配N字符容量的字符串缓冲区,我会选择
char *str;
str = malloc(N * sizeof *str);
或者(仅限字符串)如上所述省略sizeof
,但这当然更通用,对任何类型的指针也一样。
答案 3 :(得分:6)
没有必要。请参阅here(例如)。
sizeof(char)
由C标准定义为始终 1 (字节)。请注意,因为sizeof
返回多个字节,所以每个字节的位数无关紧要(实际上也是8)。
答案 4 :(得分:6)
虽然没有必要,但我认为留下sizeof(char)是一种好习惯,因为它使代码更具可读性并避免使用幻数。此外,如果稍后需要更改代码,那么代替char而不是将某个东西的大小拼接成该对象的指针,与仅仅只有“1”相比,更改代码更容易。
答案 5 :(得分:3)
要记住的其他事情是编译器静态地知道sizeof(char)的值是1并且它也知道将数字乘以静态1意味着不需要进行乘法;编译器会优化它。对表现的担忧不应以这些理由加以考虑。
答案 6 :(得分:3)
来自“新C标准。经济和文化评论”。
char
和1.5%来自unsigned char
。在1.2版本的书中的页面1033。字符类型表示中的位数是 无关。根据定义的数量 字节类型为字节的字节数 之一。
编码指南有时候是开发人员 将一个字节关联为始终包含 八位。在主机上 字符类型是16位,这可以 导致错误的假设 将sizeof应用于字符类型 将返回值2。 这些问题在别处讨论过。
答案 7 :(得分:-4)
使用sizeof(char)可以使代码更具可读性和可移植性。
在x86上,我们都知道一个字符是1个字节。但明确地将其写下来有助于使你的意图更加清晰,这总是一件好事。
此外,如果您的代码被放置在字符不是1字节的其他平台上,该怎么办?如果一个字符只有4位而该怎么办?
同意,这不是必要的,但它不会减慢您的运行时间,并且在极少数情况下您需要将代码移植到不同的架构中才能获得回报。