我有这个字符数组
char array[] = {1,2,3}; //FL, FH, Size
我正在尝试使用指针访问它,以便将 FLFH 值放在一起,存储在一个整数变量中。
我做了这个
int val =0;
val = *(int*)array;
printf("value of p is %d\n",val);
我期望结果是 12,但它是一些 8 位数字,我认为它可能是值的地址或其他东西。谁能告诉我我在这里做错了什么?
它永远不会给你十二个。
您正在获取两个单字节值并将它们视为包含一个单字节实体。当你把它们放在一起看时,你正在重新解释它们的价值。整数1
看起来像这样,作为 bits: 00000001
,2
像这样: 00000010
。编译器知道它们有多大,因此允许您作为个体访问它们,但它们在您的数组中按顺序排列,在内存中彼此相邻。
将两个字节一起检查,就好像它们是一个int
,你有:0000000100000010
,其值不是 12;是513。
为了您的进一步阅读,您正在做的是一种“类型双关语”。
对于可读性和可移植性而言,这是一个坏主意。如果这就是您的意思,请使用array[0] * 10 + array[1]
,并相信窥视孔优化器可以加快速度。如果您必须通过指针访问该值,请使用char
指针和 write p[0] * 10 + p[1]
,这易于理解、完全合法且可移植。
您的代码可能无法运行的原因有很多,这强烈表明您正在尝试做的事情是愚蠢的,或者至少您是在头脑中。
第一个是字节的范围是从 0 到 255,而不是从 0 到 9,所以如果你确实使用了这种技术,并且它有效,你将得到 1*256+2 =258,而不是 1*10+2 = 12. 你永远不会得到 12. 计算机不是这样工作的。这就是为什么你必须调用一个函数,比如atoi()
将字符串转换"12"
为数字 12,然后才能对其进行算术运算。
如果你有四个字节整数,那也是你得到一些大数字的原因:你认为你得到了 1*256+2,但实际上你得到了 ((1*256+2)*256+3 )*256+???。另外,正如克里斯在评论中所说,在这种情况下,无论如何你的数组太小了,从哪里来???在前面的公式中。
您可以尝试使用 ashort
而不是 an int
,看看是否效果更好;ashort
可能是一个 2 字节整数。但这并不能保证,因此它仍然不能移植到short
s 长度超过两个字节的系统。更好的做法是找出系统上与两字节整数相对应的实际类型(可能short
是 .INT2
INT2
int
另一个潜在的问题是您的系统可能使用 little-endian 字节顺序,在这种情况下,您的数组中的字节顺序错误,无法表示您想要的两字节机器整数,您的技巧永远不会奏效。即使可以在您的机器上运行,如果您必须在 little-endian 机器上运行代码,它也会中断。(您在此线程中其他地方的评论表明这正是正在发生的事情。)
因此,只需简单的方法即可。
您没有得到预期的结果,因为字节布局在 8 位边界上,因此相邻的二进制字节值按256 10而不是10 10缩放。
此外,如果您转换某物的类型并取消引用它,编译器将编译它,但从技术上讲,您的程序是不合格的。*
一个问题是对齐。如果您使用开放代码更改类型,它可能不会从正确的边界开始,并且可能不够大。您可以通过工会解决所有这些问题。它仍然是不一致的,并且没有指定结果,但实际上它是可靠的,甚至有点可移植,如果您不介意根据字节顺序和 int 大小的不同结果。
union a {
char c[3];
int i;
short s;
} a;
这也可能是一个很好的应用程序<stdint.h>
,但这是另一个问题的主题。
*那么,你可能想知道为什么存在强制转换......这是因为(A)尽管被标准禁止,类型双关语被广泛用于现有的 C 程序,特别是在操作软件中,并且(B)大多数情况下都是一致的用途定义通用接口但总是(或者,通常是)在取消引用之前将事物转换回原始类型。
也许尝试:-
char array[] = {1,2,3}; //FL, FH, Size
int val =0;
val = *(short*)array;
printf("value of p is %X\n",val);
这是假设您正在尝试将您的 char 数组重新解释为 int。尽管不同的平台,您可能会得到与预期不同的结果。