C 字符到整数指针转换
我知道整数指针增加2个字节,而字符指针增加1个字节。 这里,当int指针增加1时,只打印C(只考虑第一个字节)。是因为我们有%c说明符吗 此外,我无法理解17475是如何作为输出打印的。在第二种情况下,66是ASCII值BC 字符到整数指针转换,c,pointers,C,Pointers,我知道整数指针增加2个字节,而字符指针增加1个字节。 这里,当int指针增加1时,只打印C(只考虑第一个字节)。是因为我们有%c说明符吗 此外,我无法理解17475是如何作为输出打印的。在第二种情况下,66是ASCII值B 有人能帮我吗?当指向integerptr的指针增加时,在您的情况下,它会增加2个字节。 例如,ptr+1指向“CDEFG”。 使用字符指针取消引用此位置时,只有第一个字节C被视为sizeof(char)是1 但当它被视为整数时,2个字节将被视为与您的情况相同的sizeof(i
有人能帮我吗?当指向integer
ptr
的指针增加时,在您的情况下,它会增加2个字节。
例如,ptr+1
指向“CDEFG”
。
使用字符指针取消引用此位置时,只有第一个字节C
被视为sizeof(char)
是1
但当它被视为整数时,2个字节将被视为与您的情况相同的sizeof(int)
is2
在您的机器中,位是(因为端性)
其中,上行是位,下行是一些索引,我将使用它们来表示各个位
位0-7是ASCII值为67的字符“C”的二进制表示形式。
位8-15是ASCII值为68的字符“D”的二进制表示形式
ptr+1
指向从位0开始的位置。当该值被视为整数(大小为2字节)时,将同时使用两个字节。
也就是说,使用“C”和“D”的二进制来查找整数的值
这个二进制表示的十进制值是17475
,这是您得到的值
编辑:您的代码可能有未定义的行为,因为。您的代码违反了严格的别名规则,从而导致未定义的行为。任何输出都是毫无意义的
您可以使用
int
类型的表达式(即*(ptr+1)
)来访问内存。严格的别名规则规定此内存必须具有有效类型int
(或相关类型,如const int
)等。但是内存实际上包含char
对象,因此所有赌注都是无效的。首先要注意的是,您的代码具有未定义的行为。这意味着我们不能仅通过参考C标准来说明生成的输出。输出可能/将因系统而异,有些系统甚至可能无法执行代码
问题是您有许多char
(一个char
数组),但您使用int
指针访问它。这是不允许的
但是,在特定的系统(您的系统)上,可以考虑为什么输出看起来像这样但请记住它不是有效的C代码。注意:正如Antti Haapala所指出的,代码语法是有效的-只是程序的行为没有定义
字符串(又名字符数组)将放在内存中的某个位置,如:
+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+
| 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+
请注意,内存包含二进制值。十六进制、十进制、Ascii列只是相同二进制值的“人工”视图
您的指针s
具有值base
,即它指向保存值0100 0001
(又称A)的内存位置
然后让ptr
也指向base
打印时(即printf(“%c%d\n”,*(ptr+1),*(ptr+1));
,ptr+1
将指向一个位置,该位置取决于整数的大小(因系统而异)。由于int的大小为2,ptr+1
是位置base+2
,即01000011
(又名C)
因此,本声明的第一部分:
Address | Bin | Hex | Dec | Ascii char
--------------------------------------------
base | 0100 0001 | 41 | 65 | A
base+1 | 0100 0010 | 42 | 66 | B
base+2 | 0100 0011 | 43 | 67 | C
base+3 | 0100 0100 | 44 | 68 | D
base+4 | 0100 0101 | 45 | 69 | E
and so on
打印一个C
,即位于base+2
位置的字符
第二部分
printf("%c %d\n",*(ptr+1),*(ptr+1));
^^ ^^^^^^^^
打印位于base+2
处的整数值。(注意-这是非法的,因为这里没有整数,但让我们暂时忘记这一点)
在您的例子中,int
是两个字节。因此,使用的字节将是C
(十六进制:0x43)和D
(十六进制:0x44)。打印的值将取决于系统的末端
Big-endian(MSB优先)将给出:
printf("%c %d\n",*(ptr+1),*(ptr+1));
^^ ^^^^^^^^
0x4344 which is 17220 in decimal
Little endian(LSB优先)将提供:
printf("%c %d\n",*(ptr+1),*(ptr+1));
^^ ^^^^^^^^
0x4344 which is 17220 in decimal
因此,从这个角度来看,你的系统似乎是小endian
正如你所看到的,很多东西都非常依赖于系统,从C标准的角度来看,不可能知道结果会是什么。可能重复的Huh。17475确实是使用ASCII编码、小端整数存储、
CHAR\u BIT==8
和sizeof(int)==2
(违反最小int\u MAX
的标准要求)的系统的打印值。您在哪里找到这个编译器?@Zephyr-原则上是的-是%c
说明符导致了c的打印。但是,这是未定义的行为,不能仅从c标准解释输出。请参阅BTW-int的大小也因系统而异,因此int指针也不会增加2。更常见的是它们增加4。@Zephyr-我们决定用十进制、十六进制或二进制来写一个数字只是为了方便,即键入更少的字母,例如,我们写129(十进制)或81(十六进制),而不是10000001
(二进制)。在计算机内部,一切都是二进制的。我使用十六进制是因为十进制很笨拙:十进制数“存储”在纸上的方式意味着每个数字都代表10的幂,而不必这样说。但是计算机并没有以这种格式存储整数——每个字节代表256的幂。在十进制中,为了解释字节序列67 68
,我需要说67+68*256
,因为字节存储的基数是256而不是10。用十六进制写它更方便,比如0x4443
@4386427,那么改为“指向从位0开始的位置”怎么样?需要注意的一点是:这是非常有效的C代码,遵循标准的语法,可能