我有这个字符数组
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位数字,我认为可能是价值的地址或其他东西。谁能告诉我,我在这里做错了什么?
答案 0 :(得分:4)
它永远不会给你十二个。
您正在获取两个单字节值,并将它们视为包含一个双字节实体。当你一起看它们时,你就会重新解释它们的价值。整数1
看起来像这样:位00000001
和2
,如下所示:00000010
。编译器知道它们有多大,因此允许您作为个体访问它们,但它们按顺序排列在数组中,在内存中彼此相邻。
将两个字节一起检查,就像它们是int
一样,你有:0000000100000010
,其值不是12;这是513。
为了您的进一步阅读,您正在做的是一种"type punning"。
答案 1 :(得分:3)
这是一个糟糕的主意,可读性和便携性。如果这是你的意思,请使用array[0] * 10 + array[1]
,并相信窥视孔优化器可以加快速度。如果必须通过指针访问该值,请使用char
指针并编写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 + ???。另外,正如克里斯在评论中所说,在这种情况下你的数组太小了,无论如何,???在上一个公式中。
您可以尝试使用short
代替int
,看看是否效果更好; short
可能是一个2字节的整数。但这并不能保证,因此它仍然不能移植到short
s长于两个字节的系统。更好的做法是找出系统上与两个字节整数相对应的实际类型(也许是short
,或许是其他的东西),然后键入像INT2
这样的类型,并使用INT2
取代int
。
另一个潜在的问题是你的系统可能使用小端字节顺序,在这种情况下,你的数组中的字节顺序错误,以表示你想要的双字节机器整数,你的技巧永远不会工作。即使可以在您的机器上运行,如果您必须在小端机器上运行代码,它也会中断。 (你在这个帖子的其他地方的评论表明这正是发生的事情。)
所以就这么简单。
答案 2 :(得分:3)
您没有得到预期的结果,因为字节是在8位边界上布局的,因此相邻的二进制字节值按 256 10 缩放,不是 10 <子> 10 子> 强>
此外,如果你转换某种东西并取消引用它,编译器会编译它,但从技术上讲你的程序是不合格的。 *
一个问题是对齐。如果使用开放代码更改类型,则可能无法从右边界开始,并且可能不够大。你可以用联盟解决所有问题。它仍然是不一致的,结果没有指定,但实际上它是可靠的,甚至有些可移植,如果你不介意根据字节顺序和int大小的不同结果。
union a {
char c[3];
int i;
short s;
} a;
这也可能是<stdint.h>
的一个很好的应用,但这是另一个问题的主题。
* 你可能想知道为什么演员阵容存在......这是因为(A)尽管被标准禁止,但是在现有的C程序中广泛使用了类型惩罚,特别是操作软件,以及(B)大多数符合要求的用途定义了通用接口,但总是(或者,通常通常)在撤消引用之前将其转换回原始类型。
答案 3 :(得分:-1)
也许可以尝试: -
char array[] = {1,2,3}; //FL, FH, Size
int val =0;
val = *(short*)array;
printf("value of p is %X\n",val);
这假设您正在尝试将char数组重新解释为int。虽然不同的平台可能会得到与预期不同的结果。