谭浩强版C++笔记Word文件下载.docx

上传人:b****6 文档编号:17022730 上传时间:2022-11-27 格式:DOCX 页数:111 大小:172.93KB
下载 相关 举报
谭浩强版C++笔记Word文件下载.docx_第1页
第1页 / 共111页
谭浩强版C++笔记Word文件下载.docx_第2页
第2页 / 共111页
谭浩强版C++笔记Word文件下载.docx_第3页
第3页 / 共111页
谭浩强版C++笔记Word文件下载.docx_第4页
第4页 / 共111页
谭浩强版C++笔记Word文件下载.docx_第5页
第5页 / 共111页
点击查看更多>>
下载资源
资源描述

谭浩强版C++笔记Word文件下载.docx

《谭浩强版C++笔记Word文件下载.docx》由会员分享,可在线阅读,更多相关《谭浩强版C++笔记Word文件下载.docx(111页珍藏版)》请在冰豆网上搜索。

谭浩强版C++笔记Word文件下载.docx

endl;

则会输出:

abc\,然后换行。

同理执行cout<

″Isay\″Thankyou!

\″\n″;

的输出是:

Isay″Thankyou!

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

如cout<

″WemuststudyC\//本行最后的“\”后面的空格和换行均不起作用

++hard!

″;

//本行的字符紧连在上一行最后的“\”前面字符之后

则输出:

WemuststudyC++hard!

8、在国外软件开发工作中,常习惯在变量前面加一个字母以表示该变量的类型,如iCount表示这是一个整型变量,cSex表示这是一个字符型变量。

9、如果对变量未赋初值,则该变量的初值是一个不可预测的值(静态变量如果不赋初值则系统自动赋初值0)

10、初始化不是在编译阶段完成的(只有静态存储变量和外部变量的初始化是在编译阶段完成的),而是在程序运行时执行本函数时赋予初值的,相当于执行一个赋值语句。

11、在定义常变量时必须同时对它初始化(即指定其值),此后它的值不能再改变。

不能写成这种形式:

constinta;

a=3;

要写constinta=3;

12、请区别用#define命令定义的符号常量和用const定义的常变量。

符号常量只是用一个符号代替一个字符串,在预编译时把所有符号常量替换为所指定的字符串,它没有类型,在内存中并不存在以符号常量命名的存储单元。

而常变量具有变量的特征,它具有类型,在内存中存在着以它命名的存储单元,可以用sizeof运算符测出其长度。

与一般变量惟一的不同是指定变量的值不能改变。

13、需要说明,两个整数相除的结果为整数,如5/3的结果值为1,舍去小数部分。

但是,如果除数或被除数中有一个为负值,则舍入的方向是不固定的。

例如,-5/3在有的C++系统上得到结果-1,有的C++系统则给出结果-2。

多数编译系统采取“向零取整”的方法,即5/3的值等于1,-5/3的值等于-1,取整后向零靠拢。

14、逗号表达式的求解过程是:

先求解表达式1,再求解表达式2。

整个逗号表达式的值是表达式2的值。

如,逗号表达式a=3*5,a*4,逗号运算符是所有运算符中级别最低的。

第3章

1、输入和输出并不是C++语言中的正式组成成分。

C和C++本身都没有为输入和输出提供专门的语句结构。

输入输出不是由C++本身定义的,而是在编译系统提供的I/O库中定义的。

2、优先级相同(高):

<

、<

=、>

、>

=优先级相同(低):

==、!

=

关系运算符的优先级低于算术运算符。

关系运算符的优先级高于赋值运算符。

3、C++增加了逻辑型数据。

逻辑型常量只有两个,即false(假)和true(真)。

在编译系统处理逻辑型数据时,将false处理为0,将true处理为1。

因此,逻辑型数据可以与数值型数据进行算术运算。

4、逻辑运算符中的“&

&

”和“||”低于关系运算符,“!

”高于算术运算符。

“!

”>

算数运算>

“&

”、“||”

第4章

1、调用函数时需要一定的时间和空间的开销。

C++提供一种提高效率的方法,即在编译时将所调用函数的代码直接嵌入到主调函数中,而不是将流程转出去。

这种嵌入到主调函数中的函数称为内置函数(inlinefunction),又称内嵌函数。

在有些书中把它译成内联函数。

指定内置函数的方法很简单,只需在函数首行的左端加一个关键字inline即可。

inlineintmax(int,int,int);

可以在声明函数和定义函数时同时写inline,也可以只在其中一处声明inline,效果相同,都能按内置函数处理。

使用内置函数可以节省运行时间,但却增加了目标程序的长度。

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

应当说明:

对函数作inline声明,只是程序设计者对编译系统提出的一个建议,也就是说它是建议性的,而不是指令性的。

并非一经指定为inline,编译系统就必须这样做。

编译系统会根据具体情况决定是否这样做。

归纳起来,只有那些规模较小而又被频繁调用的简单函数,才适合于声明为inline函数。

2、C++允许用同一函数名定义多个函数,这些函数的参数个数和参数类型不同。

这就是函数的重载。

重载函数除了允许参数类型不同以外,还允许参数的个数不同。

3、所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。

这个通用函数就称为函数模板。

凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。

在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。

#include<

iostream>

usingnamespacestd;

template<

typenameT>

//模板声明,其中T为类型参数

Tmax(Ta,Tb,Tc)//定义一个通用函数,用T作虚拟的

类型名

{if(b>

a)a=b;

if(c>

a)a=c;

returna;

}

intmain()

{inti1=185,i2=-76,i3=567,i;

doubled1=56.87,d2=90.23,d3=-3214.78,d;

longg1=67854,g2=-912456,g3=673456,g;

i=max(i1,i2,i3);

//调用模板函数,此时T被int取代

d=max(d1,d2,d3);

//调用模板函数,此时T被double

取代

g=max(g1,g2,g3);

//调用模板函数,此时T被long取代

cout<

″i_max=″<

i<

″f_max=″<

f<

″g_max=″<

g<

return0;

}

程序第3~8行是定义模板。

定义函数模板的一般形式为template<

typenameT>

或template<

classT>

在建立函数模板时,只要将例4.5程序中定义的第一个函数首部的int改为T即可。

即用虚拟的类型名T代替具体的数据类型。

在对程序进行编译时,遇到第13行调用函数max(i1,i2,i3),编译系统会将函数名max与模板max相匹配,将实参的类型取代了函数模板中的虚拟类型T。

此时相当于已定义了一个函数:

intmax(inta,intb,intc)

然后调用它。

后面两行(14,15行)的情况类似。

类型参数可以不只一个,可以根据需要确定个数。

如template<

classT1,typenameT2>

可以看到,用函数模板比函数重载更方便,程序更简洁。

但应注意它只适用于函数的参数个数相同而类型不同,且函数体相同的情况,如果参数的个数不同,则不能用函数模板。

4、一个函数不能既作为重载函数,又作为有默认参数的函数。

因为当调用函数时如果少写一个参数,系统无法判定是利用重载函数还是利用默认参数的函数,出现二义性,系统无法执行。

5、递归调用:

程序中不应出现这种无终止的递归调用,而只应出现有限次数的、有终止的递归调用,这可以用if语句来控制,只有在某一条件成立时才继续执行递归调用,否则就不再继续。

intage(int);

//函数声明

intmain()//主函数

{cout<

age(5)<

}

intage(intn)//求年龄的递归函数

{intc;

//用c作为存放年龄的变量

if(n==1)c=10;

//当n=1时,年龄为10

elsec=age(n-1)+2;

//当n>1时,此人年龄是他前一个

人的年龄加2

returnc;

//将年龄值带回主函数

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

6、在C++中变量除了有数据类型的属性之外,还有存储类别(storageclass)的属性。

存储类别指的是数据在内存中存储的方法。

存储方法分为静态存储和动态存储两大类。

具体包含4种:

自动的(auto)、静态的(static)、寄存器的(register)和外部的(extern)。

为静态局部变量赋初值是在编译时进行值的,即只赋初值一次,在程序运行时它已有初值。

以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。

而为自动变量赋初值,是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。

如果在定义局部变量时不赋初值的话,对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符型变量)。

而对自动变量来说,如果不赋初值,则它的值是一个不确定的值。

虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的,也就是说,在其他函数中它是“不可见”的。

static声明使变量采用静态存储方式,但它对局部变量和全局变量所起的作用不同。

对局部变量来说,static使变量由动态存储方式改变为静态存储方式。

而对全局变量来说,它使变量局部化(局部于本文件),但仍为静态存储方式。

从作用域角度看,凡有static声明的,其作用域都是局限的,或者局限于本函数内(静态局部变量),或者局限于本文件内(静态外部变量)。

7、在多文件的程序中声明外部变量:

如果一个程序包含两个文件,在两个文件中都要用到同一个外部变量num,不能分别在两个文件中各自定义一个外部变量num。

正确的做法是:

在任一个文件中定义外部变量num,而在另一文件中用extern对num作外部变量声明。

即externintnum;

编译系统由此知道num是一个已在别处定义的外部变量,它先在本文件中找有无外部变量num,如果有,则将其作用域扩展到本行开始,如果本文件中无此外部变量,则在程序连接时从其他文件中找有无外部变量num,如果有,则把在另一文件中定义的外部变量num的作用域扩展到本文件,在本文件中可以合法地引用该外部变量num。

file1.cppfile2.cpp

externinta,b;

inta=3,b=4;

intmain()┆

{cout<

a<

″,″<

b<

extern只能用来声明已定义的外部变量,而不能用于变量的定义。

只要看到extern,就可以判定这是变量声明,而不是定义变量的语句。

8、有时在程序设计中希望某些外部变量只限于被本文件引用,而不能被其他文件引用。

这时可以在定义外部变量时加一个static声明。

不要误认为用static声明的外部变量才采用静态存储方式(存放在静态存储区中),而不加static的是动态存储(存放在动态存储区)。

实际上,两种形式的外部变量都用静态存储方式,只是作用范围不同而已,都是在编译时分配内存的。

(全局变量静态存储)

9、如果一个函数只能被本文件中其他函数所调用,它称为内部函数。

在定义内部函数时,在函数名和函数类型的前面加static。

函数首部的一般格式为static类型标识符函数名(形参表)如staticintfun(inta,intb)

内部函数又称静态(static)函数。

使用内部函数,可以使函数只局限于所在文件。

如果在不同的文件中有同名的内部函数,互不干扰。

通常把只能由同一文件使用的函数和外部变量放在一个文件中,在它们前面都冠以static使之局部化,其他文件不能引用

10、在定义函数时,如果在函数首部的最左端冠以关键字extern,则表示此函数是外部函数,可供其他文件调用。

如函数首部可以写为externintfun(inta,intb)

这样,函数fun就可以为其他文件调用。

如果在定义函数时省略extern,则默认为外部函数。

本书前面所用的函数都是外部函数。

然后在需要调用此函数的文件中,用extern声明所用的函数是外部函数。

11、例4.16在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。

可以在源程序中插入条件编译段。

下面是一个简单的示例。

(选择编译)

#defineRUN//在调试程序时使之成为注释行

{intx=1,y=2,z=3;

#ifndefRUN//本行为条件编译命令

″x=″<

x<

″,y=″<

y<

″,z=″<

z;

//在调试程序时需要输出这些信息

#endif//本行为条件编译命令

″x*y*z=″*y*z<

第5章数组

1、如果用二维数组名作为实参和形参,在对形参数组声明时,必须指定第二维(即列)的大小,且应与实参的第二维的大小相同。

第一维的大小可以指定,也可以不指定。

2、用一个字符数组可以存放一个字符串中的字符。

如charstr[12]={′I′,′′,′a′,′m′,′′,′h′,′a′,′p′,′p′,′y′};

用一维字符数组str来存放一个字符串″Iamhappy″中的字符。

字符串的实际长度(10)与数组长度(12)不相等,在存放上面10个字符之外,系统对字符数组最后两元素自动填补空字符′\0′。

字符串″Iamhappy″共有10个字符,但在内存中它共占11个字节,最后一个字节′\0′是由系统自动加上的。

将整个字符串一次输入或输出。

例如有以下程序段:

charstr[20];

cin>

str;

//用字符数组名输入字符串

//用字符数组名输出字符串

在运行时输入一个字符串,如

China↙

3、字符串连接函数strcat其函数原型为strcat(char[],constchar[]);

(注意里面是char型)

strcat是stringcatenate(字符串连接)的缩写。

该函数有两个字符数组的参数,函数的作用是:

将第二个字符数组中的字符串连接到前面字符数组的字符串的后面。

第二个字符数组被指定为const,以保证该数组中的内容不会在函数调用期间修改。

连接后的字符串放在第一个字符数组中,函数调用后得到的函数值,就是第一个字符数组的地址。

例如

charstr1[30]=″People′sRepublicof″;

charstr2[]=″China″;

strcat(str1,str2));

输出:

People′sRepublicofChina

4、字符串复制函数strcpy其函数原型为strcpy(char[],constchar[]);

strcpy是stringcopy(字符串复制)的缩写。

它的作用是将第二个字符数组中的字符串复制到第一个字符数组中去,将第一个字符数组中的相应字符覆盖。

charstr1[10],str2[]=″China″;

strcpy(str1,str2);

执行后,str2中的5个字符″China″和′\0′(共6个字符)复制到数组str1中。

说明:

(1)在调用strcpy函数时,第一个参数必须是数组名(如str1),第二个参数可以是字符数组名,也可以是一个字符串常量。

(2)可以用strcpy函数将一个字符串中前若干个字符复制到字符数组中去。

(3)只能通过调用strcpy函数来实现将一个字符串赋给一个字符数组,而不能用语句将一个字符串常量或字符数组直接赋给一个字赋值符数组。

5、字符串长度函数strlen函数原型为strlen(constchar[]);

6、C++提供了一种新的数据类型——字符串类型(string类型),在使用方法上,它和char、int类型一样,可以用来定义变量,这就是字符串变量——用一个名字代表一个字符序列。

string>

//注意头文件名不是string.h

也可以用一个字符串变量给另一个字符串变量赋值。

如string2=string1;

不要求string2和string1长度相同,假如string2原来是″China″,string1原来是″Canada″,赋值后string2也变成″Canada″。

字符串连接用加号

stringstring1=″C++″;

//定义string1并赋初值

stringstring2=″Language″;

//定义string2并赋初值

string1=string1+string2;

//连接string1和string2

不仅可以用string定义字符串变量,也可以用string定义字符串数组。

stringname[5];

//定义一个字符串数组,它包含5个字符串元素

stringname[5]={″Zhang″,″Li″,″Fun″,″Wang″,″Tan″};

//定义一个字符串数组并初始化

第6章指针

1、在程序中一般是通过变量名来对内存单元进行存取操作的。

其实程序经过编译以后已经将变量名转换为变量的地址,对变量值的存取都是通过地址进行的。

这种按变量地址存取变量值的方式称为直接存取方式,或直接访问方式。

2、一般的C++编译系统为每一个指针变量分配4个字节的存储单元,用来存放变量的地址。

在定义指针变量时要注意:

(1)不能用一个整数给一个指针变量赋初值。

(2)在定义指针变量时必须指定基类型。

3、在用指针变量指向数组元素时要注意:

指针变量p可以指向有效的数组元素,实际上也可以指向数组以后的内存单元。

如果有

inta[10],*p=a;

//指针变量p的初值为&

a[0]

*(p+10);

//要输出a[10]的值

4、*p++。

由于++和*同优先级,结合方向为自右而左,因此它等价于*(p++)。

作用是:

先得到p指向的变量的值(即*p),然后再使p的值加1。

(*p)++表示p所指向的元素值加1,即(a[0])++,如果a[0]=3,则(a[0])++的值为4。

是元素值加1,而不是指针值加1。

*(p++)与*(++p)作用不同。

前者是先取*p值,再使p加1。

后者是先使p加1,再取*p。

若p的初值为a(即&

a[0]),输出*(p++)得到a[0]的值,而输出*(++p)则得到a[1]的值。

5、inta[3][4]={{1,3,5,7},{9,11,13,15},{17,18,21,23}};

a是一个数组名。

a数组包含3行,即3个元素:

a[0],a[1],a[2]。

而每一元素又是一个一维数组,它包含4个元素(即4个列元素),例如,a[0]所代表的一维数组又包含4个元素:

a[0][0],a[0][1],a[0][2],a[0][3]。

可以认为二维数组是“数组的数组”,即数组a是由3个一维数组所组成的。

从二维数组的角度来看,a代表二维数组首元素的地址,现在的首元素不是一个整型变量,而是由4个整型元素所组成的一维数组,因此a代表的是首行的起始地址(即第0行的起始地址,&

a[0]),a+1代表a[1]行的首地址,即&

a[1]。

a[0],a[1],a[2]既然是一维数组名,而C++又规定了数组名代表数组首元素地址,因此a[0]代表一维数组a[0]中0列元素的地址,即&

a[0][0]。

a[1]的值是&

a[1][0],a[2]的值是&

a[2][0]。

0行1列元素的地址可以直接写为&

a[0][1],也可以用指针法表示。

a[0]为一维数组名,该一维数组中序号为1的元素显然可以用a[0]+1来表示。

欲得到a[0][1]的值,用地址法怎么表示呢?

既然a[0]+1是a[0][1]元素的地址,那么,*(a[0]+1)就是a[0][1]元素的值。

而a[0]又是和*(a+0)无条件等价的,因此也可以用*(*(a+0)+1)表示a[0][1]元素的值。

依此类推,*(a[i]+j)或*(*(a+i)+j)是a[i][j]的值。

6、例6.8输出二维数组任一行任一列元素的值。

{inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

int(*p)[4],i,j;

i>

j;

p=a;

*(*(p+i)+j)<

return0;

由于执行了“p=a”,使p指向a[0]。

因此p+2是二维数组a中序号为2的行的起始地址(由于p是指向一维数组的指针变量,因此p加1,就指向下一个一维数组),见图6.18。

*(p+2)+3是a数组2行3列元素地址。

*(*(p+2)+3)是a[2][3]的值。

7、

(1)指向数组元素的指针变量

例6.7输出二维数组各元素的值

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 军事政治

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1