C/C++中取地址符&的语义

在C语言中,&符号大家一定很熟悉吧。

它除了可以作为按位运算“与”之外还有更常用的功能——取变量地址。

我们首先看下面一个简单的例子:

 
#include <stdio.h>
int main(void)
{
    int a = 0;
    int *p = &a;
    printf("The value is: %d/n", *p);
    return 0;
}

上面代码中,指针p指向变量a的地址。在C/C++中,每个变量都有其相应的地址,通过在变量标识符前加&符号即可获得变量的地址。

那么我们这么写可以吗?int *p = &0x01000;

这显然不行。因为对于一个数值常量,它是没有地址的。而变量之所以有地址就是因为要有一个存储单元对变量进行标识(当然,变量也可以直接映射到某个寄存器)。

我们再看下面的代码:

 
#include "stdio.h"
int main(void)
{
    int a = 0; // &a = 0x0012ff60 
    int *p = &*(int*)0x0012ff60;
    printf("The value is: %d/n", *p);
    return 0;
}

 上面代码又是怎么回事呢?

先前已经调查过变量a的地址——0x0012ff60,那么这里的指针p实际上也是指向变量a的地址。

首先,将0x0012ff60作为int*,这时它与&a是等价的。

然后*(int*)0x0012ff60表示取变量a的内容。

最后,&*(int*)0x0012ff60表示再脱去*(int*)0x0012ff60的解引用,相当于又变为(int*)&a。

因此,这里的&与第一个例子中的&是不同的语义。这里的&不是取地址,因为一个*(int*)0x0012ff60不是变量,它是没有地址的。每一个变量标识符在编译期间,编译器会为它们创建一个符号表,其中存放着变量标识符相应的各种属性,如类型、地址标识等。地址标识在连接后即可确定逻辑地址值。简而言之,&作为取地址操作,当且仅当&后面跟着的是变量或函数标识符。所以这里的&表示脱去解引用。

由此我们可以得出:&作为取地址操作时,其行为结果是在编译时就被确定的;而*,解引用操作(或取内容)操作,其行为结果只能在运行时才可被确定。

 

再看下面的例子,加深印象:

 
#include "stdio.h"
int main(void)
{
    int a = 0;
    int *p = &*&*&a;
    printf("The value is: %d/n", *p);
    return 0;
}

在C++中,&还可以表示引用,这个就不多说了。
#include "iostream"
using namespace std;
int main(void)
{
    int a = 0;
    int &r = a;
    cout << "The value is: " << r << endl;
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我了解您的要求了。针对您的问题,我可以给出以下回答: PL/0是一种简单的编程语言,它的语法和语义都比较容易实现。在编写PL/0编译程序时,我们通常需要包括以下几个部分:词法分析、语法分析、语义分析、间代码生成和目标代码生成。 其语义分析的主要作用是检查程序语义错误,并生成语义相关的信息,例如号表和四元式等。在C/C++语言,我们可以通过使用语法树来实现语义分析。具体来说,我们可以先进行语法分析,将程序转换为语法树的形式,然后在语法树上进行语义分析。 语义分析的主要任务包括以下几个方面: 1. 建立号表:在语法分析的过程,我们需要对程序出现的标识进行记录,以便在后续的语义分析和间代码生成使用。号表通常包括标识的名称、类型、作用域等信息。 2. 检查类型匹配:在进行表达式计算和赋值操作时,需要检查操作数的类型是否匹配。例如,加法运算的操作数必须都是数字类型。 3. 检查变量和函数的使用:在程序使用变量和函数时,需要检查其是否已经定义和声明,并且是否合作用域规定。例如,局部变量只能在其所在的函数使用。 4. 生成四元式:在语义分析的过程,我们可以根据程序的语义信息生成四元式,以便后续的间代码生成。四元式通常包括操作、操作数、结果等信息。 在C/C++语言,我们可以使用递归下降法来实现语法分析和语义分析。具体来说,我们可以使用一个递归函数来处理每个语法规则,并在函数进行相应的语义检查和四元式生成。最终,我们可以将生成的四元式输出到文件,以便后续的目标代码生成。 当然,以上只是一个简单的介绍,实际实现还需要考虑各种细节和特殊情况。如果您需要更具体的帮助或代码示例,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值