【问题标题】:How many 'char' types are there in C?C中有多少'char'类型?
【发布时间】:2018-08-23 00:58:18
【问题描述】:

我一直在阅读“KnR”的“The C Programming Language”一书,我遇到了这样的说法: “普通字符有符号或无符号”

  1. 所以我的问题是,什么是普通字符,它与 有符号字符和无符号字符?
  2. 在下面的代码中,'myPlainChar' - 'A' 与 'mySignChar' - 'A' 和 'myUnsignChar' - 'A'?
  3. 谁能解释一下“可打印字符是 总是积极的”。

注意:请写例子并解释。谢谢。

{
    char myChar = 'A';
    signed char mySignChar = 'A';
    unsigned char myUnsignChar = 'A';
}

【问题讨论】:

  • 最好将第三个问题作为一个新问题发布。与前两者关系不大。如果你这样做,我将撤回我的近距离投票。
  • "Printable char's are always positive" 那是错误的,不是吗?如果有的话,不可打印的将是在大多数编码中总是在正范围内的那些(因为 ISO 编码至少不添加任何不可打印的字符除了 ASCII 字符),对吧?

标签: c


【解决方案1】:

signed charunsigned charchar 默认是有符号还是无符号取决于编译器及其设置。通常是签名的。

【讨论】:

  • “通常是有符号的”使无符号变体看起来很不寻常,这取决于您如何衡量“通常”。
  • @IanAbbott 如果在 90% 的情况下签名,这是“通常”。例如 GCC + VC。
  • 也许,也许不是。如果以基于 ARM 的 Android 手机主导操作系统市场的市场份额来衡量,那么“未签名”将获胜。所以这取决于你如何衡量“通常”。
【解决方案2】:

char 类型只有一种,就像int 类型只有一种。

但就像int 一样,您可以添加一个修饰符来告诉编译器它是无符号的还是有符号的char(或int):

signed char   x1;  // x1 can hold values from -128 to +127 (typically)
unsigned char x2;  // x2 can hold values from 0 to +255 (typically)
signed int    y1;  // y1 can hold values from -2147483648 to +2147483647 (typically)
unsigned int  y2;  // y2 can hold values from 0 to +4294967295 (typically)

普通未修改的charint 之间的最大区别在于,没有修饰符的int总是被签名,但如果@,它是定义的实现(即取决于编译器) 987654330@不带修饰符是有符号还是无符号:

char x3;  // Could be signed, could be unsigned
int  y3;  // Will always be signed

【讨论】:

  • signedunsigned 可以单独使用,所以我认为将它们称为修饰符是不正确的。
  • @IanAbbott signedunsigned 本身实际上只是 signed intunsigned int 的别名(分别)。
  • 并非如此。相反,signedunsignedcharshortintlonglong long 的某些合法组合会产生某些非限定整数类型,其中一些是相同的。
  • @IanAbbott 我也有同样的想法,但犹豫了;我知道这是关于 C,而不是 C++,但 C++ 中的一个简单检查是重载有符号、无符号和纯字符的函数,并使用每个参数进行调用。它会编译吗?是的。编译器选择了什么?每个相应的函数,即即使 char 在功能和实现上与有符号/无符号类型之一相同,C++ 编译器仍将其视为不同类型而不是别名。 C 对字符类型关系有特定的措辞吗? [哦,对 OP 的评论中的链接引用了 C99 中的注释 35。]
  • @IanAbbott intsigned int 的位域不同。在这种情况下,int 可能已签名或未签名。
【解决方案3】:

普通的char 是拼写为char 的类型,没有signedunsigned 前缀。

普通 charsigned charunsigned char 是三种不同的整数类型(是的,字符值是(小)整数),即使普通 char 与一个表示相同其他两个。哪一个是实现定义的。这与 int 不同:普通的 int 始终与 signed int 相同。

这里有一个微妙的地方:如果普通的char 是有符号的,那么它就是一个有符号的类型,我们说“普通字符是在这个系统上签名的”,但它仍然是不是signed char 相同的类型。

这两行的区别

signed char mySignChar = 'A';
unsigned char myUnsignChar = 'A';

和这两行的区别完全一样:

signed int mySignInt = 42;
unsigned int myUnsignInt = 42;

“Printable char's are always positive”这句话的意思正是它所说的。在某些系统上,一些普通的 char 值是负数。在所有系统上,一些有符号字符值都是负数。在所有系统上,每种类型的字符都恰好为零。但这些都不是可打印的。不幸的是,语句不一定正确(对于基本执行字符集中的所有字符都是正确的,但对于扩展执行字符集则不正确)。

【讨论】:

  • "但它仍然是 notsigned char 相同的类型-以什么方式(在“char 默认为签名”系统上)可以区分这两种类型?
  • @psmears 它们的运行时行为完全相同,但例如char*signed char* 是不同的指针类型,只能通过显式转换才能相互转换。所以如果一个函数被声明为int func(const signed char*),你不能调用它func("abc"),编译器会报错。
  • 啊,是的,关于指针转换的好点,我只考虑原始类型:)
  • 对字符和其他整数类型之间区别的有趣澄清。
  • @n.m.我明白你说的一切,但究竟有什么区别?
【解决方案4】:

C 中有多少种 char 类型?

有一种char 类型。有 3 种小字符类型:charsigned charunsigned char。它们在 C 中统称为字符类型

charsigned charunsigned char 具有相同的范围/大小/排名/编码,但却是不同的类型。


  1. 什么是普通字符,它与有符号字符和无符号字符有何不同?

它们是 C 中的 3 种不同类型。普通字符 char 将匹配与 singed charunsigned char 相同的范围/大小/排名/编码。在所有情况下,大小都是 1。


2 .myPlainChar - 'A'mySignChar - 'A'myUnsignChar - 'A' 有何不同?

myPlainChar - 'A' 将匹配另外两个之一。
通常,mySignChar 的值在 [-128...127] 范围内,myUnsignChar 在 [0...255] 范围内。因此,减去'A'(通常为 65)会产生不同范围的潜在答案。


  1. 谁能解释一下“Printable char's are always positive”的说法。

可移植的 C 源代码字符(basic 执行字符集)是正数,因此打印源代码文件只会打印非负值的字符。

当打印带有printf("%c", some_character_type)putc(some_character_type) 值的数据时,正数或负数都会在打印前转换为unsigned char。因此,它是一个与打印的非负值相关联的字符。

C 有isprint(int c),它“测试包括空格在内的任何打印字符”。该函数仅对unsigned char 范围内的值和负值EOF 有效。 isprint(EOF) 报告 0。因此只有非负值通过 isprint(int c) 测试。

如果不转换为unsigned char,C 确实无法将负值打印为字符。

【讨论】:

  • 如果 char 的范围与 signed char 的范围相同,那么即 -128 - +127 那么普通 char 与 signed char 的细微差别是什么? -> 因为这三个的大小相同,即 1 字节,编码也相同。
  • @shaiknisarahmed “如果 char 与 signed char 具有相同的范围......普通 char 与 signed char 的细微差别是什么?”两种类型具有相同的大小 (1)、相同的范围、秩(整数转换秩)和编码(2 的补码、1 的补码、符号幅度)。在 C 中,两种不同的类型可能共享相同的属性。不同之处在于它们仍然是不同的类型。区分a的方法见_Generic(a):是输入char还是输入signed char
【解决方案5】:

我认为这意味着前面没有“无符号”的字符,即:

unsigned char a;

相对

char a; // signed char

所以基本上一个变量总是有符号的(对于整数和字符),除非你使用“无符号”语句。

这也应该回答第二个问题。

第三个问题:ascii 集中的字符被定义为无符号字符,即数字-60 不代表字符,但65 可以,即'A'。

【讨论】:

  • 部分正确,大部分错误。如果charsignedunsigned,则定义它的实现。
  • @Someprogrammerdude 我想可以在上下文中说最后半句是正确的(-60 不代表 ASCII 字符,真的);其他一切都错了。
猜你喜欢
  • 2023-02-22
  • 1970-01-01
  • 2012-07-19
  • 1970-01-01
  • 2016-07-15
  • 2016-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多