Poedu_C++_Lesson02_1_20161219_C到C++

  • 原生bool

    c++支持原生bool

    在C语言中,如果要使用bool,需要包含stdbool.h,而在stdbool.h中是用宏的方式定义了一个0和1,true=1,false=0。
    但是这种定义不是真正原始意义上的bool,只是用了代替品来代表bool。在C++中的true和bool才是真正意义上的bool。C++中bool,0为false,非0为true。其它各种方式的bool,(如BOOL),都不是原生bool,其中的区别是非常大的:
    >

真/假原生booldefine定义的bool
true非01
false00

其中,false的值都是0,没问题。但是,在true中,原生bool对于非0的值都认为是true,而define的true,定义为1。举个例子:

-1对于原生bool来说,它就是true。而define的true并不会认为它是true。但是,我们平时用的时候完全没毛病啊,并不会出现-1不能判断为true的情况。这是因为,编译器为此做了很多工作,将它进行了转换。

注意:_Bool是在c98之后加上的布尔类型,等同于bool。在使用布尔类型的时候,建议使用bool,会更加安全

头文件的三种标准

标准1:C++特有的标准库

如:include< iostream >;

没有.h后缀,后缀名用于进行区分使用

标准2:前缀cxxx,从C继承来,但是符合C++标准的库

如:#include< cstdio >

标准3:从C继承来的库(不符合C++标准)

如:#include< stdio.h >

补充:stdafx与stdafx.cpp是VC特有的东西,也可以没有。称为预编译头,微软认为给我们了便利,但其实没有,也是不被C++承认的。有它没它都可以

域作用符

符号

::

作用

访问指定的命名空间

示例1:

int num=10;
std::cout<< num;
std::cout<< “试试”;

std代表的是一个命名空间叫做std,是一个非常特殊的命名空间,这个命名空间中的所有函数及变量都是标准库中的函数及变量(可通过打开文档查看)

示例2:

int num=100;
int main()
{
  int num=10;
  std::cout<<num;
}

代码解析:
由此打印出的值为10,也就是局部变量的值。根据就近原则,局部变量将全局变量num覆盖了

如果需要在此处打印全局变量的值,那么应该怎么做的?

int num=100;
int main()
{
int num=10;
std::cout<<::num;
}

在num之前加了域作用符(::),因为域作用符之前没有说明命名空间,所以默认为全局。也就是通过这个域作用符,规定了此处所用的num属于全局的那个num。

C++中加了命名空间,可以用来控制作用域,可以在变量名之前加::用来说明是在哪个命名空间中

示例3:

namespace Podeu
{
  int num=20;
}
int num=100;
int main()
{
  int num=10;
  std::cout<<::num;
}
std::cout<<num+::num+Poedu::num;

此时打印的结果就是局部变量num+全局变量num+Poedu中的num的和,也就是130。

补充:在写C项目的时候,碰到了各种各样的ndex和count,这些变量都可以通过命名空间来避免冲突。

new和delete

作用

C++为我们提供的进行堆操作的运算符

注:在C语言中,想在堆上面进行一些操作的时候,使用的是两个函数:malloc和free。

示例

int main()
{
  int *pNum=new int(100);
  //分配了一个int类型大小的空间,并将值设为100.
  std::cout<<*pNum;
  delete pNum;
 //分配连续的内存空间
  int *pArr=new int[10];
  delete[] pArr;
  return 0;
}

与malloc和free的区别

ew和delete是运算符,它们不是函数,malloc和free是一个函数。

但是,注意,这两对都是配套使用的

重载

C++当中一个非常强大的机制
示例:

std::cout<<1;
std::cout<<‘c’;
std::cout<<”Try”;
std::cout<<1.002;

上例中,我们使用了一个函数cout输出了int型的1,char型的c,char*型的Try,float型的1.002。这在C语言中是很难得的,如果我们要达到这样的效果,也可以,但是我们需要做非常多的事情。而C++中的重载却让这件事情变得非常简单了,构成重载后,它会根据参数找到适合的函数进行工作。

原理

我们在上例中使用了同一个函数:cout,这个函数名在我们看来是一样的,但其实是不一样的,编译器会根据后面的参数类型进行匹配。

从反汇编中看,每个Mycout所Call的地址都是不一样的,也就是说,我们把它们都成为cout,但是它其实是几个不同的函数,每一个函数都有自己的空间

那么为什么能够做一一匹配呢?因为编译器会保存一个符号表的东西(记录:变量占用的空间(长度),解析方式(和类型相关)

编译器同时记录函数的参数类型,传入的参数类型,再进行匹配,其记录符号可以是这样的:

MyCout@int
MyCout@char
MyCout@char*
MyCout@float
MyCout@int@char
MyCout@char@int

它将每一个函数都进行了命名粉碎(命名重定向),它在符号表中的存储名字是函数名加上参数类型,使得每一个函数名变得不同。

在本地中用没有问题,但是被其他人调用的时候,实际上个名称已经被更改了。可以用extern C,C编译模式下进行编译时不会有命名粉碎的。

重载规则:

函数名相同,参数不同即可构成重载,与类型(返回值)无关。类型不同,函数名、参数相同构不成重载

如:
int MyCout(int i,char c);
void MyCout(int i,char c);

这样是不能构成重载的,尽管返回值不同,但是两者的函数名和参数完全相同,这样改改就可以了:

int MyCout(char c,int i);
void MyCout(int i,char c);

这样改一下,它实际的名字就变成了MyCout@char@int 与 MyCout@int@char,这两者是不同的,不会发生冲突

注意:实际的命名粉碎不是这样的,还会加上一些类和命名空间等等的一些东西。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值