程序填空题:指针入门
小可爱们,咱们来做一个简单的计算器:输入两个整数,输出它们的和。
#include <stdio.h>
int main()
{
int a,b;
scanf("%d%d",@@[&a,&b](2)); //输入a,b
printf("%d\n",@@[a+b](2));//输出和
return 0;
}
小可爱们,这次使用scanf函数输入时,有没有忘记在变量前面加&符号?
为什么使用scanf函数变量前面要加&,printf函数变量前面不加&,这个&符号是什么作用呢?
咱们先看下面图片中编译器的输出。

小伙伴们,你发现了么?变量其实同时有地址和值两个属性,它的数据值,存储在某个内存地址中,这个值被称为变量的右值。我们也可认为右值的意思是被读取的值。它的地址值,即存储数据值的那块内存的地址,被称为变量的左值。
我们一般用一个变量,都是直接写一个名字,其实如果这个名字在赋值号右边,就是代表右值,也就是变量的值,如果在赋值号左边,就是代表左值,即代表变量的地址,写出来一样,意义是不一样的,编译器自动帮我们选择了正确的意义。
回到我们第一个问题:为什么使用scanf函数变量前面要加&,printf函数变量前面不加&?
因为scanf要变量里写入数值,所以它必须知道那个变量的地址,至于变量里存的是什么值,它是不关心的,反正写入之后就被覆盖成新的值了。
对比printf,是要输出变量里的数值,它只管要那个值,至于地址在哪,它也无所谓。
而变量名字写在函数参数里面时,和写在赋值号右边一样,也是代表值,可是像scanf这种函数,它确实需要地址,编译器只认为在赋值符左边的才是左值,那在scanf函数里,没法自动获得左值,这时就需要我们手动加一个取地址运算符&,明确告诉编译器去获取变量的地址给这scanf来用。
再仔细看看上面的图片,我们会发现这里的&a是int $$*$$类型,a是int类型。&其实是取地址运算符,&a得到的就是变量a分配的内存地址。&a表达式的值是地址,所以咱们在编译器里看到&a是int $$*$$类型,即指针类型。
类似的,我们可以使用下面语句定义一个指针变量:
int *p;
和普通变量不同,指针变量赋值必须指向一个已经分配的内存地址,例如:
int a = 2;
int *p = &a;
我们定义了一个变量a,其值为2。我们又定义了一个指针变量p(这里的$$*$$是指针变量定义符号),将其初始化为变量a的地址。
如果我们想使用指针变量p来修改变量a的值要怎么做呢?使用指针运算符,如下:
*p = 3;
这里的$$*$$是运算符。因为p是a的地址(p指向变量a),$$*$$p就是访问p指向的对象,$$*$$p赋值为3,就是a赋值为3。
答案:
第1空:&a,&b
第2空:a+b
#include <stdio.h>
int main()
{
int a,b;
scanf("%d%d",@@[&a,&b](2)); //输入a,b
printf("%d\n",@@[a+b](2));//输出和
return 0;
}
小可爱们,这次使用scanf函数输入时,有没有忘记在变量前面加&符号?
为什么使用scanf函数变量前面要加&,printf函数变量前面不加&,这个&符号是什么作用呢?
咱们先看下面图片中编译器的输出。

小伙伴们,你发现了么?变量其实同时有地址和值两个属性,它的数据值,存储在某个内存地址中,这个值被称为变量的右值。我们也可认为右值的意思是被读取的值。它的地址值,即存储数据值的那块内存的地址,被称为变量的左值。
我们一般用一个变量,都是直接写一个名字,其实如果这个名字在赋值号右边,就是代表右值,也就是变量的值,如果在赋值号左边,就是代表左值,即代表变量的地址,写出来一样,意义是不一样的,编译器自动帮我们选择了正确的意义。
回到我们第一个问题:为什么使用scanf函数变量前面要加&,printf函数变量前面不加&?
因为scanf要变量里写入数值,所以它必须知道那个变量的地址,至于变量里存的是什么值,它是不关心的,反正写入之后就被覆盖成新的值了。
对比printf,是要输出变量里的数值,它只管要那个值,至于地址在哪,它也无所谓。
而变量名字写在函数参数里面时,和写在赋值号右边一样,也是代表值,可是像scanf这种函数,它确实需要地址,编译器只认为在赋值符左边的才是左值,那在scanf函数里,没法自动获得左值,这时就需要我们手动加一个取地址运算符&,明确告诉编译器去获取变量的地址给这scanf来用。
再仔细看看上面的图片,我们会发现这里的&a是int $$*$$类型,a是int类型。&其实是取地址运算符,&a得到的就是变量a分配的内存地址。&a表达式的值是地址,所以咱们在编译器里看到&a是int $$*$$类型,即指针类型。
类似的,我们可以使用下面语句定义一个指针变量:
int *p;
和普通变量不同,指针变量赋值必须指向一个已经分配的内存地址,例如:
int a = 2;
int *p = &a;
我们定义了一个变量a,其值为2。我们又定义了一个指针变量p(这里的$$*$$是指针变量定义符号),将其初始化为变量a的地址。
如果我们想使用指针变量p来修改变量a的值要怎么做呢?使用指针运算符,如下:
*p = 3;
这里的$$*$$是运算符。因为p是a的地址(p指向变量a),$$*$$p就是访问p指向的对象,$$*$$p赋值为3,就是a赋值为3。
答案:
第1空:&a,&b
第2空:a+b