精华内容
下载资源
问答
  • 函数声明和定义

    万次阅读 多人点赞 2019-04-03 16:26:45
    函数声明 1.让编译器知道函数的名字,参数,返回类型.但是具体是否存在,无关紧要. 2.函数的声明一般出现在函数...通过例子来看函数声明和函数定义. //函数定义 double Add(double x, double y){ return x+y; } //函数...

    函数声明
    1.让编译器知道函数的名字,参数,返回类型.但是具体是否存在,无关紧要.
    2.函数的声明一般出现在函数的使用之前,一定要先声明在使用.
    3.函数的声明一般要放在头文件中.
    函数定义
    函数的定义就是指函数的具体实现方式,交代清楚函数的功能.
    通过例子来看函数声明和函数定义.

    //函数定义
    double	Add(double x, double y){
    	return x+y;
    }
    //函数声明
    double 	Add(double x, double y);
    

    这里我们要注意,当我们的函数定义放在函数调用之后的时候,我们必须要在函数调用之前加上函数声明.
    另外,当我们在一个.c文件中定义了一个函数,我们想要在另一个.c文件中调用这个函数,一定要记得加函数声明.
    当我们用到很多函数声明的时候,为了方便我们的调用,我们可以创建一个头文件.h(比如test.h),将函数声明放在头文件当中.这样我们在想要调用该函数时,就可以在程序的开始加头文件#include “test.h”.
    除此之外,我们在写头文件时,要注意加上#pragma once,这是为了保证头文件只引用一次.

    展开全文
  • C++函数声明和定义

    千次阅读 2016-04-12 11:06:44
    在上一节,我们已经学会了如何阅读函数原型如何调用一个函数。然而,仅靠系统给出的标准库函数是不够用的。我们有时候要根据我们的实际要求,写出一个合适自己使用的函数。 那么,我们如何来自己动手编写一个函数...
    在上一节,我们已经学会了如何阅读函数原型和如何调用一个函数。然而,仅靠系统给出的标准库函数是不够用的。我们有时候要根据我们的实际要求,写出一个合适自己使用的函数。
    
    那么,我们如何来自己动手编写一个函数呢?

    首先,我们要告诉电脑,我们自己编写了一个函数,即这个函数是存在的,这叫作函数的声明(Declaration)。其次,我们要告诉电脑这个函数是怎么运作的,这叫作函数的定义(Definition)。显然,函数的声明和函数的定义是两个不同的概念。 声明表示该函数存在,而定义则是表示该函数怎么去运行。

    我们平时做事都是要有先后顺序的,如果把次序颠倒了可能会惹些麻烦出来。编写函数的时候也一样。我们必须在调用一个函数之前就告诉电脑这个函数已经存在了,否则就成了“马后炮”。 所以,我们一般把函数的声明放在主函数前面。

    函数的声明

    在C++中,函数原型就是函数的声明。所以,函数原型除了向用户说明如何使用一个函数以外,还告诉电脑存在这样一个可以使用的函数。

    我们已经介绍了函数原型的结构,只不过“产生结果类型”这个名称是为了方便理解而起的。它应该称为“返回值类型”,用任意一种数据类型来表示,比如int或者char等等,当然还包括空类型void。多个参数则构成了“参数表”,表示运行这个函数需要哪些数据。于是,函数原型的结构就是:
         返回值类型函数名(参数表);
    函数声明同变量的声明一样,是一句语句。所以在语句结束要加上分号。函数名、参数名的规则和注意事项同变量名一样。

    关于“返回”的概念稍后再作介绍,我们先来说说参数表。我们知道,在声明函数的时候,会写一些参数,而在调用函数的时候需要一一对应地填入这些参数。虽然它们都叫参数,但在不同的情况下,它们的含义是不同的。 在声明一个函数的时候,参数是没有实际值的,只是起到一个占位的作用,所以称为形式参数,简称“形参”;在调用一个函数的时候,参数必须有一个确定的值,是真正能够对结果起作用的因素,所以称为实际参数,简称“实参”。 我们拿数学中的函数作为例子,g(x,y)=x/4+y中的x和y就是形式参数,而g(4,1)=4/4+1=2中的4和1就是实际参数;如果令a=4、b=1,那么g(a,b)中的a和b也是实际参数。

    函数的定义

    说完了函数的声明,我们来说函数的定义。其实函数的定义对大家来说是比较熟悉的。因为我们之前所写的程序都是对主函数的定义。函数定义的格式为:
    没有分号结尾的函数原型
    {
        语句块;
    }


    我们把函数定义中没有分号结尾的函数原型称为函数头,把之后的语句块称为函数体。任何一个函数的定义不能出现在另一个函数体内。但函数体内可以调用任何一个函数,包括其本身。
    下面我们先来看一个例子,你就会对函数定义有些了解了。(程序6.2.1)



    运行结果:
    5
    程序在运行的时候从main函数开始,遇到调用一个用户定义的函数max,则去查找这个max函数的定义,然后运行max函数。运行完了以后,回到调用max函数的地方,继续后面的语句,直到程序结束。所以整个程序的运行过程如箭头所示。

    不要使用相同的变量和参数

    如果在一个班级里有两个同名同姓的同学,那么老师上课点名将是件麻烦事。因为大家都搞不清到底是在叫谁。可是,如果两个不同的班级有两个同名同姓的同学,就不会发生这种尴尬,因为老师在不同的教室点相同的名字,会有反应的只有一个同学。

    我们把这个问题套用到函数上来。如果在同一个函数有两个名字相同的变量,那么电脑将无法分清到底要使用哪个变量,导致错误发生。而在不同的函数中,即使有相同名称的变量,由于在某一个函数中该变量的名称是唯一的,电脑也能方便的识别要使用哪个变量。因此,我们得到这样一个结论: 一般情况下,在同一个函数中,不能有名称相同的变量或参数;在两个不同的函数中,可以有名称相同的变量或参数。

    下面就让我们来看一个实例:(程序6.2.2)
    #include "iostream.h"
    int max(int a,int b,int c);//求三个整数的最大者
    int min(int a,int b,int c);//求三个整数的最小者
    void output(int a);//输出功能
    int main()
    {
       int a=3,b=4,c=2;
       output(max(a,b,c));//把max函数的返回值作为output函数的实参
       output(min(a,b,c));
       return 0;
    }
    int max(int a,int b,int c)//不在同一个函数中,参数名重复没关系
    {
       if (a>=b && a>=c) return a;
       if (b>=a && b>=c) return b;
       return c;//一旦执行了前面的return,这句就不会被执行到
    }
    int min(int a,int b,int c)
    {
       if (a<=b && a<=c) return a;
       if (b<=a && b<=c) return b;
       return c;
    }
    void output(int a)
    {
       cout <<a <<endl;
       return;//返回空类型
    }
    运行结果:
    4
    2
    要注意,一旦函数运行结束,那么该函数中声明的参数和变量都将消失。就像下课了,同学们都回家了,老师叫谁都是叫不应的。
    展开全文
  •  函数的声明和定义区别: 函数声明: 返回类型 函数名(参数类型1 参数名1,·····,参数类型n 参数名n); 如:int fun(int a, int b); void display(); 函数定义: 返回类型 函数名(参数类型1 参数名...

      简单地说下函数以及结构体的声明(说明)和其定义的区别,避免混淆。

      函数的声明和定义的区别:

      函数声明:

      返回类型 函数名(参数类型1 参数名1,·····,参数类型n 参数名n);

      如:int fun(int a, int b);

        void display();

      函数定义:

      返回类型 函数名(参数类型1 参数名1,·····,参数类型n 参数名n)

      {

        函数体······

      }

      如:int  fun(int a,int b)
             {  int  c;
    
                 if(a > b) 
                   c = a - b;
                 return c;    
         }
    
    
    
          在C语言程序中,如果main()函数在前,必须在mian()中写函数声明;如果函数在main()前面,可以不在main()中写函数声明。
    
    
    
    
      结构体的说明和定义的区别:
    
    
      结构体的说明:
    
          struct 结构体名
    
          {
    
        类型     变量名;
    
            类型     变量名;
            ...
          };
          如:struct string
                {
    
                   char name[8];
    
                   int age;
                   char sex[2];
    
                 };
    
        结构体的定义:
            struct 结构体名  结构体变量;
            如:struct string person;
     
    
         当然对于结构体来说可以直接说明并且定义:
           如: struct string
                  {
                    char name[8];
                    int age;
    
                    char sex[2];
    
                   }person;
    
    
    

    原创文章,欢迎转载,转载请注明:blog.csdn.net/jjzhoujun2010

    作者:Dream V Fly

    展开全文
  • c++模板函数声明和定义分离

    千次阅读 2016-09-24 12:32:39
    c++模板不支持分离编译, 把你模板类的声明和实现放到.h文件里面 。按照这个说的把.h.cpp文件合并后,果然可以了。 但是为什么呢,为什么模板就不支持分离编译?---继续google ing 搜到了如下文章(文章原文...

    转载至:点击打开链接

    c++模板不支持分离编译, 把你模板类的声明和实现放到.h文件里面 。按照这个说的把.h和.cpp文件合并后,果然可以了。

    但是为什么呢,为什么模板就不支持分离编译?---继续google ing

    搜到了如下文章(文章原文链接:http://blog.csdn.net/bichenggui/article/details/4207084):

    首先,一个编译单元(translation unit)是指一个.cpp文件以及它所#include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件(假定我们的平台是win32),后者拥有PE(Portable Executable,即windows可执行文件)文件格式,并且本身包含的就已经是二进制码,但是不一定能够执行,因为并不保证其中一定有main函数。当编译器将一个工程里的所有.cpp文件以分离的方式编译完毕后,再由连接器(linker)进行连接成为一个.exe文件。

    举个例子:

    //---------------test.h-------------------//
     
    void  f(); //这里声明一个函数f
     
    //---------------test.cpp--------------//
     
    #include”test.h”
     
    void  f()
     
    {
     
    //do something
     
    } //这里实现出test.h中声明的f函数
     
    //---------------main.cpp--------------//
     
    #include”test.h”
     
    int  main()
     
    {
     
    f(); //调用f,f具有外部连接类型
     
    }

    在这个例子中,test. cpp和main.cpp各自被编译成不同的.obj文件(姑且命名为test.obj和main.obj),在main.cpp中,调用了f函数,然而当编译器编译main.cpp时,它所仅仅知道的只是main.cpp中所包含的test.h文件中的一个关于void f();的声明,所以,编译器将这里的f看作外部连接类型,即认为它的函数实现代码在另一个.obj文件中,本例也就是test.obj,也就是说,main.obj中实际没有关于f函数的哪怕一行二进制代码,而这些代码实际存在于test.cpp所编译成的test.obj中。在main.obj中对f的调用只会生成一行call指令,像这样:

    call f [C++中这个名字当然是经过mangling[处理]过的]

    在编译时,这个call指令显然是错误的,因为main.obj中并无一行f的实现代码。那怎么办呢?这就是连接器的任务,连接器负责在其它的.obj中(本例为test.obj)寻找f的实现代码,找到以后将call f这个指令的调用地址换成实际的f的函数进入点地址。需要注意的是:连接器实际上将工程里的.obj“连接”成了一个.exe文件,而它最关键的任务就是上面说的,寻找一个外部连接符号在另一个.obj中的地址,然后替换原来的“虚假”地址。

    这个过程如果说的更深入就是:

    call f这行指令其实并不是这样的,它实际上是所谓的stub,也就是一个jmp 0xABCDEF。这个地址可能是任意的,然而关键是这个地址上有一行指令来进行真正的call f动作。也就是说,这个.obj文件里面所有对f的调用都jmp向同一个地址,在后者那儿才真正”call”f。这样做的好处就是连接器修改地址时只要对后者的call XXX地址作改动就行了。但是,连接器是如何找到f的实际地址的呢(在本例中这处于test.obj中),因为.obj与.exe的格式是一样的,在这样的文件中有一个符号导入表和符号导出表(import table和export table)其中将所有符号和它们的地址关联起来。这样连接器只要在test.obj的符号导出表中寻找符号f(当然C++对f作了mangling)的地址就行了,然后作一些偏移量处理后(因为是将两个.obj文件合并,当然地址会有一定的偏移,这个连接器清楚)写入main.obj中的符号导入表中f所占有的那一项即可。

    这就是大概的过程。其中关键就是:

    编译main.cpp时,编译器不知道f的实现,所以当碰到对它的调用时只是给出一个指示,指示连接器应该为它寻找f的实现体。这也就是说main.obj中没有关于f的任何一行二进制代码。

    编译test.cpp时,编译器找到了f的实现。于是乎f的实现(二进制代码)出现在test.obj里。

    连接时,连接器在test.obj中找到f的实现代码(二进制)的地址(通过符号导出表)。然后将main.obj中悬而未决的call XXX地址改成f实际的地址。完成。

    然而,对于模板,你知道,模板函数的代码其实并不能直接编译成二进制代码,其中要有一个“实例化”的过程。举个例子:

    //----------main.cpp------//
     
    template < class  T>
     
    void  f(T t)
     
    {}
     
    int  main()
     
    {
     
    //do something
     
    f(10); // call f<int> 编译器在这里决定给f一个f<int>的实例
     
    //do other thing
     
    }

    也就是说,如果你在main.cpp文件中没有调用过f,f也就得不到实例化,从而main.obj中也就没有关于f的任意一行二进制代码!如果你这样调用了:

    f(10); // f<int>得以实例化出来

    f(10.0); // f<double>得以实例化出来

    这样main.obj中也就有了f<int>,f<double>两个函数的二进制代码段。以此类推。

    然而实例化要求编译器知道模板的定义,不是吗?

    看下面的例子(将模板的声明和实现分离):

    //-------------test.h----------------//
     
    template < class  T>
     
    class  A
     
    {
     
    public :
     
    void  f(); // 这里只是个声明
     
    };
     
    //---------------test.cpp-------------//
     
    #include”test.h”
     
    template < class  T>
     
    void  A<T>::f() // 模板的实现
     
    {
     
    //do something
     
    }
     
    //---------------main.cpp---------------//
     
    #include”test.h”
     
    int  main()
     
    {
     
    A< int > a;
     
    f(); // #1
     
    }

    编译器在#1处并不知道A<int>::f的定义,因为它不在test.h里面,于是编译器只好寄希望于连接器,希望它能够在其他.obj里面找到A<int>::f的实例,在本例中就是test.obj,然而,后者中真有A<int>::f的二进制代码吗?NO!!!因为C++标准明确表示,当一个模板不被用到的时侯它就不该被实例化出来,test.cpp中用到了A<int>::f了吗?没有!!所以实际上test.cpp编译出来的test.obj文件中关于A::f一行二进制代码也没有,于是连接器就傻眼了,只好给出一个连接错误。但是,如果在test.cpp中写一个函数,其中调用A<int>::f,则编译器会将其实例化出来,因为在这个点上(test.cpp中),编译器知道模板的定义,所以能够实例化,于是,test.obj的符号导出表中就有了A<int>::f这个符号的地址,于是连接器就能够完成任务。

    关键是:在分离式编译的环境下,编译器编译某一个.cpp文件时并不知道另一个.cpp文件的存在,也不会去查找(当遇到未决符号时它会寄希望于连接器)。这种模式在没有模板的情况下运行良好,但遇到模板时就傻眼了,因为模板仅在需要的时候才会实例化出来,所以,当编译器只看到模板的声明时,它不能实例化该模板,只能创建一个具有外部连接的符号并期待连接器能够将符号的地址决议出来。然而当实现该模板的.cpp文件中没有用到模板的实例时,编译器懒得去实例化,所以,整个工程的.obj中就找不到一行模板实例的二进制代码,于是连接器也黔驴技穷了。

    展开全文
  • --------------------------------------------...注:类的静态函数与非静态函数定义上并没有任何区别 只是在声明的时候 静态函数前面有关键字static  而非静态函数是没有这个关键字的。
  • 关于C++模板函数声明定义的问题

    万次阅读 多人点赞 2018-07-22 21:59:37
    关于C++模板函数声明定义的问题 关于C++模板函数声明定义的问题 模板函数出现的问题 模板函数问题解决 模板函数出现的问题 今天在写代码的时候,发现了一个关于模板函数的问题。如下所示, demo...
  • 【C/C++面试必备】声明和定义区别

    千次阅读 多人点赞 2021-07-16 07:25:44
    ???? 作者:Linux猿 ???? 简介:CSDN博客专家?...,C/C++、面试、刷题、算法尽管咨询我,...2.3 函数声明和定义区分 三、声明和定义区别 3.1 声明/定义次数 3.2 分配内存 3.3 做了什么 本文来介绍一下声明和定义
  • 函数定义声明区别

    万次阅读 多人点赞 2019-01-06 15:42:38
    C语言编译系统是由上往下编译的.一般被调函数放在主调函数后面的话,前面就...函数声明由函数返回类型、函数名形参列表组成。形参列表必须包括形参类型,但是不必对形参命名。这三个元素被称为函数原型,函数原型描...
  • 函数声明可以定义命名的函数变量,而无需给变量赋值。函数声明是一种独立的结构,不能嵌套在非功能模块中。可以将它类比为 变量声明。就像变量声明必须以“var”开头一样,变量声明必须以“function”开头。函数名在...
  • 函数声明和函数表达式的区别

    千次阅读 2019-05-20 10:34:59
    函数声明和函数表达式的区别】 每篇分享文从 【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】 八个方面深度解析前端知识/技能,本篇分享的是: 【函数...
  • C++之函数声明和定义

    千次阅读 2017-11-08 22:47:47
    在程序中使用函数时,你必须先声明它...通常我们把函数声明叫做函数原型,而把函数定义叫做函数实现。 声明并未给函数分配内存,只有定义的时候才给函数分配内存 如图所示,标注1为函数的声明,标注2为函数的定义
  • extern 关键字放在函数声明之前:&gt; test.hextern int test();如果这样函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义。这样一来,就是在程序中取代include “*.h”来声明函数,在...
  • 当第一次拿到被人的程序的时候不知道如何向VS或者keil这样的编译器可以直接右键...2、Ctrl+鼠标左键单击,这样就可以跳转到头文件或者函数声明/函数定义的地方了 3、后退到原来的地方可以按下图左上角那样的箭头 ...
  • 虚函数的声明和定义具体关于虚函数的知识不做多讲,我在定义一个抽象类时,忘了将一个虚函数声明为 纯虚函数,又没有对其定义, 导致编译报错时报错如下:undefined reference to `vtable for Fibonacci'错误提示的...
  • 函数声明函数表达式区别

    千次阅读 2019-06-17 19:51:51
    javascript中声明函数的方法有两种:函数声明函数表达式. 一、区别如下: 1).以函数声明的方法定义的函数,函数名是必须的,而函数表达式的函数名是可选的。(函数声明会被提升到当前作用域的顶部,函数表达式则不会...
  • 关于模板函数声明定义的问题

    万次阅读 2016-01-08 21:20:37
    c++ primer上说:c++模板函数声明定义通常放在头文件中,而普通的函数通常是声明放在头文件中,定义放在源文件中,为什么会有这样的区别呢?模板函数与普通成员函数到底有什么区别? 测试代码: tem.h #...
  • inline函数和定义区别 整理

    千次阅读 2017-09-15 13:42:48
     内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函数可以直接呗镶嵌到目标代码中。内联函数要做参数类型检查,这是内联函数跟宏相比的优势。  inline是指嵌入代码,就是在...
  • K&R C的函数声明: function(); 这种方式声明的函数,在向其传递参数时,较小类型的参数会被进行隐式类型转换,如char、short被转换为int,float被转换为double。即堆栈中所存储的参数其所占字节数大于实际...
  • 函数指针指针函数用法和区别

    万次阅读 多人点赞 2018-05-24 08:11:10
    函数指针指针函数,在学习 C 语言的时候遇到这两个东西简直头疼,当然还有更头疼的,比如什么函数指针函数、指针函数指针、数组指针、指针数组、函数指针数组等等,描述越长其定义就越复杂,当然理解起来就越难,...
  • 声明和定义区别

    万次阅读 多人点赞 2019-01-10 13:21:07
    声明和定义区别: 在我上课的书中并没有说明两者的区别,书上写着“在本书中,声明和定义有着相同的含义”,当时学的时候也没注意到这点,后来看到一些面试题,才注意到这些坑。  一种是需要建立存储空间的。...
  • C语言的函数定义和函数声明

    万次阅读 多人点赞 2017-11-10 10:04:18
    C语言不同于Java语言,在Java语言中,在一个类中,定义函数/方法后,在调用时不需要声明。在C语言中定义函数后,在使用前,需要在main函数前进行声明,否则会报错。 #include //使用函数前,需要在main函数前对...
  • 内联函数和定义函数区别

    千次阅读 2019-05-17 19:53:55
    1、不同点: 内联函数是在编译时展开,而宏在预编译时展开;在编译的时候,内联函数直接被嵌入到目标代码中去,而宏只是一个简单的文本替换。 ... inline有点类似于宏定义,但是它定义不同...
  • 函数声明和定义一般都有参数,C语言中函数声明关注的是函数返回值类型、函数名称、函数参数类型,其中函数参数名称并不关注,因此参数名称可以在声明时省略,在定义时取任意名称。 注意:声明和定义是有区别的,具体...
  • C++ 函数声明和定义

    万次阅读 多人点赞 2019-03-23 01:07:00
    在程序中使用函数时,你必须先声明它然后再定义,声明的目的是告诉编译器你...通常我们把函数声明叫做函数原型,而把函数定义叫做函数实现。 函数的声明: 如:int Add(int, int); 1,在C++中,函数原型就是函...
  • 1.js中函数表达式的定义 表达式(expression)JavaScript中的一个短语,javascript会将其计算(evaluate)出一个结果。程序中的常量是一个最简单的表达式。变量名也是一种简单的表达式,它的值就是赋值给变量的值。...
  • 1,函数的定义 函数(function),又称为方法(method),或过程(procedure) ...2,函数声明 语法: function 函数名(){ //代码块(函数体) } 函数调用: 使用已声明好的函数 语法: 函数名(); ...
  • C 函数声明, 函数原型, 函数定义

    千次阅读 2016-11-04 12:22:49
    函数声明的发展1 隐式函数声明 implicit function declaration main 函数 printf 函数返回值类型为 int, 若不声明, 编译器默认函数返回值为 int 类型 C90标准起,这种写法就步入了被逐步抛弃的过程(尽管当时还没有...
  • 因此,我们将类定义和函数声明放置在头文件中,普通函数成员函数的定义放置在源文件中。 模板则不同,为了生成一个实例化版本,编译器需要掌握函数模板或者类模板成员函数的定义。 结论: 函数模板类模板成员函数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,104,490
精华内容 441,796
关键字:

函数声明和定义的区别