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

strlen与传值传址调用

目录

一、strlen的模拟实现

1、功能说明

2、函数原型

3、实现原理

4、模拟实现代码

5、注意事项

二、传值调用和传址调用

1、问题引入

2、传值调用的局限性

问题分析:

传值调用的特点:

3、传址调用的解决方案

解决方案分析:

传址调用的特点:

4、两种调用方式的对比

5、实际应用建议

传值调用适用于:

传址调用适用于:

安全建议:


一、strlen的模拟实现

1、功能说明

        strlen是C语言标准库中的一个字符串函数,用于计算字符串的长度。其功能是统计字符串中'\0'(空字符)之前的字符个数。

2、函数原型

size_t strlen(const char *str);

3、实现原理

  1. 函数接收一个字符串的起始地址

  2. 从该地址开始逐个字符向后遍历

  3. 每遇到一个非'\0'字符,计数器加1

  4. 遇到'\0'字符时停止计数

  5. 返回累计的字符个数

4、模拟实现代码

#include <assert.h>
#include <stdio.h>int my_strlen(const char *str)
{int count = 0;assert(str != NULL);  // 确保传入的指针不为空while(*str)  // 等价于 while(*str != '\0'){count++;str++;}return count;
}int main()
{int len = my_strlen("abcdef");printf("%d\n", len);  // 输出6return 0;
}

5、注意事项

  • 使用assert宏检查指针有效性,防止空指针导致的程序崩溃

  • 参数使用const修饰,保证不会意外修改原字符串

  • 返回类型可以根据需要选择int或size_t(无符号整型)


二、传值调用和传址调用

1、问题引入

        在C语言中,当我们需要在函数中修改主调函数的变量时,简单的传值调用无法实现这一目的。例如,实现一个交换两个整型变量值的函数。

2、传值调用的局限性

#include <stdio.h>void Swap1(int x, int y)
{int tmp = x;x = y;y = tmp;
}int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);printf("交换前:a=%d b=%d\n", a, b);Swap1(a, b);printf("交换后:a=%d b=%d\n", a, b);return 0;
}

当我们运行代码,结果如下:

问题分析

  1. 在main函数中创建变量a和b,各有自己的内存地址

  2. 调用Swap1时,将a和b的值传递给形参x和y

  3. x和y是独立的新变量,有自己的内存地址

  4. 在Swap1内部交换x和y的值,不会影响main函数中的a和b

  5. 这种传递方式称为"传值调用"

传值调用的特点

  • 实参的值被复制给形参

  • 形参和实参位于不同的内存空间

  • 对形参的修改不会影响实参

3、传址调用的解决方案

#include <stdio.h>void Swap2(int *px, int *py)
{int tmp = *px;  // 解引用获取px指向的值*px = *py;      // 将py指向的值赋给px指向的内存*py = tmp;      // 将临时值赋给py指向的内存
}int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);printf("交换前:a=%d b=%d\n", a, b);Swap2(&a, &b);  // 传递变量的地址printf("交换后:a=%d b=%d\n", a, b);return 0;
}

解决方案分析

  1. 函数参数改为指针类型,接收变量的地址

  2. 在main函数中调用时传递变量的地址(&a, &b)

  3. 在Swap2函数中通过解引用操作(*px, *py)直接操作原变量

  4. 这种传递方式称为"传址调用"

传址调用的特点

  • 实参是变量的地址,形参是指针

  • 通过指针间接访问和修改原变量的值

  • 函数和主调函数之间建立了真正的联系

  • 可以在函数内部修改主调函数中的变量

4、两种调用方式的对比

特性传值调用传址调用
参数形式普通变量指针变量
传递内容变量的值变量的地址
内存使用创建新变量副本直接操作原变量
修改影响不影响原变量直接影响原变量
适用场景只需读取变量值的操作需要修改变量值的操作
安全性高(不会意外修改原值)低(可能意外修改原值)

5、实际应用建议

传值调用适用于:

  • 只需使用变量值进行计算

  • 不修改原变量的场景

  • 简单数据类型(int, char, float等)

传址调用适用于:

  • 需要修改原变量的值

  • 传递大型数据结构(避免拷贝开销)

  • 需要函数返回多个值的场景

  • 实现链式数据结构(如链表、树等)

安全建议:

  • 对于不需修改的指针参数,使用const修饰

  • 对指针进行有效性检查

  • 明确区分输入参数和输出参数

通过理解指针和传址调用的原理,可以更灵活地设计函数,实现更复杂的程序功能。

http://www.xdnf.cn/news/17968.html

相关文章:

  • 设计模式(Design Patterns)
  • C++:stl-> list的模拟实现
  • 条件变量的基本介绍与有界缓冲区问题
  • 异步开发:协程、线程、Unitask
  • C语言——深入理解指针(四)
  • 获取农历日期
  • Jeecg后端经验汇总
  • strings命令和findstr命令验证iso文件中ntkrnlmp.exe系统版本
  • 如何避免网盘中资源被和谐?
  • LeetCode算法日记 - Day 12: 寻找旋转排序数组中的最小值、点名
  • Erlang notes[2]
  • Vue 侦听器(watch 与 watchEffect)全解析1
  • 图解软件知识库体系
  • GaussDB 常用数值类型
  • 分布式锁:从理论到实战的深度指南
  • python自学笔记8 二维和三维可视化
  • 深入解析Prompt缓存机制:原理、优化与实践经验
  • 云原生俱乐部-杂谈1
  • CVE-2014-6271(bash破壳漏洞 )
  • Android数据缓存目录context.getCacheDir与Environment.getExternalStorageDirectory
  • Git 中切换到指定 tag
  • 会议系统进程池管理:初始化、通信与状态同步详解
  • Fiddler抓包
  • 【FreeRTOS】刨根问底4: 优先级反转是啥?咋解决?
  • 为什么Integer缓存-128 ~ 127
  • 学习设计模式《二十二》——职责链模式
  • 搭建 Docker 私有仓库
  • springboot项目不同平台项目通过http接口AES加密传输
  • UE5配置MRQ编解码器输出MP4视频
  • 机器人“ChatGPT 时刻”倒计时