C语言函数完全指南:10大核心要点从入门到精通

1. 函数:C语言的最小执行单元

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}
1.1 函数的基本结构
int sum(int a, int b) {
    int result = a + b;
    return result;
}
1.2 函数的底层实现

栈内存分配结构:

  1. 返回地址
  2. 参数值拷贝
  3. 局部变量存储区
  4. 寄存器保存区

2. 函数的参数传递:值传递的陷阱

2.1 基本类型参数传递
void swap(int x, int y) {
    int temp = x;
    x = y;
    y = temp;
}
2.2 指针参数的妙用
void real_swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}
2.3 数组参数的特殊处理
void print_array(int *arr, int len) {
    for(int i=0; i<len; i++){
        printf("%d ", arr[i]);
    }
}

3. 函数的返回值:不仅仅是数据输出

3.1 返回指针的注意事项
int* dangerous_func() {
    int local = 100;
    return &local; // 错误示例
}
3.2 多返回值实现技巧
typedef struct {
    int sum;
    int product;
} Result;

Result calculate(int a, int b) {
    return (Result){a+b, a*b};
}

4. 函数指针:C语言的超能力

4.1 函数指针的声明与使用
typedef int (*CompareFunc)(int, int);

void sort(int *arr, int len, CompareFunc cmp) {
    // 使用cmp指针调用比较函数
}

5. 递归函数:优雅与风险并存

5.1 经典递归案例
int fibonacci(int n) {
    if(n <= 1) return n;
    return fibonacci(n-1) + fibonacci(n-2);
}
5.2 递归优化技巧
#define MAX_N 100
int memo[MAX_N] = {0};

int optimized_fib(int n) {
    if(n <= 1) return n;
    if(memo[n] != 0) return memo[n];
    memo[n] = optimized_fib(n-1) + optimized_fib(n-2);
    return memo[n];
}

6. 可变参数函数:灵活性的代价

#include <stdarg.h>

double average(int count, ...) {
    va_list ap;
    va_start(ap, count);
    double sum = 0;
    for(int i=0; i<count; i++){
        sum += va_arg(ap, double);
    }
    va_end(ap);
    return sum / count;
}

7. 函数的高级技巧

7.1 函数属性扩展
__attribute__((always_inline)) void fast_func() {}
7.2 动态加载函数
#include <dlfcn.h>
void* handle = dlopen("./mylib.so", RTLD_LAZY);

8. 常见函数问题排查

调试命令:

valgrind --leak-check=full ./your_program
gprof program gmon.out > analysis.txt

9. 现代C语言函数新特性

9.1 C11泛型选择
#define cbrt(X) _Generic((X), \
    long double: cbrtl, \
    default: cbrt, \
    float: cbrtf)(X)

10. 最佳实践指南

/**
 * @brief 计算加权和
 * @param weight 权重系数(0.0-1.0)
 */
float weighted_sum(float a, float b, float weight) {
    weight = (weight < 0.0f) ? 0.0f : (weight > 1.0f) ? 1.0f : weight;
    return a * weight + b * (1 - weight);
}
C语言编程注意事项 1. 每个程序中一定包含main()函数, 尽管C语言中对函数命名没有限制。 2. printf函数永远不会自动换行, 只能用\n来实现, 回车键进行的换行在编译中会出现错误信息。 3. 在vs2008等平台中编译、测试要加 system("pause"); 来暂停dos自动退出引起的printf无法显示。 4. 所有自定义变量必须声明才能使用。 5. 每行一般只写一条语句, 在运算符两边加一个空格, 便于阅读。 6. 整数除法将会自动舍位, 不进行四舍五入的操作。 7. for(初始化部分;条件部分;增长部分) 比while 更适用于初始化和增长步长都是单条语句的情况。 8. 使用 #define 名字替换文本对部分"幻数" 赋予意义便于阅读 #define结尾无需;号来结束。 9. EOF(end of file)表示没有字符输入时定义在stdio.h 头文件中 EOF不等于\n 换行等。 10. 由于!= 的优先级大于 = ,因此如果对判断中存在变量赋值时 应对赋值加() 例如: while((c = getchar()) != EOF)。 11. getchar() 用于用户输入直至键入回车键。 12. 变量名以字母和数字组成, (下划线"_"被默认为字符, 以下划线为首写字母的为库类变量名), 变量常以小写字母开头,内部变量名前31位有效, 外部变量名至少前6位保持唯一性。 13.在C语言中是区分字母大小写的。 14. 一个字符常量为一个整数, 用''单引号括起来。例如: '0' 为48, 它与0没有任何关系。 15. ANSI C语言的转义符: \a 响铃符; \b 回退符; \f 换页符; \n 换行符; \r 回车符; \t 横向制表符 ; \v 纵向制表符; \\ 反斜杠; \? 问号; \' 单引号; \" 双引号; \ooo 八进制数; \xhh 十六进制数; '\0' 表示0, 即(null)。 16. 'x'与"x"的区别: 'x'表示一个整数, 字母x在其字符集中对应的数值, "x"表示包含一个字符x 以及一个结束符'\0'。 17. const在声明变量中起限制作用, 该限定变量的值不能被修改。 18. %运算符不能应用于float或double类型。 19. char类型转换为int型时, 因为无法判断它是signed还是unsigned,这样其结果有可能为负数, 所以转换时尽量指定signed和unsigned限制符。 20. ++i与i++ 的不同之处: ++i是先 +1再使用i, i++ 是先使用i再 +1。 21. 三元运算符"?:" 第一个表达式的括号不是必须的, 但是由于三元表达式的优先级非常低, 因此我们还是将第一个表达式用()括起来以便于阅读和理解。 22. C语言中可以使用递归 (即函数调用自身函数), 这样做并不节省储存空间也不加快执行速度, 只是使程序紧凑便于理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值