CPP_CH01_第一个C++程序
1.1第一个C++程序
#include <iostream>
int main()
{
std::cout<<"Hello World"<<std::endl;
std::cin.get();
}
1.2 解释
1.2.1 #include < iostream >
这一行被称为预处理,#之后的的都是预处理,编译器compiler一接收到源代码,就会先处理预处理的代码。发生在实际编译之前。
include是将一些file拷贝到当前的文件中,而这些file被称为头文件。比如这里的iostream。
而之所以要调用头文件是因为,之后所用的一些函数需要提前声明,为了方便简洁,将这些声明提前封装到头文件中。
1.2.2 main()
程序的入口。意思是开始执行代码的第一站就是main。
main函数不一定需要返回值。如果什么都没返回他会返回0。
1.2.3 std::cout<<“Hello world”<<std::endl
<< 类似一种函数,这段代码就像这样一样:
std::cout.print("Hello world").print(std::endl);
<<的另一层含义是将"Hello world"推送到cout流中,然后打印到终端。
然后推送一行结束符号:std::endl。endl告诉机器跳到下一行。
1.2.4std::cin.get()
类似C当中的getchar(),都是等待操作者按enter。否则会暂停程序。
1.3 C++如何工作
1.3.1 编译
我们已经得到了源代码文件main.cpp,如何把他转换成可执行的二进制文件:
编译器会首先处理预处理。这里会将iostream包含的所有声明拷贝粘贴过来。
之后如何编译取决于两个重要的设置:
Debug框:解决方案配置 有Debug和Release两个选项
x86(win32)框:解决方案平台,有x86(win32)和x64(win64)两个选项。
解决方法平台是指你的编译的代码目标运行的平台。
release版本相对于Debug有很多优化,速度会更快,但是debug可以调试代码,release不可以。
1.3.2 生成文件
每一个cpp文件被编译成了一个object文件,如果是vs编译而成的这些文件的后缀名是xxx.obj。我们需要将这些文件合并成一个可执行文件
此时链接(link)出现了。link把所有obj文件合并成一个可执行的exe文件。
如果只是单纯的要编译,直接ctrl+f7,可以调试。此时如果写的cpp没有问题,会在输出栏显示succeed。如果有错误,在error list栏会显示出错在第几行,在output栏目会显示为什么出错。
1.3.3一个项目包含多个文件
还是要输出Hello world,但是我们不想用std::cout<< <<std::endl这样的语法,我们就可以自己写一个函数。
void my_printf(const char* message)
{
std::cout<< message <<std::endl;
}
之后再在已经有的project里创建新的file,我们梳理一下:
project (my_first hello world)
================
main函数在file1;
my_printf()在file2;
================
此时我们对main函数做一下修改
#include<iostream>
int main()
{
message = "Hello world";
my_printf(message);
std::cin.get();
}
此时ctrl+f7编译,发现output栏报错。原因是file2中电脑不知道cout是什么,原因是在文件2中我们没引入头文件,所以要加入
#include<iostream>
void my_printf(const char* message)
{
std::cout<< message <<std::endl;
}
此时再对file1单独编译,发现还是不行,编译器不知道my_printf()是什么。因此我们单独对某个文件编译,只要没在该文件声明的函数,都是无法识别的。因此我们把printf的声明放在file1中:
#include<iostream>
void my_printf(const char* message);
int main()
{
message = "Hello world";
my_printf(message);
std::cin.get();
}
此时再编译,就没有问题了。当然你可以在声明的时候不加上message,这样也没错:
#include<iostream>
void my_printf(const char* );
int main()
{
message = "Hello world";
my_printf(message);
std::cin.get();
}
但是加上最好,这样能更清晰地知道我们在干嘛。
在file1中,为什么我们只是告诉了编译器有这个函数叫my_printf(),而没有说他的body是什么,编译器就通过了呢?因为编译相信我们。
而在运行的时候,为什么file1又知道my_printf()是怎样实现的呢?因为有link的存在。之前我们说过,link将一个项目的所有生成的obj文件链接起来。
此时file1,file2分别生成了一个file1.obj,file2.obj.然后一个项目有一个xxx.lnk文件,将这些obj链接在一起,生成可执行文件project.exe。
如果在file1中,编译器相信我们,但是我们辜负了他的相信,file2中我们并没有定义my_printf(),在build项目时就会出现链接错误。