C++是对C的扩充,C中的所有知识点,在C++中均可使用
C语言是面向过程>语言,C++是半面向过程半面向对象语言,C#是完全面向对象语言
C++可以完成面向过程的程序设计,也可以完成面向对象的程序设计
所谓面向对象,就是将能够实现某一事物的万事万物都封装在一起,我们称之为类,在类中提供公共的接口。用户可以通过公共的接口对类中的相关属性进行控制。
概念:
面向过程:把事情拆分成几个步骤(相当于拆分成一个个的方法和数据),然后按照一定的顺序执行。
面向对象:面向对象会把事物抽象成对象的概念,先抽象出对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法。
面向过程和面向对象的优缺点:
优点 | 缺点 | |
---|---|---|
面向过程 | 效率高,因为不需要实例化对象 | 耦合低(易复用),扩展性强,易维护,由于面向对象有封装、继承、多态性的特点,可以设计出低耦合的系统,使系统更加灵活、更加易于维护 |
面向对象 | 耦合度高,扩展性差,不易维护(例如:每个步骤都要有,不然就不行) | 效率比面向过程低 |
C++兼容了绝大部分的C,但是C++的编译器比C语言的编译器更加严格
#include
#include //C++中,头文件必须要加
using namespace std; // 将整个命名空间全部声明
void fun(void* arg)
{
// int *p = arg; //C的编译器支持万能指针类型转换
int* p = (int*)arg; // C++编译器不允许万能指针自动类型转换
printf("*p = %d\n", *p); // 100
}
int main()
{
int a = 100;
fun(&a);
return 0;
}
C++源文件的后缀:.cpp .C .cxx .cc
C++编译器是g++: g++ 文件.cpp -o 可执行文件
C++中的头文件一般不以.h结尾,如果想要使用c中的头文件,可以将.h去掉,在前面加个c即可
#include
#include
//#表明是一条预处理指令
//include:表明是一条文件包含指令
//<>:使用的是库中的文件,如果使用自定义的则用""包裹
//iostream:i(input)\o(output)\stream :引入的是输入输出流类
using namespace std;
//using:使用命名空间的关键字 第一种使用方式
//using my_int = int; //using的第二种使用方式,相当于typedef
//namespace:命名空间额关键字
//std:系统提供的标准的命名空间
//主函数,可以是有参函数,也可以是无参函数,可以是有返回值函数,也可以是无返回值函数
int main()
{
cout << "Hello World!" << "\t"<<1314<< "\t" << 520 <<"\t"<<'G'<< endl;
//cout:标准输出流对象,类似于printf,但是不是函数调用,cout输出时会自动识别要输出数据的类型,不需要格式控制符
//<< :插入运算符,结合cout对象共同完成输出功能
//endl:换行,相当于\n
return 0;
}
来自于ostream的类对象,用于输出数据使用
功能类似于printf,可以输出各种类型的数据,但是,不需要加格式控制符%d%u%s。。。
允许级联使用,也就是可以输出多个数据,这些数据可以是不同数据类型,但是需要用<<隔开
endl是std命名空间中的换行,相当于’\n’
#include
using namespace std;
int main()
{
int m = 520;
float n = 3.14159265358;
double d = 3.14159265358;
char c = 'G';
cout << "m = " << m << endl; // 输出整型数据
cout << "n = " << n << endl; // 输出单精度浮点型
cout << "d = " << d << endl; // 输出双精度浮点型
cout << "c = " << c << endl; // 输出字符数据
return 0;
}
来自于istream的类对象,用于输入使用
功能类似于scanf,但是同样不需要使用格式控制符,自动识别类型
输入时不需要加endl
#include
using namespace std;
int main()
{
int m = 520;
float n = 3.14159265358;
double d = 3.14159265358;
char c = 'G';
cout << "请输入m的值:";
cin >> m; // 输入整数
cout << "m = " << m << endl;
cout << "请输入n的值:";
cin >> n; // 输入单精度小数
cout << "n = " << n << endl;
cout << "请输入d的值:";
cin >> d; // 输入双精度小数
cout << "d = " << d << endl;
cout << "请输入c的值:";
cin >> c; // 输入字符数据
cout << "c = " << c << endl;
return 0;
}
如果调用函数,则需要加对应的头文件:#include
相关格式化控制,也有对应的关键字搭配使用
相关函数了解即可
#include
#include
using namespace std;
int main()
{
int m = 101; // 默认是十进制数据
cout << "m = " << m << endl; // 101
// 输出其他进制
// 关键字版本
cout << "m = " << oct << m << endl; // 输出八进制数据 145
cout << "m = " << hex << m << endl; // 输出八进制数据 65
cout << "m = " << dec << m << endl; // 101
// 函数版本
cout << "m = " << setbase(8) << m << endl; // 输出八进制数据 145
cout << "m = " << setbase(16) << m << endl; // 输出八进制数据 65
cout << "m = " << setbase(10) << m << endl; // 输出八进制数据 101
// 设置输出的宽度printf("%5d\n", m);
cout << setw(5) << right << m << endl; // 设置输出的最下宽度
cout << setw(5) << right << setfill('*') << m << endl; // 设置填充字符
// 输出小数printf("%.2f", 3.14159265358);
double n = 314.159265358;
cout << "n = " << n << endl; // 默认保留6位有效数字
cout << "n = " << setprecision(10) << n << endl; // 保留自定义的有效数字
cout << "n = " << fixed << setprecision(2) << n << endl; // 如果没有使用关键字fixed固定小数点,
// 则setprecision里面的参数是有效数字个数
// 如果使用关键字fixed固定小数点,
// 则setprecision里面的参数是小数点后几位
return 0;
}
变量名、函数名、数组名、枚举名、结构体名、共用体名、类名。。。
以上这些名字,都属于标识符,可以由程序员自己定义,只要满足命名规则即可
在多人协同开发一个程序时,可能会出现这种情况,即使在每个人的程序中,命名非常规范,但是也会出现同名情况,当将程序进行合成时,会出现上述名字冲突问题,该问题也称为"命名污染"问题。
C++提供命名空间机制,用以解决命名冲突或命名污染问题,相当于给上述名字加一个”姓氏“
每次使用std命名空间中的名字时,都加上命名空间名和作用域限定符
std::cout << “Hello World!” << std::endl;
在程序的某个地方,将要使用的名字提前进行声明,后期对该名字直接使用即可,但是没有声明的名字,不可直接使用
using std::cout;
cout << “23021班”<
将整个命名空间全部进行声明,在此后程序中就可以使用该命名空间中的全部名字
using namespace std;
cout<<“我是二狗”<
#include
// 使用方式2:将要使用的某个名字提前声明,对于没有声明的名字,依然不能使用
using std::cout;
// 使用方式3:将整个命名空间全部进行声明
using namespace std;
int main()
{
std::cout << "Hello World!" << std::endl; // 使用方式1:每次使用前加命名空间名和作用域限定符
cout << "23021班" << std::endl; // 使用方式2
cout << "我是二狗" << endl; // 使用方式3
return 0;
}
定义格式
namespace 空间名
{
//各种名字
}
#include
#include
using namespace std;
namespace zpp
{
int age; // 年龄 整形变量名
char name[10]; // 姓名 数组名
void show(); // 命名空间内声明函数名
}
// 命名空间外进行定义
void zpp::show() // 函数名
{
cout << "name = " << name << " age = " << age << endl;
}
// 上述为定义一个命名空间,其使用方式有三种
using zpp::name; // 声明命名空间中的某个名字
using namespace zpp; // 将整个命名空间全部声明
int main()
{
zpp::age = 18; // 使用方式1:将zpp中的age更改内容
strcpy(name, "zhangsan"); // 使用方式2
show(); // 调用命名空间中的函数
return 0;
}
多个不同命名空间中产生同名的问题。如果两个命名空间全部被声明了,那么,命名空间中产生冲突的名字,要使用命名空间名和作用域限定符进行修饰,没 有产生冲突的名字,不需要加。
当命名空间中的名字和全局变量冲突时,也需要使用命名空间名和作用域限定符进行区分。全局中的名字会默认放入匿名空间中,使用方式作用域限定符加名字即可
命名空间中的名字和局部变量同名时,就近访问原则,优先使用局部变量,如果非要使用命名空间中的名字,则需要加命名空间名和作用域限定符
#include
using namespace std;
namespace zpp
{
char name[20];
char sex; // 性别
int age; // 年龄
}
namespace lisa
{
char name[20];
char sex; // 性别
int age; // 年龄
int a;
int num = 666;
int value = 1111;
}
// 声明命名空间
using namespace zpp;
using namespace lisa;
int num = 999; // 全局中的名字会默认放入匿名空间中,如果想使用匿名空间中的名字
// 只需使用::名字即可
int main()
{
zpp::age = 18; // 此时使用zpp命名空间中的名字
lisa::age = 20; // 此时使用lisa命名空间中的名字
a = 520; // 没有产生冲突的名字,不需要进行区分,直接使用即可
cout << lisa::num << endl; // 此时使用的是lisa中的名字
cout << ::num << endl; // 此时使用的是全局变量的名字
// 定义变量
int value = 22222;
cout << "value = " << value << endl; // 此时会输出局部变量
cout << "value = " << lisa::value << endl; // 此时使用的是命名空间中的名字
return 0;
}
#include
using namespace std;
namespace zpp
{
char name[20];
char sex; // 性别
int age; // 年龄
namespace zll
{
int age;
double score;
double salary;
}
}
// 在一个程序中,可以定义多个同名的命名空间,但是,在编译时,系统会自动合成一个命名空间
namespace zpp
{
int key;
// int age; //不允许多个同名命名空间中出现定义同名的名字
}
using namespace zpp;
int main()
{
zpp::age = 18; // zpp命名空间中的age变量
zpp::zll::age = 20; // 需要使用作用域限定符一级一级找到最低一级进行使用
return 0;
}
系统会默认提供一个标准的命名空间std,使用方式有三种
系统运行用户自定义属于自己的命名空间
多个命名空间产生冲突时的解决方式,在名字前面加上命名空间名和作用域限定符
命名空间允许嵌套定义
命名空间中如果有函数,一般在命名空间中进行声明,命名空间外进行定义
ce zpp
{
int key;
// int age; //不允许多个同名命名空间中出现定义同名的名字
}
using namespace zpp;
int main()
{
zpp::age = 18; // zpp命名空间中的age变量
zpp::zll::age = 20; // 需要使用作用域限定符一级一级找到最低一级进行使用
return 0;
}
## 3.7 命名空间的总结
1. 系统会默认提供一个标准的命名空间std,使用方式有三种
2. 系统运行用户自定义属于自己的命名空间
3. 多个命名空间产生冲突时的解决方式,在名字前面加上命名空间名和作用域限定符
4. 命名空间允许嵌套定义
5. 命名空间中如果有函数,一般在命名空间中进行声明,命名空间外进行定义
6. 一个程序中可以出现多个同名的命名空间,编译时系统会自动合成一个,所以不允许出行同名的相关名字