C++对C的增强

一、namespace命名空间

1.C++命名空间基本常识
所谓namespace,是指标识符的各种可见范围。c++标准程序库中的所有标识符都被定义与一个名为std的namespace中。
1.1:<iostream>和<iostream.h>格式不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的,后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和c区别开,也为了正确使用命名空间,规定有文件不适用后缀.h。因此,
(1)当使用<iostream.h>时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的 c++实现;
(2)当使用<iosream>时,该头文件没有定义全局命名空间,必须使用namespace std;
这样才能正确使用cout;
1.2:由于namespace的概念,使用c++标准程序库的任何标识符时,可以有三种选择:
(1)直接指定标识符,例如std::ostream而不是ostream。完整语句如下:

std::cout <<std::hex << 3.4 <<std:endl;


(2)使用using关键字。using std::cout;using std::endl;using std::cin;以上程序可以写成

cout << std::hex <<3.4 <<endl;

(3)最方便的就是使用using namespace;例如, using namespace std;这样命名空间std内定义的所有标识符都有效(曝光)。就好像让门被声明为全局变量一样。那么以上语句可以如下写:

cout << hex <<3.4 <<endl;

因为标准库非常庞大,所以程序员在选择的类的名臣干活函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字重涂,就把标准库中的一切都放在名字空间std中。但这又会带来一个新的问题。无数原有的c++代码都依赖于使用了多年的为标准库中的功能,他们都是在全局空间下的。所以就有了<iostream>和<iostream>等等这样的头文件,一个是为了兼容以前的c++代码,一个是为了智齿新的标准。命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加“.h”。

2.C++命名空间定义及使用语法
在c++中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和对象等等。为了避免,在大规模程序的设计中,以及在程序员使用各种各样的c++库时,这些标识符的命名发生冲突。
标准库c++引入了关键字namespace(命名空间/名字空间/名称空间/名域),可以更好地控制标识符的作用域。
std时c++标准命名空间,c++标准程序库中的所有标识符都被定义在std中,比如标准库中的类iostream,vector等都定义在该命名空间中,使用时要加上using声明(using namespace std;)或using 指示(如:std::string;std::vector<int>;)

c中的命名空间
在c语言中只有一个全局作用域。
c语言中所有的 全局标识符共享一个作用域。
标识符之间可能发生冲突。
c++中提出了命名空间的概念
命名空间将全局作用域分成不同的部分
不同命名空间中的标识符可以同名而不会发生冲突。
命名空间可以相互嵌套。
全局作用域也叫默认命名空间

c++命名空间的定义
namespace nameA{...};
c++命名空间的使用
使用整个命名空间:using namespace nameA;
使用命名空间中的变量:using naeA::variable;
使用默认命名空间中的变量:::variable;
默认情况下可以直接使用默认命名空间中的所有标识符。

3.C++命名空间编程实践

#include <iostream>
using namespace std;

namespace namespaceA{
int a=10;
}

namespace namespaceB{
int a=1;
namespace namespaceC{
struct Teacher{
char name[10];
int age;
}
}
}
int main()
{
using namesapce nameSpaceA;
using namespaceB::namespaceC::Teacher;
printf("a = %d\n",a);
printf("a = %d\n",namespaceB::a);

Teacher t1={"aaa",33};
printf("t1.name = %s\n",t1.name);
printf("t1.age = %d\n",t1.age);
return 0;
}

  

4.结论
(1)当使用<iostream>时,该头文件没有定义全局命名空间,必须使用namespace std;
这样才能正确使用couot。若引入using namespace std;需要这样做。std::cout。
(2)c++标准为了和c区别开,也为了正确使用命名空间,规定头文件不适用后缀.h。
(3)c++命名空间的定义:namespace name{...};
(4)using namespace namespaceA;
(5)namespace 定义可嵌套。

二、“实用性”加强
#include"iostream"
using namespace std;
//c语言中的变量都必须在作用域开始的位置定义!
//c++中更强调语言的“实用性”,所有的变量都可以在需要使用时定义。

int main11()
{
int i=0;
printf("ddd");
int k=0;
return 0;
}


三、register关键字加强
在C语言中有这么一个关键字——register,这个关键字的意思就是告诉编译器,最好把该关键字修饰的变量放在寄存器内。关于这个关键字还有一些注意点要学一下。

注意:cpu不直接跟内存打交道,需要通过寄存器做中转。

1.被register修饰的变量必须是CPU能够接受的类型,因为有的机器识别不了浮点型,所以register变量的长度应该小于等于整形,但现在有的机器是可以使用浮点型的register变量的。

2.在C语言中,一旦声明为寄存器变量,由于可能会保存到寄存器中,编译器是不允许对其取地址(&)的

3.只有局部自动变量和形参可以是寄存器变量,比如在C语言中,全局变量是不能用register修饰的,并且局部静态变量也不能用register修饰

4.register变量的个数是有限的,因为一个CPU只有那么多个寄存器,并且类型也会受到CPU的限制,并且某些寄存器只能接受特定的类型,如指针类型

开头也说了,这个关键字只是告诉编译器最好将被修饰的变量放到寄存器中以加快存取速度,但是是否真正的存储的寄存器由编译器自己决定。

而在C++中,该关键字又有几点不同:
(1)register 关键字无法在全局中定义变量,否则会被提示为寄存器无效。其实这一点在新的gcc编译器下C语言也不允许定义全局的register变量,因为生命周期直到程序结束,期间都作为寄存器变量的话明显不妥。
(2)register 关键字在局部作用域中声明时,可以用 & 操作符取地址,一旦使用了取地址操作符,被定义的变量会强制存放在内存中

//register关键字,请求编译器让变量a直接放在寄存器里面,数据块。
//在c语言中register修饰的变量,不能去抵制,但是在c++里面做了内容。
/*
1、
register关键字的变化。
register关键字请求“编译器”将局部变量存储与寄存器中。
  C语言中无法取的register变量地址
在c++中依然支持register关键字。
  c++中可以取得regiter变量的地址
2、
c++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效。
3、
早期c语言编译器不会对代码进行有话,因此register变量是一个很好的补充。
*/

int main22()
{
register int a=0;
printf("&a=%x\n",&a);
return 0;
}

  


四、函数类检测加强

在c语言中,重复定义多个同名的全局变量时合法的
在c++中,不允许定义多个同名的全局变量

c语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间
int g_val;
int g_val=10;

c++拒绝这种二义性的做法

int main(int argc,char *argv[])
{	
printf("g_var = %d \n",g_val);
return 0;
}

  


五、struct类型加强

六、C++中所有的变量和函数都必需有类型


七、新增Bool类型关键字


八、三木运算符功能加强

猜你喜欢

转载自www.cnblogs.com/cthon/p/9166135.html