目录
一、C++的发展历史

二、C++的第一个程序
在C语言入门时,我们常常编写的第一个程序是以下代码:
#include<stdio.h>
int main() {
printf("hello,world!");
return 0;
}
在C++程序中,使用当初C语言的程序我们依旧能够执行。这样反映了C++兼容C语言绝大多数语法,所以C语言实现的hello world 能够执行。
当然在C++中,我们实现如上目的不会再像之前那样,有新的标准。
#include<iostream>
using namespace std;
int main() {
cout << "hello world" << endl;
return 0;
}
三、命名空间 namespace
1.namespace的价值
命名空间主要是解决C/C++中常出现的命名冲突,因为一些函数、变量、还有之后学习的类常存在于全局域,极易产生命名冲突。常常开玩笑说,如果命名空间没有出现,在工作的时候带个锤子,到时候用谁的代码就用锤子决定啊哈哈哈。
C语言类似下面程序的命名冲突经常出现,C++引入namespace就是为了解决类似的问腿。
#include<stdio.h>
#include<stdlib.h>
int rand = 10;
int main() {
printf("%d", rand);
return 0;
}
这里会报错的原因就是在stdlib的头文件包含命名为rand的函数,而在全局中存在相同名字的int型变量rand 出现了命名冲突所以程序会报错。
2.namespace的定义
- 命名空间的定义需要用到namespace关键字,接着是命名空间的名字,接着用{}即可,在{}中可以定义有函数/变量/类型等。
#include<stdio.h>
namespace Alone {
int Add(int x, int y) {
return x + y;
}
int rand = 10;
struct Node {
int n;
};
}
- 命名空间本质上是定义了一个域,它与全局域是相互独立的,不同的域可以定义同名的函数变量等,用命名空间的话上面存在的命名冲突rand就可以解决。
- C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找一个变量/函数类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量生命周期。
- namespace只能定义在全局,当然他还可以嵌套定义。
- 项目工程中多文件中定义的同名namespace会认为是同一个namespace,不会冲突
- C++标准库都放在一个叫std(standard)的命名空间中。
3.namespace的使用
编译查找一个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。所以下面程序会编译报错。所以我们要使用命名空间中定义的变量/函数。有三种方式:
指定命名空间访问,项目中推荐这种方式。
#include<stdio.h>
namespace Alone {
int a = 1;
int b = 0;
}
int main() {
printf("%d", Alone::a);
//这是指定命名空间进行访问。
return 0;
}
using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式。
#include<stdio.h>
namespace Alone {
int a = 1;
int b = 0;
}
using Alone::a;
int main() {
printf("%d", a);
//这是展开经常访问且不会产生冲突的成员方法。
return 0;
}
展开命名空间中全部成员,项目不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。
#include<stdio.h>
namespace Alone {
int a = 1;
int b = 0;
}
using namespace Alone;//展开命名空间全部成员
int main() {
printf("%d %d", a, b);
return 0;
}
大家根据使用场景去选择适合的方法。
四、C++输入和输出(简略)
- <iostream>是 Input Output Stream 的缩写,是标准的输入、输出流库,定义了标准的输入、输出对象。
- cout/cin/endl等都属于C++标准库,C++标准库都放在一个叫std(standard)的命名空间中,所以要通过命名空间的使用方式去用他们。
- std:cin 是istream 类的对象,它主要面向窄字符(narrow characters(oftype char))的标准输入流。
- std::cout 是 ostream 类的对象,它主要面向窄字符的标准输出流。
- std::endl是一个函数,流插入输出时,相当于插入一个换行字符加刷新缓冲区。
- <<是流插入运算符,>>是流提取运算符。(C语言还用这两个运算符做位运算左移/右移)使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动指定格式,C++的输入输出可以自动识别变量类型(本质是通过函数重载实现的),其实最重要的是C++的流能更好的支持自定义类型对象的输入输出。
- IO流涉及类和对象,运算符重载、继承等很多面向对象的知识,这里我们只能简单认识一下C++ IO流的用法。
- 一般日常练习中我们可以usingnamespace std,实际项目开发中不建议using namespace st的。
- 这里我们没有包含<stdio.h>,也可以使用printf和scanf,在包含<iostream>间接包含了。我使用的vs2022编译器包含的。
五、缺省参数
- 缺省函数定义是在定义函数时指定一个实参作为函数参数的缺省值,在调用函数时,如果没有指定实参,函数就会使用定义函数时设定的缺省值。缺省函数又分为全缺省和半缺省。(部分称缺省参数也称默认参数)
- 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。
这样就是一个半缺省函数。下面这种情况就是错误的,犯的是间隔跳跃给定缺省值。
下图错误是因为C++规定必须从右往左设定缺省值。
- 带缺省参数的函数调用,C++规定必须从左到右依次给实参,不能跳跃给实参。
- 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。
六、函数重载
C++规定在同一作用域可以出现同名函数,但要求这些同名函数的形参不同,可以是函数个数不同或者函数类型不同。这样体现出函数的多态行为,使用更加灵活。C语言是不支持这种行为。
下面是两种类型的演示:
但是函数重载存在一个情况比较坑人,大家判断下下图两个函数是否构成函数重载??
答案是构成函数重载。但是,在调用的时候是会报错的,因为程序不知道调用哪个函数。
文章为作者学习总结,如有错误可及时沟通,如有冒犯可联系作者删除。谢谢共勉。