精华内容
下载资源
问答
  • (1.cpp) #include <stdio.h> #include "2.h" void main() { my();... printf("我是外边的的函数,我被调用了\n"); } 2.h头文件 void my(); 上面的非常好,没问题。 如果是s...

    C如何引用别的文件中的static函数

    1.cpp)
    #include <stdio.h>
    #include "2.h"
    void main()
    {
    	my();
    }
    
    2.cpp)
    #include "2.h"
    #include <stdio.h>
    void  my()
    {
    	printf("我是外边的的函数,我被调用了\n");
    }
    
    2.h头文件
    void my();
    

    上面的非常好,没问题。

    如果是static函数呢?

    1.cpp)
    #include <stdio.h>
    #include "2.h"
    void main()
    {
    	my_static();
    }
    
    2.cpp)
    #include "2.h"
    #include <stdio.h>
    static  void my_static()
    {
    	printf("我是外边的的函数,我被调用了\n");
    }
    
    2.h头文件
    static void my_static();
    

    在这里插入图片描述
    出错了。
    怎么办呢????

    1.cpp)
    #include <stdio.h>
    #include "2.h"
     
    
    void main()
    {
    	haha();
    }
    
    2.cpp)
    #include "2.h"
    #include <stdio.h>
    static  void my_static()
    {
    	printf("我是外边的static的函数,我被调用了\n");
    }
    
    void haha()
    {
    	my_static();
    };
    
    2.h头文件
    static void my_static();
    
    void haha();
    

    很勉强??????

    缺点是我必须在haha中使用my_static,有时候你可能不想立即使用my_static


    ============================================================================================================================================================================================================================================================================================================================================================================
    nodeNestloop.c文件中定义了

    static TupleTableSlot *
    ExecNestLoop(PlanState *pstate)
    

    但是在

    NestLoopState *
    ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
    

    中选用了

    NestLoopState *nlstate;
    
    	/* check for unsupported flags */
    	Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
    
    	NL1_printf("ExecInitNestLoop: %s\n",
    			   "initializing node");
    
    	/*
    	 * create state structure
    	 */
    	nlstate = makeNode(NestLoopState);
    	nlstate->js.ps.plan = (Plan *) node;
    	nlstate->js.ps.state = estate;
    	nlstate->js.ps.ExecProcNode = ExecNestLoop;
    

    这样就似乎可以在外部调用了这个文件。
    /
    /
    /
    /
    /

    试验一下

    1.cpp)
    #include <stdio.h>
    #include "2.h"
     
    
    void main()
    {
    	struct stru stru1;
    	use_my_static(&stru1);
    	stru1.f();
    }
    
    2.cpp)
    #include "2.h"
    #include <stdio.h>
    static  void my_static()
    {
    	printf("我是外边的static的函数,我被调用了\n");
    }
    
    void use_my_static(struct stru *h)
    {
    	h->f=my_static;
    };//作用要知道哦
    
    2.h头文件
    static void my_static();
    struct stru{
    	void (*f)();
    };
    void use_my_static(struct stru *h);
    

    这样就可以在主函数中随便啥时候调用my_static了

    结论:你还得在static所在的文件里面搞点小动作才可以实现在别的文件里调用它。哎,苦哦!

    展开全文
  • 如果你有多个文件,重要是声明和函数定义之间区别。定义可能是您在定义函数时习惯定义:您编写函数的内容,如int square(int i) {return i*i;}另一方面,声明允许您向编译器声明您知道函数存在,但是您不告诉...

    这里有几件不同的事情。首先,我将介绍多个文件的基本编译是如何工作的。

    如果你有多个文件,重要的是声明和函数定义之间的区别。定义可能是您在定义函数时习惯的定义:您编写函数的内容,如

    int square(int i) {

    return i*i;

    }

    另一方面,声明允许您向编译器声明您知道函数存在,但是您不告诉编译器它是什么。例如,你可以写

    int square(int i);

    编译器会期望函数“square”在别处定义。

    现在,如果你有两个不同的文件想要互操作(例如,假设函数“square”在add.c中定义,并且你想在main.c中调用square(10)),你需要同时做一个定义和一个声明。首先,在add.c中定义square。然后,在main.c的开头声明它。这让编译器知道它在编译main.c时有一个函数“square”,它在别处定义。现在,您需要将main.c和add.c编译为目标文件。你可以通过电话来做到这一点

    gcc -c main.c

    gcc -c add.c

    这将生成文件main.o和add.o.它们包含已编译的函数,但不完全可执行。这里要理解的重要一点是,main.o在某种意义上是“不完整的”。在编译main.o时,你告诉它函数“square”存在,但函数“square”没有在main.o中定义。因此main.o对函数“square”有一种“悬空引用”。除非将它与另一个包含“square”定义的.o(或.so或.a)文件合并,否则它不会编译成完整的程序。如果您只是尝试将main.o链接到程序中,即

    gcc -o executable main.o

    您将收到错误,因为编译器将尝试解析对“square”函数的悬空引用,但不会找到它的任何定义。但是,如果在链接时包含add.o(链接是将.o文件转换为可执行文件或.so文件时解析所有这些对未定义函数的引用的过程),那么就不会有任何问题。即

    gcc -o executable main.o add.o

    这就是如何在C文件中功能性地使用函数,但在风格上,我刚刚向您展示的是“不正确的方式”。我做的唯一原因是因为我认为它会更好地帮助你了解正在发生的事情,而不是依赖于“#include magic”。现在,您可能已经注意到,如果您必须重新声明要在main.c顶部使用的每个函数,事情会变得有点混乱。这就是为什么C程序经常使用名为“headers”的辅助文件,其扩展名为.h 。标题的概念是它只包含函数的声明,而没有它们的定义。这样,为了使用add.c中定义的函数编译程序,您不需要手动声明您正在使用的每个函数,也不需要#include代码中的整个add.c文件。相反,你可以#include add.h,它只包含add.c的所有函数的声明。

    现在,重新开始#include:#include只是将一个文件的内容直接复制到另一个文件中。所以,例如,代码

    abc

    #include "wtf.txt"

    def

    完全等同于

    abc

    hello world

    def

    假设wtf.txt包含文本“hello world”。

    那么,如果我们将add.c的所有声明都放在add.h中(即

    int square(int i);

    然后在main.c的顶部,我们写

    #include "add.h"

    这在功能上与我们刚刚在main.c顶部手动声明函数“square”一样。

    所以使用标题的一般想法是你可以有一个特殊的文件,通过#including它自动声明你需要的所有函数。

    但是,标题还有一个更常见的用途。我们假设main.c使用50个不同文件的函数。 main.c的顶部看起来像:

    #include "add.h"

    #include "divide.h"

    #include "multiply.h"

    #include "eat-pie.h"

    ...

    相反,人们经常将所有#includes移动到main.h头文件中,只需从main.c中#include main.h.在这种情况下,头文件有两个目的。它声明了main.c中的函数,供其他文件包含时使用,并且包含main.c中包含的main.c的所有依赖项。以这种方式使用它也允许依赖链。如果#include add.h,不仅可以获得add.c中定义的函数,还可以隐式获取add.c使用的任何函数,以及它们使用的任何函数,等等。

    另外,更巧妙的是,#包含来自它自己的.c文件的头文件会隐式检查你所犯的错误。例如,如果您不小心将square定义为

    double square(int i);

    在add.h中,你通常可能没有意识到,直到你链接main.o正在寻找square的一个定义,add.o正在提供另一个不兼容的。这会导致链接时出错,因此在构建过程的后期才会意识到错误。但是,如果你从add.c #include add.h到编译器,你的文件看起来像

    #include "add.h"

    int square(int i) {

    return i*i;

    }

    处理完#include语句之后会是这样的

    double square(int i);

    int square(int i) {

    return i*i;

    }

    编译add.c时编译器会注意到哪些,并告诉你。实际上,以这种方式包括您自己的标题可以防止您错误地向其他文件宣传您提供的功能类型。

    为什么你可以在没有声明的情况下使用函数

    正如您所注意到的,在某些情况下,您实际上可以使用函数而不是每次声明它或#including任何声明它的文件。这是愚蠢的,每个人都同意这是愚蠢的。但是,它是C编程语言(和C编译器)的遗留特性,如果你在没有首先声明它的情况下使用函数,它只是假设它是一个返回类型为“int”的函数。所以实际上,使用函数隐式地将该函数声明为一个函数,如果它尚未声明,则返回“int”。如果你考虑它,这是非常奇怪的行为,编译器应警告你,如果你做这种行为。

    头卫

    另一种常见做法是使用“Header Guards”。为了解释标题保护,让我们看看可能存在的问题。假设我们有两个文件:herp.c和derp.c,它们都希望使用彼此包含的函数。遵循上述准则,您可能会有一行herp.h

    #include "derp.h"

    和一行derp.h

    #include "herp.h"

    现在,如果你考虑一下,#include“derp.h”将被转换为derp.h的内容,而derp.h又包含#include“herp.h”行,它将被转换为herp的内容。 h,包含……等等,所以编译器将继续只是扩展包含。类似地,如果main.h#包括herp.h和derp.h,并且herp.h和derp.h都包含add.h,我们看到在main.h中,我们最终得到了两个add.h副本,一个是#including herp.h的结果,另一个是包含derp.h的结果。那么,解决方案呢?一个“Header guard”,即一段防止任何标题被#included两次的代码。例如,对于add.h,执行此操作的常规方法是:

    #ifndef ADD_H

    #define ADD_H

    int sqrt(int i);

    ...

    #endif

    这段代码基本上是告诉预处理器(处理所有“#XXX”语句的编译器部分)来检查是否已经定义了“ADD_H”。如果它不是(ifndef)那么它首先定义“ADD_H”(在这个上下文中,ADD_H不必定义为任何东西,它只是一个定义或不定义的布尔值),然后定义其余的标题的内容。但是,如果已经定义了ADD_H,则#including此文件将不执行任何操作,因为#ifndef块之外没有任何内容。因此,我们的想法是,只有第一次将它包含在任何给定文件中时,它才会实际向该文件添加任何文本。之后,#include它不会在文件中添加任何其他文本。 ADD_H只是您选择的任意符号,用于跟踪add.h是否已包含在内。对于每个标题,您使用不同的符号来跟踪它是否已被包含。例如,herp.h可能会使用HERP_H而不是ADD_H。使用“标题保护”将解决我上面列出的任何问题,其中包含文件的重复副本,或#includes的无限循环。

    展开全文
  • C语言中一旦程序的功能复杂时,我们便会想到使用多个文件来写函数,即是在主函数(含有main()函数的.c文件)中调用别的文件的函数。而这里的函数调用方式可以用2种方式来完成。 方式1:使用#include“XXX.X”...

    在C语言中一旦程序的功能复杂时,我们便会想到使用多个文件来写函数,即是在主函数(含有main()函数的.c文件)中调用别的文件的函数。而这里的函数调用方式可以用2种方式来完成。
    方式1:使用#include“XXX.X”直接将别的文件的内容直接包含到主函数中。
    方式2:使用extern 声明外部文件已经定义的函数。

    这里就先把这两种方式的简单栗子举一个。
    (下面的所有代码编辑和编译运行都是使用VS2010完成的。)

    方式1 栗子:

    //fun.h   *注意:这里的文件名是.h文件
    #include <stdio.h>
    void fun2()
    {
        printf("This is fun2.\n");
    }
    //main.c
    #include <stdio.h>
    #include <stdlib.h>
    
     //直接将fun.h的文件包含(即内容复制)到main.c文件中
    #include "fun.h"  
    
    int main()
    {
       printf("This is main.\n");
       fun2();
       system("pause");
    }

    运行结果:
    This is fun2.
    This is main.
    请按任意键继续…

    方式2 栗子:

    //fun.c   *注意:这里的文件名是.c文件
    #include <stdio.h>
    void fun2()
    {
        printf("This is fun2.\n");
    }
    //main.c
    #include <stdio.h>
    #include <stdlib.h>
    //外部函数的声明语句,extern 只是标记这个函数别的文件定义的
    extern  void fun2(); 
    
    int main()
    {
       printf("This is main.\n");
       fun2();
       system("pause");
    }

    运行结果:
    This is fun2.
    This is main.
    请按任意键继续…

    说明:

    • 首先,用方式1:include包含的方式 和方式2:extern声明外部函数的方式运行的结果是一样的。
    • 其次,注意到两种方式分别命名fun.h文件和fun.c文件。而不能在方式1中命名fun.c然后include到main.c中,在方式2中命名fun.h然后extern void fun()。这是因为在VS2010中,在一个工程文件中,自动将.c文件都编译成.obj文件(这个可以到工程文件夹的debug文件里看到),而.h文件不会被编译。
      所以,对文件命名的问题可以解释如下:方式1中,include直接把fun.h的文件内容完整复制到main.c,所以可以正常运行,如果是fun.c则会造成重定义(fun.obj和main.obj都有对fun2()函数的定义);方式2中,fun.c可以使fun2()得到编译,在main.c中extern 就能顺利编译通过,而命名fun.h则不然。

    说完这两个栗子,下面我来详细总结我对多文件编译问题的理解。主要介绍:

    1. extern的用法
    2. # include 包含文件的问题
    3. 声明和定义,什么时候会出现重定义?
    展开全文
  • 知识覆盖  基本程序设计技术,递归程序设计,程序结构,文件,结构体,类型定义 实验内容 1.分别调试课件中的给定n求Fibonacci(n)递归与非...3. (自选题)编写程序,统计英文文件中的每个单词的出现次数(词频)。
  • 这条规则很难受,就不能像C语言那样,把多个函数写在一个m文件里,供别的m文件调用吗 目前找到了2种方法,第一种使用函数句柄,也就是函数指针,第二种使用类的静态函数: 方法1: 方法2: classdef FcCommon...

    一般都是每个函数独占一个m文件,而且函数名与文件名必须相同。这条规则很难受,就不能像C语言那样,把多个函数写在一个m文件里,供别的m文件调用吗?当然可以,只是方法非常另类。

    目前找到了2种方法,第一种使用函数句柄,也就是函数指针,第二种使用类的静态函数:

    方法1:

    方法2:

    classdef FcCommon < handle
        
        
        properties
            静态成员变量 %列向量
        end
        
        methods %普通函数块--开始        
           
           
        end %普通函数块--结束
        
        
        
        methods(Static) %静态函数块---开始
            %把静态成员函数都写在这个区域
            function a = readPara(b,c,d,e)
                ......
            end
        end %静态函数块---结束       
            
            
        
    end %类定义结束

    主程序调用如下:

    fc = FcCommon();%调用构造函数生成对象

    val = fc.readPara(a,s,d,f);%调用对象的静态成员

     

    展开全文
  • C语言中static函数,只能被本文件中的函数所使用,别的c文件中不能访问这个函数, 而且你可以在别的文件中定义与之同名的函数,不会互相干扰。
  • 1、在函数体修饰变量时,一个被声明为static静态变量在这一函数调用过程维持其值不变。在下一次调用时,这个值还是维持上次调用结束时值。 2、在模块内(但在函数体外)修饰变量时,一个被声明为static...
  • 一起学习C语言函数(三)

    千次阅读 2020-09-06 22:28:01
      上一篇<... 在C语言中,全局变量可以如全局函数那般在别的文件内使用,局部变量也可以具有全局变量相同的生命周期。   在前面的内容,我们了解到内存分为动态内存和静态内存。其中动态
  • fopen是C语言库函数,open是系统调用,mmap是将大文件映射到内存使用。fopen与open函数区别网上有很多介绍,但是大多数都是没有注意平台上差异(特别是百度百科)。在Linux文件编程,fopen函数的使用就有不少...
  • C语言

    2015-08-19 16:48:33
    如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。 定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示: static ...
  • C语言文件输入与输出

    2018-04-21 11:48:59
    因此,用来进行磁盘文件的函数也同样可以用来进行打印机的写入。在TurboC2.0有两种性质的流:文字流(textstream)和二进制(binarystream)。对磁盘来说就是文本文件和二进制文件。本软件为了便于让读者易理解TurboC...
  • C语言文件项目

    千次阅读 2018-06-22 23:36:16
    将所有文件放到一个项目下,可以一次编译所有cpp文件,通过main文件引用文件中函数的方法:将所有函数声明在一个.h文件中,在需要调用这个函数的文件中#include".h"即可(文件前面加上#pragma once,...
  • c语言split实现代码

    2018-07-06 09:29:00
    我们知道在其他语言有...但是有时候在项目工作,又会用到这样的函数,特别是解析配置文件的时候。所以这里就写了一个split c语言的实现方法。  函数原型:void split(char *src,const char *separator,cha...
  • “输出”是C语言文件数据编程概念,在C语言文件数据输入输出中,当调用输出函数把程序中变量值输出到外部文件中时,这种操作称为“输出”或“写”。 程序员们为了便于记忆和理解,通常将“输出”和“写”共读为...
  • 你必须知道495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    1.28 文件中的第一个声明就报出奇怪的语法错误,可我看没什么问题。这是为什么? 1.29 为什么我的编译器不允许我定义大数组,如doublearray[256][256]? 命名空间 1.30如何判断哪些标识符可以使用,哪些被保留了...
  • C语言中extern可以置于变量或函数前,以表示变量或函数定义在别的文件中,提示编译器遇到此类变量或函数时在其他模块中寻找其定义 C语言中定义只能一次,调用或声明可以有多次 typedef 定义一种类型的别名,而不只是...
  • 在阅读linux2.6 版本内核的虚拟文件系统和驱动子系统的时候,我发现内核纯用c语言编写其实也是有一点不方便,特别是内核中大量存在了对象的概念,比如说文件对象,描述起来使用对象描述,但是对象在c语言中的构建远...
  • 关键字extern作用_C语言

    千次阅读 2019-03-02 09:56:10
    前段时间,有个同事跑过来问我,我在一个.c文件有个变量。在另一个文件 如何调用 ...以表示变量或者函数的定义在别的文件中。提示编译器遇到此变量或函数时。在其它模块中寻找其定义。另外。ext...
  • 如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。 定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示:
  • 《你必须知道495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    1.28 文件中的第一个声明就报出奇怪的语法错误,可我看没什么问题。这是为什么? 15 1.29 为什么我的编译器不允许我定义大数组,如double array[256][256]? 15 命名空间 15 1.30 如何判断哪些标识符可以使用,...
  • 1.28 文件中的第一个声明就报出奇怪的语法错误,可我看没什么问题。这是为什么? 15 1.29 为什么我的编译器不允许我定义大数组,如double array[256][256]? 15 命名空间 15 1.30 如何判断哪些标识符可以使用,...
  • C++和C语言混编

    2015-09-05 17:20:57
    大家知道C语言和C++是可以相互调用的...那么必须要加上extern “C” 来注明使用c编译方式编译,否则会在C++中调用的地方会找不到匹配的函数,这里特别注意,其实还有一个方法是将函数或者声明直接卸载.C文件中,引用的
  • 你必须知道495个C语言问题(PDF)

    热门讨论 2009-09-15 10:25:47
    3.12 我需要根据条件把一个复杂的表达式赋值给两个变量中的一 个。可以用下边这样的代码吗? ((condition) ? a : b) = complicated expression; . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 目录iii ...
  • C语言中的函数相当于其它高级语言的子程序。 C语言不仅提供了极为丰富的库函数(如Turbo C,MS C 都提供了三百多个库函数),还允许用户建立自己定义的函数。用户可把自己的算法编成一个个相对独立的函数模块,然后...
  • C语言本身是不提供输入、输出语句的,在一个程序中的输入/输出都是依赖于C语言的函数库,这也降低了对硬件的依赖程度,让C语言的输入、输出更加灵活方便。 简单来说: 输入:将数据从文件中读取到程序内部 输出:将...

空空如也

空空如也

1 2 3 4 5 6
收藏数 119
精华内容 47
关键字:

c语言调用别的文件中的函数

c语言 订阅