函数:一段能被反复调用的代码,可以接收输入,进行处理并(或)产生输出
– 返回类型:表示了函数返回结果的类型,可以为 void
– 函数名:用于函数调用
– 形参列表:表示函数接收的参数类型,可以为空,可以为 void ,可以无形参。
// 参数列表为空
void fun(){}
// 参数列表无形参:保留程序接口,同时防止函数内部误操作使用到传入的形参
void fun(const char* str, int a)
{
std::cout << str;
}
// 上面的代码int a没有使用,但是加入它是为了保持函数的接口不变。更好的方式是下面无形参的方式,
// 也就是形参没有名字,那么内部肯定就无法调用了
void fun(const char* str, int)
{
std::cout << str;
}
– 函数体:具体的执行逻辑
main 函数:特殊的函数,作为整个程序的入口
– 返回类型为 int ,表示程序的返回值,通常使用 0 来表示正常返回。
echo $?
就可以打印main函数返回给终端的值– 形参列表有两种形式:
// 形参列表为空
int main()
// 形参列表是传入的参数。注意必须是int 和 char* [], 即char* 数组的形式
int main(int argc, char* argv[])
iostream :标准库所提供的 IO 接口,用于与用户交互
– 输入流: cin ;输出流: cout / cerr / clog
– 输出流的区别: 1. 输出目标; 2. 是否立即刷新缓冲区
– 缓冲区与缓冲区刷新: std::flush; std::endl
cout/cerr/clog
都可以输出到屏幕上来显示,但是也可以输出到文件中。系统输出有两种不同的接受,1和2,就用来存储普通的显示和error显示,此时这几种输出流就会输出到不同的文件中了。cout
是普通的打印信息,clog
是日志信息,都不是很重要,所以他们输出之后并不会立即刷新缓冲区进行输出。而cerr
是比较严重的错误信息,所以每次输出之后都会立即刷新缓冲区。cout
和clog
想立即显示,也那么就需要手动刷新一下缓冲区。其中刷新缓冲区的是std::flush
,而std::endl
除了可以刷新缓冲区之外,还可以把输出换行。所以不建议使用std::endl
进行换行,因为它每次都要刷新缓冲区,会让程序变慢,而使用\n
这种换行符是更好的方式,它能换行,但是不会刷新缓冲区。名字空间:用于防止名称冲突
– std 名字空间,即标准的IO命名空间
– 访问名字空间中元素的 3 种方式 : 域解析符 :: ; using 语句;名字空间别名
注意using namespace
的方式不推荐,因为本来就是为了防止变量和函数的重复命名而引入的命名空间,这里如果使用using namespace
的话,就失去使用命名空间的意义了。尤其是不能在头文件中这样做。
namespace NameSapce1
{
void fun()
{}
}
// 1.解析符
NameSpace1::fun();
// 2.using
using namespace NameSpace1;
fun();
// 3.命名空间别名
namespace ns1 = NameSpace1;
ns1::fun();
– 名字空间与名称改编( name mangling )
这个是存在于编译的时候,编译器会把函数和变量都加上奇怪的前缀和后缀,以唯一的区分不同命名空间中的变量和函数。
– printf: 使用直观,但容易出错
– cout: 不容易出错,但书写冗长,不直观
int num = 10;
printf("num = %d\n", num):
std::cout << "num = " << num << "\n";
注意:
printf
,最规范的做法要#include <cstdio>
,即C语言的标准IO头文件。但是如果只是#include <iostream>
,好像也能调用printf
,不知道为什么。printf
的使用风险,就是在%d
格式化输出的时候,如果num
是一个float
数,那么这样输出就是强制用%d
即int
数来解析内存中存储的float
数,输出就是不正确的。– C++ 20 格式化库:新的解决方案,但是目前的编译器对这个标准的支持都不太好,这就是现实编译器跟不上标准的变化。