精华内容
下载资源
问答
  • 内联函数 ,即inline函数 外部函数 ,即extern函数 静态函数,即static函数 内联函数: 即 inline函数 是一种在文件作用域内用inline说明或定义的局部函数, 是一种直接将其函数体代码插入到主调函数调用位置,以...

    C++声明或定义的函数可分为4种作用域:

    1. 默认全局函数
    2. 内联函数 ,即inline函数
    3. 外部函数 ,即extern函数
    4. 静态函数,即static函数

    内联函数:
    inline函数
    是一种在文件作用域内用inline说明或定义的局部函数
    是一种直接将其函数体代码插入到主调函数调用位置,以代替函数调用,提高执行效率的函数

    在进行函数调用时,除了完成函数体对应的计算指令外,还需要完成传递实参、保存寄存器和恢复寄存器等操作,这些操作都是计算指令之外的操作或开销,而真正用于函数体计算的指令很少,此时通过内联函数,由编译器将函数调用指令替换为函数体计算指令,既可以降低调用开销,又可以提高执行效率。

    //计算圆的面积和周长
    inline double PI = 3.1416;
    inline double perimeter(double r);//内联函数声明
    inline double area(double r)//加上inline,相当于在函数前加上了static,所以该函数只能在当前代码文件调用 
    {
    	//注意:不能在内部定义inline变量
    	return PI*r*r;
    }
    void main()
    {
    	double a;
    	double p;
    	p = perimeter(10.0);//内联失败,函数的定义出现在调用之后了
    	a = area(10.0);//内联成功,编译为m = 3.1416*10.0*10.0
    }
    double perimeter(double r)//内联函数定义
    {
    	return 2*PI*r;
    }
    

    注:
    内联函数内部不能使用分支、循环、多分支和函数调用等引起转移的语句,否则还是被编译为调用指令

    外部函数:
    使用关键字extern修饰的函数,
    声明函数时,不能直接定义函数体。

    C语言函数作用域分:
    1)全局函数,即任何代码文件都可访问或调用的函数
    2)静态函数
    外部函数要么来自全局函数,要么来自静态函数

    利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数

    在同一个文件中:

    int sum(m,n);
    void main()
    {
    	cout << num;//这样写的话,编译器是找不到num的,会报错
    	sum(2,num);//在sum函数里面是可以使用的,因为num的声明在调用之前
    }
    int num;
    int sum(m,n)
    {
    	return m + n;
    }
    

    这个时候我们可以这样写:

    int sum(m,n);
    void main()
    {
    	extern int num;//此时可以使用在后面定义的变量
    	cout << num;
    	sum(2,num);
    }
    int num=3;
    int sum(m,n)
    {
    	return m + n;
    }
    

    在两个文件中:
    a.cpp

    int num = 10;
    int sum()
    {
    	return num+num;
    }
    

    main.cpp

    void main()
    {
    	extern int num;//若不想变量被修改,加上const,变为extern const int num;
    	extern int sum();//此时就可以调用到a.cpp里面的变量和函数
    	num = 5;//修改变量的值
    	cout << num;
    	cout << sum();
    	
    }
    
    

    静态函数:
    用static修饰的函数,其作用域仅限于当前代码文件,仅能够被当前代码文件内的函数访问或调用。

    代码文件:.cpp
    目标文件:.obj
    静态链接库文件:.lib
    动态链接库文件:.dll

    展开全文
  • 目录: 一:定义 二:函数的一般形式 组成部分 1.返回类型 2.函数名称 ...内联函数 1.内部函数 定义: 2.外部函数 定义: 3.内联函数 定义: 注意: 七:main 函数的参数 1. main 函数带参...

    目录:

    一:定义

    二:函数的一般形式

    组成部分

     1.返回类型

    2.函数名称

    注意: 

    3.参数

    4.函数主体

    实例:

    三:函数声明

    补充:

    四:调用函数

    实例:

    五:函数参数

    六:内部函数&外部函数&内联函数

    1.内部函数

    定义:

    2.外部函数

    定义:

    3.内联函数

    定义:

    注意:

    七:main 函数的参数

    1. main 函数带参数 :

    2.main函数没有参数:

    3.argc 和 argv 

    4.如何传递给main函数的argc和argv的呢?

    八:函数参数传递都是值传递

    为什么? 

    实例:


    一:定义

    函数是一组一起执行一个任务的语句

    每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数

    函数声明告诉编译器函数的名称、返回类型和参数

    函数定义提供了函数的实际主体

    二:函数的一般形式

    return_type function_name( parameter list )
    {
       body of the function
    }

    组成部分

     1.返回类型

    • 返回类型:一个函数可以返回一个值
    • return_type 是函数返回的值的数据类型
    • 有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void

    2.函数名称

    • 函数名称:这是函数的实际名称
    • 函数名参数列表一起构成了函数签名

    注意: 

    函数名参数列表一起构成了函数签名

    意味着可以出现参数列表不同但是函数名相同的函数。

    void print()
    {
        printf("hello world!");
    }
    
    void print(int nums)
    {
        printf("%d\n",a);
    }

    这是合法的!!!

    3.参数

    • 参数:参数就像是占位符
    • 当函数被调用时,您向参数传递一个值,这个值被称为实际参数
    • 参数列表包括函数参数的类型、顺序、数量
    • 参数是可选的,也就是说,函数可能不包含参数

    4.函数主体

    • 函数主体:函数主体包含一组定义函数执行任务的语句

    实例:

    /* 函数返回两个数中较大的那个数 */
    int max(int num1, int num2) 
    {
       /* 局部变量声明 */
       int result;
     
       if (num1 > num2)
          result = num1;
       else
          result = num2;
     
       return result; 
    }

    该函数有两个参数 num1 和 num2,会返回这两个数中较大的那个数

    三:函数声明

    return_type function_name( parameter list );

    补充:

    在函数声明中,参数的名称并不重要,只有参数的类型是必需的

    int max(int num1, int num2);
    
    等价于
    int max(int, int);

    四:调用函数

    当程序调用函数时,程序控制权会转移给被调用的函数

    实例:

    #include <stdio.h>
     
    /* 函数声明 */
    int max(int num1, int num2);
     
    int main ()
    {
       /* 局部变量定义 */
       int a = 100;
       int b = 200;
       int ret;
     
       /* 调用函数来获取最大值 */
       ret = max(a, b);
     
       printf( "Max value is : %d\n", ret );
     
       return 0;
    }
     
    /* 函数返回两个数中较大的那个数 */
    int max(int num1, int num2) 
    {
       /* 局部变量声明 */
       int result;
     
       if (num1 > num2)
          result = num1;
       else
          result = num2;
     
       return result; 
    }

    运行结果:

    Max value is : 200

    由于程序是从上向下执行,所以函数要先声明,后调用 

    由于程序是从上向下执行,所以函数要先声明,后调用

    五:函数参数

    调用类型 描述
    传值调用 该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
    引用调用 通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

    六:内部函数&外部函数&内联函数

    根据函数能否被其他源文件调用,将函数区分为内部函数和外部函数

    内部函数又称静态函数

    可以使函数的作用域只局限于所在文件

    1.内部函数

    定义:

    如果一个函数只能被本文件中其他函数所调用,它称为内部函数

    在定义内部函数时,在函数名和函数类型的前面加 static

    static 类型名 函数名 (形参表)

    2.外部函数

    定义:

    如果在定义函数时,在函数的首部的最左端加关键字 extern,则此函数是外部函数,可供其它文件调用

    extern int max (int a,int b)

    注意:如果在定义函数时省略 extern,则默认为外部函数

    3.内联函数

    定义:

    内联函数是指用inline关键字修饰的函数

    在类内定义的函数被默认成内联函数

    内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质

    内联扩展是用来消除函数调用时的时间开销

    通常用于频繁执行的函数,对于小内存空间的函数非常受益

    注意:

    • 递归函数不能定义为内联函数
    • 内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数
    • 内联函数只能先定义后使用,否则编译系统也会把它认为是普通函数
    • 对内联函数不能进行异常的接口声明

    七:main 函数的参数

    main 函数其实与我们写的函数没有什么区别,它也会有自己的参数 

    1. main 函数带参数 :

    int main( int argc, char *argv[] )

    2.main函数没有参数:

    int main()

    3.argc 和 argv 

    argc 和 argv 是 main 函数的形式参数

    这两个形式参数的类型是系统规定的

    变量名称argc和argv是常规的名称,当然也可以换成其他名称

     main 的两个参数的参数名如下:

    int main( int argc, char *argv[] )

    以写成下面这样:

    int main( int test_argc, char *test_argv[] )  

    argc 是指传入参数的个数

    argv[] 是一个指针数组,指向传递给程序的每个参数

    4.如何传递给main函数的argc和argv的呢?

    C程序在编译和链接后,都生成一个exe文件,执行该exe文件时,可以直接执行

    也可以在命令行下带参数执行,命令行执行的形式为:

    可执行文件名称 参数1 参数2 ... ... 参数n

    可执行文件名称和参数、参数之间均使用空格隔开

    命令行字符串将作为实际参数传递给main函数:

    • (1) 可执行文件名称所有参数的个数之和传递给 argc
    •  (2) 可执行文件名称(包括路径名称)作为一个字符串,首地址被赋给 argv[0],参数1也作为一个字符串,首地址被赋 argv[1],... ...依次类推

    八:函数参数传递都是值传递

    本质上说,C 里面所有的函数参数传递,都是值传递

    为什么? 

    因为指针传递之所以能改变传递参数变量的值,是因为 swap 函数交换不是传递进来的指针本身而是指针指向的值

    实例:

    void swap(int *x, int *y);
    void swap(int *x, int *y){
        int temp;
        //这里操作的是指针指向的值 而不是指针
        temp = *x;
        *x = *y;
        *y = temp;
    //   倘若直接交换指针 a、b的值不会交换
    //    temp = x;
    //    x = y;
    //    y = temp;
    }
    
    int main( int argc, char *argv[] )
    {
        int a = 5;
        int b = 10;
        swap(a, b); //调用交换函数
        printf("交换结果为 a = %d, b = %d\n",a,b);
        return 0;
    }

     

    展开全文
  • 为了定义内联函数,通常必须在函数定义前面放一个inline关键字 但是在类内部定义内联函数时并不是必须的 任何在类内部定义的函数自动地成为内联函数    //: C09:Inline.cpp // From Thinking in C++, 2nd ...

    为了定义内联函数,通常必须在函数定义前面放一个inline关键字
    但是在类内部定义内联函数时并不是必须的
    任何在类内部定义的函数自动地成为内联函数 

     

    //: C09:Inline.cpp
    // From Thinking in C++, 2nd Edition
    // Available at http://www.BruceEckel.com
    // (c) Bruce Eckel 2000
    // Copyright notice in Copyright.txt
    // Inlines inside classes
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Point {
      int i, j, k;
    public:
      Point(): i(0), j(0), k(0) {}
      Point(int ii, int jj, int kk)
        : i(ii), j(jj), k(kk) {}
      void print(const string& msg = "") const {
        if(msg.size() != 0) cout << msg << endl;
        cout << "i = " << i << ", "
             << "j = " << j << ", "
             << "k = " << k << endl;
      }
    };
    
    int main() {
      Point p, q(1,2,3);
      p.print("value of p");
      q.print("value of q");
      getchar();
    } ///:~

     

    两个构造函数和print()函数都默认为内联函数
    在main()函数中使用内联函数是自然而然的事

    因为类内部的内联函数节省了外部定义成员函数的额外步骤,所以一定
    想在类声明内每一处都使用内联函数。

    使用内联函数的目的是减少函数调用的开销
    但假如函数较大,由于需要在调用函数的每一处重复复制代码,会使代码膨胀
    在速度方面获得的好处就会减少

    输出
    value of p
    i = 0, j = 0, k = 0
    value of q
    i = 1, j = 2, k = 3

    展开全文
  • 内联函数

    2019-10-06 00:17:13
    内联函数 内联函数_百度百科 内联函数 目录 定义 动机 函数内联问题 行情 宏比较 注意事项 编辑本段定义 内联函数从源代码层看,有函数的结构,而在编译后,...

    内联函数_百度百科

        内联函数

        目录

            定义
            动机
            函数内联问题
            行情
            宏比较
            注意事项

        编辑本段定义
        内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。
        编辑本段动机
        内联扩展是用来消除函数调用时的时间开销。它通常用于频繁执行的函数。 一个小内存空间的函数非常受益。
        如果没有内联函数,编译器可以决定哪些函数内联 。 程序员很少或没有控制哪些职能是内联的,哪些不是。 给这种控制程度,作用是程序员可以选择内联的特定应用 。
        编辑本段函数内联问题
        除了 相关的问题, 内联扩展一般,语言功能作为一个内联函数可能不被视为有价值的,因为它们出现的原因,对于一个数字:
        通常,一个编译器是在一个比人类更有利的地位来决定某一特定功能是否应该被内联。 有时,编译器可能无法尽可能多的功能内嵌作为程序员表示。
        一个重要的一点需要注意的是代码(内联函数)得到暴露其客户端(调用函数)。
        随着功能的演变,它们有可能成为合适的内联,他们不前,或不再在他们面前的内联合适。 而内联或取消内联函数比从宏转换为更容易,但仍需要额外的维修,一般产量相对较少的利益。
        用于本机C型编译系统的扩散可以增加编译时间,因为他们的身体的中间表示是到每个调用点,他们都是内联复制内联函数。在代码大小可能增加是由在编译时间可能增加镜像。
        C99中内嵌的规范要求只有一个额外在另一个编译单元,功能的外部定义时,相应的内联定义,可以发生在不同的编译单元多次,如果该函数用于地方。这很容易导致连接器,因为这样的定义不是由程序员提供的错误。 出于这个原因,往往是在C99内联一起使用静态的,也给出了函数的内部联系。
        在C + +,有必要定义一个在每一个模块(编译单元)内联函数使用一个普通的功能,而必须在只有一个模块中定义它。否则,就不可能编制的所有其他模块一个模块独立。
        对于功能问题与优化本身,而不是语言,请参阅使用内联扩展问题 。
        内联函数是使用inline关键字声明的函数,也成内嵌函数,它主要的作用是解决程序的运行效率。
        使用内联函数的时候要注意:
        1.递归函数不能定义为内联函数
        2.内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数。
        3.内敛函数只能先定义后使用,否则编译系统也会把它认为是普通函数。
        4.对内敛函数不能进行异常的接口声明。
        编辑本段行情
        “一个函数声明[。。。]说明符声明一个内联与内联函数。内联说明符指示的实现,内联函数体替代了在调用点是首选通常的函数调用机制。一个实现不要求在调用执行此点内联替代,但是,即使这个内嵌替代省略,由7.1.2内联函数定义的其他规则,仍应得到尊重“。
        - 国际标准化组织14882:1998(E)的,目前的C + +标准,第7.1.2
        “的函数说明符声明的内联函数是一个内联函数。[。。。]制作一个内联函数的函数表明该函数被调用尽可能快。在何种程度上这些建议是有效的,是实现定义( 注:例如,一个实施内联替换可能不会执行,或者可能只执行替换内联在声明中要求的范围内联的)。
        “[。。。]内联定义不提供外部定义的功能,并且不禁止的定义,还有一个是外部的翻译单位。一个内联定义提供了任何其他的外部定义,翻译可能用来实现呼吁在相同的翻译单元的功能。没有指定是否调用该函数内联定义或使用外部定义。”
        - 国际标准化组织9899:1999(E)的C99标准,第6.7.4
        编辑本段宏比较
        内联函数的功能和预处理宏的功能相似。相信大家都用过预处理宏,我们会经常定义一些宏,如
        #define TABLE_COMP(x) ((x)>0?(x):0)
        就定义了一个宏。
        为什么要使用宏呢?因为函数的调用必须要将程序执行的顺序转移到函数
        所存放在内存中的某个地址,将函数的程序内容执行完后,再返回到转去执行
        该函数前的地方。这种转移操作要求在转去执行前要保存现场并记忆执行的地
        址,转回后要恢复现场,并按原来保存地址继续执行。因此,函数调用要有一
        定的时间和空间方面的开销,于是将影响其效率。而宏只是在预处理的地方把
        代码展开,不需要额外的空间和时间方面的开销,所以调用一个宏比调用一个
        函数更有效率。
        但是宏也有很多的不尽人意的地方。
        1、.宏不能访问对象的私有成员。
        2、.宏的定义很容易产生二义性。
        我们举个例子:
        #define TABLE_MULTI(x) (x*x)
        我们用一个数字去调用它,TABLE_MULTI(10),这样看上去没有什么错误,
        结果返回100,是正确的,但是如果我们用TABLE_MULTI(10+10)去调用的话,
        我们期望的结果是400,而宏的调用结果是(10+10*10+10),结果是120,这显
        然不是我们要得到的结果。避免这些错误的方法,一是给宏的参数都加上括号。
        #define TABLE_MULTI(x) ((x)*(x))
        这样可以确保不会出错,但是,即使使用了这种定义,这个宏依然有可能
        出错,例如使用TABLE_MULTI(a++)调用它,他们本意是希望得到(a+1)*(a+1)的
        结果,而实际上呢?我们可以看看宏的展开结果: (a++)*(a++),如果a的值是
        4,我们得到的结果是4*4 = 16,a = 6。而我们期望的结果是5*5=25,这又出现了问题。
        事实上,在一些C的库函数中也有这些问题。例如:Toupper(*pChar++)就会对
        pChar执行两次++操作,因为Toupper实际上也是一个宏。
        我们可以看到宏有一些难以避免的问题,怎么解决呢?
        下面就是用我要介绍的内联函数来解决这些问题,我们可以使用内联函数
        来取代宏的定义。而且事实上我们可以用内联函数完全取代预处理宏。
        内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是
        通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时
        候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开
        销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一
        些问题。
        我们可以用Inline来定义内联函数,不过,任何在类的说明部分定义的函
        数都会被自动的认为是内联函数。
        下面我们来介绍一下内联函数的用法。
        内联函数必须是和函数体申明在一起,才有效。像这样的申明
        Inline Tablefunction(int I)是没有效果的,编译器只是把函数作为普通的函
        数申明,我们必须定义函数体。
        Inline tablefunction(int I) {return I*I};
        这样我们才算定义了一个内联函数。我们可以把它作为一般的函数一样调
        用。但是执行速度确比一般函数的执行速度要快。
        我们也可以将定义在类的外部的函数定义为内联函数,比如:
        Class TableClass{
        Private:
        Int I,j;
        Public:
        Int add() { return I+j;}
        Inline int dec() { return I-j;}
        Int GetNum();
        }
        inline int tableclass::GetNum(){
        return I;
        }
        上面申明的三个函数都是内联函数。在C++中,在类的内部定义了函数体的
        函数,被默认为是内联函数。而不管你是否有inline关键字。
        内联函数在C++类中,应用最广的,应该是用来定义存取函数。我们定义的
        类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我
        们类成员的数据了。
        对于私有或者保护成员的读写就必须使用成员接口函数来进行。如果我们把
        这些读写成员函数定义成内联函数的话,将会获得比较好的效率。
        Class sample{
        Private:
        Int nTest;
        Public:
        Int readtest(){ return nTest;}
        Void settest(int I) {nTest=I;}
        }
        当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如
        果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式
        调用函数。这样,内联函数就和普通函数执行效率一样了。
        编辑本段注意事项
        使用内联函数应注意的事项
        内联函数具有一般函数的特性,它与一般函数所不同之处只在于函数调用的处理。一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换。在使用内联函数时,应注意如下几点: 1.在内联函数内不允许用循环语句和开关语句。 如果内联函数有这些语句,则编译将该函数视同普通函数那样产生函数调用代码,递归函数(自己调用自己的函数)是不能被用来做内联函数的。内联函数只适合于只有1~5行的小函数。对一个含有许多语句的大函数,函数调用和返回的开销相对来说微不足道,所以也没有必要用内联函数实现。 2.内联函数的定义必须出现在内联函数第一次被调用之前。 3.本栏目讲到的类结构中所有在类说明内部定义的函数是内联函数。
    posted on 2013-01-24 10:02 lexus 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/lexus/archive/2013/01/24/2874286.html

    展开全文
  • c++内联函数

    2019-05-11 11:32:26
    内联函数: 内联函数简单来说就是实现在编译时将函数的代码副本放在每个调用函数的地方. 内联函数存在的意义就是解决函数调用的... 同时在外部定义的内联函数超过 10 行左右也会被忽略 inline. 这种校正规则一定...
  • 内联函数和宏函数

    2019-03-17 15:47:41
    内联函数 内联函数关键字inline,所谓的内联函数和普通函数的区别主要是在函数调用上的区别,内联函数的调用和宏函数有点类似,他在调用点会将代码展开,而不是开辟函数栈。举一个简单的例子。 int fun(int a,int ...
  • C++内联函数

    2021-01-31 15:55:25
    以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。 1.1 不使用内联函数的反汇编代码 1.1 使用内联函数的反汇编代码 2. 内联函数...
  • 内联函数学习

    2016-01-22 21:39:33
    内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数。   定义:内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。内联函数不是在调用时发生控制转移,而是在编译时将...
  • 如果读者也遇到过这个问题,请继续看下去,如果链接时提示未定义的变量是一些内联函数(即使用了关键字__inline)。那么就是笔者遇到的问题了。希望这篇文章对您有所帮助。在MDK中使用关键字__inline时,除了执行速度...
  • 什么是内联函数:  内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。  内联函数不是在调用时发生控制转移...
  • 内联函数  概念:以inline修饰的函数叫做内联函数,编译是C++编译器会在调用内敛函数的地方展开,没有函数压栈  的开销,内联函数提升程序运行的效率  特性:1.Inline是一种用空间换取时间的做法,省去调用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,277
精华内容 17,710
关键字:

外部内联函数