C++高级参考手册04

合集下载

C语言标准参考手册

C语言标准参考手册
Traditional C 现在只会在一些非常老的代码中才能见到了,除非你在维护旧代 码,否则不应该再使用它。
所以,个人觉得当前还是以 C89(包括 C95)标准为主。
1 引言
本手册描述的 c 语言是 1988 年 10 月 31 日提交给 ANSI 的草案,批准号为“美国 国家信息系统标准―C 程序设计语言,X3.159-1989”。尽管我们已非常小心, 以便这个手册的介绍可以信赖,但它毕竞不是标准本身,而是对标准的一个解释。 这个手册的安排基本与标准相似,也与本书的第 1 版相似,但是对细节的组织是 不同的。本手册给出的语法与标难是一样的,只是有少量产生式有所修改,词法 元素和预处理器的定义也非形式化。注释部分说明了 ANSI 标准 C 与本书第 1 版 介绍的或其他编译器所支持的语言的细微差别。
1.3 C95
这是对 C89 的一个修订和扩充,称为“C89 with Amendment 1”或 C95,严格说 来并不是一个真正的标准。
C95 的主要改动:
• 3 个新标准头文件:iso646.h、wctype.h、wchar.h; • 一些新的标记(token)和宏(macro); • 一些新的 printf/scanf 系列函数的格式符; • 增加了大量的宽字符和多字节字符函数、常数和类型。
• 浮点常量的后缀是新增加的。
2.5.4 枚举常量
定义为枚举符的标识符是 int 类型的常量(见 8.4 节)。
2.6 字符串字面值
字符串字面值也叫字符毒常量,是由双引号括起来的一个字符序列,如"..."。 字符串的类型为“字符数组”,存储类为 static(见 4 节),由给定的字符来初 始化。相同的字符串字面值是否看做是不同的取决于具体的实现。如果程序试图 改变字符串字面值,那么该行为是未定义的。

c++4语言程序设计(第四版

c++4语言程序设计(第四版
38
C++语言程序设计
Point::Point(int xx,int yy) { X=xx; Y=yy; } Point::~Point() { } //...其他函数的实现略

31
C++语言程序设计
构造函数举例
构 造 函 数 和 析 构 函 数
class Clock { public: Clock(int NewH,int NewM,int NewS);//构造函数 void SetTime(int NewH,int NewM,int NewS); void ShowTime(); private: int Hour,Minute,Second; };
18
void Clock::SetTime(int NewH, int NewM, int NewS) { Hour=NewH; Minute=NewM; Second=NewS; } void Clock::ShowTime() { cout<<Hour<<":"<<Minute<<":"<<Second; }
C++语言程序设计
例4-1类的应用举例
类 和 对 象
#include<iostream> using namespace std; class Clock { ......//类的声明略 } //......类的实现略 int main() { Clock myClock; myClock.SetTime(8,30,30); myClock.ShowTime(); }
的 基 本 特 点
边界
10
C++语言程序设计

C语言程序设计教程CJ04预处理命令潭浩强第3版精品PPT课件

C语言程序设计教程CJ04预处理命令潭浩强第3版精品PPT课件
#define PP printf
字符串
说明: 宏名也是字符串。宏名习惯用大写字母表示。 宏展开只是用字符串代替宏名,作简单替换,无语法检查。 宏定义不是C语句。出现在函数外。作用域是从出现点到文件
末。可用 #undef 撤销已定义的宏。格式: #undef 宏名
宏替换可以嵌套定义。 双引号内宏替换失效。 例9.1 9.2:
Page 5
《程序设计》-2005秋
二、带参数的宏替换/宏定义
格式: #define 宏名(形参表) 字符串
例:#define S(M, N) M*N
说明: 带参数的宏定义不是进行简单字符串替换,还要进行参数
替换。形参表列中的参数出现在字符串中。 宏展开只是将程序语句中宏名后括号内的实参代替
#define命令中的形参,并不计算。 宏名与其后括号间不能有空格。 例9.3-9.5:
加工,是C编译系统的组成部分.
预编译命令:
宏定义 “文件包含”处理 条件编译
预编译命令格式: #预处理命令
#define …… #include ……
Page 4不带参数的宏替换/宏定义
格式: #define 宏名
例: #define M 3
格式1: #include <文件名>
只按系统指定的标准方式(从编译系统所在子目录中)检索 文件目录。
格式 2: #include “文件名”
系统首先在当前源文件所在目录中寻找该文件,若找不到, 再按系统指定的标准方式检索其他文件目录。
例:9.6
Page 8
《程序设计》-2005秋
9.3 条件编译
Page 6
《程序设计》-2005秋
带参宏替换
函数调用

C语言标准参考手册

C语言标准参考手册

同时也提供中文版本,内容来自该书对应的中译版“《C 程序设计语言》,徐宝 文等译,机械工业出版社出版,ISBN 7111075897”。
文档仅供个人参考使用(建议以英文版为主):
英文版
中文版
为方便起见,提供一份标点符号中英对照表,希望有用:标点符号中英对照表。
3 C 标准的选择
选择标准依赖于编译器的支持和对可移植性的要求。 C99 是当前的标准,但它仍未得到广泛支持,虽然标准发布已经多年。C99 对 C89(C95)的改动非常大,如果编写 C99 的代码,那么可移植性必然受到限制。此 外,个人认为 C99 的一些新特性在大多数程序设计中并不是必须的。 C89(包括 C95)是目前使用最广泛的,并得到所有主流编译器的支持。
Traቤተ መጻሕፍቲ ባይዱitional C 现在只会在一些非常老的代码中才能见到了,除非你在维护旧代 码,否则不应该再使用它。
所以,个人觉得当前还是以 C89(包括 C95)标准为主。
1 引言
本手册描述的 c 语言是 1988 年 10 月 31 日提交给 ANSI 的草案,批准号为“美国 国家信息系统标准―C 程序设计语言,X3.159-1989”。尽管我们已非常小心, 以便这个手册的介绍可以信赖,但它毕竞不是标准本身,而是对标准的一个解释。 这个手册的安排基本与标准相似,也与本书的第 1 版相似,但是对细节的组织是 不同的。本手册给出的语法与标难是一样的,只是有少量产生式有所修改,词法 元素和预处理器的定义也非形式化。注释部分说明了 ANSI 标准 C 与本书第 1 版 介绍的或其他编译器所支持的语言的细微差别。
2 C 标准文档
2.1 C99
这是一个 pdf 文件:c99.pdf。
2.2 C89

C语言参考手册

C语言参考手册

版权说明:本资料内容摘录自《C程序设计语言(第二版)》K&R著 徐宝文 李志译 尤晋元审校 机械工业出版社出版 一书。

版权属原作者和出版社所有。

制作本资料为了我本人学习和参考,非商业用途。

建议读者阅读原书学习比较好,它更详细。

目录:A.12 预处理主要介绍预处理器的功能和预处理的过程。

A.12.1三字符序列主要介绍 ??=, ??(, ??<等三字符序列。

A.12.2 行连接主要介绍反斜杠\结束的指令行处理过程。

A.12.3 宏定义和扩展主要介绍#define 标识符 记号序列,#define 标识符(标识符表opt) 记号序列,#undef 标识符,还有#和##等一些东西,有一些例子。

A.12.4 文件包含主要介绍#include <文件名>和#include “文件名”指令。

A.12.5 条件编译介绍#if 常量表达式/#ifdef 标识符/#ifndef 标识符,#elif 常量表达式,#else,#endif语句。

A.12.6 行控制介绍#line指令。

A.12.7 错误信息生成介绍#error指令。

A.12.8 pragma介绍#pragma。

A.12.9 空指令介绍空指令#。

A.12.10 预定义名字介绍__LINE__, __FILE__, __DATE__, __TIME__, __STDC__等。

A.12 预处理 返回目录预处理器执行宏替换,条件编译以及包含指定的文件。

以#开头的命令行(“#”前可以有空格)就是预处理器处理的对象。

这些命令行的语法独立于语言的其它部分,他们可以出现在任何地方,其作用可以延续到所在编译单元的末尾(与作用域无关)。

行边界是有实际意义的;每一行都将单独进行分析(有关如何将行连接起来的详细信息参考A.12.2节)。

对预处理器而言,记号可以是任何语言记号,也可以是类似于#include指令(参见A.12.4节)中表示文件名的字符序列。

C++04

C++04

•4.8 有默认参数的函数
•4.9 函数的嵌套调用
12
定义函数的一般形式
定义无参函数的一般形式 定义无参函数的一般形式为
类型标识符 函数名()
{ 声明部分 语句 }
类型标识符 函数名(void) {
声明部分
语句 }
类型标识符指定函数的类型,即函数带回来的值的类型。
13
定义函数的一般形式
定义有参函数的一般形式 定义有参函数的一般形式为
10
概述
从函数的形式看,函数分两类: (1) 无参函数。调用函数时不必给出参数。
(2) 有参函数。在调用函数时,要给出参数。在主调函数和被 调用函数之间有数据传递。
11
函数与预处理
•4.1 概述 •4.2 定义函数的一般形式
•4.3 函数参数和函数的值
•4.4 函数的调用 •4.5 内置函数 •4.6 函数的重载 •4.7 函数模板
续上页 int main( ) { int a,b,c; cout<<“please enter two integer numbers:”;
cin>>a>>b;
c=max(a,b); //调用max函数,实参为a,b。 cout<<″max=″<<c<<endl;
return 0;
}
SX04-2
19
cin>>a>>b;
c=add(a,b); cout<<″sum=″<<c<<endl; 接下页
SX04-3
31
函数的调用
续上页 float add(float x,float y) //定义add函数 { float z;

C语言入门经典(第四版)4-循环

C语言入门经典(第四版)4-循环

C入门经典(第4版) 入门经典(
4.6.6 再谈循环控制选项
前面介绍了如何用++和 前面介绍了如何用++和– –运算符递增或递减循环计数器.可以对循环计 数器递增或递减任意数值.
C入门经典(第4版) 入门经典(
4.6.7 浮点类型的循环控制变量
循环控制变量也可以是一个浮点类型的变量.下面的循环汇总从1/1~1/10 循环控制变量也可以是一个浮点类型的变量.下面的循环汇总从1/1~1/10 的分数: double sum = 0.0; for(double x = 1.0 ; x<11 ; x += 1.0) sum += 1.0/x;
C入门经典(第4版) 入门经典(
4.5.3 递减运算符
递减运算符的操作和递增运算符完全相同.它的形式是– 递减运算符的操作和递增运算符完全相同.它的形式是– – ,作用是给它 操作的变量减1.它的使用方式和++完全相同.例如,假设变量count是int类 操作的变量减1.它的使用方式和++完全相同.例如,假设变量count是int类 型,下面3 型,下面3条语句会有相同的结果: count = count - 1; count -= 1; --count; --count;
C入门经典(第4版) 入门经典( 4. 8 嵌套循环
有时需要将一个循环放在另一个循环里面.例如计算某条街上每间房子 的居住 人数.这需要进入每间房子,计算每间房子的居住人数.统计所有的 房子是一个外部循环,在外部循环的每次迭代中,都要使用一个内部循环来计 算居住人数.
C入门经典(第4版) 入门经典( 4. 9 嵌套循环和 嵌套循环和goto语句 语句
/* Loop body executed 10x20x30 times */ /* Do something useful */ } 由i控制的外部循环每次迭代时,都会执行一次由j控制的内部循环.由j控 控制的外部循环每次迭代时,都会执行一次由j控制的内部循环.由j 制的循环每次迭代时,都会执行一次由k 制的循环每次迭代时,都会执行一次由k控制的最内层循环.因此最内层的循 环体会执行6 000次. 环体会执行6 000次.

C C经典教程(四)

C C经典教程(四)
转化为 if ((x>=-EPSINON) && (x<=EPSINON)) 其中 EPSINON 是允许的误差(即精度)。
4.3.4 指针变量与零值比较 l l 【规则 4-3-4】应当将指针变量用“==”或“!=”与 NULL 比较。 指针变量的零值是“空”(记为 NULL)。尽管 NULL 的值与 0 相同,但是两者意义不同。假设指针变量 的名字为 p,它与零值比较的标准 if 语句如下: if (p == NULL) // p 与 NULL 显式比较,强调 p 是指针变量
伍亿人才招聘网—人才基地,企业动力,群英汇聚在伍亿!
|= <<= >>=
表 4-1 运算符的优先级与结合律
l
l 级。
【规则 4-1-1】如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用默认的优先
由于将表 4-1 熟记是比较困难的,为了防止产生歧义并提高可读性,应当用括号确定表达式的操作顺 序。例如:
C C经典教程(四).txt30生命的美丽,永远展现在她的进取之中;就像大树的美丽,是展现在它负势向上高耸入云的蓬勃生机中;像雄鹰的美丽,是展现在它搏风击雨如苍天之魂的翱翔中;像江河的美丽,是展现在它波涛汹涌一泻千里的奔流中。 本文由2012shijiebei贡献
doc文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。
表 4-4(c) 效率低但程序简洁 4.5 for 语句的循环控制变量
l l
表 4-4(d) 效率高但程序不简洁
【规则 4-5-1】不可在 for 循环体内修改循环变量,防止 for 循环失去控制。
l
l
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第4章初始化与清除第2章利用了一些分散的典型C语言库的构件,并把它们封装在一个s t r u c t中,从而在库的应用方面做了有意义的改进。

(从现在起,这个抽象数据类型称为类)。

这样不仅为库构件提供了单一一致的入口指针,也用类名隐藏了类内部的函数名。

在第3章中,我们介绍了存取控制(隐藏实现),这就为类的设计者提供了一种设立界线的途径,通过界线的设立来决定哪些是用户可以处理的,哪些是禁止的。

这意味着数据类型的内部机制对设计者来说是可控的和能自行处理的。

这样让用户也清楚哪些成员是他们能够使用并加以注意的。

封装和实现的隐藏大大地改善了库的使用。

它们提供的新的数据类型的概念在某些方面比从C中继承的嵌入式数据类型要好。

现在C ++编译器可以为这种新的数据类型提供类型检查,这样在使用这种数据类型时就确保了一定的安全性。

当然,说到安全性,C ++的编译器能比C编译器提供更多的功能。

在本章及以后的章节中,我们将看到许多C ++的另外一些性能。

它们可以让我们程序中的错误暴露无遗,有时甚至在我们编译这个程序之前,帮我们查出错误,但通常是编译器的警告和出错信息。

所以我们不久就会习惯:在第一次编译时总听不到编译器那意味着正确的提示音。

安全性包括初始化和清除两个方面。

在C语言中,如果程序员忘记了初始化或清除一个变量,就会导致一大段程序错误。

这在一个库中尤其如此,特别是当用户不知如何对一个s t r u c t 初始化,甚至不知道必须要初始化时。

(库中通常不包含初始化函数,所以用户不得不手工初始化s t r u c t)。

清除是一个特殊问题,因为C程序员一旦用过了一个变量后就把它忘记了,所以对一个库的s t r u c t来说,必要的清除工作往往被遗忘了。

在C ++中,初始化和清除的概念是简化类库使用的关键所在,并可以减少那些由于用户忘记这些操作而引起的许多细微错误。

本章就来讨论C ++的这些特征。

4.1 用构造函数确保初始化在s t a s h和s t a c k类中都曾调用i n i t i a l i z e()函数,这暗示无论用什么方法使用这些类的对象,在使用之前都应当调用这一函数。

很不幸的是,这要求用户必须正确地初始化。

而用户在专注于用那令人惊奇的库来解决他们的问题的时候,往往忽视了这些细节。

在C ++中,初始化实在太重要了,所以不能留给用户来完成。

类的设计者可以通过提供一个叫做构造函数的特殊函数来保证每个对象都正确的初始化。

如果一个类有构造函数,编译器在创建对象时就自动调用这一函数,这一切在用户使用他们的对象之前就已经完成了。

对用户来说,是否调用构造函数并不是可选的,它是由编译器在对象定义时完成的。

接下来的问题是这个函数叫什么名字。

这必须考虑两点,首先这个名字不能与类的其他成员函数冲突,其次,因为该函数是由编译器调用的,所以编译器必须总能知道调用哪个函数。

S t r o u s t r u p的方法似乎是最容易也是最符合逻辑的:构造函数的名字与类的名字一样。

这使得这样的函数在初始化时自动被调用。

下面是一个带构造函数的类的简单例子:现在当一个对象被定义时:这时就好像a 是一个整数一样:为这个对象分配内存。

但是当程序执行到a 的定义点时,构造函数自动被调用,因为编译器已悄悄地在a 的定义点处插入了一个X ::X ()的调用。

就像其他成员函数被调用一样。

传递到构造函数的第一个参数(隐含)是调用这一函数对象的地址。

像其他函数一样,我们也可以通过构造函数传递参数,指定对象该如何创建,设定对象初始值等等。

构造函数的参数保证对象的所有部分都被初始化成合适的值。

举例来说:如果类t r e e 有一个带整型参数的构造函数,用以指定树的高度,那么我们就必须这样来创建一个对象:tree t(12); // 12英尺高的树如果t r e e (i n t )是唯一的构造函数,编译器将不会用其他方法来创建一个对象(在下一章我们将看到多个构造函数以及调用它们的不同方法)。

关于构造函数,我们就全部介绍完了。

构造函数是一个有着特殊名字,由编译器自动为每个对象调用的函数,然而它解决了类的很多问题,并使得代码更容易阅读。

例如在上一个代码段中,对有些i n i t i a l i z e ()函数我们并没有看到显式的调用,这些函数从概念上说是与定义分开的。

在C ++中,定义和初始化是同一概念,不能只取其中之一。

构造函数和析构函数是两个非常特殊的函数:它们没有返回值。

这与返回值为v o i d 的函数显然不同。

后者虽然也不返回任何值,但我们还可以让它做点别的。

而构造函数和析构函数则不允许。

在程序中创建和消除一个对象的行为非常特殊,就像出生和死亡,而且总是由编译器来调用这些函数以确保它们被执行。

如果它们有返回值,要么编译器必须知道如何处理返回值,要么就只能由用户自己来显式地调用构造函数与析构函数,这样一来,安全性就被破坏了。

4.2 用析构函数确保清除作为一个C 程序员,我们可能经常想到初始化的重要性,但很少想到清除的重要性。

毕竟,清除一个整型变量时需要作什么?只需要忘记它。

然而,在一个库中,对于一个曾经用过的对象,仅仅“忘记它”是不安全的。

如果它修改了某些硬件参数,或者在屏幕上显示了一些字符,或在堆中分配了一些内存,那么将会发生什么呢? 如果我们只是“忘记它”,我们的对象就永远不会消失。

在C ++中,清除就像初始化一样重要。

通过析构函数来保证清除的执行。

析构函数的语法与构造函数一样,用类的名字作函数名。

然而析构函数前面加上一个~,以和构造函数区别。

另外,析构函数不带任何参数,因为析构不需任何选项。

下面是一个析构函数的声明:class Y {p u b l i c :~ Y ();} ;当对象超出它的定义范围时,编译器自动调用析构函数。

我们可以看到,在对象的定义点处构造函数被调用,但析构函数调用的唯一根据是包含该对象的右括号,即使用g o t o语句跳出这一程序块(为了与C 语言向后兼容,g o t o在C ++中仍然存在,当然也是为了方便)。

我们应该注意一些非本地的g o t o语句,它们用标准C语言库中的setjmp() 和l o n g j m p()函数,这些函数将不会引发析构函数的调用。

(这里作一点说明:有的编译器可能并不用这种方法来实现。

依赖那些不在说明书中的特征意味着这样的代码是不可移植的)。

下例说明了构造函数与析构函数的上述特征:58下面是上面程序的输出结果:我们可以看到析构函数在包括它的右括号处被调用。

4.3 清除定义块在C中,我们总要在一个程序块的左括号一开始就定义好所有的变量,这在程序设计语言中不算少见(P a s c a l中例外),其理由无非是因为“这是一个好的编程风格”。

在这点上,我有自己的看法。

我认为它总是给我带来不便。

作为一个程序员,每当我需要增加一个变量时我都得跳到块的开始,我发现如果变量定义紧靠着变量的使用处时,程序的可读性更强。

也许这些争论具有一定的普遍性。

在C ++中,是否一定要在块的开头就定义所有变量成了一个很突出的问题。

如果存在构造函数,那么当对象产生时它必须首先被调用,如果构造函数带有一个或者更多个初始化参数,我们怎么知道在块的开头定义这些初始化信息呢?在一般的编程情况下,我们做不到这点,因为C中没有私有成员的概念。

这样很容易将定义与初始化部分分开,然而C ++要保证在一个对象产生时,它同时被初始化。

这可以保证我们的系统中没有未初始化的对象。

C并不关心这些。

事实上,C要求我们在块的开头就定义所有变量,在我们还不知道一些必要的初始化信息时,就要求我们这样做是鼓励我们不初始化变量。

通常,在C ++中,在还不拥有构造函数的初始化信息时不能创建一个对象,所以不必在块的开头定义所有变量。

事实上,这种语言风格似乎鼓励我们把对象的定义放得离使用点尽可能近一点。

在C ++中,对一个对象适用的所有规则,对预定义类型也同样适用。

这意味着任何类的对象或者预定义类型都可以在块的任何地点定义。

这也意味着我们可以等到我们已经知道一个变量的必要信息时再去定义它,所以我们总是可以同时定义和初始化一个变量。

我们可以看到首先是b u f被定义,然后是一些语句,然后x 被定义并用一个函数调用对它初始化,然后y 和g 被定义。

在C 中这些变量都只能在块的一开始定义。

一般说来,应该在尽可能靠近变量的使用点定义变量,并在定义时就初始化(这是对预定义类型的一种建议,但在那里可以不做初始化)。

这是出于安全性的考虑,减少变量误用的可能性。

另外,程序的可读性也增强了,因为读者不需要跳到程序头去确定变量的类型。

4.3.1 for 循环在C ++中,我们将经常看到f o r 循环的计数器直接在f o r 表达式中定义:上述声明是一种重要的特殊情况,这可能使那些刚接触C ++的程序员感到迷惑不解。

变量i 和j 都是在f o r 表达式中直接定义的(在C 中我们不能这样做),然后他们就作为一个变量在f o r 循环中使用。

这给程序员带来很大的方便,因为从上下文中我们可以清楚地知道变量i 、j 的作用,所以不必再用诸如i _l o o p _c o u n t e r 之类的名字来定义一个变量,以表示这一变量的作用。

这里有一个变量生存期的问题,在以前这是由程序块的右大括号来确定的。

从编译器的角度来看这样是合理的,因为作为程序员,我们显然想让i 只在循环内部有效。

然而很不幸的是,如果我们用这种方法声明:(无论有没有大括号,)在同一程序块内,编译器将给出一个重复定义的错误,而新的标准C ++说明书上说,一个在f o r 循环的控制表达式中定义的循环计数器只在该循环内才有效,所以上面的声明是可行的。

(当然,并不是所有的编译器都支持这一点,我们可能会遇到一些老式风格的编译器。

)如果这种转变引起一些错误的话,编译器会指出,解决起来也很容易。

注意,第4下载那些局部变量会屏蔽这个封闭范围中的变量。

我发现一个在小范围内设计良好的指示器:如果我们的一个函数有好几页,也许我们正在试图让这个函数完成太多的工作。

用更多的细化的函数不仅有用,而且更容易发现错误。

4.3.2 空间分配现在,一个变量可以在某个程序范围内的任何地方定义,所以在这个变量的定义之前是无法对它分配内存空间的。

通常,编译器更可能像C 编译器一样,在一个程序块的开头就分配所有的内存。

这些对我们来说是无关紧要的,因为作为一个程序员,我们在变量定义之前总是无法得到存储空间。

即使存储空间在块的一开始就被分配,构造函数也仍然要到对象的定义时才会被调用,因为标识符只有到此时才有效。

编译器甚至会检查我们有没有把一个对象的定义放到一个条件块中,比如在s w i t c h 块中声明,或可能被g o t o 跳过的地方。

相关文档
最新文档