2009-5-7
version 1.0
基础 C++ 概述 大纲l 词法要素
l 预处理器
l 变量、函数和类
l 定义和声明
l 复合语句
l 循环语句
l for 循环
l while 循环
l do while 循环
l break和continun语句
l 条件分支
l If 语句
l switch 语句
l C++数组
l 多维数组
l 指针
l 把数组作为参数传递
l 字符数组
词法要素
标识符:字母(包括下划线’_’)和数字序列。首字符必须是字母。标识符对字母大小写敏感,比如:Foo_Bar1 是与foo_bar1不同的标识符。
保留字:关键字不是由程序员重新定义的。例如:int, while,double,return, catch,delete.目前,C++ 有48个保留字。
操作符:在各种类型的操作数是执行运算的符号。C++有大约50个操作符和16个优先级别。
预处理指示符:常用于条件编译。总是与#打头。如:#include, #ifdef, #define, #if, #endif。
注释:由/* */或//分隔。注释会被/忽略。
对编译器来说,注意下面可以达到与注释相同的效果:
#if 0
……
#endif
常量:字符串,整数,浮点数类型,以及枚举类型。如:”hello world”,2009,3.1416及FOORBAR。
预处理器
l Less import for C++ than for C due to inline functions and const objects.
l C++预处理器有4个主要的功能
n 文件包含
#include <stream.h>
#include “foo.h”
n 符号常量
#define SCREEN_SIZE 80
#define FALSE 0
n 参数化的宏
#define SQUAREA(A) ((A) * (A))
#define NIL(TYPE) ((TYPE*) 0)
#define IS_UPPER (C) ((C) >= ‘A’ && (C) <= ‘Z’)
n 条件编译
#ifdef __”cplusplus”
#inclue “c++-prototypes.h”
#elif __STDC__
#include “c-prototypes.h”
#else
#include “nonprototypes.h”
#endif
变量、函数和类
l 变量
n 在C++中所有变量必须在使用前声明。而且,变量必须以在某种意义上和它相关类型保持一致来使用。
l 函数
n 与C不同,C++的函数必须先声明再使用,缺省的返回类型是int 。然后,对函数作完整声明被认为是一个好的方式。
n 使用void 关键字来指明无返回值的函数。
l 类
n 把数据对象和函数组合在一起来提供抽象数据类型(ADT)。
定义和声明
l 在C中,区别变量以函数的声明和定义是很重要的。
n 定义
指的是变量或函数创建或分配存储空间的地方。每个外部变量或函数必须定义且只能定义一次。
n 声明
指的是表明变量的类型的地方,并不分配存储空间。
n 注意:class,struct, union以及enumod 类型的声明同时也是定义。这是因为就一个编译单元而言它们不能多次出现。
l Variables and functions must be declared for each function that wishes to access them.声明为编译器提供大小和类型以便于编译器能生成正确的代码。
复合语句
l 通用形式:
‘{‘
[decl-list] // 声明列表
[stmt-list] // 语句列表
‘}’
l 示例
int c = ‘A’; // 全局变量
int main (void)
{
If (argc > 1)
{
putchar (‘[‘];
for (int c= ::c; c <= ‘Z’; putchar (c++))
;
}
}
l 注意:
这里使用了作用域解析操作符(::)指示不要隐藏全局的int c。
循环语句
l 在程序中C++有5种方法执行重复操作:
1. for: 循环前检查条件
2. while: 循环前检查条件
3. do/while循环后检查条件
4. 递归
5. 无条件分支: 局部(goto)和非局部(setjmp和longjmp)
for 循环
l 通用形式
for (<initialize>; <exit test>; <increment>)
<stmt>
Initialize: 初始化
exit test: 退出条件测试
increment: 循环条件值增加
stmt: 循环体中的语句
l For循环把初始化、退条条件测试和循环条件值增加集中放在一起。
l 循环头部的三个部分都是可选的,并都可以包含任意的表达式。
l 注意:可以在<initialize>部分声明变量 (与C不同之处)。
l 使用示例
for ( ; ;) ; /* 永久循环 */
/* 把stdin复制到 stdout */
for (int c, (c = getchar()) != EOF; putchar (c));
/* 求 n的阶乘 */
for (int i = n; n > 2; n--) i *= (n – 1);
/* 遍历链表*/
for (List *p = head; p != 0; p = p->next) action (p);
while 循环
l 通用形式
while (<condition>)
<stmt>
<condition>: 循环条件
<stmt>: 循环体中的语句
l 当检查到循环条件为非0时重复执行循环体中的语句。
l 实际上,for 循环可以用while循环来表达:
<initialize>
while (<exit test>)
{
<loop body>
<increment>
}
l 使用示例:
while (1) ; /* 永久循环 */
int c;
while ( (c = getchar ()) != EOF)
putchar();
/* 求 n的阶乘 */
i = n;
while (n >=0 )
i *= --n;
/* 遍历链表*/
p = head;
while (p != 0)
{
action (p);
p = p->next;
}
do while 循环
l 通用形式:
do <stmt> while ( <condition> );
l do while没有for 和while 常见。
l 注意:检查退出条件是在循环体的后面,所以循环体至少要被执行一次。
int main( void )
{
const int MAX_LEN = 80;
char name_str [MAX_LEN];
do {
cout << “ enter name (exit to quit”);
cin.getline (name_str,MAX_LEN);
process (name_str);
} while (strcmp (name_str,”exit”)!=0);
return 0;
}
break 和 continue 语句
l 提供在循环体中的类似goto 的控制形式
#include <stream.h>
int main (void)
{
/* 找出第一个负数*/
int number;
while (cin >> number)
if (number < 0)
break;
cout << “number = “ << number << “/n”;
//…
/* 从控制台读取数据,将其中的偶数累加起来*/
int sum, total;
for (sum = total = 0; cin >> number; total++)
{
If (number & 1)
continue;
sum += number;
}
cout << “sum = “ << sum << “, total = “ << total << “/n”;
return 0;
}
条件分支
l C++有两种通用的条件分支形式。
l If/else:
根据条件选择一个分支执行的一般方法,它线性的检查条件并检查条件为TRUE,当第一个条件为TRUE时不在检查后面的条件。
l switch
因为switch可以使用”转移表(jump table)”,所以它选对分支更有效。
if 语句
l 通用形式
If (<cond>)
<stmt1>
[else
<stmt2> ]
l 条件地执行一个语句序列的一般机制
#include <ctype.h>
char* character_class (char c) {
{
if (isalpha (c)
{
If (isupper ( c ) )
return “ is upper case”;
else
return “is lower case”;
}
else if (isdigit ( c ))
return “is a digit”;
else if (isprint ( c ))
return “is a printable char”;
else
return “ is an unprintable char”;
}
switch 语句
l 通用形式
switch (<expr> { <case> }
l switch只能用于标量变量。即: 整形,字符型,枚举形。
l 可以从一组标量变量中有效的进行选择
enum symbol_type
{
CONST, SCALAR, STRING,RECORD,ARRARY
} symbol;
switch (symbol)
{
case CONST: put (“constant”);
case SCALAR: puts (“scalar”); break;
case RECORD: puts (“record”); break;
default: puts (“either array or string”);break;
}
l 在switch中出现的break语句与循环中的break语句用法相似。
C++ 数组
l 数组是包含同一类型元素的数据类型。
l C++中,数据类型为ELEMENT,元素个数为k的一维数组是长度是一块连续的内存空间(大小为 k * sizeof (ELEMENT))。
l C语言数组有几个明显的限制
n 所有数组的范围是从0到k – 1
n 大小需要在编译时作为常量确定
n 运行时不能改变大小
n 在运行时不执行下标范围的检查。如:
{
int a[10];
for (int i = 0; i <= 10; i++ ) // BAD CODE
a[i] = 0;
}
l 数组在定义时需要提供类型,名称和大小。例如,两个大小分别为10 和100的整型数数声明:
int array[10], vector[1000];
l 在 C++中数组与指针很相似。数组名自动的转换为指向其第一个元素的常指针。与指针不同的仅是执行 sizeof array_name。
l 数组可以在编译时初始化,也可以在运行时初始化。例:
int eight_primers[] = { 2,3,5,7,11,13,17,19};
int eight_count[8],i;
for (i = 0; i < 8; i++)
eigth_count[i] = eigth_primes[i];
多维数组
l C++提供矩形式多维数组。
l 数组元素是与行序存储。
l 多维数组也可以初始化,如:
static char daytab[2][13] =
{
{ 0, 31,28,31,30,31,30,31,31,30,31,30,31},
{ 0, 31,29,31,30,31,30,31,31,30,31,30,31},
}
l 可以省略已确定的初始维度值。
static char daytab[][] =
{
{ 0, 31,28,31,30,31,30,31,31,30,31,30,31},
{ 0, 31,29,31,30,31,30,31,31,30,31,30,31},
}
指针
l 指针是保存另一个变量地针的变量。例:
int I = 10;
int *ip = &i;
l 可以通过直接个修改ip指向的值来修改变量i的值。如:
*ip = i + 1;
/* 总是为真 */
If (*ip == i) { /**/}
l 注意:指针的大小通常与int的大小一致。32位的系统,大小为4字节,64位的系统为8字节。
l 注意:C++中有时常用引用来代替指针。例如与引用的方式传变量的值。
把数组作参数传递
l 把数组作参数传递的C++语法非常令人迷惑。
l 比如,下面两种声明是等价的:
int sort (int base[], int size);
int sort (int *base, int size);
l 但是,在这里如果您传入一个不正确的变量,编译器将不作任何提示:
int I, *ip;
sort(&I,sizeof i);
sort(ip,sizeof *ip);
l 注意下面才是您真正想要的:
int a[] = { 10, 9, 8, 7, 6, 5,4,3,2,1};
sort (a, sizeof a / sizeof *a);
l But it is difficult to tell this from the function prototype…
字符串
l C++字符串实现为与NUL结尾(‘/0’)的字符数组。所以,每个字符串都有隐含地需要一个额外的字节来保存NUL字符。
l 示例:
char *p; /* 尚未指定存存的字符串 */
char buf[40]; /* 40个字符的字符串 */
char *s = malloc (40); /*40个字符的字符串 */
char* string = “hello”;
sizeof (string) == 4; /* 32bit os */
sizeof(“hello”) == 6;
sizeof buf == 40;
strlen(“hello”) == 5;
l 在<string.h>中定义了一些操作标准字符串的函数。
l 使用C++字符串要特别小心:
下面的操作不会是你期望的那样,它会是让str1和strl2都指向”bar”
char *str1 = “foo”, *str2 = “bar”;
str1 = str2;
l 为了执行字符串复制,您需要用到strcpy函数。如:
strcpy (str1, str2);
l 注意数组和指针的区别:
char* foo = “I am a string constant”;
char bar[] = “I am a charater array”;
sizeof foo == 4;
sizeof bar == 23;
l 使用 C++ String类通常比使用内置的 string要方便。