【01】C到C++(基础)

版权声明:zhuhurry 未经博主允许不得转载    https://blog.csdn.net/zhuhurry


为什么要学C++:

C++是更高级的C语言,在保证C语言运行效率的同时具有现在语言的特性、在工业等性能要求较高的领域运用广泛
C与C++的区别简介
C语言是一个结构化语言,重在算法和数据结构,它是面向过程的编程思想
C++全面兼容C,支持C风格、基于对象、面向对象、泛型、函数式5种编程方式

一、bool 布尔型
其值为true(逻辑真)和false(逻辑假),存储的字节在不同的编译系统中不同,vc++中为1个字节。可以当作整数用(true一般为1,false为0)
声明方式:bool result
把其它类型的值转换为布尔值时,非零值转换为true,零值转换为false

二、const 限定符
C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。
提高程序的效率:编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

1. 修饰变量
int const a= 100;//两种修饰方法效果一致,变量a的值不可变, 必须要初始化
const int a= 100;
2. 修饰指针
const int * p; //const在*左边,表示*p为常量,即p指向的内容不可变
int* const p; //const在*右边,表示p为常量,指针本身是常量不可变
const int* const p; // 两者都不可变
3. const修饰参数和返回值
(1)const修饰函数参数
void function(const int Var); // 传递过来的参数在函数内不可以改变 (无意义,因为Var本身就是形参,不会改变实参)
void function(const char* Var); // 参数指针所指内容为常量不可变
void function(char* const Var); //参数指针本身为常量不可变(也无意义,因为char* Var也是形参)
void function(const int& Var); // 引用参数在函数内为常量不可变,参数为引用,为了增加效率同时防止修改,C++中比较常见
(2)const 修饰函数返回值
const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。
4. const修饰类的成员函数
const修饰的成员函数不能修改任何的成员变量
const成员函数不能调用非onst成员函数,因为非const成员函数可以会修改成员变量

三、#define使用及在定义常量时和const的区别
1.const定义的常量 有类型,而#define定义的没有类型 ,编译可以对前者进行 类型安全检查 ,而后者仅仅只是做简单 替换
2.const定义的常量有类型,而#define定义的没有类型,编译可以对前者进行类型安全检查,而后者仅仅只是做简单替换
3.作用域不同,const定义的常变量的作用域为该变量的作用域范围。而#define定义的常量作用域为它的定义点到程序结束,当然也可以在某个地方用#undef取消

#define 替换 在底层实现的时候应用广泛
#define注意出错的地方:
#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))
int a = 5;
int b = 0;
CALL_WITH_MAX(++a, b); //a被累加二次
CALL_WITH_MAX(++a, b+10); //a被累加一次

四、结构体内存对齐
内存对齐:编译器为每个“数据单元”按排在某个合适的位置上,C、C++语言非常灵活,它允许你干涉“内存对齐”。
为什么要对齐
性能原因:在对齐的地址上访问数据快。
如何对齐
(1)第一个成员与结构体变量的偏移量为0
(2)其它成员要对齐到对齐数的整倍数的地址,( 注意是地址
(3)对齐数取编译器预设的一个对齐整数与该成员大小的较小值
(4)结构体总大小为最大对齐数的整数倍
如何干涉“内存对齐”
#pragma pack(1) //指定编译器的对齐整数
struct test{}; //需要对齐的结构体
#pragma pack() //取消设定的对齐整数

五、域运算符(C++新增)::
用于对与局部变量同名的全局变量进行访问
用于表示类的成员 ,这将在关于类的一节中详细说明



六、new、delete运算符
new运算符可以用于创建堆空间,成功返回首地址
指针变量=new 数据类型 int *p; p=new int;
指针变量=new 数据类型[长度n]; char *pStr=new char[50];
delete运算符 可以用于释放堆空间
delete 指针变量; delete p;
delete [] 指针变量; delete [] pStr;
new一个新对象
内存分配(operator new)
调用构造函数
delete释放一个对象
调用析构函数
释放内存(operator delete)

七、重载
相同的作用域,如果两个函数名称相同,而参数不同,我们把它们称为重载overload,函数重载又称为函数的多态性,调用重载函数时,编译器通过检查实际参数的个数、类型和顺序来确定相应的被调用函数。
函数重载不同形式:
形参数量不同 形参类型不同
形参的顺序不同 形参数量和形参类型都不同
注意,如果函数的返回类型不同,但函数名、参数相同,则不是重载,编译器报错

八、name managling与extern “C”
name managling这里把它翻译为 名字改编 C++为了支持重载,需要进行name managling
extern “C”实现C与C++混合编程, 即对C语言写的函数不进行改名。如果我们在c++编译环境中没有使用 extern “C”来引用C的函数 ,则C++编译器会对其函数名进行改编,则找不到对应的函数实现。
我们一般书写格式如下:
#ifdef __cpluscplus //如果是C++编译器,则引用extern “C”
extern “C”
{
#endif
...
#ifdef __cpluscplus
}
#endif
这样书写的方便之处是当书写的代码可用于C和C++语言,不需要做修改。

九、带默认形参值的函数
函数声明或者定义的时候,可以给形参赋一些默认值、调用函数时,若没有给出实参,则按指定的默认值进行工作。

需要注意的地方:
1.若函数具有多个形参,则默认形参值必须 自右向左连续地定义 ,并且在一个默认形参值的右边不能有未指定默认值的参数。
void func1(int a, double b=4.5, int c=3); //合法的
void func1(int a=1, double b, int c=3); //不合法的
在调用一个函数时,如果省去了某个实参,则直到最右端的所有实参都省去
int f(int a, float b=5.0, char c='c', int d=10);
f(9,4.5) == f(9,4.5,'c') == f(9,4.5,'c',10)
2. 默认形参值的说明必须出现在函数调用之前 ,如果存在函数的声明则在函数的声明中给默认值,一般不再函数定义中给默认值。如果不存在很熟声明则在函数定义中给默认值。若函数原型中已给出了形参的默认值,则在函数定义中 不得重复指定 ,即使所指定的默认值完全相同也不行。
int sub(int x=8,int y=3);
int sub(int x=8,int y=3){ //不合法、重复指定
return x+y;
}
需要注意的错误:

sum=add(10,20)语句产生二义性性,可以认为该语句是调用第一个函数,也可以是第二个,因此编译器不能确定调用的是哪一个函数。

十、namespace命名空间
所谓namespace,是指 标识符的各种可见范围 。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
为了避免在大规模程序的设计中标识符名称发生冲突,标准C++引入了namespace,可更好的控制标识符的作用域。c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。
C语言中只有一个全局作用域,所有的标识符共享一个作用域,标识符之间可发生冲突,而在C++中,命名空间将全局作用域分成不同的部分, 不同命名空间中的标识符可以同名而不会发生冲突 命令空间可以相互嵌套 ,全局作用域也叫默认命名空间
命名空间的定义:
namespace name {...}
命名空间的使用:
使用整个命名空间:using namespace name
使用命名空间中的变量:using name::variable
使用默认命名空间中的变量: ::variable
默认情况下可以直接使用默认命名空间中的所有标识符

十一、“实用性”增加
C语言中的变量都必须在作用域开始的位置定义
C++中更强调语言的“实用性”,所有的变量都可以在需要使用时再定义

十二、register关键字增强
在C和C++中,这个关键字请求编译器尽可能的将变量存在 CPU内部寄存器 中,而不是通过内存寻址访问,以提高效率。 注意是尽可能,不是绝对 。假如,CPU内部寄存器不够时,该变量就是一个普通的变量。
在C中:
register可以在全局中定义变量,当对其使用&时,只是警告“有坏的存储类”
register可以在局部作用域中声明,但这样就无法对其使用&。否则编译不通过
在C++中:
register无法在全局中定义变量,否则会被提示为不正确的存储类
register在局部作用域中声明时,可以用&操作符取地址,一旦使用了取地址操作符,被定义的变量会强制存放在内存中
总之:
建议不要用register定义全局变量,因为全局变量的生命周期是从执行程序开始,一直到程序结束才会终止,而register变量可能会存放在cpu的寄存器中,如果在程序的整个生命周期内都占用着寄存器的话,这是个相当不好的举措。

十三、struct类型加强
C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型
C++中的struct是一个新类型的定义声明,与类功能相同



















  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值