1.原因1——通过函数改变变量的值
1、练习:封装一个函数,实现两个数的交换
- 思路:根据函数的形参只有在调用时才会被分配内存空间,从而函数的实参和形参根本不是同一个变量,所以,如果我们不传递这两个变量的地址给函数,就不可能实现两个数的交换。这个时候就需要用指针作为函数的形参,然后通过间接访问的方式访问变量值。
f1. 封装交换两个数的API: void changeTwoData(int *pdata1, int *pdata2); 形参是指针值为data1的地址的指针变量pdata1,以及指针值为data2的地址的指针变量pdata2 f1.1 通过间接访问的方式,交换data1和data2中的数据 1. 定义变量data1和data2并初始化 2. 打印交换前的数据 3. 调用API1. 交换data1和data2中的数据 4. 打印交换后的数据
- 代码:
#include <stdio.h> void changeTwoData(int *pdata1, int *pdata2); int main(int argc, char const *argv[]) { int data1 = 10; int data2 = 20; int temp; printf("交换前:data1=%d, data2=%d\n", data1, data2); changeTwoData(&data1, &data2); printf("交换后:data1=%d, data2=%d\n", data1, data2); return 0; } void changeTwoData(int *pdata1, int *pdata2) { int temp; temp = *pdata1; *pdata1 = *pdata2; *pdata2 = temp; }
2、指针作为函数参数的代码心得:
- 想要通过函数修改某个变量的值,那么就必须传递这个变量的地址给函数。
- 函数的形参是指针类型的变量,写形参列表时记得加 * 作为修饰符。
- 函数知道你传递进来的是地址,所以在函数体中,需要通过间接访问的方式来访问变量值。
- 我们在定义形参时,最好前面加个p,比如int *pdata1,来告知变量pdata1里面的值是data1的地址。
2.原因2——指针指向固定的区域
1、应用场景:单片机开发、ARMBootLoader代码的编写。
- 举例:先获取一个合法的地址,然后在程序中自定义一个指针指向这个固定的地址,这个地址比方说在单片机中我们把它当做寄存器的地址。
#include <stdio.h> int main(int argc, char const *argv[]) { int a = 10; printf("address of a is 0x%p\n", &a); //用指针的强制转化,把一个固定的、合法的编号转化成地址,承接给一个指针变量 volatile unsigned int *p = (volatile unsigned int *)0x000000000061FE33; printf("p = 0x%p\n", p); return 0; }
2、指定固定内存地址当做寄存器地址的代码心得:
- 在合法的内存区域选择自己选择一个内存地址
- volatile的作用是防止操作系统自动优化内存地址