菜鸟学习历程【25】C++入门

时间:2022-09-09 21:29:35

C++入门

命名空间

将全局空间进行划分,全局空间也被称为默认命名空间,命名空间可以相互嵌套。

例如:

这里在全局空间中,开辟了三个大的命名空间分别为Name1,Name2, Name3,其中Name3中又有两个命名空间Name4和Name5;
菜鸟学习历程【25】C++入门

//命名空间的定义,命名空间内可以写变量、函数、宏定义
namespace Name1
{

int a;
}

namespace Name2
{

int a;
int b;
int c;
}

命名空间的使用:

1.使用域解析符
Name1::a = 10;
Name2::a = 20;
cout<<"a1 = "<<Name1::a<<", a2 = "<<Name2::a<<endl;

2.使用using关键字
//将命名空间Name1打开,后面直接可以使用命名空间Name1中的变量,函数,宏定义
using namespace Name1;
a = 10;
Name2::a = 20;
cout<<"a = "<<a<<endl; 结果是:a = 10
原因:
**using后面但凡没有明确指明具体命名空间的变量,函数,宏定义,默认使用的是Name1中的**

当然也可只开启部分内容:
比如,using Name2::c;
后面但凡没有指明具体命名空间的c,默认使用Name2中的C;

3.命名空间之间命名冲突
using namespace Name1;
using namespace Name2;
a = 10; //有歧义,不知道使用哪一个命名空间内的a
Name1::a = 10;//使用域解析符可以解决两个命名空间明明冲突的问题

如果定义了一个全局变量a;
a = 10; //有歧义,全局变量与命名空间发生冲突
::a = 10;//使用默认命名空间的域解析符,使用全局变量

c++标准库和std命名空间

C++ 是在C语言的基础上开发的,早期的 C++ 还不完善,不支持命名空间,没有自己的编译器,而是将 C++ 代码翻译成C代码,再通过C编译器完成编译。这个时候的 C++ 仍然在使用C语言的库,stdio.h、stdlib.h、string.h 等头文件依然有效;此外 C++ 也开发了一些新的库,增加了自己的头文件,例如:
iostream.h:用于控制台输入输出头文件。
fstream.h:用于文件操作的头文件。
complex.h:用于复数计算的头文件。

和C语言一样,C++ 头文件仍然以.h为后缀,它们所包含的类、函数、宏等都是全局范围的。

后来 C++ 引入了命名空间的概念,计划重新编写库,将类、函数、宏等都统一纳入一个命名空间,这个命名空间的名字就是std。std 是 standard 的缩写,意思是“标准命名空间”。

但是这时已经有很多用老式 C++ 开发的程序了,它们的代码中并没有使用命名空间,直接修改原来的库会带来一个很严重的后果:程序员会因为不愿花费大量时间修改老式代码而极力反抗,拒绝使用新标准的 C++ 代码。

头文件:
c语言:去掉.h, 并在前面加c 例如,stdio.h => cstdio
c++: 去掉.h 例如,iostream.h => iostream

原来的c++头文件:
例如:

test.h
{
int a;
}

新文件的名字:test

{
namespace std;
{
int a;
}
}

C++ PK C

1.实用性加强

c语言规定所有变量的定义必须放在开头,c++对变量定义的位置没有要求,建议是在使用的时候再定义。
最小化变量的适用范围,在用的时候再去定义变量

2.register关键字的变化

首先讲一下,CPU、内存、寄存器三者之间的关系,它们之间的关系用下图进行说明:

菜鸟学习历程【25】C++入门

内存单位:字节
将内存划分为很多小块,每个小块都有编号,编号对应于地址,也就是指针。地址也只在内存当中才有意义。

寄存器脱离内存,因此没有地址这一说法。

在C++中,如果对一寄存器变量取地址操作,那么register声明无效。但在C语言中,如果对一寄存器变量取地址操作,那么编译就不能通过。

举个例子形象的说明,这三者的关系:
内存就像是军机大臣,寄存器就是太监,CPU就是皇上。大臣将要处理的事情交由太监转交给皇上来处理,皇上处理后再交给太监转交给大臣。

3.全局变量重复定义

C语言中允许全局变量重复定义;
C++中不允许全局变量重复定义;

4.struct类型加强

C语言中,struct只是一种数据的集合,而不是一种新的数据类型,所以在定义时要在变量前加上struct关键字。

例如:

struct Student
{
int age;
char name[20];
};

int main()
{
struct Student stu = {10, "小明"};
return 0;
}

但在C++中,认为结构体是一种新的数据类型,可以直接用来定义变量;

例如:

struct Student
{
int age;
char name[20];
};

int main()
{
Student stu = {20, "小红"};
return 0;
}

除此以外,还有三点也要注意:

  1. C语言中,函数没有参数时,调用可以填写任意个数的实参;
  2. C语言中,函数可以没有返回值;
  3. C语言中,形参可以没有类型。

对于C++,上面三种情况都不允许发生

5.新增bool类型

bool值只有2种,一个为真,值为1,另一个为假,值为0;
C++中,0表示假,所有非0都为真。

#include <iostream>

using namespace std;

int main()
{
bool b = true;
bool b1 = false;

cout << "b = " << b << ", b1 = " << b1 << endl; // b = 1, b1 = 0

int a = 2;
b = a;
cout << "b = " << b << endl; // b = 1;

b++;
cout << "b = " << b << endl; // b = 1;

b = b - 1;
cout << "b = " << b << endl; // b = 0;

b = -1;
cout << "b = " << b << endl; // b = 1;

return 0;
}

6.浮点型数与0进行比较

float精度为7位,double 精度为15位。

float f = 1.2f;

if(f - 0.0000001 < 0 && f + 0.0000001 > 0) //**0.0000001**这个精度取决于客户要求
{
cout<<f<< " > 0"<<endl;
}

7.三目运算符的增强

C++中的三目运算符可以当左值,而C语言返回的是数据的值,C++返回的是变量本身

#include <iostream>

using namespace std;

int main()
{
int a = 10;
int b = 20;
int c = (a > b) ? a : b;

(a > b ? a : b) = 90; // 在C语言中,*(a > b ? &a : &b) = 90,也可以将b的值变为90

cout<<"a = "<<a<<", b = "<<b<<", c = "<<c<<endl; // a = 10, b = 90, c = 20

return 0;
}

注意:当三目运算符当左值使用时,表达式中不能有常量。

8.const:设置变量的属性为只读

C语言中,const修饰的是变量,不能通过变量名修改内存中的值,但可以通过其他方式进行修改;

const ina a = 10;

int *p =(int *)&a;
*p = 20;

printf("a = %d\n", a); // a = 20;

C语言通过上面两行代码,就能改变常量的值

在C++中,const修饰的是一个常量,放在符号表中,符号表由编译器维护。

键值
a 10

如果对const修饰的常量进行取地址操作,则编译器会为这个变量分配一个内存,但这段内存不可使用。

菜鸟学习历程【25】C++入门

const ina a = 10;
int *p =(int *)&a;
*p = 20;

printf ("&a = %p\n", &a); // 004FFBA8
printf ("p = %p\n", p); // 004FFBA8
printf ("a = %d, *p = %d\n", a, *p); // a = 10, *p = 20;

原因是:&a中的a并不是符号表内的a,而是新的内存中a,因此p与a的地址相同,但当输出时,a是符号表中。

在C++中,建议使用const代替宏常量,因为C++中的const就是常量。
最典型的例子就是,在C语言中数组的容量不能用常量来写,即

const int a = 10;
int b[a]; // 是不正确的

但在C++中,这是允许的。

原因:

  1. 宏常量不会做类型检查,在预处理器件完全替换,const常量在编译时处理,会做类型检查。
  2. 宏常量不会做作用域检查,const
C语言中:

void func()
{
#define B 20;
}

int main()
{
printf("B = %d\n", B); //B = 20;
return 0;
}

C++中:
void func()
{
const int a = 25;
}

int main()
{
printf("a = %d\n", a);
return 0;
}

编译不会通过