返回值类型 函数名(参数列表) {
// 工厂内部的加工流程(函数体)
return 加工结果; // 没有返回值就省略
}
int
、char
、void
(啥也不产)等。就像你点奶茶,得先知道能拿到珍珠奶茶还是白开水。add
、swap
。别学“小明”他妈给函数起名叫a1b2c3
,连自己都找不到工厂大门。(int a, char b)
。如果没原料就写()
或者void
。// 加法工厂:接收两个整数,返回它们的和
int add(int x, int y) {
int sum = x + y; // 加工过程
return sum; // 交货!
}
// 无返回值的“唠嗑工厂”:接收一个字符,打印问候
void sayHello(char name) {
printf("你好呀,%c!\n", name); // 只干活不交货
}
void changeValue(int num) { // num是实参a的复印件
num = 100; // 改的是复印件
}
int main() {
int a = 5;
changeValue(a); // 把a的值5寄给num
printf("a还是%d,没被改变哦~\n", a); // 输出5
return 0;
}
*
能直接操作原始数据。void swap(int *p1, int *p2) { // 接收两个int类型的地址
int temp = *p1; // 取出p1地址里的值
*p1 = *p2; // 通过地址修改p1指向的值
*p2 = temp; // 通过地址修改p2指向的值
}
int main() {
int x = 3, y = 5;
swap(&x, &y); // 把x和y的地址当快递寄过去
printf("x变成%d,y变成%d啦!\n", x, y); // 输出5和3
return 0;
}
特性 | 值传递 | 指针传递 |
---|---|---|
传递内容 | 数据的副本 | 数据的地址 |
对实参影响 | 无影响 | 可修改原始数据 |
内存开销 | 小(复制简单数据) | 小(只传地址,4/8字节) |
安全性 | 高(不怕函数内部搞破坏) | 低(操作不当容易内存越界) |
典型场景 | 传递int、char等基本类型 | 传递数组、结构体,需修改原始值 |
void processArray(int arr[], int length)
时,其实arr[]
会被编译器自动转换成int *arr
,本质还是传递指针。证据如下:void printArray(int arr[]) {
printf("数组首元素地址:%p\n", arr); // 输出和实参数组地址相同
printf("sizeof(arr)=%d\n", sizeof(arr)); // 结果是4/8(指针大小),不是数组长度!
}
length
参数。比如写一个计算圆面积的函数,只需要用半径计算,不需要修改半径本身:
double calculateArea(double radius) { // 值传递,radius是副本
return 3.14159 * radius * radius;
}
经典案例:交换两个变量的值,必须用指针才能真正改变外部变量:
// 错误示范:值传递改不了原始数据
void wrongSwap(int a, int b) {
int temp = a; a = b; b = temp; // 改的是复印件,外面不变
}
// 正确示范:指针传递直接操作原始数据
void rightSwap(int *a, int *b) {
int temp = *a; *a = *b; *b = temp; // 改的是原件!
}
sizeof
在调用处计算后传进去。为什么说指针像女朋友?
因为如果你不好好管理(初始化),她们都会让你崩溃(程序报错)!
(温馨提示:现实中女朋友比指针可爱多了,一定要好好对待~)
“参数传递就像送快递,值传递是寄复印件,安全但改不了原件;指针传递是寄钥匙,高效但得小心别弄丢了地址!”