目录
一、概述
二、C函数参数
2.1 一张图讲清
2.2 按数据类型分类:
2.2.1 基本数据类型参数:
2.2.2 数组参数:
2.2.3 结构体参数:
2.2.4 指针参数:
2.2.5 函数指针参数:
2.3 按传递方式分类:
2.3.1 值传递:
2.3.2 指针传递(或引用传递):
三、例程
3.1 值传递-副本的地址不同
3.2 结构体的传递效率
3.3 数组参数
嵌入式科普(16)c语言函数参数的传递方式
一、概述
-
c语言函数参数分类简介
-
为【八、e2studio VS STM32CubeIDE之const修饰库函数形参】做铺垫
二、C函数参数
2.1 一张图讲清
2.2 按数据类型分类:
2.2.1 基本数据类型参数:
int、char、float、double 等基本数据类型可以直接作为函数的参数。
特点:参数是通过值传递的,即函数接收到的是参数值的一个副本,对参数值的修改不会影响到原变量。
2.2.2 数组参数:
在C语言中,数组作为函数参数时通常会退化为指向数组首元素的指针。
特点:传递的是地址,而不是数组本身,因此在函数内部可以修改数组元素的值。通常还需要传递数组的大小作为另一个参数。
2.2.3 结构体参数:
结构体可以作为整体作为函数的参数。
特点:如果结构体较大,按值传递会导致较大的性能开销,因此通常选择传递结构体的指针。
2.2.4 指针参数:
指针本身可以作为函数的参数,用于传递变量的地址。
特点:通过指针参数,函数可以访问和修改原变量的值。
2.2.5 函数指针参数:
函数指针也可以作为函数的参数,用于实现回调函数等高级功能。
特点:允许将函数作为参数传递给另一个函数,增加了程序的灵活性和模块化。
2.3 按传递方式分类:
2.3.1 值传递:
默认情况下,C语言中的函数参数是通过值传递的。
特点:函数接收到的是参数值的一个副本,对参数值的修改不会影响到原变量。
2.3.2 指针传递(或引用传递):
通过传递指针或引用,函数可以访问和修改原变量的值。
特点:提高了函数的灵活性,但也需要额外注意内存管理和指针操作的正确性。
三、例程
3.1 值传递-副本的地址不同
#include <stdio.h> // 这是一个函数,它接收一个整数作为参数(值传递)
void printValueAndAddress(int value) { printf("Inside function:\n"); printf("Value: %d\n", value); printf("Address of value (local variable): %p\n", (void*)&value);
} int main() { int a = 5; printf("Before function call:\n"); printf("Value: %d\n", a); printf("Address of a: %p\n", (void*)&a); printValueAndAddress(a); // 传递的是a的副本 printf("After function call:\n"); printf("Value: %d\n", a); printf("Address of a: %p\n", (void*)&a); return 0;
}
Before function call:
Value: 5
Address of a: 0x20001000
Inside function:
Value: 5
Address of value (local variable): 0x20000ffc
After function call:
Value: 5
Address of a: 0x20001000
3.2 结构体的传递效率
#include <stdio.h>
#include <time.h> typedef struct { int data[1000];
} LargeStruct; // 这是一个函数,它接收指向结构体的指针(指针传递)
void modifyStructByPointer(LargeStruct *structPtr) { for (int i = 0; i < 1000; ++i) { structPtr->data[i] = i; }
} // 这是一个函数,它接收结构体的副本(值传递)
void modifyStructByValue(LargeStruct structVal) { for (int i = 0; i < 1000; ++i) { structVal.data[i] = i; } // 注意:由于是值传递,这里的修改不会影响main中的原始结构体
} int main() { clock_t start, end; double cpu_time_used; LargeStruct myStruct; // 使用指针传递修改结构体 start = clock(); modifyStructByPointer(&myStruct); end = clock(); cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; printf("Time taken by pointer: %f seconds\n", cpu_time_used); // 使用值传递(虽然这里的修改没有意义,但仅为了对比时间) start = clock(); modifyStructByValue(myStruct); // 注意:这里的修改不会影响myStruct end = clock(); cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; printf("Time taken by value: %f seconds\n", cpu_time_used); return 0;
}
3.3 数组参数
#include <stdio.h> // 函数声明中使用了数组类型,但实际上接收的是指向数组首元素的指针
void printArray(int myArray[], int length) { for (int i = 0; i < length; i++) { printf("%d ", myArray[i]); } printf("\n");
} int main() { int myArray[] = {1, 2, 3, 4, 5}; int length = sizeof(myArray) / sizeof(myArray[0]); // 计算数组长度 // 调用函数,传递数组和长度 printArray(myArray, length); return 0;
}