目录
输入输出 & 命名空间使用
缺省参数
函数重载
缺省函数的二义性
关于为什么可以函数重载
结束语
hello world!
命名空间全部展开
#include
using namespace std; //在一般的学习使用中我们可以这样写
//意思是把名为 std 里面定义的东西全部展开(库函数之类的)
int main()
{
cout << "hello world!" << endl; //cout -- console cout(控制台输出)
//endl -- end line(结束行、换行的意思)
// << 流插入
return 0;
}
注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
相比C语言在C++中输出可以被自动识别类型
可以看出在一些场合中C++的输出方式更加方便,但在一些情况下(比如控制打印浮点数后面几位小数,C++就比较麻烦),C++并没有C中的方便因此,遇到这种情形时可以结合这C的写法都是可以的。 哪个方便就用那个嘛。
C++总结说明:1. 使用 cout 标准输出对象 ( 控制台 ) 和 cin 标准输入对象 ( 键盘 ) 时,必须 包含 < iostream > 头文件以及按命名空间使用方法使用std 。2.cout 和 cin 是全局的流对象, endl 是特殊的 C++ 符号,表示换行输出,他们都包含在包含 <iostream > 头文件中。3. <<是流插入运算符 , >>是流提取运算符 。4. 使用 C++ 输入输出更方便,不需要像 printf/scanf 输入输出时那样,需要手动控制格式。 C++的输入输出可以自动识别变量类型。5. 实际上 cout 和 cin 分别是 ostream 和 istream 类型的对象, >> 和 << 也涉及运算符重载等知识,所以我们这里只是简单学习他们的使用。注意:早期标准库将所有功能在全局域中实现,声明在.h 后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std 命名空间下,为了和 C 头文件区分,也为了正确使用命名空间,规定C++ 头文件不带 .h ;旧编译器 (vc 6.0) 中还支持格式,后续编译器已不支持,因此推荐 使用 +std 的方式。
命名空间直接展开使用
下面一种方式同样也可以,并且相对上面的方式下面这种方式更安全,但是明显这样写会比较麻烦
命名空间部分展开
推荐这种写法(不用全部展开 -- 但在一些日常学习与练习中,为方便可以直接全部展开)
#include
using std::cout;
using std::endl;
int main()
{
cout << "hello world!" << endl;
return 0;
}
分步解析
1.std -- 标准库(在C++中,把我们使用的库函数都封装在了一个命名空间之中 -- 就是std里面)
std命名空间的使用惯例:
1. 在日常练习中,建议直接 using namespace std 即可,这样就很方便。2. using namespace std 展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型 / 对象 / 函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像 std::cout 这样使用时指定命名空间 +using std::cout 展开常用的库对象 / 类型等方式。
打个比方就是:命名空间就是一堵高墙把里面的东西都围起来了,外面的调用查找都看不到它,而using namespace std 就是把高墙拆掉了,但显然就失去了原先命名空间的作用
2. :: -- 域使用,与命名空间相呼应
//命名空间
#include
int a = 0;
int main()
{
int a = 1;
printf("%d\n", a); //这里用到就是局部变量a
printf("%d\n", ::a); //这里用到的就是全局变量 -- :: 前为空白(什么都没有)
return 0; //空白默认为全局域
}
命名空间
3.1命名空间 -- 当程序代码不断的增多,难免会定义一个相同的变量(重定义),为避免这种情况的发生,C++中有了命名空间这一手段.
在C/C++ 中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化 ,以避免命名冲突或名字污染 , namespace 关键字的出现就是针对这种问题的。
解析:这里函数名就是函数的地址,并且并没有使用定义的命名空间,所以打印出来的是地址(X64环境下)。还有一点要注意的是,在程序编译的过程中,会把头文件展开(所以rand可以向上被找到),但是在我没有指定使用命名空间的时候它并不会去里面找那个变量。
ps:这些变量存放在静态区,是全局变量哦 原因:这里的变量不影响变量的生命周期
3.2 -- 函数也可以放在命名空间中
我们到现在就可以发现,其实基本上都可以放在命名空间里面,这样就可以很好的弥补C语言里面因为命名相同而产生的各种bug,方便了大型程序的开发。
ps:还有一个需要注意的时,同名的同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。 (.h文件在编译器编译的时候就会展开,相当于在同一个文件下)
缺省参数概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实 参则采用该形参的缺省值,否则使用指定的实参。
缺省函数总结
1. 半缺省参数必须 从右往左依次 来给出,不能间隔着给2. 缺省参数不能在函数声明和定义中同时出现3. 缺省值必须是常量或者全局变量4. C 语言不支持(编译器不支持)
注意:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值
解释:当一个函数声明在声明文件(通常在大型的程序中,声明与实现会分离)中,
函数重载:是函数的一种特殊情况, C++ 允许在 同一作用域中 声明几个功能类似 的同名函数 ,这些同名函数的形参列表 ( 参数个数 或 类型 或 类型顺序 ) 不同 ,常用来处理实现功能类似数据类型不同的问题。
第一种情况 -- 无法区分
//缺省函数的二义性
#include
using std::cout;
using std::endl;
void f()
{
cout << "f()" << endl;
}
void f(int a = 0, char b = 1)
{
cout << "f(int a, char b)" << endl;
}
int main()
{
f(1);
f(1, 2);
//f(); 在前面存在的前提下,直接调用f()会报错 -- 二义性
return 0;
}
第二种情况 -- 参数顺序不同
第三种情况 -- 返回值不同
结论:在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变。
采用C++编译器编译后结果
由此可知在C语言中这个是不被支持的,因为C语言中是直接使用地址找到函数的,并没有后面的一串转化。
C++中:函数名修饰规则 -- 参数不同,修饰出来的名字就不同了
岂曰无碑,以身立之面不倒,
岂曰无碑,以躯立之面不逝,
岂曰无碑,以墓立之终不归,
岂曰无碑,以名立之永不朽。
夫边上者,可倒,可逝,可不归,不可退。