![](/img/trans.png)
[英]Why char* directly set the value but not in the case of int* in c programming
[英]Why does following C code print 45 in case of int 45 and 36 in case of STRING and ASCII value of CHAR?
struct s{
int a;
char c;
};
int main()
{
struct s b = {5,'a'};
char *p =(char *)&b;
*p = 45;
printf("%d " , b.a);
return 0;
}
如果*p
更改为任何character
,则不输出ASCII
值;如果*p
更改为任何string ("xyz")
,则不打印36
。 为什么会这样呢?
能否给出结构s和* p的内存映射?
根据我的结构记忆
s as z-> (****)(*) assuming 4 byte for int .
并且当s初始化时,它将变为(0000000 00000000 00000000 00000101)(ASCII OF char a)
,* p指向z的起始地址。 * p是字符指针,因此它将在每个BYTE位置存储ASCII值,即在每个*处将由char的ASCII占用。 但是现在我们将其设置为45,因此z将变为(45 0 0 5 )(ASCII of char a)
。 但这不是真的吗?
你的结构看起来像小尾数:
00000101 00000000 00000000 00000000 01100001
所以p
点到5
和覆盖它。 在printf的4个小端排序的字节打印45
。
如果你想尝试它大端754974725
会是这个结果,因为p
指向INT的MSB侧。
一个简单的测试程序,以找出是否你是在很少或大端:
int main()
{
int a = 0x12345678;
unsigned char *c = (unsigned char*)(&a);
if (*c == 0x78)
printf("little-endian\n");
else
printf("big-endian\n");
return 0;
}
通过char *
指针写入该结构时,会将45
存储在该结构的第一个字节中。 如果您使用的是Little-Endian实现,则将写入ba
的低端。 如果您使用的是Big-Endian实现,则将写入ba
高端。
这是分配*p=45
之前和之后带有16位int的实现上的结构通常发生什么情况的可视化。 注意,该结构被填充为sizeof(int)
的倍数。
Before: a [05][00] (int)5 c [61] [ ] After: a [2d][00] (int)45 c [61] [ ]
Before: a [00][05] (int)5 c [61] [ ] After: a [2d][05] (int)11525 c [61] [ ]
如果使用更大的整数,则可以使用更多方式对字节进行排序,但是在现实生活中,您几乎不可能遇到以上两种情况。
但是 ,由于以下两个原因,下一行调用了未定义的行为 :
printf("%d " , b.a);
ba
的一部分。 这可以给出ba
“陷阱表示”,并读取包含陷阱表示的值可导致未定义的行为。 (不,您在现实生活中不太可能会遇到陷阱表示形式(整数类型)。) #include <stdio.h>
。 未定义的行为意味着可能发生任何事情,例如打印错误的值,使程序崩溃或(完全是最糟糕的事情)完全按照您的期望进行。
C标准保证的结构的第一个成员的地址是该结构的地址。 也就是说,就您而言
int* p =(int*)&b;
是一种安全的演员。 但访问的标准方式char
从结构的地址成员。 这是因为标准不说的连续成员在内存中的任何连续性:其实编译器可能会或可能不会插入成员之间的空隙(称为结构填料),以适应芯片组。
所以,你在做什么,基本上是不确定的。
因为这
*p = 45;
将p指向的值更改为45。然后将p指向b。
尝试构造此指针。
#include<stdio.h>
struct s{
int a;
char c[1];
};
int main()
{
struct s *p;
struct s b = {5, 'a'};
p = &b;
printf("%d %s", p->a, p->c);
return 0;
}
如果您希望Pointers作为结构成员而不是char数组。 尝试这个..
#include<stdio.h>
struct s{
int a;
char *c;
};
int main()
{
struct s b = {5, "a"};
printf("%d %s", b.a, b.c);
return 0;
}
char *p = (char*) &b;
-在此行中, p
指向b
结构的开头,作为char指针。
*p = 45;
将45写入b
的存储空间, ba
也可以访问该存储空间。
当您打印printf("%d ", ba);
你会打印存储在指定为堆栈存储器的45 a
成员struct b
,你会得到45。
尝试自己调试一下,您会在监视窗口中看到它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.