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

C语言指针深度解析:函数参数与数组关系详解 - 教程

一、指针作为函数参数

1. 值传递(Pass by Value)

核心机制

  • 实参将值复制给形参

  • 形参是实参的一个副本

  • 在被调函数内部修改形参,不会影响实参的值

适用场景:被调函数只需要读取实参内容,不需要修改实参

代码示例

#include 
// 值传递函数示例
void swap_by_value(int a, int b) {int temp = a;a = b;b = temp;printf("函数内: a=%d, b=%d\n", a, b); // 值已交换
}
int main() {int x = 10, y = 20;printf("交换前: x=%d, y=%d\n", x, y);swap_by_value(x, y);printf("交换后: x=%d, y=%d\n", x, y); // 值未改变return 0;
}

内存示意图

主调函数栈帧:
x = 10, y = 20
被调函数栈帧(swap_by_value):
a = 10 (x的副本), b = 20 (y的副本)
交换后:a = 20, b = 10
返回主函数后:
x = 10, y = 20 (原值不变)

2. 地址传递(Pass by Address)

核心机制

  • 实参将自己的地址传递给形参

  • 形参是一个指向实参的指针

  • 通过间接访问方式读写实参内容

适用场景:被调函数需要读取和修改实参内容

代码示例

#include 
// 地址传递函数示例
void swap_by_address(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}
void modify_array(int *arr, int size) {for(int i = 0; i < size; i++) {arr[i] *= 2; // 通过指针修改数组元素}
}
int main() {int x = 10, y = 20;int numbers[5] = {1, 2, 3, 4, 5};printf("交换前: x=%d, y=%d\n", x, y);swap_by_address(&x, &y);printf("交换后: x=%d, y=%d\n", x, y); // 值已交换modify_array(numbers, 5);printf("数组修改后: ");for(int i = 0; i < 5; i++) {printf("%d ", numbers[i]); // 所有元素乘以2}return 0;
}

内存示意图

主调函数栈帧:
x=10(地址0x1000), y=20(地址0x1004)
被调函数栈帧(swap_by_address):
a=0x1000(指向x), b=0x1004(指向y)
通过*a和*b直接操作x和y的内存空间

二、指针和数组的关系

1. 数组名的本质

核心概念:数组名是指向第一个元素的指针常量

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

2. 数组与指针的三个关键区别

特性

数组 int a[5]

指针 int *p

sizeof运算

sizeof(a) = 20(5×4字节)

sizeof(p) = 8(指针大小)

&运算符

&a类型为 int(*)[5](数组指针)

&p类型为 int**(二级指针)

可变性

指针常量,地址不可变

指针变量,地址可变

详细解释

int a[5] = {1, 2, 3, 4, 5};
int *p = a;
// 1. sizeof区别
printf("sizeof(a)=%lu\n", sizeof(a)); // 输出20
printf("sizeof(p)=%lu\n", sizeof(p)); // 输出8(64位系统)
// 2. &运算符区别
printf("&a类型: %p\n", (void*)&a);   // 数组指针
printf("&p类型: %p\n", (void*)&p);   // 指针的指针
// 3. 可变性区别
p++;        // 合法,指针可以移动
// a++;     // 错误!数组名是常量

3. 字符数组和字符串的传递

字符串遍历的三种方式

#include 
// 方式1:数组下标法
void output_str1(char a[]) {int i = 0;while(a[i] != '\0') {putchar(a[i]);i++;}putchar('\n');
}
// 方式2:指针法(推荐)
void output_str2(char *a) {while(*a) {  // 等价于 while(*a != '\0')putchar(*a);a++;}putchar('\n');
}
// 方式3:指针偏移法
void output_str3(char *a) {int i = 0;while(*(a + i)) {putchar(*(a + i));i++;}putchar('\n');
}
int main() {char str[] = "Hello, World!";output_str1(str);output_str2(str);output_str3(str);return 0;
}

三、需要掌握的字符串函数实现

1. 字符串长度计算(mystrlen)

#include 
int mystrlen(const char *str) {int len = 0;while(*str++) {  // 遇到'\0'时循环结束len++;}return len;
}
// 测试
int main() {char str[] = "Hello";printf("长度: %d\n", mystrlen(str)); // 输出5return 0;
}

2. 字符串复制(mystrcpy)

#include 
char *mystrcpy(char *dest, const char *src) {char *ret = dest;  // 保存目标字符串起始地址while((*dest++ = *src++)) {;  // 循环复制,包括'\0'}return ret;
}
// 测试
int main() {char src[] = "Hello";char dest[20];mystrcpy(dest, src);printf("复制结果: %s\n", dest);return 0;
}

3. 字符串连接(mystrcat)

#include 
char *mystrcat(char *dest, const char *src) {char *ret = dest;// 移动到dest的末尾while(*dest) {dest++;}// 追加src内容while((*dest++ = *src++)) {;}return ret;
}
// 测试
int main() {char str1[20] = "Hello";char str2[] = " World!";mystrcat(str1, str2);printf("连接结果: %s\n", str1); // 输出"Hello World!"return 0;
}

四、关键总结

参数传递选择指南

场景

传递方式

理由

只读不写

值传递

安全,不影响实参

需要修改实参

地址传递

可以直接操作原始数据

大结构体/数组

地址传递

避免复制开销

数组名与指针关系总结

  • 相同点:都可以用下标[]*运算符访问元素

  • 不同点:数组名是常量,包含长度信息;指针是变量,只存储地址

  • 字符串处理:利用'\0'作为结束标志,可以避免传递长度参数

http://www.jsqmd.com/news/325819/

相关文章:

  • 分析新型减温减压阀国产品牌,杭州杭辅电站辅机性价比如何?
  • 梳理车载连接器库存管理要点,与传感器连接注意啥及周转率咋计算
  • 一篇博文『标/题』浅说『标/题/党』的“威势”
  • 技术思维陷阱:当用例设计变成产品枷锁
  • 【医疗AI】面向机构分布偏移的自适应异构差分隐私联邦医学影像分割 完整实现 附源码开源
  • 2026合规专业的南非跨境物流全境派送专线品牌排名,前十有哪些
  • 企业级AI平台架构设计及AI应用架构师的前沿技术应用
  • 2026年高性价比压力匹配器品牌推荐,高效型压力匹配器优质工厂盘点
  • 2026年纵环缝焊接专机生产厂家推荐:焊接滚轮架/变位机/操作机全系供应
  • 烟台巴斯夫合法品牌授权公司,专业汽车改装技术创新揭秘
  • 明瑞国际靠谱吗,深聊其服务保障与客户案例
  • 好的,我来写一篇关于BLDC无刷直流电机Simulink模型的博文,中间穿插代码和分析
  • 量子测试新规热度解析:聚焦从业者最关注的三大爆点
  • 隐秘的脉动:多智能体系统如何在生成与审查的张力中进化
  • 2026年江苏本地扫码枪哪家性价比高,新算技术优势凸显
  • 变频式减温减压装置有哪些知名品牌,快来了解
  • 2026年鸿蒙跨平台开发:Flutter、React Native 及其他框架前瞻
  • 2026年育龙化工等靠谱葡萄糖厂家,全国服务值得选购
  • 代码与耕地:山东开发者的双面人生——农耕智慧如何重塑软件测试思维
  • 2026长沙心理咨询中心哪家好?专业机构选择指南
  • 工业交换机生产企业选择哪家好?为你解惑
  • 【亲测可用,米牛照片相似度检测删除工具】智能图像优化革命:释放存储空间的终极解决方案
  • HTTP 状态码清单大全
  • Fortran 中动态加载动态库
  • 网站敏感资料_目录大全(分类记忆+风险标注)
  • 讲讲醋酸钠选购要点,全国有哪些推荐的正规厂家?
  • 计算机毕业设计springboot校园帮助系统 基于SpringBoot的校园互助服务平台的设计与实现 面向高校的智慧校园援助系统构建——SpringBoot框架实践
  • PHP跨平台上传大附件时进度条怎么兼容?
  • 计算机毕业设计springboot文博篮球场地预定系统 基于 SpringBoot 的“文博体育”篮球馆在线预约平台 SpringBoot 驱动的智慧篮球场地资源预订系统
  • 2026年光端机主要的国产品牌有哪些,哪个口碑好