【问题标题】:How the printf function works with integer?printf 函数如何处理整数?
【发布时间】:2012-10-01 07:37:40
【问题描述】:

我有以下代码

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 byte 这是 0 但它现在是一个整数指针,但它如何打印 0,因为它必须检查最多 4 个字节的内存,然后它必须打印最多 4 个字节的整个数据。 我认为它将打印 3 作为最多 4 个字节。

我想要的是整数数据是如何通过 printf 打印的,谁能告诉这个。

【问题讨论】:

  • p 始终是一个字符指针!
  • 感谢您的回答,但是那里的 (int *) 有什么用处。请告诉。
  • (int*) 强制转换是不必要的(错误?),因为 p 和 p+1 已经是赋值兼容的。特别是,它甚至会发出警告(“来自不兼容的指针类型的赋值”)。如果你有类似int* i; ... i = p + 1;

标签: c


【解决方案1】:

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

它仍然是一个指向 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。需要强制转换以避免编译器警告/错误,因为编译器拥有“想知道”这里发生了什么以及是否可能存在编程错误的所有权利。

现在pupc 都指向同一个位置,即变量u 的开头。但它们有不同的类型,一种指向unsigned char,另一种指向unsigned int

因此,如果您取消引用 pupc,您将获得不同的值,这些值也将属于不同的类型。

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

你开始看到了吗?

【讨论】:

  • 感谢您的回答,但我能知道类型转换的用途吗?
  • 感谢您的明确解释,我通过了 ISO 标准的铸件,但我无法捕捉到那里的所有东西。你能建议类似那个标准的东西,我可以在那里得到很少的东西简单明了一点。
  • 该标准不易阅读,不应该成为最先学习的资源之一。查找 SO 以获取好的/推荐的 C/C++ 书籍。某处有一个大帖子列出了这些。等等,here it is
【解决方案2】:

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

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

【讨论】:

  • 我得到了相同的结果。即使它指向第三个字节结果,这里实际发生的情况也是相同的并且总是说 0。
【解决方案3】:

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

【讨论】:

  • 感谢您的回答,但“由于 p 是一个 char 指针,当 p 增加它时,这意味着 p 向前移动 2 个字节”我认为这是不正确的,因为 char 是 1 个字节,它只会转发一个字节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 2014-04-13
  • 2016-03-31
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
相关资源
最近更新 更多