【问题标题】:Demonstration of Virtual Memory with C用 C 演示虚拟内存
【发布时间】:2016-09-19 02:00:34
【问题描述】:
#include <stdio.h>
#include <unistd.h>

int staticVar = 0;

int main()
{
    staticVar += 1;

    sleep(10);
    printf("Address: %x\nValue: %d\n", &staticVar, staticVar);

    return 0;
}

我很困惑这个程序如何打印出变量“staticVar”的地址。通过使用代码,我注意到如果您将 printf 语句更改为此...

printf("Address: %x\nValue: %d\n", staticVar, staticVar);

然后将变量“staticVar”的值打印在“Address”位置。

一些快速的研究让我明白,添加“&”意味着变量“staticVar”被引用,并且 printf 语句中的“%x”打印出十六进制值。即使有了这些信息,我仍然对为什么会这样感到困惑。

我也在网上看到你可以用这一行打印出某个变量的地址...

printf("Address: %p\n", (void*) &staticVar);

这样做有好处吗?

我可能只需要解释一下“&”符号的作用。

【问题讨论】:

  • 如果您不了解&amp;,您是如何尝试了解虚拟内存的?
  • 我认为学习操作系统听起来很酷,所以我拿起一本书。我不太了解 C 或 C++。这通常是我学习东西的方式。我所在级别的虚拟内存纯粹是概念性的。目前我不想知道操作系统如何从虚拟地址变为物理地址,因为正如我所读到的,这是一个困难的过程。不过我会的。
  • 启用警告并解决所有报告的警告。您的代码调用未定义的行为。 %x 是指针的无效转换类型说明符!在开始使用操作系统之前,请选择一本关于 C 或 C++ 的书。它们是不同的语言,因此请选择您想学习的语言。首先学习语言,关于操作系统编程。
  • C 没有引用,&amp; 一元运算符也称为“地址”运算符。
  • 我的计划是在阅读 OS 书籍的同时学习 C。我认为我不能像使用 Java 那样直接学习一门语言。我确实找到了一本我喜欢的 C 书籍,所以每当我需要 C 编程帮助时,我都会尝试参考它。

标签: c


【解决方案1】:

首先,您应该熟悉指针的概念。幸运的是,那里有很多很好的参考资料like this(前 5 部分很重要)。

在做了一些指针读取之后,底线是 & 是 C 中的一个运算符,它返回它之前的变量的地址。 (它实际上可以有两种用途,具体取决于它所在的上下文中使用,另一个是按位与运算符,但在需要使用之前不要担心)。

另外,您应该始终使用 %p 打印出指针。原因是因为它让你的代码更portable to different operating systems

 printf("Address: %p\n", (void*) &staticVar);

这段代码可以工作,但是我不会强制转换为 void 指针,因为这种类型转换是不必要的,并且会降低代码的可读性。试试这个吧。

 printf("Address: %p\n", &staticVar);

【讨论】:

  • 谢谢。这对我帮助很大。
  • 在开始使用指针之前,OP 应该正确掌握基础知识。这意味着通过结构化的教程工作,resp。书(大多数在线教程不值得花时间)。
  • 一点点:使用%p 的原因是在某些编译器中指针的大小可能与int 的大小不同(通常,int 是 32 位的 64-位码)。当使用可变数量的参数调用诸如printf() 之类的函数时,您确实需要将int* 转换为void*char*,否则您会得到未定义的行为。 int* 并不要求void* 一样宽! (OP,别担心。我是语言律师。)
  • void * 演员表在可移植代码中是必需的。您的最后一段抵消了上一段。
  • @GandhiGandhi 谢谢。我的建议是:需要注意的语言律师不是“这个聪明的组合在技术上有效吗?”但是,“我所做的假设在未来是否有效?”很多代码在 32 位到 64 位的转换中出现问题,因为程序员假设 long int 的宽度正好是 32 位,而且指针、偏移量、索引、时间戳、网络地址等的大小。
【解决方案2】:

在这个特定的上下文中,符号 '&' 有效地将其后的任何变量替换为变量的地址。

【讨论】:

  • 从我用 C++ 和另一个用 C 编写的测试来看,在类似 print 的语句中包含“&”似乎总是打印地址。它是否正确?是否存在包含“&”不会为变量提供地址的情况?
  • 在 C++ 中,函数参数声明中的符号 '&' 表示参数是通过引用而不是值传递的。
  • @VictorHavin:问题是关于 C,而不是 C++。它们是不同的语言,但是。 &amp; 不替代任何东西(替代的概念甚至不是核心语言的一部分,除了预处理器)。
  • @VictorHavin:编译器生成的代码采用左值的地址,就像例如~ 或二进制表达式 a + b。它不会“替代”任何东西。有人可能会争辩说,它可能会用生成代码中的最终结果替换 constant-expression。但这是一个实现细节,标准未涵盖。而且这里不适用,因为地址在编译时是未知的。
  • 标准中只提到了两次“替代”,但是关于宏参数替代,这是一种文本替代,这使得该术语在下一阶段明显错误。对于表达式,使用“评估”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-09
  • 2018-11-12
  • 2013-10-21
  • 2015-09-01
  • 2015-05-25
  • 2010-12-24
  • 1970-01-01
相关资源
最近更新 更多