不学会指针就不算学会C语言

不说废话这章我直接发干货。

首先讲解以下指针变量的一个重要符号

  1. *:间接运算符/解引用运算符(*p),访问指针变量保存地址中的值,后跟一个指针名或地址名,给出存储在指针向地址上的值。
  2. *:表示定义的是一个指针类型。
int x=1,y=2,int z=[10];//普通变量会被分配内存空间,保存数值
int *ip;//定义一个指针类型的变量ip,指针变量也会被分配内存空间用来保存地址
ip=x;//ip指向x
y=*ip;//y现在的值为1,y取ip指向x的值
*ip=0;//x的值为0,*ip操作它指向地址的数值为0
ip=&z[0];//ip现在指向z[0]的地址,&取地址(这里指针变量ip和普通数组Z的类型要和被保存的z[0]地址的类型保持一致)
(*ip)++;//就是对ip保存的地址中的数值进行++,现在ip保存的是数组z的首地址,就是对z[0]中的数值进行++

程序运行时,变量数据保存在RAM内存中,变量保存的数据被分配到内存地址空间由CPU和编译器自动分配内存空间。

需要操作地址的场景:

通过地址访问寄存器

#define GPIOA_ODR        (*(uint32_t*)0x4001200)

以下几点是我以前区分不清的地方:

  1. 指针变量与普通变量的区别在于,普通变量保存普通数值,指针变量保存地址,他们的本质都是变量。
  2. 单片机的存储空间最小单位是字节,每个字节都有对应的地址,保存uint8_t类型要一个字节,保存uint16_t类型要两个字节,保存uint32_t类型就需要四个字节。
  3. 存储空间保存的数据既可以是普通数值,也可以是变量。
  4. 指针变量要保存地址,指针数据类型要和这个地址中数据类型保持一致。(解释一下这句话,也就是说你想保存一个int8_t的地址类型的数据,指针类型要是int8_t *

指针的使用

指针在定义时会被分配空间用来保存地址,这个空间的大小只取决于硬件平台的位数,对于ARM32,指针变量用于保存地址空间是4个字节,它与定义时的数据类型无关。

int x=1;//普通变量会被分配内存空间,保存数值
int *ip;//定义一个指针变量,分配地址保存地址

指针变量常见定义错误

uint32_t *p1,p2;//p1是指针变量,p2是普通变量
uint32_t *p1,*p2;//*要挨着变量名

指针的应用

1、指针做传递参数

使用指针做传参可以修改变量的数值


void test(int* p)
{
	printf("内层a:%d \n",*p);//读取上一层参数的值 
	*p=1;//修改上一层参数的值 
}
int main()
{
	int a=0;
	test(&a);
	printf("外层a:%d \n",a);
	return 0;
}

2、通过指针访问寄存器

#define GPIOG_CTL0 (* (uint32_t *)0x40012000)//0x40012000是一个16进制数值,编译器并不认为是一个地址,通过强制类型转换(uint32_t *)0x40012000,让编译器认为是地址(或者说是一个指针变量),最后通过*访问这个地址
GPIOG_CTL0 = 0xFFFFFFFF;//访问指针变量保存地址中的值
也可以用指针来解析协议,比如4字节的数据,可以定义(uint_8 *)的指针直接指,而不需要用位移。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jarrett_Zheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值