Answers:
在C ++中,存在三种不同的字符类型:
charsigned charunsigned char如果将字符类型用于文本,请使用不限定的字符char:
'a'或的类型'0'。"abcde"它也可以作为数字值计算,但是不确定该值是带符号的还是无符号的。注意通过不等号进行字符比较-尽管如果将自己限制为ASCII(0-127),则几乎是安全的。
如果将字符类型用作数字,请使用:
signed char,该范围至少为-127至127。(-128至127是常见的)unsigned char,该值至少为0到255。“至少”,因为C ++标准仅给出了每种数字类型都必须覆盖的最小范围的值。sizeof (char)要求1为1(即一个字节),但是理论上一个字节可以是例如32位。sizeof仍将其大小报告为1 -表示您可以拥有sizeof (char) == sizeof (long) == 1。
sizeof因为它不是函数,而是运算符。取变量的大小时,省略括号是一种更好的样式。sizeof *p或sizeof (int)。这样可以快速弄清楚是否适用于类型或变量。同样,在后面加上括号也是多余的return。这不是功能。
char:这是字符文字的类型,例如'a'或'0'。” 在C ++中是正确的,但在C中不是。在C中,'a'是int。
这取决于实现,因为C标准没有定义的符号char。根据平台的不同,char可能是signed或unsigned,因此您需要明确要求signed char或unsigned char您的实现是否依赖于它。仅char在您打算表示字符串中的字符时使用,因为这将与您的平台在字符串中放置的字符匹配。
signed char和之间的区别unsigned char是您所期望的。在大多数平台上,signed char将是8位二进制补码,范围是从-128到127,并且unsigned char将是8位无符号整数(0to 255)。注意,该标准不要求char类型具有8位,仅要求sizeof(char)return 1。您可以在位的数量得到一个字符用CHAR_BIT的limits.h。如今,几乎没有任何平台会提供8,而不是。
有这个问题的一个很好的总结在这里。
正如我自发布此文章以来其他人提到的那样int8_t,uint8_t如果您真的想表示小整数,最好使用。
CHAR_BIT标准要求至少为8位。
因为我觉得确实需要这样做,所以我只想陈述一些C和C ++的规则(在这方面它们是相同的)。首先,所有unsigned char参与的位都参与确定该值(如果有任何未签名的char对象)。第二,unsigned char明确声明未签名。
现在,我与某人讨论了将-1int类型的值转换为时会发生什么unsigned char。他拒绝将结果的unsigned char所有位都设置为1 的想法,因为他担心符号的表示。但他不必。遵循此规则,转换立即达到了预期的目的:
如果新类型是无符号的,则通过重复添加或减去比新类型中可以表示的最大值多一个值来转换该值,直到该值在新类型的范围内为止。(
6.3.1.3p2在C99草案中)
那是数学上的描述。C ++用模演算来描述它,这产生了相同的规则。无论如何,不能保证整数-1中的所有位在转换前都是1。那么,我们有什么,可以断言结果的unsigned char所有CHAR_BIT位都变为1?
UCHAR_MAX+1,以-1将产生在范围内的值,即UCHAR_MAX够了,实际上!因此,每当您想拥有一个unsigned char全部的位时,您就会
unsigned char c = (unsigned char)-1;
随之而来的是,转换不只是截断高阶位。二进制补码的幸运事件是它只是一个截断,但对于其他符号表示形式并不一定是正确的。
UCHAR_MAX?
(unsigned type)-1是某种成语。~0不是。
int x = 1234和char *y = &x。1234 is的二进制表示形式00000000 00000000 00000100 11010010。我的机器是小字节序的,因此它将其反转并存储在内存中11010010 00000100 00000000 00000000LSB优先。现在主要部分。如果我使用printf("%d" , *p)。printf将读取第一个字节11010010只输出-46,但11010010就是210为何还打印-46。我真的很困惑,我想一些将char转换为整数的促销正在做某事,但我不知道。
例如unsigned char的用法:
unsigned char通常在计算机图形学中使用,它经常(尽管并非总是)为每个颜色分量分配一个字节。通常会看到以24(或32)位表示的RGB(或RGBA)颜色,每个为unsigned char。由于unsigned char值在[0,255]范围内,因此通常将这些值解释为:
因此,最终将得到RGB红色为(255,0,0)->(100%红色,0%绿色,0%蓝色)。
为什么不使用signed char?算术和位移会成为问题。正如已经说明的,signed char的范围实际上偏移了-128。将RGB转换为灰度的一种非常简单且幼稚的方法(几乎未使用)是对所有三个颜色分量求平均值,但是当颜色分量的值为负时,就会遇到问题。使用unsigned char算术运算时,红色(255,0,0)平均为(85,85,85)。但是,如果值是signed chars(127,-128,-128),我们最终将得到(-99,-99,-99),在我们的unsigned char空间中将是(29,29,29),这是不正确的。
如果要将字符用作小整数,最安全的方法是使用int8_tand uint8_t类型。
int8_t并且uint8_t是可选的,并且未在字节大小不完全为8位的体系结构上定义。相反,signed char并且unsigned char始终可用,并保证至少持有8位。这可能是常见的方法,但不是最安全的方法。
signed char和unsigned char?还是在特定情况下您会推荐一个更好的“更安全”的选择?例如,坚持使用“实数”整数类型signed int,unsigned int而出于某种原因呢?
signed char和unsigned char可移植到所有符合要求的实现中,将节省存储空间,但可能会导致代码大小增加。在某些情况下,通过将较小的值存储在规则整数类型的位字段或单个位中,可以节省更多的存储空间。这个问题没有绝对的答案,这种方法的针对性取决于具体情况。而且这个答案也不能解决这个问题。
char并unsigned char不能保证在所有平台上均为8位类型,而是保证为8位或更大。某些平台具有9位,32位或64位byte。但是,当今最常见的平台(Windows,Mac,Linux x86等)具有8位字节。
An unsigned char是无符号字节值(0到255)。您可能会想到char成为“字符”,但这实际上是一个数字值。常规char符号是带符号的,因此您有128个值,并且这些值使用ASCII编码映射到字符。但是无论哪种情况,您存储在内存中的都是一个字节值。
就直接值而言,当已知值介于CHAR_MIN或之间时使用常规字符CHAR_MAX,而无符号字符在正数端提供两倍的范围。例如,如果CHAR_BIT为8,则常规的范围char仅保证为[0,127](因为它可以签名或无符号),而unsigned char将为[0,255],并且signed char为[-127,127]。
就其用途而言,标准允许将POD(普通旧数据)的对象直接转换为无符号字符数组。这使您可以检查对象的表示形式和位模式。对于char或signed char,不存在相同的安全类型修剪保证。
unsigned char,而不是一个阵列具体地,&任何“转化率”是只由正式定义复制从对象到一个真实的,宣告阵列的unsigned char&然后检查后者。尚不清楚OR是否可以直接重新解释为这样的数组,是否需要使用指针算术,即==在此用法中是否使用“序列” “数组”。有一个核心问题#1701已公开,希望对此予以澄清。值得庆幸的是,这种模糊性最近确实困扰了我。
unsigned charOR 的第一个,然后++ptr从那里开始使用它来读取它的每个字节是合理的……但是AFAICT,没有明确定义为允许,所以我们可以从标准中的许多其他段落(以及在许多方面,仅仅是的存在memcpy)推断出它“可能还可以”,类似于拼图游戏。这是不理想的。好吧,也许措辞最终会有所改善。这是我提到的CWG问题,但缺乏链接空间-open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1701
unsigned char是所有骗术的心脏。在几乎所有平台的ALL编译器中,unsigned chara只是一个字节和(通常)8位的无符号整数,可以将其视为小整数或一包位。
正如其他人所说,在成瘾中,标准没有定义字符的符号。所以你有3种不同的char类型:char,signed char,unsigned char。
无符号字符使用保留给常规字符符号的位作为另一个数字。这会将范围更改为[0-255],而不是[-128-127]。
通常,当您不想要符号时使用未签名的字符。这在执行诸如移位位(shift扩展符号)之类的操作以及将char作为字节而不是将其用作数字的其他操作时会有所不同。
signed char和unsigned char都代表1字节,但是它们具有不同的范围。
Type | range
-------------------------------
signed char | -128 to +127
unsigned char | 0 to 255
在signed char如果我们考虑char letter = 'A',“A”是代表在65二进制ASCII/Unicode,如果65可以存储,还-65可以存储。那里没有负的二进制值,ASCII/Unicode无需担心负值。
例
#include <stdio.h>
int main()
{
signed char char1 = 255;
signed char char2 = -128;
unsigned char char3 = 255;
unsigned char char4 = -128;
printf("Signed char(255) : %d\n",char1);
printf("Unsigned char(255) : %d\n",char3);
printf("\nSigned char(-128) : %d\n",char2);
printf("Unsigned char(-128) : %d\n",char4);
return 0;
}
输出-
Signed char(255) : -1
Unsigned char(255) : 255
Signed char(-128) : -128
Unsigned char(-128) : 128