指针声明和间接寻址之间的区别

Difference between pointer declaration and indirection

本文关键字:区别 之间 间接寻址 声明 指针      更新时间:2023-10-16

我正在读一本书,我对这些语法中的每一个都有疑问。前三行我可以理解,但下面不能。非常感谢你,如果你帮助我,朱丽叶

int m; //m is int variable 
int *p; //Pointer p pointing to an integer value
p=&m //The memory address of the variable m is assigned to p
float *longitud;
longitud=&cable1;
*longitud=40.5;

指针引用的概念经常让人们感到困惑,特别是因为他们经常被教导从实现而不是语言的角度来看待它们。

价值是存在并有意义的事物。它总是有一个类型(对其含义的约束),如intfloatcharvector<string>

对象存在于内存中某处的值。(而不是,比如说,篡改成机器指令代码或以某种方式即时生成。也就是说,如果我的手指足够灵活,我可以拿出我的记忆芯片,把手指放在上面。

引用别名— 对象的名称。这个名字对于我们程序员来说很方便。编译器如何维护该名称并不重要。重要的是(语言角度!)如果你有一个名字,你就可以直接访问一个对象。

为了正确看待这一点,无论何时命名对象,您都会获得对该对象的直接引用。您可以使用其名称直接操作该对象。

指针是一个值。它的类型是某个对象在计算机内存中的位置。使用此位置,我可以访问对象的值。换句话说,我可以使用指针来获取对对象的直接引用。

词汇+时间=善变的理解,鼓励人们问无用的事情2.让我们稍微清理一下我们的头脑。

  • 首先,指针不是引用,而是间接引用。为了获得对指向对象的实际或直接引用,我们">取消引用"指针。换句话说,我们执行一个魔术,转换指针值以获取对对象的引用。

指针如何工作的机制通常根据底层硬件如何执行诸如"跟随指向值的指针"之类的操作来构建。我们用箭头和一切画画。我们似乎忘记问这个魔法是如何工作的。也没有人问变量名称是如何工作的,但它是完全相同的魔法。当被告知"编译器会处理它"时,我们只是相信。

遗漏的是(直接)引用(对象的
  • 别名或名称)和间接引用(指针或其他可用于获取对对象的引用的东西)之间的区别。

在C++之前,直接引用和间接引用之间的区别实际上只在指针的上下文中有意义,并且很容易将指针称为"引用"而不是完整的短语"间接引用",因此词汇词在我们的脑海中混杂,我们开始误解所涉及的实际概念。

进入C++,舞台左侧。除了指针之外,我们现在还有称为"引用"的东西。就语言而言,它们是其他对象1的真实别名。

举个例子:

int  x = 7;   // "x" is a reference to the integer object with value 7
int& y = x;   // "y" is a reference to the same integer object as "x".
int* p =      // "p" is a pointer object whose value is an 
//     indirect reference to some integer object:
&x;  // The & operator obtains an indirect reference (or pointer value) to "x"

这是最后一点。"&"的含义不止一个!

  • 附加到类型时,这意味着该类型是对某个对象的直接引用
  • 当附加到对象时,这意味着获得对该对象的间接引用

1在C++中,抽象泄漏,因为对象的生存期仅绑定到原始引用。但这既不在这里也不在那里。SO还有其他主题涉及这一点。

2那么,要回答大家最喜欢的问题:引用是不是指针?答案是,没关系。(除非您正在编写编译器。您正在询问有关用于维护语言级概念的魔术的实现细节。因此,有时它可能是一个实际的指针,有时它可能只是编译器本地符号表中的另一个条目,如果编译器编写者认为它有用且合适,它甚至可能是其他条目。

3语言变得模糊。我之前说过"p" is a pointer.从技术上讲,它是一个对象,其值是指针类型。不过,我们通常可以通过说出物体是什么类型的东西来摆脱困境,并且很容易理解。只有当我们(在上下文中)分裂头发时,词汇才需要更多的关注,就像这里一样。

longitude是指向浮点变量的指针

longitud=&cable1cable1的地址(大概是浮点数?)分配给longitud,现在引用cable1

*longitud=40.5取消引用经度并为其赋值 40.5。 因为longitud引用cable1,这会将值分配给cable1。 这是*longitudcable1是一回事。

这些都与问题标题"指针声明和间接寻址之间的区别">无关 - 间接寻址是一个通用的计算概念,指针是在 C 和 C++ 中实现间接寻址的手段。

假设您在每个部分中再添加一行(不同的)行:

int m;              // m is int variable 
int *p;             // pointer p is pointing to an integer value
p = &m;             // the memory address of m is assigned to p
*p = 42;            // ADDED: assign 42 to m, where p points to
float cable1;       // ADDED: the variable where longitud points
float *longitud;    // pointer longitud is pointing to a float value
longitud = &cable1; // the memory address of cable1 is assigned to longitud
*longitud = 40.5f;  // assign 40.5 to cable1, where longitud points to

这样就完成了使用不同变量类型的类似示例。

执行行后

float cable1;       // ADDED: the variable where longitud points
float *longitud;    // pointer longitud is pointing to a float value
longitud = &cable1; // the memory address of cable1 is assigned to longitud

满足以下条件:

longitude == &cable1
*longitude ==  cable1

IOW,表达式*longitud等效于表达式cable1。 所以当你写的时候

*longitud = 40.5f;

这相当于写作

cable1 = 40.5f;

*运算符取消引用longitud指针,以便表达式的计算结果*longitudcable1相同。

Cable1 需要有一个位置记忆,然后纵向才能指向它。

前 3 行执行此操作:

  1. 为整数留出内存。
  2. 创建一个整数指针。
  3. 获取 int 指针以指向 int 的内存地址。指针引用 int。

后 3 行执行此操作:

  1. 创建浮点指针。
  2. 获取浮点指针以指向不存在的地址。
  3. 尝试为该地址分配浮点值。

如果您在第 4 行写道:

float cable1;

你会留出内存,一切都会好起来的。

在这个主题上,你的意思是指针声明和取消引用。我可以举一组简短的例子,尽管主要需要阅读和练习来学习。试试这些,感受一下。

float f = 22.2f;   //sets aside memory for a float with the name "f", stores 22.2
float *pf;         //declares a float pointer.
pf = &f;           //sets pf to point to f's memory address. pf references p.
printf("%f", *pf); //prints the value at the referenced address (22.2)
printf("%x", pf);  //prints the memory address of the pointer itself
*pf = 33.3f;       //changes the value at f's address to 33.3 (from 22.2)
f = 44.4f;         //changes the value at f's address to 44.4 (from 33.3)
float *pf2;
*pf2 = 33.3        //BAD. pf2 is not assigned to an address, no value to change.
*pf2 = f;          //BAD. pf2 has no memory address to copy the value to.
*pf2 = pf;         //BAD. several reasons.
pf2 = pf;          //pf2 now points to f's address, too.
pf2 = &f;          //redundant. Same as the last line.
*pf2 = 55.5        //f has changed to 55.5. both pf2 and pf point to it.

只需在声明时将 * 视为代表"指针"即可。稍后使用 * 时,表示"取消引用"。取消引用指针意味着要查看/使用/更改引用的值。稍后,您将了解指针可以指向其他指针。因此,(char **) 类型的值是类型 (char *),而不是类型 (char)。

如果你没有书,我推荐 C 编程 - 现代方法 2nd Edition。这有点过时,但这是学习基础知识的绝佳方式。