我正在读一本书,我对这些语法中的每一个都有疑问。前三行我可以理解,但下面不能。非常感谢你,如果你帮助我,朱丽叶
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;
值、指针和引用的概念经常让人们感到困惑,特别是因为他们经常被教导从实现而不是语言的角度来看待它们。
价值是存在并有意义的事物。它总是有一个类型(对其含义的约束),如int
、float
、char
和vector<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=&cable1
将cable1
的地址(大概是浮点数?)分配给longitud
,现在引用cable1
。
*longitud=40.5
取消引用经度并为其赋值 40.5。 因为longitud
引用cable1
,这会将值分配给cable1
。 这是*longitud
和cable1
是一回事。
这些都与问题标题"指针声明和间接寻址之间的区别">无关 - 间接寻址是一个通用的计算概念,指针是在 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
指针,以便表达式的计算结果*longitud
与cable1
相同。
Cable1 需要有一个位置记忆,然后纵向才能指向它。
前 3 行执行此操作:
- 为整数留出内存。
- 创建一个整数指针。
- 获取 int 指针以指向 int 的内存地址。指针引用 int。
后 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。这有点过时,但这是学习基础知识的绝佳方式。