2.2 程序设计范式
编程范式:指的是计算机编程的基本风格或典范模式。设计C++就是为了支持数据抽象、面向对象的程序设计和通用型程序设计。
2.3 过程式程序设计
原始的程序设计范式是:
Decide which procedures you want; use the best algorithms you can find. |
2.3.1 变量和算术
一个声明是一个语句,它为程序引入一个名字,还为这个名字确定了一个类型。类型则定义了名字或者表达式的正确使用方式。
C++提供了一批各种各样的基本类型,它们都直接对应于一些硬件功能。例如:bool、char、int、double。算术运算可以用于这些类型的任意组合:+、-、*、/、%; 比较运算符也是这样:==、!=、<、>、<=、>=。
2.3.2 检测和循环(PSword使用:如果从vs贴过来的数据,得用行距使用固定值)
一个检测的小程序,检测了一个yes的情况
bool accept()
{
cout<<"Do you want to proceed (y or n)?\n"< char answer = 0; cin>>answer; if (answer == 'y') return true; return false; } 如果将回答‘n’也纳入考虑的范围,可以对这个例子做一点改进: bool accept2() { cout<<"Do you want to proceed (y or n)?\n"< char answer; cin>>answer; switch(answer) { case 'y': return true; case 'n': return false; default: cout<<"I `ll take that for a no"< return false; } } 加入endl会立即显示,cout<<"Do you want to proceed (y or n)?\n";,这样的输入不会立即输出到屏幕上, 会写入缓冲区中。除了具备“\n”的换行功能外,还调用输出流的flush函数,刷新缓冲区,让数据直接文件或屏幕上。这两种都可以用的,不过不需要立即显示,并且要兼顾代码的执行效率的时候,可以考虑“\n”,这样不刷新缓冲区,会更快。 2.3.3 指针和数组 数组可以如下定义: char v[10]; 指针的定义与此类似: char *p; 在声明里,[]表示”的数组”,而*表示”指向”。 C++语言强制要指向const对象的指针也必须具有const特性。本质上来说,系统是没有办法分辨常量指针所指向的对象是否为const,系统会把它所指的所有对象都是为const。如果指向const的指针所指的对象并非const,则可直接给该对象赋值或间接地利用普通的非const指针来修改:毕竟这个值不是const。 const double *cptr; 如果把指向const的指针理解为“自以为指向const的指针”。这个可能会对理解有所帮助。 Const指针 int errNumb = 0; int *const curErr = &errNumb;//error const指针的值不能修改, 这就意味着不能使curErr指向其他对象。 2.4 模块程序设计 设计程序的重点已经从有关过程的设计转移到数据的组织了。除了其他的因素外,这种转移也反映了程序规模增大的情况。 C++提供了一种机制,可以把相关的数据、函数等组织到一个独立的名字空间里。例如,模块Stack的接口可以按如下的方式声明和使用: namespace Stack //interface { void push(char); char pop(); } void f() { Stack::push('c'); if (Stack::pop() != 'c') error("impossible"); } 这里的Stack::限定词表明push()和pop()都是Stack名字空间。“::”域操作符。A::B表示A范围内的B。 namespace Stack //implement { const int max_size = 200; char v[max_size]; int top = 0; void push(char c){/*检查上溢°并压入c*/} char pop(){/*/检查下溢出并弹出*/} } 有关这个Stack 模块的关键点是, 用户代码完全隔离于Stack的数据表示之外,隔离的方式是通过写出的Stack::push() 和Stack::pop()代码来实现。用户不用知道Stack是数组实现的。 2.4.1 分别编译 C++支持C语言中有关分别编译的概念。这种机制可以将程序组织为一组部分独立的片段。将接口放在.h 文件内、而将实现放在.cpp内。
第三章标准库预览
要是即刻就忘,何必费时去学?
1.1 引言
没有任何一个重要程序只是用某种赤裸裸的程序设计语言写出的。首先总是要开发出一组支撑库,这也就形成了进一步工作的基础。
3.2 Hello World!
最小的C++程序
int main { }
main函数返回的int值, 如果有的话就是这个程序返回给“系统”的值。如果没有值返回,系统将接到一个表示程序成功完成的值。也就是说main函数末尾的return 0可有可无。 由反斜线字符\后跟一个字符表示的是某个特殊字符。
#include
int main()
{
std::cout<<"Hello world\n"< } 3.3 标准库名字空间 标准库定义在一个称为std的名字空间里,这也就是为什么写的是std::cout,而不直接写cout的原因。这样做的目的是明确说出要使用的是标准库里的cout。 标准库的每个功能都是通过某个像 #include #include iostream.h是C语言格式的标准输入输出流文件,为非标准。由于当时没有命名空间这个说法,所以也就不存在std这个命名空间标示符。所以用iostream.h也就用不着std或者using namespace std。(参见范磊 书籍) iostream为标准输入输出流,它是C++规范的带有命名空间的头文件,它包含在std命名空间内。 3.5 字符串 标准库提供了一个string类型,作为前面所用的字符串文字量的补充,常用的操作有+, substr, replace,c_str。 3.6 输入 标准库提供了istream。与ostream一样,istream能处理内部数据类型的字符串序列。运算符>>(“取出”)被用于输入运算符。>> 右边的运算对象的类型决定可以接受什么输入。 获得输入的方式有两种: int main() { string name; cout<<"请输入您的姓名:"< cin>>name; cout<<"hello, "< return 0; } 按照默认方式,一个空白字符,例如空格符,将结束一次输入。如果你输入的是 Eric Boolaxe 回答仍然是 Hello , Eric 但是你可以使用函数getline读入一个完整的行。例如: int main() { string name; cout<<"请输入您的姓名::"< getline(cin, name); cout<<"hello, "< fflush(stdin); getchar(); return 0; } 3.7 容器 一个可以保存一批对象为主要用途的类通常被称为一个容器。C语言内部数组具有固定的规模。如果我们选择了很大的规模,那么就会浪费存储空间;而如果选择了过小的规模,数组又会溢出。这两种情况不得不去写低级的存储管理代码。标准库提供的vector能关照好所有这些情况。 vector 4.3 字符类型 每个字符常量都有一个整数值,例如在ASCII字符集里,‘b’的值是98。 int main() { char c; cout<<"请输入一个字符:"< cin>>c; cout<<"the value of "< system("pause"); return 0; } int(c)将给出字符c的整数值。 还提供了另一个类型wchar_t,用于保存更大的字符集的字符。例如Unicode的字符。在C语言里wchar_t是一个typedef而不是一个内部类型。加上后缀_t,就是为了区分标准类型和typedef。 例如你在使用ASCII字符集的机器上运行程序,‘0’的值就是48。采用字符常量而不用十进制写法能使程序更具有移植性。宽字符常量的形式是L’ab’(这里放在引号间的字符个数及意义由显示根据wchar_t类型确定)。 4.4 整数类型 与char一样,每个整数类型也有三种形式,普通的“int”,signed int ,和unsigned int 。此外,整数还有三种大小,short int(short)、 int、long int(long)。 4.5 浮点类型 浮点数也有三种大小:float、double和long double。 int main() { cout<<"largest float == "< <<", char is signed == "< system("pause"); return 0; } 注: 如果不能编译, 则需要加入头文件#include 4.8 枚举 一个枚举是一个类型,它可以保存一组由用户刻画的值。枚举的定义:enum其后是一个可选枚举类型名, 和一个用花括号括起来,用逗号分开的枚举成员。 enum open_modes{input, output, append}; 默认下,第一个枚举子被赋值0,接下来的枚举子取值是前面一个枚举子的取值+1,例如 enum weather {SUNNY, CLOUDY, RAINY, WINDY}; 其中 4.8.1枚举变量的定义、初始化和赋值 既然每个枚举都是一个类型,那么由这个类型自然可以声明变量,枚举类型变量的大小是4。例如,由前面定义的some_big_cities: enum some_big_cities { Guangzhou = 4, Shenzhen = 4, Hongkong = 4, Shanghai = 2, Beijing = 3, Chongqi = 5 }; int main() { some_big_cities wh = Guangzhou; //枚举变量定义的时候最好初始化 cout<<"the value is: "< system("pause"); return 0; } 4.9.1 声明的结构 一个声明由4个部分组成:一个可选的“描述符”,一个基础类型,一个声明符,还有一个可选的初始式。*,*const,&,[],()。后缀([],())的声明运算符比前缀的那些声明符约束力更强。因此,*kings[]就是一个指向什么东西的指针数组 4.9.4 作用域 一个声明将一个名字引进一个作用域;也就是说,这个名字只能在程序的一个特定部分内使用。被遮蔽的全局名字可以通过作用域解析运算符::去引用。 int x; void f2() { int x = 1; //遮蔽了全局的x ::x = 2; //给全局的x赋值 } 4.9.5 初始化 如果没有提供初始式,全局的、名字空间和局部静态对象(统称为静态对象)将自动初始化为适当的0。 更复杂的对象需要多于一个值做为初始式。数组和结构的C风格初始化采用的是{ } 初始式列表描述。 int a[] = {1,2}; 4.9.7 typedef 如果一个声明以typedef为前缀,它就为类型声明了一个新名字,而不是声明一个指定类型的对象。例如:typedef char *PCHAR; 这样一个可以方便地将原来笨拙的类型名缩写。还有使用typedef的作用就是易移植。例如: typedef int int32; typedef short int16; 那么很容易将我们的程序一直到一个sizeof(int)是2的机器上。 第五章 指针、数组和结构 5.1.1 零 没有任何对象会被分配到地址0,因此,0也被当做一个指针常量,表明指针并没有指向任何对象。在C中流行的是用一个宏NULL表示0指针。由于C++收紧的类型检查规则,采用普通的0而不是一些人建议的NULL宏。带来的问题会更少一些。如果感到必须定义NULL,请采用: const int NULL = 0; 5.2 数组 float v[3]; char * a[32]; 5.3 数组的初始化 数组可以用一系列值初始化。如: int vl [] = {1, 2, 3, 4}; 如果明确给出了大小,在初始化列表中给了多余的元素就是错误。 char v3[2] = {1, 2, 3}; 5.2.2 字符串常量 “this is a string”,一个字符串常量里包含的字符个数比它看起来的字符多一个。它总是由一个空字符’\0’结束。空字符的值是0。字符串常量的类型是:“适当个数的const字符的数组”,所以像”Bohr”的类型就是const char [5]。
sunny == 0,
cloudy == 1,
rainy == 2,
windy == 3;