取地址运算&
取地址运算,我们首先需要明白以下几个问题。
- 什么叫地址?
地址: 如果我们把计算的内存看作是一条长街上的一排房屋,每座房子都可以容纳数据(也就是内存),并且通过一个房号来标识,那么这个标识也就是我们这里讲的地址。 - 用什么方法取地址?
取地址,当然用取地址符& - 地址的大小是否与int相同?
可能相同,也有可能不同,主要取决于编译器。
&
&取地址符,他的操作对象必须是变量!有人肯定会问为什么?我们做一个简单的实验!
#include<stdio.h>
int main(int argc, char const *argv[])
{
int b=10;
printf("%d\n",b);
scanf("%d",&b);
printf("%d\n",b);
return 0;
}
实验告诉我们,如果操作对象是一个常量,我们对他取地址操作,他覆盖了原来的结果!
&不能取得地址
- &不能对没有地址的东西取地址
如下面几个能否取地址呢?
&(a+b)?
&(a++)?
&(++a)?
同样,我们通过实验来说明
#include<stdio.h>
int main(int argc, char const *argv[])
{
int a;
int b;
printf("%p\n",&(a+b));
printf("%p\n",&(a++));
printf("%p\n",&(++a));
return 0;
}
我们发现出现了三个error,错误描述是
error:lvalue required as unary ‘&’ operand
意思是&的操作对象必须是一个左值
指针
说那么多,终于可以进入我们的主题了——指针
什么叫指针呢?说明白了,指针就是保存地址的变量
如何定义和初始化指针呢?
类型关键字 *指针变量名
int *pa
//也可以写成 int* pa;
那么我们如何定义两个类型相同的指针呢?
int *pa,*pb;
int *pa,pb;
如果把这个也按照上面的形式 int* pa,pb;我们以为pa,pb都是指针变量,其实不然,因为*的优先级结合是从左到右,所以上面代码的实际效果是,pa为指针变量,pb为普通变量。
同样,我们做个实验,看看编译器会有什么反应。
#include<stdio.h>
int main(int argc, char const *argv[])
{
int* a,b;
int c=2;
a=&c;
b=&c;
printf("%d\n",*a);
printf("%d\n",*b);
return 0;
}
Line9| error: invalid type argument of unary ‘*’ (have ‘int’)|
编译器告诉我我们,b只是一个int型普通常量,不能按照指针来操作!
初始化指针
初始化指针变量就是给他赋一个默认的值,当然我们不用0,而是用NULL,比如这样
int *p=NULL;//注意这里NULL必须为大写
那么如何把变量的地址赋值给指针变量呢?
int a=10;//定义a;
int *p;//定义指针变量*p;
p=&a;//用指针变量存储a的地址
//或者可以写成下面这个形式
int a=10;
int *p=&a;//效果和第一种一样
指针的应用场景
交换两个变量的值
在这之前我们需要掌握一个知识点“指针作为参数”
void f(int *f)//此时的指针f就作为参数
#include<stdio.h>
void swap(int *pa,int *pb)
{
int t;
t=*pa;
*pa=*pb;
*pb=t;
}
int main(int argc, char const *argv[])
{
int a,b;
scanf("%d%d",&a,&b);
swap(&a,&b);
printf("%d%d",a,b);
return 0;
}