当前位置: 首页 > news >正文

C语言指针与参数传递详解 —— 从底层存储到高效编程

一、为什么要使用指针传参?

在函数调用时,如果直接传递变量(即值传递),系统会将实参复制一份到形参中。
这种方式简单、安全,但当参数数据量较大(例如数组、结构体等)时,会导致:

  • 效率低:复制数据耗时;

  •  内存浪费:产生多份数据;

  • 不灵活:函数内部无法修改主函数的数据。

为此,我们可以使用 指针传参,即传递变量的地址,实现主函数与子函数共享同一份数据。


 二、指针的定义与存储机制

指针的本质

指针本质上是一个变量,用于存放另一个变量的首地址

int a = 10; int *p = &a; // p中保存a的地址

此时:

  • p 是指针变量;

  • *p 表示“取出p指向的内容”;

  • &a 表示变量a的内存地址。


指针大小与系统位数

系统位数指针大小
16位系统2字节
32位系统4字节
64位系统8字节

无论指向什么类型(intfloatchar),指针的大小固定,但步长不同


三、计算机存储机制与大小端模式

存储方式

内存按“字节”为单位,每个地址存放1字节。

int a = 0x12345678;

int 占4字节,其内存布局取决于系统的字节序

模式内存中排列(低地址→高地址)
小端模式(Little Endian)78 56 34 12
大端模式(Big Endian)12 34 56 78

现代PC(x86、ARM)多采用小端存储。


十六进制与二进制的关系

十六进制是二进制的“简写”,每个十六进制数对应4个二进制位。

二进制十六进制
00000
1111F

例如:

1010 0011 0110 1111 0010 1001 1100 1101 → A36F29CD

优势:方便阅读与打印内存数据。


四、指针的基本操作

int a = 10; int *p; p = &a;

操作示例含义
取地址p = &a;获取变量a的首地址
取内容*p获取p所指向的值
自增p++指向下一个元素
自减p--指向上一个元素

五、数组与指针的关系

数组名本质上是一个常量指针,指向数组首元素。

int a[5] = {0,1,2,3,4}; int *p = a; // 等价于 int *p = &a[0];

访问方式等价:

写法等价表达
a[i]*(a + i)
p[i]*(p + i)

例:

for (int i = 0; i < 5; i++) {printf("%d ", *(p + i));}输出:0 1 2 3 4

 六、指针传参:节省内存与实现多返回值

普通传参(值传递)

void fun(char param){printf("%x\n", param); 
}
int main(){ char a = 0x77; fun(a); 
}会复制一份 a 的值给 param。

使用指针传参(地址传递)

void fun(char *param){printf("%x\n", *param); 
} 
int main(){char a = 0x77; fun(&a); 
}此时主函数与子函数共用同一份数据。

防止子函数修改主函数数据

int FindMax(const int *array, int length){int max = array[0]; for(int i = 1; i < length; i++){ if(array[i] > max)     max = array[i]; } return max; 
}const 表示“只读”,函数中若修改 array[i] 将会报错。

多返回值设计(输出参数)

void FindMaxAndCount(int *max, int *count, const int *array, int length){ *max = array[0]; *count = 1; for(int i = 1; i < length; i++){if(array[i] > *max){ *max = array[i]; *count = 1; }else if(array[i] == *max) {(*count)++; } } 
} 
int main(){int a[6] = {3,2,3,4,5,6};int max, count; FindMaxAndCount(&max, &count, a, 6); printf("max=%d\n", max); printf("count=%d\n", count); 
}结果:max=6 count=1通过指针参数实现了“多返回值”设计。

七、模块封装与返回指针

模块化设计中,函数可以返回指针,让主函数持有模块内部的数据句柄:

/******** 模块内部 ********/ 
int Time[] = {23,59,55}; 
int* GetTime(){ return Time; // 返回数组首地址 
}
/*************************/ int main(){ int *pt = GetTime(); printf("Hour=%d\n", pt[0]); return 0; 
}

这样主函数就能访问模块内部的变量,实现“间接控制”。


八、嵌入式场景:直接访问物理地址

#define DEVICE_ID_ADDR 0x40001000
unsigned int *deviceID = (unsigned int *)DEVICE_ID_ADDR; 
printf("Device ID: 0x%X\n", *deviceID);

典型用途:读取寄存器、访问硬件设备信息。


九、知识总结表

内容核心要点
指针定义存储变量首地址
存储机制小端模式为主流
数组与指针数组名即首地址
指针传参节省内存、共享数据
const修饰保护数据不被修改
输出参数实现多返回值
返回指针主函数可访问模块数据
嵌入式应用访问硬件物理地址
http://www.dtcms.com/a/453939.html

相关文章:

  • 建网站需要费用重庆网站建设首选承越
  • 定制型网站制作公司免费建网站域名
  • starrocks有哪些operator
  • vps服务器怎么创建多个网站天津建设银行东丽网站
  • 诚信网站建设的意义怎么样推销自己网站
  • 政务类信息化项目验收流程指南
  • 优秀设计赏析网站网页设计与网站的关系
  • 做网站公司促销海报从什么网站建网站好
  • MySQL Docker 容器化部署全指南
  • 建立网站用英语站长号
  • 网站建设需要学编程吗化妆品网站模版免费下载
  • 罗庄网站建设类似wordpress的建站
  • python做网站教程alexa排名什么意思
  • 单调栈知识点
  • 专业的肿瘤电场疗法厂家
  • 【02】VM二次开发——VisionMaster(VM)开发环境配置、工程搭建
  • 全面解析浏览器事件系统
  • 中国空间站模型网络工程专业是干什么的
  • 大型网站都怎么做推广wap网站建设案例
  • Windows文件资源管理器快速查看文件夹内所有视频总时长
  • 聊城网站营销信息一般的网站都是用什么系统做的
  • 网站搭建传媒公司网站模板
  • 关于我的cifar-10的模型跑取
  • linux进程详解
  • 【无约束优化】多维搜索——梯度方法
  • AI作为操作系统已经不能阻挡了,尽管它还没来
  • 哪个网站建设公司贵阳网站建设公司排行
  • 建设银行官方网站企业网银苏州市工程造价信息网官网
  • API 类别 - 选择器
  • 网站建设商业阶段谷歌网站提交