在C语言中本来可以用变量名来访问变量,那为什么还要用指针呢? 下面将从以下两点解释为什么要用指针
一、指针可以向指定的地址赋值
首先看一段代码
#include<stdio.h>
#include<stdlib.h>
int main()
{
int data = 10;
printf("data的地址=%p\ndata = %d\n",&data,data);
system("pause");
return 0;
}
运行结果如下
可以看出数据10存放在地址为0060FEFC的单元中,如果在地址为0060FE00的单元中手动存放数据10该怎么办呢?
先看一段代码
#include<stdio.h>
#include<stdlib.h>
int main()
{
(int*)0x0060fe00;//将16进制数0060fe00强制转化为int型的指针
int* data = (int*)0x0060fe00;
*data = 10;
printf("data的地址为%p\n data的值为%d\n",data,*data);
system("pause");
return 0;
}
运行结果如下
即data的地址为0060FE00,地址中的内容为10
从程序中可以看出将0060fe00强制转化成了int型的指针,然后让指针变量data指向0060fe00,再将10赋值给data指针变量指向的内容,这样就实现了将数据强制放入到一个地址中
这种用法一般用在ARM架构,ARM裸机编程或者用在ARM驱动
还有另一种写法如下
类型修饰符"volatile"
volatile int* data = volatile(int*)0x0060fe00;
在当前线程内,当读取一个变量时,为了提高读取速度编译器会先把变量读取到一个寄存器中,再读取变量时就会直接从寄存器读取,当变量在本次线程改变时,会把改变后的变量值copy到该寄存器中,保持一致,当变量因为别的线程值发生改变,寄存器的值不会相应的改变,从而照成程序读取的值和实际变量值不一样,
volatile的作用就是不将变量读取到寄存器中,或者说每一次读取都是从内存中读取变量值,牺牲了一定的效率,但提升了正确率。
二、在函数调用时可以在子函数中改变main函数的变量值
先看下面两数交换的代码
#include<stdio.h>
#include<stdlib.h>
void swap(int a,int b)
{
int data;
data = a;
a = b;
b = data;
printf("swap函数中a = %d b = %d\n",a,b);
}
int main()
{
int a = 20;
int b = 30;
swap(a,b);
printf("main函数中a = %d b = %d\n",a,b);
system("pause");
return 0;
}
运行结果
从上面代码运行结果可以知道,在swap函数中将a、b的值已经交换了,但是在main函数中调用swap函数后a、b的值并没有交换。
这是因为swap函数的生存周期为调用swap函数那一刻到swap函数执行完这一时间段,swap函数中的a和b是在调用时临时开辟的空间swap执行完空间就释放了,什么都没有了,就算在swap函数中将形式参数a、b的值交换了,但是main函数中的值并没有交换。
那么怎么才能交换main函数中a、b的位置呢?
先看下面一段代码
#include<stdio.h>
#include<stdlib.h>
void swap(int* a,int* b)
{
int data;
data = *a;
*a = *b;
*b = data;
printf("swap函数中a = %d b = %d\n",*a,*b);
}
int main()
{
int a = 20;
int b = 30;
swap(&a,&b);
printf("main函数中a = %d b = %d\n",a,b);
system("pause");
return 0;
}
运行结果
从运行结果可以看出main函数和swap函数的a和b的值都已经交换了,这是为什么呢?
从代码中可以看出调用swap函数时实际参数传递的是a和b的地址,形式参数为两个int型的指针变量a和b,分别指向实际参数a和b的地址,在swap函数中进行的交换操作是直接访问的main函数中的a和b的值,所以就算swap函数的空间释放了main函数中a和b的值已经通过swap函数进行交换了。
即通过指针可以在子函数中改变main函数的值。