第1章 由C到C++

1.1 从C转化为C++
1.2 基础知识和iostream使用
1.3 引用类型和const
1.4 内存管理
1.5 函数

应用领域
C++的应用领域(客户端)
Socket网络编程(如QQ)
串口通信(工业控制,如西门子)
多媒体处理(Power DVD)
嵌入式
游戏
书籍
C Primer/C++ Primer 、Effective C++

勿在浮沙筑高台
qt安装与使用
程序的创建过程
编译环境
内存,指针,字符串
函数(传递参数分类)
如何传参?--明确自己要做什么?
所有例子自己操作,验证。

1.1 从C转化为C++

C++:存在宏、指针、结构体、数组和函数,此外还有公有、保护、私有型成员、函数重载、带缺省参数的函数、构造和析构函数、自定义操作符、内联函数、引用、友元、模板、异常、名字空间等等。

1.2 基础知识和iostream使用

初始化方法及与赋值比较

int i(10); //等效于C中的 int i = 10;
“=”适用于基本类型和单一值类型。
“=”不再是内存复制,而是一次更耗时的函数调用
如果是类类型,用构造函数。point pt(0,0);

作用域限定运算符

运算符 :: 称作作用域限定运算符,用于访问一个在当前作用域内被当前局部变量隐藏的外层全局变量
注意:不能用于访问一个在语句块外声明的同名局部变量。
当用于限定数据成员或成员函数所属的类,这时把运算符 :: 称作类名分辨运算符或类名分辨符

C++中的头文件

头文件应该具有什么样的结构?
#include做哪些事情?
最新标准库与原标准库区别
头文件iostream.h iostream

输入输出

输入输出printf/scanf类型不安全,读写的变量和控制读写格式的信息分开。
Printf(“%d\n”,f);
Printf(“%d,%d\n”,f,sizeof(double));
输出:
0
0,1074921472
发生内存泄露,或内存溢出。
Scanf(“%f”,&f);
//从控制台输入值,寻找变量f的地址,理解地址符。
Printf(“%d %d”,a,b);
//入栈出栈,打印

放弃printf使用io流对象
C++又提供了类层次结构的输入输出流类库。
在iostream头文件中,这里定义了两个对象:
extern istream cin;
extern ostream cout;

//引入命名空间,方式1
using namespace std;
//输出方式2
using std::cout;
using std::endl;
//输出方式3
std::cout << "Hello World!" << std::endl;
<<的指向代表流的方向 cin 键盘 鼠标 cout 显示器对象

io格式控制
头文件:#include
manip是manipulator(操纵器)的缩写 iomanip的作用: 主要是对cin,cout之类的一些操纵运算子
setw(n)是设置域宽,就是你的输出要占多少个字符; setfill控制符一旦设定,就会对后面一直起作用,直到你重新设置。

cout<< setfill('0');
cout<

1.3 引用类型和const

引用

就是变量的另一个名字(当建立引用时,程序用另一个变量的名字初始化它)
int x = 0;
Int *p = &x; //指针
Int &r = x; //r绑定x
引用必须用与该引用同类型(或协变类型)的变量初始化,而且必须初始化,初始化后不能再绑定到别的变量;
int ival = 1024;
int &refVal = ival; // ok: refVal refers to ival

VC 6.0 引用不能按如下方式初始化
int & ri(i); 原因: VC 6.0编译器理解为函数声明
连续引用(正确)
int i(10);
int& ri = i;
int& rii = ri;
cout<

不可声明引用的引用、指向引用的指针、void类型的引用、或引用的数组。
解释:

  1. 声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。故:对引用求地址,就是对目标变量求地址。&ra与&a相等。
  2. 可以创建对数组的引用,但你不能创建一个元素都是引用的数组。
    声明一个数组的引用:
    int a[5];
    int (&b)[5] = a;
    改为 int &b[5] = a;则编译无法通过,因为声明了一个引用数组。即便你将引用数组b中的每一个元素b[i]看做对a[i]的引用,然后对每一个元素进行初始化,也是错误的:
    int &b[5] = {a[0],a[1],a[3],a[3],a[4]};
  3. 不能建立引用的引用,不能建立指向引用的指针。因为引用不是一种数据类型!!
    可以建立指针的引用
    例如:
  int *p;
  int *&q=p;
//编译系统把" int * "看成一体,把"&q"看成一体,即建立指针p的引用,亦即给指针p起别名q。

参考:
C++ 引用的作用和用法

实例:交换数组中的两个元素?(函数)

引用(便利性,效率),指针,数组名,全局变量。
交换两个变量(无第三个变量)
1、算术运算 2、异或 3、位运算 4、堆栈(指针)

调用函数 变量都放在哪里?
当我们调用一个函数时,会在内存中建立起一块特殊的区域,称为”程序栈“,为每个函数提供了参数的存储空间。它也提供了函数所定义的每个变量的内存空间-我们将这些变量称为局部变量。一旦函数完成,这块内存就会被释放掉.。

局部变量资源会被释放。
不能返回局部变量的引用
不能返回局部变量的地址。

实参与形参间的关联仅仅是拥有相同的值,他们之间是复制关系

void swap(int& val1, int& val2 )  //交换两个元素
{
    int temp1= val1;
    val1 = val2;
    val2 = temp1;
}

引用的应用
定义引用类型的变量
定义函数的参数为引用型
定义函数的返回值类型是引用型(例子,前++,operator=,+= )
好处:
功能就是为了实参可以进行修改。效率:可以避免大量的数据复制,加const,保证效率,又不修改

传指针和传引用

  1. 都能改变实参
  2. 引用更安全些,因为没有NULL reference。
  3. 引用更方便些,因为不用*(间址运算)

const的用途

  1. 当const类型说明符用于说明变量时,其作用是冻结所定义的变量在定义域范围内为常量。C++要求用const说明的变量必须在定义时初始化,以后不允许再有赋值操作。
    const int y = 5; // 定义为常量

  2. 当const类型说明符用于说明引用时,则称为常引用。即不能通过引用名来修改原变量的值。
    int i = 100; const int &ri = i ;

  3. 说明指针类型变量(判断修饰哪部分)
    冻结所定义的指针变量所指向的数据; const char* p;
    冻结指针的地址值;(值变地址不变) char* const p;
    或者冻结指针变量所指向的数据和指针的地址值 const char* const p;

  4. 用于函数的形式参数时,该参数不允许在函数内被修改(与指针结合)
    形参可以是const int * x或const int &rx

  5. 当const说明符用于函数的返回类型时,其作用是限定该函数返回的是个常指针或常引用:
    const int* func();
    该函数的调用定是 const int* p = func();

  6. 用于类的成员函数时,其作用是不允许该成员函数修改对象的数据成员。(构造函数)
    int classname::memfunc() const

1.4 内存管理

操作系统分配的内存有四个部分:堆区、栈区、静态区和代码区
为何需要使用堆?
处理动态分配,堆有更多的空间可用
int a[259024]; //262144 = 1024 * 1024 /4; 1M 4GB,存在栈溢出
在C里,我们使用malloc、free。而在C++,我们使用new、delete

动态申请内存
堆区申请的内存没有名字,我们只能使用指针来指向。
int* pi = new int(10);
if (NULL != pi) //效率优于pi!=NULL,判断是否是空指针
{ cout<<*pi<

Date *pmc = new Date(5, 22, 2012); //new申请内存,调用构造函数初始化。
申请一个Date类型空间,将空间地址赋值给指针变量pmc
该Date类型空间初始值为2012年5月22日

//千万不要delete非动态分配的内存,行为不确定
动态开辟数组
int *pArray = new int[10]; //使用
delete[] pArray; //delete(pArray);
pArray = NULL;

1.5 函数

带默认参数值的函数

bool screenInit( int height = 600, int width = 800,
COLORREF background = RGB(255,255,255)
); //函数声明

但是,如果有一个形参具有默认参数值,那么,它后面所有的形参都必须有默认参数值
C++编译器不认可:fun( , x);
声明 默认实参值 (右-》左) 调用 实参 (左-》右)
注:如果函数声明中说明了默认参数值,那么在函数定义中不可再次说明,如果没有函数声明,那么默认参数要在定义时指出。
调用:
screenInit();
screenInit(66);
screenInit(66, 256);
screenInit(66, 256, '#');

函数重载:避免不必要的函数命名(和名字记忆)

定义:在同一作用域中,函数名相同,形参表不同的多个函数叫重载
只有signature(参数个数,参数类型和函数的const属性) 不同才是重载,否则认为是相同的函数。signature 不包括返回值,参数的缺省值。
const int&所代表的变量仅可以是 const int

区分重载和重复定义。

  1. void f(const int i);
    void f(int j);
    调用会报错,重复定义。
  2. void f(const int* i);
    void f(int* j);
    会匹配类型,实现重载。
    合适的使用重载,使用不同的函数名能提供较多的信息,使程序易于理解。
    void f( int& nVal )
    {
    cout<<"引用版本"< }

void f( int nVal )
{
cout<<"非引用版本"< }
int main(){
int nVal = 3;
f(nVal); //调用出现问题
return 0;
}

内联函数

内联函数就是指在编译时被像宏一样直接插入到程序的调用语句处的函数,取代了函数调用,从而减少了运行时函数调用的系统开销。内联函数的标识符关键字是inline,使用方法是在函数的开始处加inline。
限制:
内联函数中不可含有循环;
内联函数中不可含有switch语句;
内联函数中不可含有静态变量;
内联函数不可为递归函数;
内联函数中不可含有异常处理。
内联函数的函数代码不要太长

你可能感兴趣的:(第1章 由C到C++)