将字符数组视为整数-通过艰苦的方式学习C,获得额外的学分
在Zed Shaw的“艰苦学习C”中,练习9()有一个额外的学分问题,我觉得很有趣。他定义了一个4个字符的数组,并要求读者了解如何将该数组用作4字节整数 +----+----+----+----+ | N1 | N2 | N3 | N4 | +----+----+----+----+ 在这一点上,我只知道足够危险,我想答案大致如下:将字符数组视为整数-通过艰苦的方式学习C,获得额外的学分,c,arrays,pointers,C,Arrays,Pointers,在Zed Shaw的“艰苦学习C”中,练习9()有一个额外的学分问题,我觉得很有趣。他定义了一个4个字符的数组,并要求读者了解如何将该数组用作4字节整数 +----+----+----+----+ | N1 | N2 | N3 | N4 | +----+----+----+----+ 在这一点上,我只知道足够危险,我想答案大致如下: #include <stdio.h> int main(int argc, char *argv[]) { char name[4] = {'
#include <stdio.h>
int main(int argc, char *argv[])
{
char name[4] = {'A'};
int *name_int;
name_int = &name;
printf("%d", *name_int);
return 0;
}
#包括
int main(int argc,char*argv[])
{
字符名[4]={'A'};
int*name_int;
name_int=&name;
printf(“%d”,*name\u int);
返回0;
}
我的想法是,如果我创建了一个int指针,其值是数组的地址,那么int类型将使用该地址中的数据字节,然后是接下来的3个可用数据字节。在我有限的理解中,我的印象是int和数组都会以相同的方式使用内存:从任意内存地址开始,而不是按顺序使用下一个地址,依此类推
然而,它的输出并不是我所期望的:我得到了ascii值'A'。在我看来,这似乎表明我的解决方案不正确,我对内存处理方式的理解不正确,或者两者都不正确
这个小技巧是如何完成的?我错在哪里?我希望在离开这里时能够更好地理解指针和引用是如何工作的,以及内存是如何存储和使用的
谢谢大家! 您遇到了数字的小端表示法和大端表示法 让我们看一下用于表示4字节整数的4-btyes的值 +----+----+----+----+ | N1 | N2 | N3 | N4 | +----+----+----+----+ 在小端表示法中,这4个字节表示:
N1*2^24 + N2*2^16 + N3*2^8 + N4
N1 + N2*2^8 + N3*2^16 + N4*2^24
就你而言
N1 = 'A' (65 decimal)
N2 = 0
N3 = 0
N4 = 0
因为您得到的整数的值是65
,所以您有一个小小的endian表示。如果要将这些数字视为大端表示,可以使用以下方法:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
char nameString[4] = {'A'};
int name = 0;
for ( i = 0; i < 4; ++i )
{
name = (name << 8) + nameString[i];
}
printf("%d\n", name);
printf("%X\n", name);
return 0;
}
#包括
int main(int argc,char*argv[])
{
int i;
char nameString[4]={'A'};
int name=0;
对于(i=0;i<4;++i)
{
name=(name使用'char name[sizeof(int)],否则有风险UB。小心幻数。此代码可能有未定义的行为,因为name
可能没有正确对齐int*
。您可以通过执行int name\u int;memcpy(&name\u int,&name,sizeof name\u int)来避免此问题
注意,虽然name\u int=&name;
(使用&
)被接受(编译器采用&name[0]
),但name\u int=name;
实际上是您想要的(尽管有警告,强制转换将删除name\u int=(int*)name;
)。为了确保我正确理解您的意思:尽管计算机的端序不同,但数组在内存中的表示方式是相同的,但整数的表示方式(在本例中)会有所不同。这是否正确?