首页 > 技术文章 > 《C++程序设计》上半部读书笔记

amanlikethis 2014-01-03 22:10 原文

目录

    前言

    第一章 C++的初步知识

        1 C语言的优点

        2 C++产生的背景

        3 C++对C的增强

        4 如何体会C++的优点

        5 类的特性

        6 C++开发工具

    第二章 数据类型与表达式

        1 数据类型

        2 浮点数

        3 字符

            3.1 转义字符极其含义

            3.2 字符串常量

        4 符号常量

        5 变量

        6 常变量

        7 数据运算过程中的数据类型转换

        8 强制类型转换运算符

        9 赋值过程中的类型转换

    第三章 程序设计初步

        1 算法的概念

        2 算法的分类

        3 算法的表示

        4 执行语句

        5 复合语句

        6 C++的输入与输出

        7 逻辑常量和逻辑变量

        8 break语句和continue语句

    第四章 函数与预处理

        1 函数类型

        2 形式参数

        3 参数传递

        4 函数定义与函数声明

        5 函数原型    

        6 内联函数

        7 函数的重载(C++特有)

        8 函数模板

        9 函数的递归调用

        10 局部变量

        11 全局变量

        12 变量的存储方式(动态存储和静态存储)

        13 用static声明的静态外部变量

        14 变量的声明(引用性声明)和定义(定义性声明)

        15 预处理命令

        16 “文件包含”处理

        17 头文件的内容

        18 条件编译                           

    第五章 数组

        1 数组的概念

        2 内存分布

        3 怎样看二维数组 

        4 数组名当实参和形参

        5 用多维数组名作函数参数

        6 字符数组 

        7 字符串

        8 字符数组存储字符串时注意的问题 

        9 字符串处理函数

        10 C++字符串类(string)与字符串常量 

        11 字符串变量的运算

        12 字符串数组 

        13 字符串变量的存储

    第六章指针 

        1 指针与指针变量 

        2 使用指针时注意的问题 

        3 数组与指针 

        4 多维数组与指针 

        5 字符串与指针 

        6 指针运算总结 

        7 引用 

    第七章 自定义数据类型 

        1 自定义数据类型 

        2 C++与C在定义结构体变量时的区别 

        3 结构体变量的定义 

        4 结构体变量的引用 

        5 指向结构体变量的指针 

        6 new与delete 

        7 共用体 

        8 枚举类型 

        9 typedef              

前言                                                                                

    大约4年前学习C语言,只是为了过计算机二级考试。当初学习也很认真,几乎将书都翻烂了,终于将计算机二级搞定了。之后的两三年,用C语言的时候也就是学单片机、ARM裸机程序等内容,但是涉及的都是极其简单的C语言编程。三种基本结构的确是都能用上;但是用的数据类型是整形的、字符型的、数组,而指针都很少用到,更别提结构体、链表、函数指针等高深的数据结构;至于算法,都是很简单的前后台系统,有时连中断服务程序都没有就能搞定小实验。就这样的两三年过去,C语言并没有得到大的提高。关键是没有复杂的编程需要用到,看来以后要给自己定高一点的目标,困难一点的任务。

    现如今,考虑到只会C语言的单薄--面向过程,最好学一门面向对象的程序设计语言。可能并不是将来会用到(应该会用到),更重要的是知识的全面性。C++是个很好的学习方向,适合学过C语言的我平稳过渡。是以,从10月份开始读谭浩强的《C++程序设计》。不过,到今天(2014.1.3),才刚把C语言部分看完。之所以认真的把C语言部分重学一遍,是一种过来人的眼光重新审视已学的东西,看看是否有新的发现。

    的确,新的发现还是有很多的。这些新的发现都是以前的盲点,在这里记录下来,以备将来查询。

第一章 C++的初步知识                                                      

1、C语言的优点

    既具有高级语言的优点,又具有低级语言的许多特点,特别适合于写系统软件。

2、C++产生的背景

    随着软件规模的增大,用C语言编写的程序渐渐显得有些吃力了。因为C程序的设计者必须细致的设计程序的每一个细节,准确的考虑到程序运行的每一时刻发生的事情。这对程序员的要求是很高的,如果面对的是很复杂的问题,程序员往往感到力不从心。当初提出“结构化”程序设计方法的目的是解决软件危机,但是这个目标并没有实现。

    为了解决这个危机,在20世纪80年代提出了面向对象的程序设计(object oriented programming,OOP),C++应运而生。

3、C++对C的增强

    表现在两个方面:

    (1)在原来面向过程的机制基础上,对C语言的功能做了不少扩充

    (2)增加了面向对象的机制

4、如何体会C++的优点

    只有编写过大型程序的人才能真正体会到C的不足和C++的优点。

5、类的特性

    类可以提现数据的封装性和信息隐蔽

6、C++开发工具

    在目前使用的各种C++编译系统中,GCC是最接近C++标准的。

第二章 数据类型与表达式                                                     

1、数据类型

                      |----------短整型(short int)

                                 |--整型 |----------整型(int)

                                 |         |----------长整型(long)

           |----- 类型-----|--字符型(char)

           |                     |           |---------单精度型(float)

           |                     |--浮点型|-------- 双精度型(double)

           |                     |           |---------长双精度型(long double)

           |                     |--布尔型(bool)

           |                     |--空类型(void)

           |

数据类型|                     |----- 枚举型(enum)

           |----非基本类型-|----- 数组类型(type [ ])

           |                     |------结构体类型(struct)

           |                     |------共用体类型(union)

           |                     |------类类型(class)

           |                     |------type *

           |

           |----指针类型 

2、浮点数

    a=3.14159可以写成如下形式:

                                            a=0.314159e1

                                            a=3.14159e0

                                            a=31.4159e-1 

                                            a=314.159e-1 

                                            a=3141.59e-3

    但在内存中都是以指数形式(即浮点形式)存储的。上例中在内存中都是以规范化的指数形式存放,如下表所示(即都是0.3.14159*10^3):

+ .314159 3
数符 数字部分 指数部分

     (1)数字部分<1

     (2)小数点后面第一个数字必须非零

     (3)存储单元分为两部分,一部分用来存放数字部分,一部分用来存放指数部分

     (4)实际上在存储单元中是用二进制数来表示小数部分,用2的幂次来表示指数部分的

     (5)以指数形式表示的数值常量,也都作为双精度常量来处理

3、字符

3.1 转义字符极其含义

字符形式 含义 ASCII
\a 响铃 7
\n 换行,将当前位置移到下一行的开头 10
\t 水平制表(跳到下一个tab位置) 9
\r 回车,将当前位置位置移到本行开头 13
\f 换页,将当前位置移到下页开头 12
\v 竖向跳格 8
\\ 反斜杠字符“\” 92
\' 单引号(撇号)字符 39
\" 双引号字符 34
\0 空字符 0
\ddd 1-3位八进制所代表的的字符  
\xhh 1-2位十六进制数所代表的的字符  
\b 退格,将当前位置移到前一列 8

3.2 字符串常量

    编译系统会自动的给字符串最后添加一个‘\0’作为字符串的结束标志,所以“abc”实际上在内存中占用了4个字节,而不是3个字节。

    如果在一个字符串最后一个字符为“\”,则它表示续行符,下一行的字符是该字符串的一部分,且在两行字符串间无空格。例如:

    cout <<"We must study C\

      ++ hard!";

    则输出:We must study C++ hard!

4 符号常量

    为了编程和阅读的方便,在C++程序设计中,常用一个符号名代表一个常量,称为符号常量,即以标示符形式出现的常量。例如:

     #define PRICE 30

好处:    

        (1)含义清楚

        (2)在需要修改一个常量时能做到“一改全改”

5 变量

(1)如果未对变量赋初值,则该变量的初值是一个不可预测的值

(2)静态存储变量和外部变量(全局变量)的初始化是在编译阶段完成的

6 常变量

    如果在定义变量时,在变量前边加上关键词“const”,则该变量的值在程序运行期间不能更改,这种变量称为常变量。

注意:

(1)在定义常变量是必须同时进行初始化

(2)运行期间不得更改常变量的值

理解:

    从计算机实现的角度,变量的特征是存在一个以变量名命名的存储单元,在一般情况下该单元中的内容是可以变化的。对常变量来说,无非是在此基础上加上一个限定:存储单元中的值不允许变化。因此常变量又称为只读变量(read-only-varialbe)。

用途:

        有时要求变量的值不允许改变(如函数的参数),这时就需要const加以限定。

常变量与常量的区别:

                          常变量是变量,占据存储空间,但是常量是没有这种特征,是变量要存放的数值。

常变量与#define命令定义的符号常量区别:

(1)符号常量只是用一个符号代替一个字符串,它没有类型,在内存中不会占据空间

(2)常变量具有变量特征,在内存中占据以它命名的空间,与一般变量的唯一区别是指定变量的值不能改变

7、数据运算过程中的数据类型转换

    在进行运算时,不同类型的数据要先转换成同一类型,然后才能进行运算。转换的规则按照下图:

(1)图中横向的箭头代表必定的转换,如字符数据必定先转换成整数,short型必定转换为int型,float型在运算过程中一律先转换成双精度型,以提高运算精度(即使两个float型数据相加,也都先转换成double型,然后再相加)。

(2)纵向的箭头代表当运算对象为不同类型时转换的方向。例如int型与double型进行运算,先将int型转换为double型,然后两个double型数据进行运算,结果为double型。箭头方向代表级别高低,由低级向高级变换。

一个例子:

            假设i为int型,f为float型,d为double型,e为long型,现进行运算:10+‘a’+i*f-d/e

运算次序:

(1)进行10+‘a’的运算,先将a转化成整数97,运算结果为107

(2)进行i*f的运算,先将i与f都转换成double型,运算结果为double型。

(3)将整数与i*f的积相加。先将107转换成double型,结果为double型。

(4)计算d/e,先将e转换成double型,d/e的运算结果也是double型

(5)将10+‘a’+i*f的结果与d/e的商相减,结果为double型。

注意:上述的类型转换都是系统自动进行的。

8、强制类型转换运算符

形式为:(类型名)(表达式)

注意:如果强制类型转换的对象是变量,可以不用括号括起来。如果对象是一个恶包含多项的表达式,则表达式必须用括号括起来。

C++还增加了形式: 类型名(表达式)

说明:在强制类型转换时,得到一个中间变量,原来变量的类型未发生变化。

9、赋值过程中的类型转换

(1)浮点型数据赋给整型变量,舍弃其小数部分

(2)将整型数据赋给浮点型变量时,数值不变,但以指数形式存储到变量中

(3)讲一个double型数据赋给float变量时,要注意数值范围不能溢出

(4)字符型数据赋给整型变量时,将字符的ASCII码赋给整型变量

(5)将一个int、short、long型赋给char型变量时,只将其低8位原封不动地送到char型变量(发生截断)。

(6)将signed型数据赋给unsigned型变量,将存储单元内容原样照搬(连原有的符号位也作为数值一起传送)。

增加说明 :不同类型的整型数据赋值归根结底就是按存储单元中的存储形式直接传送。

第三章 程序设计初步                                                           

1、算法的概念

    广义的说,为解决一个问题而采取的方法和步骤,就称为算法

    一个面向过程的程序包含两方面的内容:

                                                     (1)对数据的描述,即数据结构

                                                     (2)对操作的描述,也就是算法

    程序=算法+数据结构,程序设计人员必须要认真考虑和设计数据结构和操作步骤(算法)。

2、算法的分类

(1)数值算法

    目的求数值解,例如方程的根。数值问题的求解有现成的模型,可以运用数值分析方法,因此对于数值算法的研究比较深入,算法比较成熟。对许多数值运算都有比较成熟的算可供选用。    

(2)非数值算法

    应用的面非常广,最常见的是用于事务管理领域,例如图书检索、人事管理、行车调度管理等。非数值问题种类繁多,要求各异,难以规范化,仅对一些典型的非数值问题做比较深入的研究,例如排序。

3、算法的表示

(1)自然语言

(2)流程图

(3) 伪代码

(4)计算机语言表示算法(计算机程序)

4、执行语句

(1)控制语句

if-else 条件语句
for 循环语句
while 循环语句
do-while 循环语句
continue 结束本次循环
break 中止执行switch或while循环语句
switch 多分支选择语句
goto 转向语句
return 从函数返回语句

(2)函数和流对象调用语句,例如

    sort(x,y,z);

    cout <<x <<endl;

(3)表达式语句

    i=i+1 //表达式

    i=i+1; //表达式语句

5、复合语句

    可以用{}把一些语句括起来成为复合语句,例如。

    {

       z=x+y;

       if(z>100) z=z-100;

       cout <<z;

     }

   复合语句中也可以定义变量,但是变量的有效区域只在复合语句中。

    M:以花括号括起来的语句都可看做复合语句。

6、C++的输入与输出

    C语言通过scanf函数和printf,实现输入与输出。

    C++通过调用输入输出流库中的流对象cin和cout实现的。输入输出不是C++本身提供的,而是I/O库中定义的。

(1)在cout输出时,用户不必通知计算机按何种类型输出,系统会自动判别输出数据的类型,使输出的数据按相应的类型输出。

(2)cin从输入流中提取字符时,把空格作为数据间的分隔符,不予提取;而提取非空格的能打印的字符。

(3)不能用cin语句把空格字符和回车字符作为字符输入给字符变量,它们将被跳过。如果想将空格字符或回车换行符(或任何其他键盘上的字符)输入给字符变量,可以用getchar函数。

(4)从终端键盘向计算机输入时,是在按Enter键以后才送到内存缓冲区中的。

7、逻辑常量和逻辑变量

(1)C语言没有提供逻辑型数据,关系表达式的值(真或假)分别用数值1和0代表。

(2)C++增加了逻辑型数据,用关键字bool来定义,称为布尔变量,它的值只有两个false和true(都是逻辑常量)。

(3)编译系统在处理逻辑数据时,将false处理为0,将true处理为1,而不是将两个英文单词存放到内存单元中,逻辑变量在内存中占据1个字节用来存放0或1。

8、break语句和continue语句

(1)break语句从循环体内跳出循环体,即提前结束循环。只能用于循环语句和switch语句,不能单独使用或者用于其他语句。

(2)结束本次循环,并不是结束整个循环的运行。

第四章 函数与预处理                                                           

1、函数类型

    在C语言中规定,如果在定义函数时不指定函数类型,系统会隐含指定函数类型为int型。因此,int max(int x,int y)可以简写为max(int x,int y)。但C++取消了这一规定,这样在定义函数时必须指定函数的类型,这样做更加严格和安全。

2、形式参数

    在定义函数时指定的形参,并不会占据内存空间。只有在发生函数调用时,函数max中的形参才被分配内存单元,以便接收从实参传来的数据。在调用结束后,形参所占的内存单元也被释放。

3、参数传递

    实参变量对形参变量的数据传递是值传递,即单向传递。例如:

  函数定义: void change(int *p);

  使用函数:  {int *n;

                    change(n);

                   }

    这里p的指向改变了,并不会改变n的指向,因为p只是继承了n的值,整个过程是单向传递。

4、函数定义与函数声明

    函数的定义则是对函数功能的确立,包括指定函数名、函数类型、形参及其类型、函数体等。

    函数声明的作用是把函数的名字、函数类型以及形参的个数、类型和顺序(不包括函数体)通知编译系统,以便在对包含函数调用的语句进行编译时,据此对其进行对照检查。

5、函数原型    

    函数声明时可以不写形参名,而只写形参的类型,如float add(float,float);这种声明形式称为函数原型(function prototype)。

6、内联函数

6.1 定义

    在编译时将所调用的函数的代码直接嵌入到主调函数中,而不是将流程转出去。这种嵌入到主调函数中的函数称为内联函数(inline function)。

6.2 特点

    使用内联函数其实就相当于宏的作用,以空间换时间。

6.3 用法

    一般用到程序规模很小(一般5个语句以下),而使用频繁的函数(如定时采集数据的函数)。因为函数调用的时间开销可能相当于甚至超过执行函数本身的时间。

    内联函数中不能包括复杂的控制语句,如循环语句和switch语句。

6.4 注意

    对函数作inline声明,只是程序设计者对编译系统提出的一个建议,也就是说它是建议性的,而不是指令性的。并非一经指定为inline,编译系统就必须这样做。编译系统会根据具体情况决定是否这样做。例如,一个1000行的函数,编译系统不大可能在调用点展开,此时编译系统忽略inline的声明,而按普通函数处理。

7、函数的重载(C++特有)

7.1 定义

    同一类的功能,只是细节稍有不同。C++允许用同意函数名定义多个函数,这些函数的参数个数和参数类型不同,这就是函数的重载。例如:

        int max(int a,int b,int c);

        double max(double a,doubleb,double c);

        long max(long a,long b,long c);

        int max(int a,int b);

    也就是说重载函数并不要求函数体相同,除了允许参数类型不同以外,还允许参数的个数不同。

7.2 认识

    函数重载的引入,只是为了便于编程者分析阅读程序,实质上连接过程不变,也就是说上例中的实际上还是四个不同的函数,只是在编程时用了相同的名字。其实,这增加了编译器的负担。

7.3 使用原则

    同名函数的功能应当相同或者

8、函数模板

    函数模板比函数重载更方便,程序更简洁。但应注意它只适用于函数体相同、函数的参数个数相同而类型不同的情况。如果参数的个数不同,则不能用函数模板。

9、函数的递归调用

    在调用一个函数的过程中,又出现直接的或间接的调用该函数本身,称为函数的递归调用。包含递归调用的函数称为递归函数。

10、局部变量

(1)可以在一个函数内的复合语句中定义变量,这些变量只在本复合语句中有效。这种复合语句也称为分程序或程序块

(2)形式参数也是局部变量

11、全局变量

(1)如果在同一个源文件中,全局变量与局部变量同名,则在局部变量的作用范围内,全局变量被屏蔽,即它不起作用。

(2)建议不在必要时不要使用全局变量,原因:

    1> 程序整个运行期间,它都占据内存空间

    2> 它使函数的通用性降低了。在程序设计中划分模块时要求模块内聚性强,与其他模块的耦合性弱。

         一般要求把程序中的函数做成一个封闭体,除了通过“实参--形参”的渠道与外界发生关系,没有其他渠道。这样的程序移植性好,可读性强。

    3> 使用全局变量过多,会降低程序的清晰性。人们往往很难清除判断出每个瞬间各个全局变量的值。

12、变量的存储方式(动态存储和静态存储)

程序区
静态存储区
动态存储区

(1)全局变量全部存放在静态存储区中,在程序开始执行时给全局变量分配存储单元,程序执行完毕就释放这些空间。在程序执行过程中它们占据固定的存储空间,而不是动态的进行分配和释放。

(2)在动态存储区中存放的是函数的形式参数、函数中的自动变量(未加static)、函数调用时的现场保护和返回地址等。在函数调用开始时分配动态存储空间,函数结束时释放这些空间。在程序执行过程中,这种分配和释放是动态的,如果在一个程序中两次调用同一函数,则要进行两次分配和释放,而两次分配给此函数的局部变量的地址可能是不相同的。

13、用static声明的静态外部变量

(1)有时在程序设计中希望某些局部变量只限于本文件中引用,而不能被其他文件引用。可以在定义外部变量时添加一个static声明。

(2) 假设两个文件都用static声明了相同名字的外部变量,则这两个变量被视为不同的全局变量。

(3)在程序设计中,常由若干人完成各个模块,个人可以独立的在其设计的文件中使用相同的全局变量名而互不想干。只需要在每个文件的全局变量前加上static即可。这就为程序的模块化、通用性提供了方便。

(4)如果已知到其他文件不需要引用本文件的全局变量,可以对本文件的全局变量加上static,以免被其他文件误用。

14、变量的声明(引用性声明)和定义(定义性声明)

    变量的定义时需要开辟内存空间的,而不需要建立存储空间的声明称为声明。

15、预处理命令

    C++提供三种预处理功能:宏定义、文件包含、条件编译

16、“文件包含”处理

假设file1.cpp中有命令:#include “file2.cpp”

处理方法:将flie2.cpp文件中的内容拷贝并插入到#include “file2.cpp”命令行处。在进行编译时,将经过预处理得到的file1.cpp为一个源文件单位进行编译。

注意:

(1)被包含的文件经过修改后,凡包含此文件的所有文件都要全部重新编译

17、头文件的内容

通常是以下内容:

(1)对类型的声明

(2)函数声明,特别说明的是函数的定义是不放在头文件中的

(3)内置函数的定义

(4)宏定义

(5)全局变量的定义

(6)外部变量的声明

(7)还可以根据需要包含其他头文件

    头文件是源文件之间的接口。

    有时被包含的文件不一定在系统目录中,需要用双撇号中指出文件路径和文件名,如#include “C:\tan\C++\file1.c”

18、条件编译

条件编译的三种形式:

(1)#ifdef 标示符 //只要标示符被定义过就行了,不必要对表示符赋值

       程序段1

       #else

       程序段2

       #endif

(2)#ifndef 标示符

       程序段1

       #else

       程序段2

       #endif

(3)#if 表达式

       程序段1

       #else

       程序段2

       #endif 

第五章 数组                                                                        

1、数组的概念

    数组是有序数据的集合。

2、内存分布

    数组在内存中占据一片连续的存储空间。

3、怎样看二维数组

    可以把二维数组看作是一种特殊的一维数组,它的元素又是一个一维数组。例如:a[3][4],可以把a看做一个一维数组,a[0]、a[1]、a[2]是3个一维数组的名字。

       |a[0]-------------a[0][0] a[0][1] a[0][2] a[0][3]

    a |a[1]-------------a[1][0] a[1][1] a[1][2] a[1][3]

       |a[2]-------------a[2][0] a[2][1] a[2][2] a[2][3]

    C++中,二维数组中元素排列的顺序是:按行存放,即在内存中先顺序存放第一行的元素,再存放第二行的元素。上例的数组在内存中存放的顺序就是右边的排列图从左到右、从上到下的顺序。

4、数组名当实参和形参

    数组名当实参和形参时,传递的是数组的起始地址。这时,实参数组和形参数组共占同一段内存单元。例如,void select_sort(int array[],int n)。

5、用多维数组名作函数参数

    形参数组声明时,必须指定第二维的大小;形参数组的第一维可以与实参数组不同,因为系统不检查第一维的大小。

6、字符数组

    不能对字符数组整体赋值,而只能对字符数组的单个元素赋值。

7、字符串

    对一个字符串常量,系统会自动在所有字符的后面加一个‘\0’作为结束符。有了结束标志'\0'之后,字符数组的长度就显得不那么重要了。

    字符数组并不要求它的最后一个有效字符后边还有一个'\0'。例如: char str[]={'I',' ','a','m',' ','h','a','p','p','y'}。

注意:要保证字符数组长度始终大于字符串实际长度 。

    char str[] = "I am happy";   <===================>   char str[]={'I',' ','a','m',' ','h','a','p','p','y','\0'}

    数组str的长度不是10,而是11(因为字符串常量的最后由系统加上一个‘\0’)。

8、字符数组存储字符串时注意的问题

    从键盘输入的字符串应短于已定义的字符数组的长度,否则会出现问题。因为有可能超过待保存输入字符数据长度的多余输入会保存到其他数组中,引起无法估计的后果。

9、字符串处理函数

(1)字符串连接函数

strcat(char [] ,const char [])

(2)字符串复制函数

strcpy(char [] ,const char[])

(3)字符串比较函数

strcmp(const char[],const char[])

(4)字符串长度函数

strlen(const char[])  计算时不包括‘\0’

10、C++字符串类(string)与字符串常量

(1)使用时要加上头文件 #include <string>

(2)在定义字符串变量时不需要指定长度,它的长度随其中的字符串长度而改变。

(3)字符串常量以‘\0’作为结束符,但字符串常量存放到字符串变量中时,只存放字符串本身而不包括'\0'。

11、字符串变量的运算

    字符串变量的运算和int等类型一样,不需要专用的函数。

(1)字符串复制用赋值号 例如:string1=string2;

(2)字符串连接用加号 例如:string = string1+string2;

(3)字符串比较直接用关系运算符

12、字符串数组

     string name[5] = {"Zhang","Li","Fun","Wang"}

(1)并不要求每个字符串元素具有相同的长度

(2)每一个字符串元素中只包含字符串本身的字符,而不包含‘\0’。

13、字符串变量的存储

    编译系统为每一字符串变量分配固定长度的单元(Visual C++ 为16个字节,Gcc为4个字节),在这个存储单元中,并不是直接存放字符串本身,而是存放字符串的地址。在上例中,就是把字符串"zhang"的地址存放在name[0],把字符串“Li”的地址存放子name[1]······。

第六章指针                                                                        

1、指针与指针变量

(1)一个变量的地址称为该变量的地址

(2)一个变量专门用来存放另一个变量的地址(即指针)的,则它称为指针变量。

(3)变量的指针就是变量的地址。用来存放变量地址的变量就是指针变量。

(4)定义指针变量  基类型 *指针变量名

2、使用指针时注意的问题

(1)引用没有初始化指针的指向地址内容是危险的

(2)调用形参含有指针变量的函数,并不会改变实参指针变量的值,但可以改变实参指针变量所指向变量的值。

3、数组与指针

      int a[10]

(1)数组名代表数组中第一个元素的地址

(2)指针变量引用数组的元素 

        int *p = a

        p[9] <=============> *(p+9)

       下标法                                  指针法

(3)*p++ 先输出*p的值,然后使p值加1(p指向下一个元素)

(4)用数组名做函数的实参,传递的是数组首元素的地址;形参中的数组名一律作为指针变量来处理。

4、多维数组与指针

    int a[2][3]

(1)a[0]是数组(a[0])[3](一维)首元素的地址,即a[0] = &a[0][0]

(2)a是一维数组a[2]的首元素(a[0])的地址,即a = &a[0],所以a是指针的指针

(3)a 、a[0]、&a[0][0]的值都一样

5、字符串与指针

    char * str =  "I love CHINA!";

   实际上是把字符串第1个元素的地址赋给str。

6、指针运算总结

(1)一个指针变量加/减一个整数是将该指针变量的原值(是一个地址)和它指向的变量所占用的内存字节数相加或相减

(2)指针变量可以有空值(#define NULL 0)

(3)两个指针变量可以相减,如果两个指针指向同一个数组的元素,则两个指针变量之差是两个指针之间的元素值

(4)两个指针变量的比较 若两个指针指向同一个数组的元素,则可以进行比较。指向前面的元素的指针变量小于后面元素的指针变量。

7、引用

7.1 概念

    引用的作用是为变量起一个别名。

    int a;

    int &b = a;

    引用不是一种独立的数据类型,必须指定其代表某一类型的实体(如变量、类对象),不能定义引用数组,不能定义引用的指针。

7.2 引用作为函数参数

(1)值形参

    采用值传递的方式。

(2)变量形参

    采用地址传递方式,传送的是变量的地址而不是变量的值,使形参变量与实参变量具有同一地址。

 (3)优点

    引用变量主要用作函数的参数,它可以提高效率,同时保持程序良好的可读性。 

    c++之所以增加引用机制,主要是把它作为函数参数,易扩展函数传递数据的功能。在C语言中,只有“值形参”,而无“变量形参”。C++把引用型作为函数形参,就弥补了这个不足。

第七章 自定义数据类型                                                        

1、自定义数据类型

                    |结构体类型

自定义数据类型|共用体类型

                    |枚举类型

                    |类类型

2、C++与C在定义结构体变量时的区别

    假设已定义了一个结构体类型Student,

C++用法:Student student1,student2

C用法:struct Student student1,student2

3、结构体变量的定义

    结构体中的成员名可以与程序中的变量名相同,但二者没有关系。

4、结构体变量的引用

(1)可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量。例如:

       student1 = student2;

(2)引用结构体变量中的成员的一般方式为: 结构体变量名.成员名

(3)可以引用结构体结构体变量成员的地址,也可以引用结构体变量的地址

5、指向结构体变量的指针

(1)引用指向的结构体变量的成员的方式:

       1> (*p).成员名

       2> p->成员名 只适用于结构体指针变量

(2)动态链表

    结点并没有变量名,只能先找到上一个结点,才能根据下一个结点的地址找到下一个结点。只有提供第一个结点的地址,即头指针head。

6、new与delete

    new与malloc对应

    delete与free对应

7、共用体

(1)概念

    使几个不同的变量共占同一段内存的结构,称为共用体。

(2)特点

    1> 共用体变量所占的内存长度等于最长成员的长度。

    2> 在每一瞬间只能存放其中一种

    3> 能够访问的是共用体变量中的最后一次被赋值的成员

    4> 共用体变量的地址和它的各个成员的地址都是相同的

    5> 不能对共用体变量名赋值,不能企图引用变量名来得到一个值,不能在定义共用体时对它初始化;不能用共用体变量名作为函数参数。

(3)对共用体变量的访问方式

    例如:a.ch

8、枚举类型

(1)声明方式

    enum 枚举类型名 {枚举常量表列}

(2)枚举元素作为常量,它们是有值的,C++编译按定义时的顺序对它们赋值为0、1、2、3......

(3)一个整数不能直接赋给一个枚举变量

    不用枚举变量也可以完成程序的编写。但是,倘若能够用枚举变量,则程序会变得更加直观,而且枚举变量的值被限制在定义时规定的几个枚举范围内,如果赋予它一个其他的值,就会出现错误信息,便于检查。

9、typedef

    typedef声明一个新类型名来代替已有的类型名。

(1) 定义方法

  1> 先按定义变量的方法写出定义语句

  2> 将变量名换成新类型名

  3> 在最前面加typedef

  4> 然后可以用新类型名去定义变量

   再以声明数组类型为例来说明:

  1> int n[100]

  2> int NUM[100]

  3> typedef int NUM[100]

  4> NUM n;

(2) 习惯上用大写字母表示typedef声明的类型,以便于系统的标准类型标示符相区别

(3)用typedef只是对已经存在的类型新增一个类型名,而没有创造新的类型。

(4)使用typedef有利于程序的通用和移植。

 

推荐阅读