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、实现原理
-
函数接收一个字符串的起始地址
-
从该地址开始逐个字符向后遍历
-
每遇到一个非'\0'字符,计数器加1
-
遇到'\0'字符时停止计数
-
返回累计的字符个数
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;
}
当我们运行代码,结果如下:
问题分析:
-
在main函数中创建变量a和b,各有自己的内存地址
-
调用Swap1时,将a和b的值传递给形参x和y
-
x和y是独立的新变量,有自己的内存地址
-
在Swap1内部交换x和y的值,不会影响main函数中的a和b
-
这种传递方式称为"传值调用"
传值调用的特点:
-
实参的值被复制给形参
-
形参和实参位于不同的内存空间
-
对形参的修改不会影响实参
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;
}
解决方案分析:
-
函数参数改为指针类型,接收变量的地址
-
在main函数中调用时传递变量的地址(&a, &b)
-
在Swap2函数中通过解引用操作(*px, *py)直接操作原变量
-
这种传递方式称为"传址调用"
传址调用的特点:
-
实参是变量的地址,形参是指针
-
通过指针间接访问和修改原变量的值
-
函数和主调函数之间建立了真正的联系
-
可以在函数内部修改主调函数中的变量
4、两种调用方式的对比
特性 | 传值调用 | 传址调用 |
---|---|---|
参数形式 | 普通变量 | 指针变量 |
传递内容 | 变量的值 | 变量的地址 |
内存使用 | 创建新变量副本 | 直接操作原变量 |
修改影响 | 不影响原变量 | 直接影响原变量 |
适用场景 | 只需读取变量值的操作 | 需要修改变量值的操作 |
安全性 | 高(不会意外修改原值) | 低(可能意外修改原值) |
5、实际应用建议
传值调用适用于:
-
只需使用变量值进行计算
-
不修改原变量的场景
-
简单数据类型(int, char, float等)
传址调用适用于:
-
需要修改原变量的值
-
传递大型数据结构(避免拷贝开销)
-
需要函数返回多个值的场景
-
实现链式数据结构(如链表、树等)
安全建议:
-
对于不需修改的指针参数,使用const修饰
-
对指针进行有效性检查
-
明确区分输入参数和输出参数
通过理解指针和传址调用的原理,可以更灵活地设计函数,实现更复杂的程序功能。