C编译器支持分离编译,属于one-pass 编译器(通过一遍扫描即可完成编译的编译器)。
The C compiler makes one pass over the source code.
C编译器对源代码进行一次遍历。
It starts at the top of the file, and proceeds line-by-line to the bottom, collecting declarations and outputting machine language as it goes.
它从文件的顶部开始,逐行进行到底部,收集声明并输出机器语言。
A variable (or other entity) must be declared before it is used (This is unlike Java).
变量(或其他实体)必须在使用前声明(这与Java不同)。
(Actually, modern C compilers make more than one pass, but act as if they are one-pass, top to bottom)
(事实上,现代C编译器会执行多个过程,但它们的行为就像是从上到下的一个过程)
To allow programs to be broken up into logical parts, C++ supports what is commonly known as separate compilation. Separate compilation lets us compose a program from several files.
为了允许把程序分成独立的逻辑块,C++ 支持所谓的分别编译。这样程序可以由多个文件组成。
In order for multiple files to access the same variable, C++ distinguishes between declarations and definitions.
为了让多个文件访问相同的变量,C++ 区分了声明和定义。
void main(void)
{
printf("x: %d\n", x );// won’t work, x is not defined, yet
int x = 95;
}
// if two-pass, can find the defination of x
This affects function calls, as well.
这也会影响函数调用。
A function must be defined earlier in the source file than a statement that calls it.
必须在源文件中早于调用函数的语句定义函数。
#include <stdio.h> // .h files contain declarations needed for library functions
void main(void)
{
int x = addOne( 95 ); // won’t work addOne() is not defined, yet
printf("x: %d\n", x );
}
int addOne(int x)
{
x = x+1;
return x;
}
// solution: move addOne above main in the source code
Problem: foo() calls goo(), and goo() calls foo()。
问题:foo() 调用goo(),而goo() 调用foo()。
int foo(int z)
{
...
goo( z );
...
}
int goo(int x)
{
...
foo( x );
...
}
void main(void)
{
goo( 45 );
}
This often happens when functions depend on each other.
当函数相互依赖时,通常会发生这种情况。
Each one must be declared before the other.
每一个都必须在另一个之前声明。
But only one can actually occur first !
但实际上只有一个可能首先发生!
Solution: use function prototypes
解决方案:使用函数原型。
int foo(int x); // prototypes
int goo(int x); // prototypes
int foo(int z)
{
...
goo( z ); // compiler has all it needs to know to call goo()
...
}
int goo(int x)
{
...
foo( x );
...
}
void main(void)
{
goo( 45 );
}
A prototype tells the compiler what a function looks like in terms of name, parameters, and return type.
原型告诉编译器函数在名称、参数和返回类型方面的内容。
This is all the compiler need to know when compiling a function call.
这就是编译器在编译函数调用时需要知道的全部内容。
The machine code for the function body can go elsewhere.
函数的机器代码可以转到其他位置。
Parameter names in prototype are just place holders; the name you use does not matter.
原型中的参数名称只是占位符;您使用的名称无关紧要。
one-pass compiler' s scope
#include <stdio.h>
int a = 33;
int foo(int x)
{
int b = 2;
return b+x;
}
void main(void)
{
int b = 8;
foo( a+b );
}
Identifiers can be “seen” by the compiler only inside their own block.
编译器只能在自己的块中“看到”标识符。
If another block uses the same identifier for a variable or parameter, that is a different one.
如果另一个块对变量或参数使用相同的标识符,则这是不同的标识符。
An identifier outside of any block can be seen throughout the file.
可以在整个文件中看到任何块外(函数外)的标识符(函数内也可以包含局部块,只是块内所见)。
Unless another identifier blocks the view.
除非另一个标识符阻止查看。
#include <stdio.h>
int a = 3; // a is visible from here to the end of the file
int foo(int x) // x is visible only inside this function
{
int b = -1; // b is visible only inside this block
{
int b = 111; // is visible only inside this block
}
return b+x;
}
void main(void)
{
int x, b = 8; // this is a different b. It is visible only inside this block
x= foo( a+b ); // this uses the a at the top, and the b for this block
printf("%d",x);
}
C++ 语言支持的“分别编译”(separate compilation),也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的 .cpp 文件里。.cpp 文件里的东西都是相对独立的,在编译(compile)时不需要与其他文件互通,只需要在编译成目标文件后再与其他的目标文件做一次链接(link)就行了。比如,在文件 a.cpp 中定义了一个全局函数 "void a(){}",而在文件 b.cpp 中需要调用这个函数。即使这样,文件 a.cpp 和文件 b.cpp 并不需要相互知道对方的存在(b.cpp只需声明一下voida();),而是可以分别地对它们进行编译,编译成目标文件之后再链接,整个程序就可以运行了。
编译器的特性也确定了C程序的基本构成:

ref
-End-

如若转载,请注明出处:https://www.summeng.com/17292.html