1。程序流程的基本控制结构:顺序,选择,循环。
(1)选择结构。
if(~)//“是”型
语句;
或:if(~)//“是非”型
语句1;
else
语句2;
或:if(~)//阶段处理型
语句1;
else if(~)
语句2;
......
else if(~)
语句n;
else
语句n+1;
或:switch(开关表达式)//开关结构
{
case 常量1:
语句1;
case 常量2:
语句2;
..................
default:
语句n;
}
(2)for(表达式1;表达式2;表达式3)
循环体
或:while(判断表达式)
循环体
或:do{
循环体
}while(判断表达式);
2。变量的存储属性(包括生存期和作用域),extern变量,普通static变量属性及区别,类成员static变量/函数。
一:C++的生存期:其内存分类网上有不同的分法。个人觉得如果把程序分成DATA区和CODE区的话,程序代码区就是所谓的CODE区,而DATA区会有五部分组成。也就是DATA区内存的分配问题。我还是比较认同我转帖得这一篇:http://blog.csdn.net/jieisme/archive/2008/12/02/3426929.aspx
注意:new/delete和malloc/free的区别。
(1)new在自由存储区分配内存,malloc在堆中分配内存。访问方式不同,不能混用,否则导致程序崩溃。
(2)new自动计算需要分配的空间,malloc需要手动计算字节数。
(3)new是类型安全的,而malloc不是。
int *p=new float[2];//编译报错
int *p=malloc(2*sizeof(float));//编译不报错
(4)对非数据类型的对象而言,new/delete在分配内存上调用构造函数和析构函数来初始化和销毁对象,并可以重载;而malloc/free则不能。
(5)分配失败时表现不一样,new分配失败抛出异常;而malloc分配失败则返回NULL。所以用返回值判断malloc分配是否成功绝对正确;而new则不总是可靠。
二:C++的作用域:可以分为:语句,语句块,函数,文件和程序5个域。前三个域内起作用的是局部变量;后两个域内起作用的是全局变量。
(1)注意“内层”变量和“外层”变量的覆盖问题,这是基本问题,C语言中就已经有了。//定义的“内层”变量会覆盖“外层”同名变量。
void fun()
{ int x=1;
int y=x;
cout<<x<<","<<y<<endl;
{
x=2;
int y=2;
cout<<x<<","<<y<<endl;
}
cout<<x<<","<<y<<endl;
}
四:extern的基本概念
extern变量生存期是全局的,作用域也是全局(此处全局是以文件或编译单元范围界定)的,另外其声明的变量/对象还可以用于多个文件共享,这一点是其它类型所无法比拟的。
分为定义性声明和引用性声明。很多人对这两种声明方式不清楚。我在此先依照自己的思路说以下几点:
1)书上说了:定义性声明的格式为:extern 类型 变量名=初始化表达式。
书上也说了:可以把extern默认;当把extern默认时,初始化表达式也可以默认。我的理解是定义性声明语句中如果带有extern,初始化表达式肯定也必须附带;如果不带有extern,初始化表达式可带可不带。
一句话:从声明格式上就可以区分两者。
定义性声明格式:extern int i=5;int i=5; int i;
引用性声明格式:extern int i;
略做验证:
#include <iostream.h>
extern int i;
void main()
{
cout<<i<<endl;
}
编译OK,运行报错,因此可以看出extern int i形式的声明格式实为声明语句。
2)声明范围不同。定义性声明只能定义于外部且只能一次性定义;而引用性声明在内、外部均可以声明,且可使用多次。
上题答案:(1,1;2,2;2,1)解析:观察内层域内有无改变变量情况?都有重新赋值所以第二次输出为2/2;作用域结束后,重定义者释放空间,再应用者覆盖空间。再应用者x会使用最后一次被赋的值,y值会使用进入内层之前的值。因此为2/1。
五:普通静态变量(static)
1)存储属性:静态变量/静态数据成员/静态成员函数/都被分配在静态存储区;生存期是全局的,但是作用域既可以全局,也可以局部。教材上对“全局”的定义比较模糊,所以我们不妨这么界定。全局=全文件(或者编译单元);如果程序由多个文件组成,那属于另外一个范畴,暂且放到下一点提及,不然很容易造成混淆。
2)声明格式:static 类型名 变量名;
与extern不同的是,普通static变量在声明的同时就要被初始化,默认为0。测试:如果在上面的程序中把extern换做static,编译运行均OK。
六:类成员静态变量/函数
这里把普通静态变量与类成员静态变量区分开,原因是它们在使用和用法上仍存在一些不同之处。C++标准,为了避免被多次重复声明,在class的声明中只能够包括static member的原型(声明),而不能包括其定义(初始化操作)。所以为了初始化一个静态数据成员,必须在class外包括一个正式的定义。
1)格式:类内声明,类外定义(呵,这点让我想到了友元函数);定义时不须使用static。
class XX{...... static int Number;.....} int XX::Number=0;
特殊得,有序型const静态数据成员可以类内常量初始化,当然仍需要类外定义。因为类内已初始化,所以类外不能再进行初始化了。
class A{static const int i=16;//C++标准支持有序类型在类体中初始化;但VC6不支持。
static const char n[16];
}
const int A::i;
const int A::n[16]="Saving";
2)特征:每个静态成员函数(或静态数据成员)只有一个实体,而不是每个对象都有一个它的实体。这样就保证了共用数据的一致性。可以说,不与特定的对象相联系,调用时用类名的格式比较好,也“可以”用对象名,但不推荐。
推荐调用方式:类名::静态成员函数
不推荐调用方式:对象名+成员运算符
3)任意被访问性:类中任何成员函数都可以访问类对象的静态成员,这主要归功于它的共用特征;而静态成员函数只能通过对象名(或指针)访问该对象的非静态成员。至于例子就看书上的例题吧。
4)静态数据成员和非静态数据成员的独特功能/偏僻特点。
前者类型可以是其所属类,后者只能被声明为该类对象的指针或引用。
class ABC{static ABC n1; //OK
ABC *n2;//OK
ABC n3;//Error
};
前者可以作为类成员函数之缺省实参,而后者不可。
extern int var;
class Foo
{
private:
int var;
static int stcvar;
public:
int mem1(int=var); //错误
int mem2(int=stcvar); //正确
int mem3(int=::var); //正确
……
} ;
七:多文件程序中的连接属性
在多文件程序结构中,“如何在不同的源文件中使用同一变量”和“如何在不同的源文件中使用同一变量而不管别的源文件是否也在使用这个名字”,这被称为“文件的连接属性”。也可以这么说,如果把之前的“全局”理解成狭义上的全局(即文件范围或编译单元范围),那么在上面这句话里,前者谈论的是广义上的全局(多文件)问题,用extern实现;后者讨论的是狭义上的全局(单文件)问题,用static实现。
按编写规范讲,头文件的作用就是要给外部提供接口使用的,用到extern时,最好在头文件中做声明,而不是定义。一般情况下,声明定义static时,最好放在原文件中而不是头文件,这样就不会给其它模块造成不必要的信息污染。
详见:http://blog.chinaunix.net/u2/63316/showart_1355297.html