C/C++ sizeof运算符:为什么sizeof('a')返回不同的值?

14 浏览
0 Comments

C/C++ sizeof运算符:为什么sizeof('a')返回不同的值?

可能是重复问题:

C/C++中字符'a'的大小

我是C的初学者,对此感到困惑。

C:我尝试使用"%zu"修饰符在C中打印sizeof('a'),它打印出一个值4。

C++:在C++中使用cout和printf(使用上述格式)打印sizeof('a'),都打印出一个值1。

我相信正确的值应该是1,因为'a'将被视为一个char。为什么C中它不返回4?这两种语言中的sizeof操作是否不同?如果是这样,有什么区别,为什么返回不同的值?

我在两种情况下都使用了gcc编译器。

0
0 Comments

在C语言中,`'a'`是一个字符常量,它被视为整数,所以得到的大小是4,而在C++中它被视为一个`char`类型。这是一个重复的问题,可以在这里找到答案:Size of character ('a') in C/C++。我曾经尝试搜索,但没有找到任何相关的问题。谢谢你让我知道这个重复问题。

-1:在C语言中,没有对整数的大小进行定义,除了与`char`和`long`的大小有关的定义。

- 如果你阅读链接的答案,你可以清楚地在第一个和唯一的答案的评论中看到`int`的`sizeof`是与平台相关的。我没有解决这个问题,因为1. 链接的帖子已经解决了这个问题,我期望一个mod来关闭这个帖子;2. 鉴于提问者的问题背景,显然他的机器上`int`的`sizeof`是4。

:这并不能改变一个事实,即许多C编程错误是由于断言`int`是4个字符而引起的,而你的回答继续传播这个错误的神话。如果你知道4是不正确的,为什么还要写上呢?我认为我们必须同意各自的观点,这是我一直以来的一个痛点。

0
0 Comments

在C语言中,字符字面值(常量)的类型为int。因此,考虑下面的程序:

#include 
main(int argc, char *argv[])
{
  printf("%zu\n", sizeof('a'));
  printf("%zu\n", sizeof('ab'));
  printf("%zu\n", sizeof('abc'));
  printf("%zu\n", sizeof('abcd'));
  printf("%u\n", 'a');
  printf("%u\n", 'ab');
  printf("%u\n", 'abc');
  printf("%u\n", 'abcd');
  printf("%x\n", 'a');
  printf("%x\n", 'ab');
  printf("%x\n", 'abc');
  printf("%x\n", 'abcd');
  printf("%c\n", 'a');
  printf("%c\n", 'ab');
  printf("%c\n", 'abc');
  printf("%c\n", 'abcd');
}

前四个语句都将字面值视为一个字符常量,并且它们都打印出4,即sizeof(int),至少在gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3上是这样的。请注意,这个编译器对上述程序输出了多个警告:

warning: multi-character character constant

基本上,字符字面值指定了构成一个int的四个字节,从左到右,高位字节在前。缺失的前导字节填充为0。因此,在我的机器上,第二组和第三组printf语句的输出是:

97
24930
6382179
1633837924
61
6162
616263
61626364

在十六进制输出中,你可以看到字面值中四个字符的布局(从左到右的ASCII码):'a'映射到最高位字节0x61。最后,第四组打印:

a
b
c
d

即字符字面值被推送到栈上作为整数,但printf只打印该整数的最低字节作为字符。C++的行为类似,但一字节的字符字面值被认为是char类型,而不是int类型。下面的程序:

#include 
using namespace std;
main(int argc, char *argv[])
{
  cout << sizeof('a') << endl;
  cout << sizeof('ab') << endl;
  cout << sizeof('abc') << endl;
  cout << sizeof('abcd') << endl;
  cout << 'a' << endl;
  cout << 'ab' << endl;
  cout << 'abc' << endl;
  cout << 'abcd' << endl;
}

将使用GCC编译并给出类似的警告。它的输出与C语言的输出不同:

1
4
4
4
a
24930
6382179
1633837924

因此,一字节的字符字面值被视为char类型,而多字节的字面值被视为int类型。

重要提示:我在一个32位的Linux系统上运行了我的测试,其中int占用4个字节。有趣的是看看其他系统上会发生什么,比如64位的系统。

编辑:修正回答(感谢提示):字符字面值在C中的类型为int,它们不会被强制转换为int。大多数系统都有4字节的int,除了16位的系统。

小的不正确之处:字符常量不会被强制转换为int,它们在C中的类型为int。谢谢,我会修复这个问题。这意味着每次赋值时它们都会被强制转换为char。

我从未见过一个int占用64位的实现,但据我所知,最初的想法是在C中,int对应于处理器寄存器的宽度。不过,我认为在64位处理器上,char应该是8位,short应该是16位,int应该是32位,long应该是64位(对我来说,64位的int感觉有点奇怪)。

另外,我有点惊讶在小端架构上'abcd'被表示为0x61626364,我以为会是0x64636261。

64位int的问题在于你会在整数类型层次结构的较低部分有一个“间隙”,并且无法使用标准类型实现int32_t。

是的,这就是我所想的。在整数层次结构的较低部分会有一个间隙,而int、long和long long类型会重叠(除非例如long是128位,long long是256位)。

0