前体知识:格式控制符%p可以输出十六进制格式的地址;%lu可以输出无符号十进制整数地址。
9.1.1 取地址运算
运算符&
我们在第一周就见过这个符号“&”了,当时我们规定scanf("%d",&x);中变量之前一定要有这个符号
今天我们要开始学习关于它的知识,&,与加减乘除同类的运算符。
&:获得变量的地址,它的操作对象必须是变量。
那地址是个什么值呢?我们用代码试一下
#include<stdio.h>
int main()
{
int i;
printf("0x%x\n",&i);//0x开头,输出16进制数,因为c不会自动补上0x
return 0;
}
程序先给了一个warning,然后输出了0xbff12d70。
warning的提示是,如果想输出地址,不应该用%x而是%p,%p会自带0x开头输出十六进制的变量地址。
因此我们将上面打印一句改为
printf("%p",&i);
此时两种方式输出的值完全相同。然而这个地址很像一个整数,十六进制下的整数。那么试想一下我们先将地址的整数赋值给变量,再输出这个变量的值,得到的结果还一样吗?
#include<stdio.h>
int main()
{
int i=0;
int p;
p=(int)&i;//注意这里必须要强制转换为int类型,因为取地址实际上是指针类型
printf("0x%x\n",p);//输出整数p
printf("%p\n",&i);//输出地址
return 0;
}
结果如下:可以看到结果是一样的 (32位,即x86下编译运行时相同,64位下正常的地址是八字节,int是四字节)
因此地址的大小是否与int相同取决于编译器、架构。
&不能取的地址
&不能对没有地址的东西取地址
p=(int)&(p+i);
p=(int)&(++i);
p=(int)&(i++);
这三种都不能编译,必须是一个明确的变量
试试&能取的地址
- 变量地址(前面已试过,可行)
- 相邻变量(连续定义)的地址(地址也相邻)
- sizeof(&变量)(前面已试过,可行)
- 数组的地址
- 数组单元的地址
- 相邻数组单元的地址
int i=0;//最好初始化这样能确定其地址
int p;
//相邻变量
printf("%p\n",&i);
printf("%p\n",&p);
结果如图:
十六进制的c=12,因此两变量地址相差4,即一个int的字节大小。我们此时是在32位架构下编译,因此说明了,相邻变量在内存中的地址也是相邻的。
</