C语言指针与双重指针的使用

在C语言的实际开发中,指针是非常常用的功能,不夸张的说指针是C语言的灵魂。有时甚至会用到双重指针。我在之前的项目中使用到过一些指针,现在试着做一下总结,希望能够帮忙到需要使用,但没怎么用过的初学者。我尽可能说的简单,如有不正确的地方,希望大家见谅。闲言少叙,正式开始。

  • 变量在内存中的存在形式

我们定义的变量都会存放在内存中一定的地址,见下面代码:

#include <stdio.h>
int variable_example = 0;
printf("Variable's address is %d\r\n", &variable_example);

编译器为会variable_example分配一个内存空间,如0x20001000. 实际变更在内存中的存在形式如下图:

变更在内存中的存在形式
变量名地址       变量值
variable_example0x200010000
another_vairable...0x20001004X
  • 指针变量

指针即地址,指针变量是指值是指针(地址)的变量。见下例:

#include <stdio.h>
int variable_example = 0;
int* pointer_example = NULL;
pointer_example = &variable_example;
printf("Variable's value is %d\r\n", variable_example);
printf("Variable's address is %d\r\n", &variable_example);
printf("Pointer's value is %d\r\n", pointer_example);
printf("Pointer's address is %d\r\n", &pointer_example);
printf("The value referenced by the pointer is: %d\r\n", *pointer_example);

变更和指针变更在内存中的存在形式如下:

变量名地址       变量值
variable_example0x200010000
another_vairable...0x20001004X
......X
pointer_example0x200020000x20001000

pointer_example是个变量,它里面存的是指针,所以它是指针变量。创建时将它赋值为NULL,即为空,表示这个指针还未被赋值,不能调用。然后将变量variable_example的地址赋给了它,即pointer_example这个变量的值为variable_example的地址。

Variable's value is 0

Variable's address is 0x20001000

Pointer's value is 0x20001000

Pointer's address is 0x20002000

The value referenced by the pointer is: 0

  • 指针变量的类型

指针变量的类型,指的是存放在指针所指向地址中的变量的类型。如示例中的int*,整型指针类型,指的是指针所指向的地址中存放的变量是整型,指针本身的类型初始是固定的。拿32位系统来说,指针本身的类型就是32位的无符号整型。

  • 指向指针的指针 -- 双重指针

试想一下这样的需求场景:为产品的实时状态信息做一个接口函数,供其他模块来获取这些实时状态。产品的实时状态是指产品运行时的一些过程数据,比如电机电流。有多个模块会用到电机电流,比如电机控制、电机保护、电流显示等等。首先做如下设计。

int Get_Porcess_Data(int id)
{
    ...
    return process_data_list[n];
}

以id去索引去查询process data list,并返回相应的结果。这个实现了数据查询,但这个问题:没有执行正确与否的指示,即没有返回错误码。产品中比较重要的接口,需要返回错误码来指示接口是否运行正确,来增加产品的可靠性和稳定性。因此改进设计如下。

ERR_TYPE Get_Porcess_Data(int id, int* value)
{
    ...
    *value = process_data_list[n];
    return NO_ERR;
}

这个改进的接口,实现了运行状态反馈,但还有一个问题:调用这个接口产生了一个过程数据的备份。调用此接口时一般为这样:

int motor_current = 0;
ERR_TYPE err_code = NO_ERR;
err_code = Get_Process_Data(0x01, &motor_current);

变量motor_current即为过程数据表process_data_list中电机电流的一个备份,这个备份只有调用接口时才会更新。如何不产生这个备份呢?双重指针能解决这个问题。再次改进设计如下:

ERR_TYPE Get_Porcess_Data(int id, int** value)
{
    ...
    *value = &process_data_list[n];
    return NO_ERR;
}

调用此接口时一般类似如下操作:

int* motor_current = NULL;
ERR_TYPE err_code = NO_ERR;
err_code = Get_Process_Data(0x01, &motor_current);
if(*motor_current > CURRENT_LIMIT)
{
    // Report motor current alarm
}

调用接口Get_Process_Data后,指针变量的值变为process_data_list中电机电流的地址,即指针变量指向了process data list中的电机电流,而不是备份。这样调用*motor_current时,始终取的是process data list中的实时值,而不用再次调用接口去刷新备份值了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值