一.第一个C++程序:
1.编译器: g++ ,如果用gcc需要带上-lstdc++指定其使用标准C++的运行库;
2.源文件的扩展名:.cpp/.cc/.C/.cxx/.c++,最好使用.cpp
3.头文件:#include<iostream>
大多数标准库头文件都没有.h后缀;
4.输出:cout------标准输出对象;
输入:cin--------标准输入对象;
插入运算符: <<
提取预算符: >>
5.std:所有标准库的函数,对象,类型都位于std名字空间;
--------------------------------------------------------------------------------------------------
二.名字空间
1.对程序中的标志符(类型,函数,变量)按照某种逻辑规则划分成若干组;
2.定义名字空间
namespace 名字空间名{ 名字空间成员 }
3.使用名字空间
(1 )作用域限定符:
名字空间名::名字空间成员
表示访问特定名字空间中的特定成员;
(2)名字空间指令:
using namespace 名字空间名;
在该条指令之后的代码对指令所指的名字空间中的所有成员都可见,可以直接访问这些成员无需加“::”
(3)名字空间声明:
using 名字空间名::名字空间成员;
将指定名字空间中的某个成员引入当前作用域,可以直接访问这些成员无需加“::”
(4)匿名名字空间
如果一个标识符没有被显示地定义在任意名字空间中,编译器会将其缺省的置于匿名名字空间中;
对匿名的名字空间中的成员通过 ::名字空间成员的形式访问;
(5)名字空间合并
(6)名字空间的嵌套
-----------------------------------------------------------------------------------------------------------------------
三.C++中的结构,联合,和枚举
1.结构
(1)定义结构型变量,可以省略struct关键字;
(2)结构体内部可以定义函数-----成员函数;
(3)sizeof(空结构) = 1
2.联合
增加了匿名联合的概念;
借用匿名联合的语法形式,描述一些变量在内存中的布局方式;
3.枚举
枚举是一个独立的数据类型;
----------------------------------------------------------------------------------------------------------------------
C++中的布尔类型
bool b = true;
b = false;
cout<<sizeof(b)<<endl;//一个字节
cout<<boolalpha<<b<<endl;//false,格式控制
作用:更安全,更简洁;
--------------------------------------------------------------------
C++中运算符的别名
&& ------- and
|| ---------- or
& ----------bitand
^-----------Xor
{-----------<%
}------------%>
[------------<:
]------------:>
-----------------------------------------------------------------------
C++中的函数
1.重载:
在同一作用域中,函数名相同,参数列表不同的函数,构成重载关系;
C++编译器会对程序中的函数做换名,将参数列表中的类型信息汇合到函数名中,以保证函数名的唯一;
通过extern "C"可以要求编译器不做C++换名,以实现C和C++混合编程;
2.缺省参数和哑元参数
(1)如果调用函数时,没有提供实参,那么对应形参就取缺省值;
(2)如果一个参数带有缺省值,那么它右边的所有的参数必须都带有缺省值;
(3)如果一个函数声明和定义分开,那么缺省参数只能放在声明里;
(4)避免和重载发生歧义;
(5)只有类型而没有名字的形参叫做哑元;
3.内联
(1)编译器用函数的二进制代码替换函数的调用语句,减少函数调用的时间开销,这种优化策略称为内联;
(2)频繁调用的简单函数适合内联,而稀少调用的复杂函数不适合内联;
(3)通过inline 关键字,可以建议编译器对指定的函数进行内联,但是仅仅是建议而已;
inline void foo(int x, int y){}
-------------------------------------------------------------------------------------------------
C++的动态内存分配(堆内存分配)
1.C语言中:malloc/calloc/realloc---------------------------free
2.new/delete: 对单个变量进行内存分配/释放;
3.new[]/delete[]: 对数组进行内存分配和释放;
----------------------------------------------------------------------------------------------------------------------
C++中的引用类型
1.引用即别名
int a = 20;
int& b = a;
b = 10;
cout<< a << endl;//10
2.引用必须初始化
int& b;//error
int& b = a;//ok
3.引用一旦初始化,不能再引用其他变量;
int a;
int& b = a;
int c;
b = c;//把c的值赋给b(a)
4.引用的应用场景
(1)引用型参数
可以修改实参;
避免拷贝,通过const 可以防止在函数中意外修改实参的值,还可以接受拥有常属性的实参;
(2)引用型返回值
int a = func(b);
所有的匿名变量都是右值;
从一个函数中返回引用往往是为了将该函数的返回值作为左值来使用;
但是一定要保证函数所返回的引用的目标在该函数返回以后依然存在,否则将导致不确定的后果;
不要返回局部变量的引用;
可以返回全局,静态,成员变量的引用,也可以返回引用型形变量本身;
5.引用与指针
(1)引用是用指针实现的,很多场合下引用和指针可以完成同样的功能;
(2)在C++层面上,引用和指针存在以下不同
A.指针是实体变量,但是引用不是实体变量
int& a = b; int* a = &b;
sizeof(a);//4 sizeof(a);//4
double& d = f; double* d = &f;
sizeof(d);//8 sizeof(d);//4
B.指针可以不初始化,但是引用必须初始化;
C.指针的目标可以修改,但是引用的目标不能修改;
D.可以定义指针的指针,但是不能定义引用的指针;
int a; int b;
int* p =&a; int& a = b;
int** pp = &p;//ok int&* pr = &a;//error
E.可以定义指针的引用,但是不能定义引用的引用;
int a; int& r = a;
int* p = &a; int&& rr =r;//error
int*& pr = p;//ok
F.可以定义指针数组,但是不可以定义引用的数组;(可以定义数组的引用)
int a,b,c;
int* parr = {&a,&b,&c};//ok指针的数组
int& raar[] = {a,b,c};//引用的数组error
int arr[] = {1,2,3};
int (&arr_ref)[3] = arr;//数组的引用ok
-----------------------------------------------------------------------------------------------
C++中的类型转换
1.隐式类型转换
(1)基本数据:类型同C语言;
(2)类类型: 子类对象可以隐式转换为父类对象;
2.显示类型转换
(1)类C的显示类型转换;
格式1: 目标类型变量 = (目标类型)源类型变量;
例如: A a = (A) b;
格式2: 目标类型变量 = 目标类型(源类型变量);
例如: A a = A (b);
(2)静态类型转换
static_cast<目标类型> (源类型变量);
条件:在目标类型和源类型之间某一个方向上可以做隐式类型转换,或者存在从源类型到目标类型的自定义转换规则;
例如:
int* p1 = ...;
void* p2 = p1;
p1 = static_cast<int*>(p2);
(3)动态类型转换
dynamic_cast<目标类型>(源类型变量);
多态时才能使用dynamic_cast, 不然编译器报错;
用来基类与子类指针或引用的转换;
是运行时转换,以0表示指针转换失败,以抛出异常表示引用转换失败;
(4)常类型转换
const_cast<目标类型>(源类型变量);
给一个拥有const属性的指针或引用去常;
例如:
int a = 100;
const int* p1 = &a;
*p1 = 200;//const error
int* p2 =p1;//type error
int* p2 = const_cast<int*>(p1);//去常之后ok
*p2 = 200;//ok 无const属性
(5)重解释型类型转换
reinterpret_cast<目标类型>(源类型变量);
在不同类类型的指针或引用之间做类型转换,以及指针和整型之间做类型转换;
---------------------------------------------------------------------------------------------------
C++之父的建议:
1.少用宏,多用const, enum和inline
2.变量随用随声明,并同时初始化;
3.少用malloc/free,多用new/delete;
4.少用C风格的强制类型转换,多用类型转换运算符;
5.少用C风格的字符串,多用string;
6.树立面向对象的编程思想;