指针(1)取地址运算
<1>取地址符&及其运算
(1)运算符&
-
链接scanf("%d",&i)里面的&;
1)作用:
获取变量的地址;
2)操作范围:
操作数必须是变量;
3)使用&的原因(为什么变量会有地址):
因为C语言的变量是放在内存里的;
4)以一段十六进制代码为例
#include<stdio.h>
int main(void){
int i=0;
printf("0x%x\n",&i);
}
-
//标注:引入%p(把值作为一个地址输出)——printf("%p\n",&i);输出的结果与printf("0x%x\n",&i)输出的结果相同;
1.我们对代码进行修改:(定义一个新变量p)
#include<stdio.h>
int main(void){
int i=0;
int p;
p=(int) &i;
printf("0x%x\n",p);
printf("%p\n",&i);
}
5)注意:编译器架构32/64
(1)方法1:
1.在这串代码中,当我们以32位的架构编译运行得到的输出的地址是一致的;
2.但当我们使用64位架构编译运行得到的输出地址并不相同
(2)方法2:
同时我们还可以使用另外一种方法对二者进行比较:利用sizeof
printf("%lu\n",sizeof(int));
printf("%lu\n",sizeof(&i))
-
得出结论:地址大小是否与int相同取决于编译器
出现的结果与第一种方法相近,在32位架构编译运行得到的结果相同,但64位输出地址不同
-
复习补充———链接文章:整数的类型(4):以0开头的数字字面量为八进制,输出为%o;以0x开头的数字字面量为十六进制,输出为%x;
6)&不能取的地址(不是变量不能取地址)
-
(1)&不能对没有地址的东西取值:
例如:
&(++i);&(i++);&(a+b)
-
(2)尝试相邻的变量的地址
以一段代码为例:
#include<stdio.h>
int main(){
int i=0;
int p;
printf("%p\n",&i);
printf("%p\n",&p);
return 0;
}
得到的结果是:
0061FF1C
0061FF18
-
说明:C在十六进制中相当于12;12与8相差4个字节;在32位的架构中,int=4,这也就说明在内存中二者紧挨着放
-
链接知识:堆栈-在堆栈中分配内存是自顶向下分配,所以我们先定义i,再定义p;i的内存地址在p的上方
7)数组的地址及数组单元的地址
-
以一段代码为例:
#include<stdio.h>
int main(){
int a[10];
printf("%p\n",&a);//首先将a交给取地址符
printf("%p\n",a);//直接把a这个数组变量的名字作为一个地址取出
printf("%p\n",&a[0]);//取出数组中第一个元素的地址
printf("%p\n",&a[1]);
return 0;
}
-
得出结果:
0061FEF8
0061FEF8
0061FEF8
0061FEFC
-
可见前三种方式取出的地址相同:即&a=a=&a[0]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程