关于C#:处理内存时是否需要乘以sizeof(char)?

Is it necessary to multiply by sizeof( char ) when manipulating memory?

使用malloc并执行类似的内存操作时,我可以依靠sizeof(char)始终为1吗?

例如,我需要为char类型的N个元素分配内存。 是否需要乘以sizeof( char )

1
char* buffer = malloc( N * sizeof( char ) );

或者我可以依靠sizeof(char)始终为1并跳过乘法

1
char* buffer = malloc( N );

我完全理解sizeof是在编译期间求值的,然后编译器甚至可以编译出乘法,因此性能损失将最小并且很可能为零。

我主要是在询问代码的清晰度和可移植性。 char类型是否需要这种乘法?


根据定义,sizeof(char)始终等于1。一个字节是C语言中字符的大小,无论一个字节中的位数是多少(普通台式机CPU上为8)。

一个字节不是8位的典型示例是PDP-10和其他旧的,类似微型计算机的9/36位字节的体系结构。但是我相信不是2 ^ N的字节变得非常不常见

另外,我认为这是更好的样式:

1
2
3
4
5
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,这将得出表达式值的大小:

1
2
3
char a;
printf("A char's size is %u
"
, (unsigned int) sizeof a);

这将始终在所有符合标准的C实现中打印1

我也非常同意David Cournapeau的观点,并考虑在malloc() -call中重复键入类型名称,这也是一种反模式。

代替

1
2
3
char *str;

str = malloc(N * sizeof (char));

很多人会写来分配N个字符容量的字符串缓冲区,我会

1
2
3
char *str;

str = malloc(N * sizeof *str);

或者(仅对于字符串)忽略上述的sizeof,但是这当然是更通用的,并且对于任何类型的指针都一样有效。


尽管没有必要,但我认为保留sizeof(char)是一种很好的做法,因为它使代码更易读并且避免使用幻数。另外,如果以后需要更改代码,以便将某个对象的大小分配给该对象的指针,而不是char,则比只有" 1"更容易更改代码。


没有必要。参见此处(例如)。

C标准将sizeof(char)定义为始终为1(字节)。请注意,由于sizeof返回多个字节,因此每个字节的位数无关紧要(实际上,无论如何都是8)。


摘自"新C标准。经济和文化评论"。

  • 统计资料:sizeof的2.0%来自char,而1.5%-来自unsigned char。第1033页的1.2版本的书。
  • 第1037页。
  • The number of bits in the representation of a character type is
    irrelevant. By definition the number
    of bytes in byte a character type is
    one.

    Coding Guidelines Developers sometimes
    associate a byte as always containing
    eight bits. On hosts where the
    character type is 16 bits, this can
    lead to the incorrect assumption that
    applying sizeof to a character type
    will return the value 2.
    These issues are discussed elsewhere.


    还有一点要记住的是,编译器静态知道sizeof(char)的值为1,并且还知道将数字乘以静态1意味着不需要进行乘法;编译器将对其进行优化。出于这些原因,不应考虑性能问题。


    使用sizeof(char)使您的代码更具可读性和可移植性。

    在x86上,我们都知道一个字符是1个字节。但是明确写下来可以使您的意图更清晰,这始终是一件好事。

    另外,如果您的代码被放置在字符不是1个字节的其他平台上,该怎么办。如果一个字符只有4位怎么办?

    同意,这不是必须的,但不会降低运行时间,在极少数情况下,您需要将代码移植到其他体系结构上,这是有回报的。