1、什么是内联函数?

在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗。为了解决这个问题,特别的引入了inline修饰符,表示为内联函数。 

#include <stdio.h>    
char* dbtest(int a);
//函数定义为inline即:内联函数    
inline char* dbtest(int a)   
{    
    return (a % 2 > 0) ? "奇" : "偶";    
}     
    
int main()    
{    
    int i = 0;    
    for (i=0; i < 50; i++)   
    {    
        if (i%5 == 0)
            printf("\n");
        printf("i:%d 奇偶性:%s ", i, dbtest(i));        
    }    
    printf("\n");
}

 

2、内联函数和普通函数的区别

普通函数调用步骤

  1. 保存当前函数的上下文(包括寄存器状态、返回地址等)
  2. 将控制权转移到被调用函数的代码位置
  3. 执行被调用函数的代码
  4. 恢复上下文并返回

内联函数调用步骤

  将内联函数的代码直接插入到每个调用点

 

3、内联函数和宏定义的区别

比较点 宏定义 内联函数
处理阶段 预处理阶段将宏调用替换为宏定义中的代码 编译阶段的代码展开
是否有语法检查

不检查

#define ADD(a, b) ((a) + (b))
int result = ADD(3.5, 4);  // 无类型检查,可能导致意外结果

语法检查和函数参数类型检查

inline int add(int a, int b) 
{
    return a + b;
}
int result = add(3.5, 4);  // 编译错误,参数类型不匹配
调试和维护 预处理阶段被展开,调试时无法看到宏的定义 调试时可以像普通函数一样设置断点和查看变量

性能

宏定义是简单的文本替换,不会增加额外的函数调用开销

宏定义较大且调用频繁时,可能导致代码膨胀

可以减少函数调用的开销

内联函数复杂的话,编译器通常会进行优化以避免过度膨胀

适用情形

适用于简单的文本替换,如常量定义、简单的表达式

#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))

适用于需要类型检查和调试支持的简单函数

适用于函数体较小且调用频繁的场景

inline int add(int a, int b) 
{
    return a + b;
}

 

4、内联函数使用注意点

(1)内联函数不可递归

(2)函数内容太过于复杂,编译器会忽略inline关键字,把他当成普通函数来处理

(3)函数体较小且调用频繁的场景,需要类型安全和调试支持时使用内联函数

(4)建议inline函数的定义放在头文件中,避免每个源文件都定义一次

(5)关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用

posted on 2025-02-28 10:13  轩~邈  阅读(31)  评论(0)    收藏  举报