【C++】初识C++
文章概括
谈谈C++在学习前的认知,C++是在C的基础上,容纳进去了面向对象的编程思想,并增加了许多有用的库,以及编程范式等等。所以学习C++之前一定对C有一定的认知,一个好的C++程序员一定会是一个优秀的C语言程序员。
本章主要介绍:补充C语言语法的不足,以及C++是如何对C语言程序设计不合理地方进行优化的,比如:作用域方面、IO方面、函数方面、指针方面、宏方面等等;同时也为后续学习类和对象做了铺垫。
关键字(C++98)
C++有63个关键字,C语言有32个关键字。
关键字 | 关键字 | 关键字 | 关键字 | 关键字 |
---|---|---|---|---|
asm | auto | bool | break | case |
catch | char | class | const | const_cast |
delete | do | double | dynamic_cast | else |
enum | explicit | export | extern | false |
float | goto | if | inline | int |
long | mutable | namespace | new | operator |
private | protected | reinterpret_cast | return | short |
signed | sizeof | static | static_case | struct |
switch | template | this | try | typedef |
typeid | typename | union | unsigned | using |
virtual | void | volatile | continue | for |
public | throw | wchar_t | default | friend |
register | true | while |
后续逐渐了解
命名空间
命名空间的定义
先以C语言举例:
假设需要定义一个全局变量随机数random为10
#include<stdio.h>
int rand = 10;
int main(void)
{
printf("%d\n", rand);
return 0;
}
这是可以编译成功的,但是我们之前有了解过rand是一个头文件stdlib.h的一个库函数,如果我们包含stdlib.h这个头文件会发生什么?
#include<stdio.h>
#include<stdlib.h>
int rand = 10;
int main(void)
{
printf("%d\n", rand);
return 0;
}
发生报错,这里可以明显突出一个C语言的库命名冲突问题。
有时在一个大的工程中有多个项目,每个项目会由不同的人负责,这时也会难免遇到项目之间的命名问题。
总之,C语言命名冲突的问题有:
1.库命名冲突问题
2.项目相互之间命名的冲突
在C++中,存在命名空间namespace可以解决这类型的问题。
在讲解命名空间前,需要先了解域的概念:域可以看作是一个作用区域,域包含类域、命名空间域、局部域、全局域等等
在一般情况下访问时,会先访问局部域,在局部域中未发现变量,会进而访问全局域。
假设在全局域中存在全局变量,同时在局部域中也存在一个局部变量,但是想要跳过局部域直接访问全局域,应该如何操作?
int a = 1;
int main(void)
{
int a = 0;
printf("%d\n", ::a);
return 0;
}
这里需要介绍一个操作符"::",域操作限定符,::a默认会跳过局部域,访问全局域。
那如果存在命名空间域namespace,其优先级是如何?
int a = 1;
namespace project
{
int a = 2;
}
int main(void)
{
int a = 0;
printf("%d\n", a);
printf("%d\n", ::a);
return 0;
}
由此可见,访问变量a,会先访问局部域——>然后访问全局域——>最后在默认情况下,编译器并不会主动去命名空间域搜索。
想要搜索命名空间域,有俩种方式:
1.展开命名空间域
namespace project
{
int a = 2;
}
using namespace project;
int main(void)
{
printf("%d\n", a);
return 0;
}
2.指定访问命名空间域
namespace project
{
int a = 2;
}
int main(void)
{
printf("%d\n", project::a);
return 0;
}
如果在局部域,全局域,命名空间域(展开命名空间域)中都存在变量a,会如何访问?
这里可以发现局部域的优先级最高,但如果只存在全局域与展开后命名空间域时,会发生报错,原因在于:展开的命名空间域相当于暴露在全局域。
所以不要轻易使用using namespace + 名,即不要请轻易展开命名空间域。
总结:在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
命名空间的特性
- 定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
namespace project
{
int a = 2;
}
1.命名空间域中可以定义变量、函数、类型
namespace project
{
//定义变量
int num = 10;
//定义函数
int add(int x, int y)
{
return x + y;
}
//定义结构体
struct Node
{
struct Node* next;
int data;
};
}
2.命名空间可以嵌套
namespace project
{
namespace N1
{
int a = 1;
}
namespace N2
{
int a = 2;
//定义函数
int add(int x, int y)
{
return x + y;
}
}
}
int main(void)
{
printf("%d ", project::N1::a);
printf("%d ", project::N2::a);
printf("%d ", project::N2::add(1,2));
return 0;
}
- std是C++标准库的命名空间名,C++将标准库的定义实现都放在这个命名空间里。
【注意】:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
3.同一个工程中允许存在多个相同的命名空间,编译器最后会合成同一个命名空间,即可以在多个文件中定义相同名字的命名空间
输入与输出
C++中的输入输出
早年在VC6.0时没有命名空间,头文件C++中的头文件
#include<iostream.h>
后面改为了
#include<iostream>
#include<vector>
#include<list>
使用iostream这个头文件时,需要先学习C++的输入输出.
c语言中使用printf与scanf来将数据输出与输入,而在C++中使用cout与cin实现输入输出。
#include<iostream>
using namespace std;
int main(