为啥C程序多文件编译,没有导入自己的头文件也能正常编译通过?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥C程序多文件编译,没有导入自己的头文件也能正常编译通过?相关的知识,希望对你有一定的参考价值。

我在C-Free和VS2010 下面都建立了一个工程,工程包含两个源文件main.c和Max.c 一个头文件Max.h ,main.c中调用了Max.c中的函数。
问题:为什么main.c中不导入Max.h也能编译通过,而且程序运行正常。
main.c源文件
#include <stdio.h>
//#include "Max.h"
int main(int argc, char *argv[])

int a,b;
scanf("%d %d",&a,&b);
printf("%d\n",Max(a,b));
return 0;

Max.c源文件
int Max(int a,int b)

return (a>b?a:b);


头文件Max.h
#ifndef _MAX_
#define _MAX_
int Max(int a,int b);
#endif

在C中,函数在使用前没有必要先声明,会在调用时自动声明,即使不include stdio.h,程序也可以正常编译运行。但如果你把Max.c删除的话会出现连接错误。 参考技术A 不用头文件,因为这个main.c已经包括了 参考技术B 请贴源码。

尽管注释掉了所需的头文件,为啥这个 C++ 程序仍能编译和运行? [复制]

【中文标题】尽管注释掉了所需的头文件,为啥这个 C++ 程序仍能编译和运行? [复制]【英文标题】:Why does this C++ program compile and run despite required header files being commented out? [duplicate]尽管注释掉了所需的头文件,为什么这个 C++ 程序仍能编译和运行? [复制] 【发布时间】:2018-07-19 17:43:27 【问题描述】:

我正在浏览一组 C++ 教程,并且正在使用其中一个示例的标题包含。为什么即使 algorithmvector 被注释掉,以下代码仍然会运行?

//#include <algorithm>
#include <iostream>
#include <random>
//#include <vector>

using namespace std;

int main() 
  vector<int>::const_iterator iter;

  cout << "Creating a list of scores.";
  vector<int> scores;
  scores.emplace_back(1500);
  scores.emplace_back(3500);
  scores.emplace_back(7500);

  cout << "\nHigh Scores:\n";

  for (iter = scores.begin(); iter!=scores.end(); iter++) 
    cout << *iter << endl;
  

  cout << "\nFinding a score.";
  int score;
  cout << "\nEnter a score to find: ";
  cin >> score;
  iter = find(scores.begin(), scores.end(), score);
  if (iter!=scores.end()) 
    cout << "Score found.\n";
   else 
    cout << "Score not found.\n";
  

  cout << "\nRandomising scores.";
  random_device rd;
  default_random_engine generator(rd());
  shuffle(scores.begin(), scores.end(), generator);
  cout << "\nHigh Scores:\n";
  for (iter = scores.begin(); iter!=scores.end(); iter++) 
    cout << *iter << endl;
  

  cout << "\nSorting scores.";
  sort(scores.begin(), scores.end());
  cout << "\nHigh Scores:\n";
  for (iter = scores.begin(); iter!=scores.end(); iter++) 
    cout << *iter << endl;
  

  return 0;

【问题讨论】:

唯一可行的方法是,如果注释掉的标头是从项目的其他地方隐式包含的。如果找不到std::vectorstd::find() 的定义,编译器会失败,所以&lt;vector&gt;&lt;algorithm&gt; 仍然是必需的,不管你自己是否包含它们。 标准标头可以包含任何其他标准标头,但您不能指望它。另一种看待它的方式是你需要包含必要的头文件,但如果你不这样做,编译器不需要失败。 这对我的理解很有帮助。来自强制声明所需依赖项的语言,我惊讶地发现我仍然可以编译上述内容。 【参考方案1】:

在 C++(与 C 不同)中,包含任何一个标准头文件都可以等同于包含任何或所有其他标准头文件。所以,如果你包含&lt;iostream&gt;,那可以相当于还包含&lt;algorithm&gt;&lt;vector&gt;&lt;string&gt;等。

早期,许多编译器/库都充分利用了这一点。最近,它们倾向于更接近标头声明/定义它的要求,但仍有一些标头至少间接包含其他一些标头。

【讨论】:

以上是关于为啥C程序多文件编译,没有导入自己的头文件也能正常编译通过?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在写C语言的头文件,编译时会出现重新定义变量的情况?

为啥不包含头文件却可以调用函数,谁来解释

arm-linux-gcc怎么编译自己写的头文件

如何解决gcc编译c程序找不到头文件的问题

linux下gcc编译的时候提示说头文件找不到?

c/c++源文件为何要包含自己的头文件?(编译器检查定义和声明的一致性)