一、内存地址
变量都存放在内存中,都有一个内存地址
;则这段内存空间可使用变量名
或地址
进行操作,那怎么得到这个内存地址呢?
- 取地址符号:&
在变量名前加&,即可得到改变量说在内存中的地址。
int a = 10;
printf("a在内存中的地址:%d\n", &a);
打印结果:a在内存中的地址:13039812
注意:
- 1、
13039812
就表示变量a在内存中存放的地址
(每次运行结果可能都不一样)。 - 2、地址是用一个
“整数”
表示,但不是整型
。
问:是否有一种数据类型
存储地址
?
二、指针
指针有两种意思:指针类型
、指针变量
,而我们程序员常说的“指针”是指指针变量。
指针变量就是用来存储“地址”
的,该变量的类型就是指针类型。
- 定义语法:
数据类型* 变量名;
int* p;//定义了一个指向一个整型地址的指针
- 赋值:
int a = 10;
int* p = &a;//初始赋值,定义了一个指向整型变量a的地址的指针。
p = &a;//赋值
printf("a在内存中的地址:%d--%d\n", &a, p);
printf("a在内存中的地址:%p--%p\n", &a, p);//指针(地址)打印,用%p
输出结果:
a在内存中的地址:8321956--8321956
a在内存中的地址:007EFBA4--007EFBA4
用%p打印的地址,是十六进制整数
表示。
p变量存储了变量a的地址。
3. 指针操作变量:*(取值符号)
- 取值:
int a = 10;
int* p;
p = &a;
printf("%d--%d\n", a, *p);
输出结果:10--10
- 赋值:
int a = 10;
int* p = &a;
*p = 22;
printf("%d\n", *p);
输出结果:22
- NULL:空
int* p = NULL;//指向为NULL(0),表示指针未存放任何变量的地址。
printf("%d\n", p);
输出结果:0
重点: 定义、赋值、取值的使用。
- 例:
- 有一个变量 char c = ‘a’;通过指针将其改为‘A’。
char c = 'a';
char *p = &c;
*p = 'A';
printf("%c,%c\n", c, *p);
输出结果:A,A
- 有两个变量float f1 = 1.4, f2 = 5.6;使用指针操作变量,求两个变量的和。
float f1 = 1.4f, f2 = 5.6f;
float* p1 = &f1, *p2 = &f2;
printf("sum:%.2f\n", *p1 + *p2);
输出结果:sum:7.00
- 有个两个整型变量int a = 10,b = 15;使用指针对其值进行交换。
int a = 10, b = 15;
int* p1 = &a;
int *p2 = &b;
//交换
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
printf("a:%d,b:%d\n", a, b);
输出结果:a:15,b:10
交换图示:
错误示例: 对指针进行了交换,而非交换的变量的值。
int a = 10, b = 15;
int* p1 = &a;
int* p2 = &b;
int* tmp = p1;
p1 = p2;
p2 = tmp;
printf("a:%d,b:%d\n", a, b);
输出结果:a:10,b:1
实际只是交换了指针的指向
,并没有交换变量的值。
三、指针变量的大小
使用sizeof可以得到指针类型(变量)的大小:
int a = 0;
float f = 1.6f;
double lf = 3.1415;
char c = 'A';
int* pa = &a;
float* pf = &f;
double* pd = &lf;
char* pc = &c;
printf("%d, %d, %d, %d\n", sizeof(pa), sizeof(pf), sizeof(pd), sizeof(pc));
输出结果:4,4,4,4
得出结论:指针类型(变量)的大小是4。是因为存储的地址是一个整数;
那为什么要有多种类型的指针呢?是因为需要指向对应类型
空间。
注意: 通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配;但是指针的操作也是非常危险的,一不小心可能导致程序崩溃。
int *pa = (int*)00001122;
*p = 10;
访问了非法内存
,导致程序奔溃。
总结: 指针变量用于存放
某个变量的地址
,因为变量有多种类型,所以指针也对应有多种类型;而类型一一对应是必要的,因为指针寻址
,这将在后续内容中讲解。
练习
1、指针变量是保存内存中另一个数据的 地址 其值的变量。
2、使用指针实现:定义三个整数,输出其最大和最小值。
3、指针实现:输入年份、和这一年的第N天,最后算出这一天是这一年的几月几日。(区分闰年)
4、用指针实现:输入两个整数,求其最大公约数和最小公倍数
求24和60的最大公约数,先分解质因数,得24=2×2×2×3,60=2×2×3×5,24与60的全部公有的质因数是2、2、3,它们的积是2×2×3=12,所以,(24,60)=12。
求6和15的最小公倍数,先分解质因数,得6=2×3,15=3×5,6和15的全部公有的质因数是3,6独有质因数是2,15独有的质因数是5,2×3×5=30,30里面包含6的全部质因数2和3,还包含了15的全部质因数3和5,且30是6和15的公倍数中最小的一个,所以[6,15]=30。