在动态分配char
s时,我总是这样做:
char *pCh = malloc(NUM_CHARS * sizeof(char));
然而,我最近被告知,使用sizeof(char)
是冗余和不必要的,因为"根据定义,a的大小char
是一个字节",所以我应该/可以像这样编写上面的行:
char *pCh = malloc(NUM_CHARS);
我的理解是char的大小取决于目标计算机上使用的本机字符集.例如,如果本机字符集是ASCII,则a char
是一个字节(8位),如果本机字符集是UNICODE,char
则必然需要更多字节(> 8位).
为了提供最大的可移植性,是不是必须使用sizeof(char)
,因为malloc
只需分配8位字节?我误解malloc
和sizeof(char)
?
在C99标准草案部分6.5.3.4
sizeof操作符段3种状态:
当应用于具有char,unsigned char或signed char(或其合格版本)类型的操作数时,结果为1. [...]
在C11标准草案中,它是第4段,但措辞是相同的.所以NUM_CHARS * sizeof(char)
应该相当于NUM_CHARS
.
我们可以从byte的定义中3.6
看到它是:
可寻址的数据存储单元,其大小足以容纳执行环境的基本字符集的任何成员
和注2说:
一个字节由一个连续的位序列组成,其数量是实现定义的.最低有效位称为低位; 最重要的位称为高位.
是的,它是多余的,因为语言标准指定sizeof (char)
为1.这是因为这是测量事物的单位,所以当然单位本身的大小必须是1.
对于以自身定义的单位,生活变得奇怪,这根本没有任何意义.许多人似乎"想要"假设"有8位字节,并sizeof
告诉我有多少这样的特定值".这是错误的,根本不是它的工作方式.确实存在字符大于8位的平台,这就是我们拥有的原因CHAR_BIT
.
通常你总是"知道"当你分配角色时,但如果你真的想要包括sizeof
,你应该考虑让它使用指针,而不是:
char *pCh = malloc(NUM_CHARS * sizeof *pCh);
这"锁定"被分配事物的单元大小,该指针用于存储分配结果.如果你看到这样的代码,这两种类型应该匹配:
int *numbers = malloc(42 * sizeof (float));
这是一个巨大的警告信号; 通过使用sizeof
你左手边的指针使得那种类型的错误成为不可能,我认为这是一个很大的胜利:
int *numbers = malloc(42 * sizeof *numbers);
此外,如果您更改了指针的名称,malloc()
那么如果您在其中具有(错误的)基本类型的名称,则可能无法编译.存在轻微的风险,如果你忘记了星号(而sizeof numbers
不是写sizeof *numbers
),你就不会得到你想要的东西.在实践中(对我而言)这似乎永远不会发生,因为对我来说星号已经很好地建立了这种模式的一部分.
此外,这种用法依赖于(并强调)sizeof
不是函数的事实,因为()
指针解引用表达式周围不需要s.这是一个很好的奖励,因为很多人似乎都想否认这一点.:)
我发现这种模式非常令人满意,并推荐给大家.