1

我有以下代码

int main()
{
    int arr[3] = {2, 3};
    char *p;
    p = arr;
    p = (char *)((int*)(p));
    printf("%d, ", *p);
    p++;
    p = (int*)(p+1);
    printf("%d", *p);
    return 0;
}

o/p-2,0

但我想知道它是如何在第二个 printf 中打印 0 的,我知道所有关于这些元素如何存储little-endian的记忆4 byte integer,如下

00000010 00000000 0000000 00000000 00000011 00000000 00000000 00000000

所以,在第一次printf我们得到 2 作为答案,但在第二次printf指针是second byte0 但它现在是一个整数指针但它如何打印 0,因为它必须检查最多 4 个字节的内存然后它必须打印整个数据最多4个字节。我认为它将打印 3 个最多 4 个字节。

我想要的是整数数据是如何通过 printf 打印的,任何人都可以告诉这一点。

4

3 回答 3

3

指针的类型p不会随以下两者中的任何一个而改变:p = (char *)((int*)(p)); p = (int*)(p+1);.

它仍然是指向 a 的指针char

强制转换仅适用于更改表达式中的值(或类型)。它适用于从变量中提取的值的副本,但不会修改这些变量。表达式结束后,强制转换与它关联的值副本一起消失。

例子:

signed char c = -1;
int i;
i = (unsigned char)c;

这里的值c-1 被转换/强制转换为类型unsigned char。如果 chars 是 8 位的,则 的结果(unsigned char)-1是 255 并且该值的类型为unsigned char,然后将其转换为int并分配给i

c在上述过程中无论如何都不会改变。

示例 2:

unsigned u = 0x55AA;
unsigned* pu = &u;
unsigned char* pc = (unsigned char*)pu;

这里pu被转换/转换为指向unsigned char. 该转换不会修改变量pu,它只会更改其值的副本。在这里,它只是更改了指针变量中包含的副本的类型,而不是实际地址。然后将此地址副本分配给pc。需要强制转换以避免编译器警告/错误,因为编译器拥有“想知道”这里发生了什么以及是否可能存在编程错误的所有权利。

现在pu和都pc指向同一个位置,即变量的开头u。但是它们有不同的类型,一个指向 anunsigned char另一个指向 an unsigned int

因此,如果您取消引用puand pc,您将获得不同的值,并且这些值也将具有不同的类型。

同样,如果您对两个指针进行指针运算,例如,将每个指针加 1,它们将前进以指向内存中的不同位置。pu+1将指向紧接在末尾之后的位置upc+1并将指向unsigned char从开头开始的第二个位置u

你开始看了吗?

于 2012-10-01T07:43:04.697 回答
3

我认为您的基本问题实际上是代码中的错误,您说“在第二个 printf 期间,指针位于第二个字节”,但事实并非如此。您首先使用 p++ 递增指针(现在它指向第二个字节),然后使用 p=(int *)(P+1) 再次递增指针,使 p 指向第三个字节。

在我看来,您并不真正了解类型转换是如何工作的,据我所知,删除所有类型转换根本不会改变这段代码的功能。

于 2012-10-01T07:43:20.603 回答
0

我认为对于 2,它存储为“00000010 00000000 0000000 00000000”。由于 p 是一个 char 指针,当 p 增加它时,意味着 p 向前移动了 2 个字节。而对于代码,'p = (int*) (p+1),当p增加一时,p是一个char指针。因此,在 p + 1 之后,p 指向“0000000 00000000”。所以第二个 printf 将打印 0。

于 2012-10-01T07:55:59.910 回答