第一篇:编程入门基础知识点总结
一、常量
数字常量
i.普通数字:1,35,2.7 ii.指数形式:2.45e-2等价于2.45*10-2 注意e大小写皆可,e前面的数字不能省,就算是1也不能省,后面的数字一定要是整数
iii.长整型,单精度浮点型:3235L,32.5F 分别表示3235是长整型数据,32.5是单精度浮点型左,若不写上L,F则表示3235是整型,32.5是双精度浮点型,L,F大小写皆可
字符常量
i.普通字符常量:用单引号把一个字符括起来,如‟A‟,‟@‟
ii.转义字符常量:一对单引号括起来并以“”开头的字符序列,如‟n‟(回车)、‟123‟(8进制123对应的字符), ‟x23‟(16进制23对应的字符) 字符串常量
用一对双引号把一个字符序列括起来,如“ABCef”,系统存放字符串常量,每个字符分配一个字节,各字符所占字节紧邻,并且字符串末尾会给再开一个字节里面放一个’ ’做为结束标志。
符号常量
定义格式 #define 符号常量名 符号常量值,如#define N 20则定义了符号常量N,其值为20,注意符号常量名和符号常量值之间是用空格隔开,而不是写上=号,#define和符号常量名之间也有空格的。
题目:P7—1,5,6,7,9,10
二、标识符
命名规则
以数字,字母,下划线这三类字符组成,但只能以字母或下划线开头,而不能也数字开头,另外不能将关键字做为标识符。32个关键字表在P365附录B 变量名,函数名,符号常量名全都是标识符 题目:P7—2,3,4
三、变量
变量的定义格式
类型名 变量名;如 int a;定义了一个整型常量a。变量名是由人类随便定义的,符合命名规则的前提下,爱写啥就写啥。所以什么flag,cc,y1或者函数名fun,find等全部是自定的用来做为名字而已,没有更特别的意义。
类型名
int 整型,long 长整型: 用于存放整数,只是数值范围不同
float 单精度浮点型 double 双精度浮点型:用于存放实数,数值范围,精度不同
char字符型:用于存放字符
变量赋值,初始化
int a=3;定义的同时初始化
a=6*9;定义后在程序中进行赋值
变量的值
只有在赋值操作时才会被改变,即将其放在等号左边时才会改变它的值,或自增自减操作:a=5,a++,a--,像a+3并未改变a的值,只是使用了a的值而已. 自增自减运算
变量++,++变量,变量--,--变量
使变量的值自增1或自减1 等价于 变量=变量+1 变量=变量-1 ++,--放于变量前后效果的区别:
当自增自减运算做为表达式的一部分时,++,--放在变量前面是先自增自减再使用变量的值,放在变量后面则是先使用变量的值,再自增自减。如x=3;printf(“%d”,++x);则相当于执行了++x;printf(“%d”,x);这样的操作所以打印出4 再如x=3;printf(“%d”,x++);则相当于执行了printf(“%d”,x);x++;这样的操作,则打印出3,当然最后x的值还是4。
四、表达式
运算符和运算对象
一个运算符都有若干个运算对象,如 + 必然要跟两个运算对象才能进行加法运算:3+5。C语言里称需要跟n个运算对象的运算符为n元运算符。一元运算符有:!,(类型名)二元运算符有:+,-,*,/,%(求余), =,+=,-=,*=,/=,%=,< , > , <=, >=, = =(等于),!=(不等于),&&(且), ||(或)多元运算符有:, 运算符的优先级和结合性
i.优先级:同一个运算对象左右两边若同时有两个运算符,则这两个运算符优先级高的先进行运算。
ii.结合性:若同一个运算对象左右两边的两个运算符优先级相同,则根据结合性判断先进行哪个运算,自左自右结合性的先算左边的运算符,自右自左的先算右边的运算符。
iii.各运算符的优先级和结合性见P365附录C 强制类型转换
格式:(类型名)表达式。将后跟的表达式的值的数据类型转换为与圆括号内的类型名一致的类型。注意类型名一定要用()括起来。
算术表达式
i.算术运算符:+,-,*,/,%(求余)ii.由算术运算符加上运算对象构成算术表达式,如3+3*6-9/2 iii.值:跟我们小学时学的一样,就是表达式的计算结果 iv.整数除以整数结果取整数部分,故1/3得到的值是0 v.5%3 结果为2,想想小学除法,求余得到的是余数不是商。 赋值表达式
i.赋值运算符:=,+=,-=,*=,/=,%= ii.赋值表达式:变量=表达式,如x=3+6,x+=6-9,x+=x*=3+4 注意等号左边只能是变量
iii.复合赋值运算符的运算:以/=为例:x/=表达式 等价于 x=x/(表达式)iv.值:=号左边的变量最终的值 关系表达式
i.关系运算符:< , > , <=, >=, = =(等于),!=(不等于)ii.由关系运算符加上运算对象构成关系表达式,如3>=4, 2==a iii.值:满足相应运算符所指定的关系的值为1,否则为0 逻辑表达式
i.逻辑运算符:&&(且), ||(或),!(非)ii.由逻辑运算符加上运算对象构成逻辑表达式,如3&&4, x||!y iii.值:满足相应运算符所指定的关系的值为1,否则为0 iv.进行 ||或 运算时,若||左边的表达式值为1,则不再对右边的表达式v.进行运算。进行 &&且 运算时,若&&左边的表达式值为0,则不再对右边的表达式进行运算。 逗号表达式
i.逗号运算符:,ii.用逗号将各种表达式连续起来构成逗号表达式,如3+4,a=9,8*a iii.值:组成逗号表达式的各个表达式中的最后一个的值,如上例为8*a 题目:P7—11~17 P8—18~33
五、输入输出函数
scanf(“格式控制串”,变量地址表列);如scanf(“%d%c%d”,&a,&ch,&b);
scanf(“%4f”,&x);注意:
i.格式控制串可控制截取用户输入的前几个字符给变量,但不能控制输入几位小数给变量,如不能写成scanf(“%4.2f”,&x);ii.第二个参数给的是地址,即要么是&+变量名或数组元素名的形式,要么就是一个数组名或指针变量名,如int *p,a;p=&a;scanf(“%d”,p);iii.考试时注意看题目给你写好的scanf的格式 1.若其格式控制串内各格式符用“,”隔开如scanf(“%d,%c,%d”,&a,&ch,&b);那输入时也要用逗号隔开,如此例输入时应:3,+,5 2.若是这种格式scanf(“%d %d”,&a,&b);则输入时应:3 5;3.若是这种格式scanf(“%d%c%d”,&a,&ch,&b);则输入时应3+5,若写成3 + 5则a=3,ch=‘ ’(空格),b=任意值
(自己上机运行看看结果)
printf(“格式控制串”,输出项表列);如float x=7.5;printf(“%8.2f”,x);此处的意思是将x打印出来,且占8列,保留两位小数。自己上机运行看看效果。
常用格式符汇总:
i.%d:输入输出整型数据,%ld:输入输出长整型数据 ii.%c:输入输出字符型数据
iii.%f:输出单(双)精度浮点型数据,输入单精度型数据。
%lf:输入双精度型数据
iv.%s:输入输出一个字符串,用printf输出字符串时,输出项书写时可
为字符串常量,或字符数组名。如printf(“%s”,”hello”);或char str[10]=”hello”;printf(“%s”,str);v.%u:输入输出无符号整型,%o:输入输出八进制数,%x:输入输出十六进制数
getchar();函数调用后返回用户输入的一个字符,故需再定义一个变量来存放这个字符,即使用时应 char c;c=getchar();意思就是接收用户输入的一个字符,并将其赋值给变量c。
putchar(字符常量或字符变量名);
如char c=‟A‟;putchar(c);或putchar(„A‟);都会向屏幕输出字符A。
六、C语言的语句
表达式语句:由表达式末尾加上分号构成。
函数调用语句:由函数调用表达式加上分号构成。空语句: ;
选择结构语句:if语句 switch语句
循环语句:for语句 while语句 do while语句
复合语句:用花括号{}将以上任意语句括起来构成一条复合语句。
七、C程序的基本结构
void main(){
声明部分:用来定义变量和声明自定义函数的原型,需以“;”结尾,如int x;
执行语句部分:第六点里介绍的各种语句,如x=3;printf(“%d”,x);} main函数外可写自定义函数。如 int max(){
return 0;}
八、选择结构语句
if(表达式)语句1 else 语句2
如果if语句的圆括号内的表达式值为非0,则执行语句1,值为0则执行语句2。
i.表达式可为任意表达式,if语句执行的实质是判断表达式的值是否为0来决定执行语句1还是语句2。另外请在此处表达严重关切,不管是高ii.手还是菜鸟经常会把判断两个数相等的符号“==”写成了一个等号“=”成为了赋值运算,这样的写法不会引发编译错误,但结果会与原意大大不同,所以考试前请再三提醒自己。
语句1和语句2都只能是一个语句,若要跟多条语句,切记用一对{}括起来,构成复合语句;也不要随便在圆括号后加“;”,因“ ;”构成一条空语句,这会使后面跟的语句1不再属于if语句的组成部分。
iii.if语句的三种结构
1.单边: if(表达式)语句
2.双边:if(表达式)语句1 else 语句2 3.多层(重点掌握): if(表达式1)语句1 else if(表达式2)语句2 else if(表达式3)语句3 …
else 语句n 条件运算符 表达式1? 表达式2 : 表达式3
若表达式1的值非0,则取表达式2的值做为整个表达式的值,否则取表达式3的值为整个表达式的值。如 3>4? 1:2 该表达式的值为2 switch语句
switch(表达式){ case 表达式1:语句
case 表达式2:语句
…
case 表达式n:语句
default: 语句 } 语句执行过程:先计算表达式的值,然后判断该值与表达式1到表达式n中的哪个相等,若与表达式i的值相等,则执行表达式i后的所有语句,当遇到break;语句时结束整个switch语句的执行。表达式1到表达式n的值都不相等的情况下执行default后跟的语句。每个case后可跟多条语句。
九、循环结构
for循环语句
for(表达式1;表达式2;表达式3)循环体语句 语句执行过程: 1.计算表达式1 2.判断表达式2的值是否为0,若为0,语句执行结束,若不为0,进入步骤3 3.执行循环体语句(需注意的是循环体语句只能有一个语句,若要包含多个语句要用一对{}括起来,构成一条复合语句,此处也不要随便加上 “;”,因一个“;”可构成一条空语句,这会使得后面真正的循环体语句不属于for循环语句的部分)。进入步骤4 4.计算表达式3,然后重新进入步骤2 while循环语句 do while循环语句
i.while(表达式)循环体语句 执行过程:
1.判断表达式的值是否为非0,若是进入步骤2,否则结束语句执行。2.执行循环体语句,重新回到步骤1。ii.do 循环体语句
while(表达式); 执行过程:
1.执行循环体语句,进入步骤2
2.判断表达式的值是否为非0,若是重新回到步骤1,否则结束语句执行。
这里要注意的地方跟for语句一样,即循环体语句只能有一个语句,若要包含多个语句要用一对{}括起来,构成一条复合语句,此处也不要随便加上 “;”,因一个“;”可构成一条空语句,这会使得后面真正的循环体语句不属于while循环语句的部分,另外do while循环的while(表达式)后是要加“;”的。 break语句:放在循环体内实现的功能是结束其所在的那层循环的执行。
十、数组
定义格式:数据类型
数组名[整型常量];如 int a[10];定义了一个整型数组,数组名为a,这个数组含有10个元素。
引用数组元素: 格式:数组名[下标]
切记下标值从0开始。下标可为常量,表达式,变量等,如int i=3; a[0]=5;a[3*2]=9; a[i]=7;
初始化:数据类型
数组名[整型常量]={数据表列};将数据表列的各个值依次赋值给数组的各个元素。如int a[5]={0,1,2,3,4};则数组a各元素a[0]到a[4]的值分别为0,1,2,3,4 遍历数组元素
数组定义后,我们不能对数组进行整体的操作,如int a[10];不能用a=3这样的操作将数组的各元素都赋值为3;而只能一个一个元素的进行赋值,如a[0]=3;a[1]=3;a[2]=3…a[9]=3; 当然此时我们就可以借助于一个for循环来控制下标的变化从而对数组的各个元素进行赋值 for(i=0;i<10;i++)a[i]=3;
当然这只是用for循环遍历数组各元素的最简单的例子,一般考试考的是找出数组元素的某种特性的极值,比如最大值,最小值,或对数组各元素进行排序,这时我们就可以使用for循环来遍历数组的各元素,然后在当前循环中得到一个元素再对其进行处理。如i=2时访问到的元素是a[2],你就可以问问它,你是不是最小值啊。 整型数组
int a[10];整型数组里的各个元素存放的是整数。a[3]=3; 字符型数组
char str[20];字符型数组里的各个元素存放的是字符。
str[3]=‟A‟;
十一、字符串函数
gets(字符数组名或字符指针变量);
如char str[10],* str2;str2=str;则gets(str);或gets(str2);都是接收用户输入的字符串如“ABC”存入到字符数组str中
puts(字符数组名或字符指针变量或字符串常量);
如char str[10]=”china”;char *str2;str=str2;则puts(str);或puts(str2);或 puts(“china”);都会在屏幕上打印出 china strlen(字符数组名或字符指针变量);字符串测长函数
char str[20]=”hello world!”;
int len;len=strlen(str);得出的结果是len的值为12 strcat(字符串1的地址,字符串2的地址);
将字符串2的内容连接到字符串1的尾部。char str1[20]=”ABC”,str2[20]=”xyz”;strcat(str1,str2);
则程序运行的结果是str1内存放的字符串变为ABCxyz,当然str2存放的字符串还是xyz。
strcmp(字符串1的地址,字符串2的地址);
比较串1和串2哪个比较大。比较大小的依据是,两个字符串从左往右相应位置上第一个不相等的字符ASCII码值之差。char str1[20]=”ABCE”,str2[20]=”ABDE”;int i;i=strcmp(str1,str2);第一个不相等的字符为str1的‘C’和str2的‘D’,而二者相差-1,故-1做为strcmp函数执行的结果返回到被调用的位置,该位置位于赋值表达式内,故将其值赋值给i,即此时i的值就是-1. strcpy(字符串1的地址,字符串2的地址);
将字符串2的内容复制到字符串1内。char str1[20]=”ABC”,str2[20]=”xyz”;strcpy(str1,str2);此时str1的内容为”xyz”,当然str2的内容没变 strcpy(str1,”uvw”);此时str1的内容又变成了“uvw“。
十二、函数
函数定义
函数类型
函数名(形式参数列表){
内部变量定义和声明部分
执行语句
} 如:
int max(int x , int y){ int z;
z= x > y ? x : y;
return(z);} 注意点:
1.函数类型是指返回值的类型,即要与return语句后跟的表达式的值的类型一致。若函数类型为void则说明该函数无返回值,即函数体里不能出现return 语句。2.形式参数列表里定义的变量要记得给它们指定类型,而且如果同时要定义多个,应在每个前面都分别指定类型名,而不能写成int x,y;3.函数体里能写的语句跟main函数一样,在开头可定义所需要的变量,后面跟上一堆执行语句。 函数调用流程
以上面的函数为例,在main函数进行调用: void main(){ int a,b,c;
scanf(“%d%d”,&a,&b);printf(“%d”,max(a,b));或 c=max(a,b);printf(“%d”,c)以上两种方法都会在屏幕中打印出a,b间的较大值。
调用函数的格式 函数名(实际参数列表);调用的时候像什么函数类型,形式参数的类型就不要加上去了。max(a,b)中max就是函数名,写上变量名a,b是实际参数列表,执行这个调用语句时,会先把a,b的值给相应位置的形式参数即执行了x=a,y=b这样的操作,然后开始执行max函数的函数体的语句。当max函数体里执行到一个return语句时,则max函数结束执行,将return后的表达式的值返回给main函数调用max函数的那个位置,即若上面a=3,b=5则max(a,b)return后的表达式的值应该是5也就是说执行完max后把5返回到调用max的位置可看成printf(“%d”,5);或另一种解法的c=5。}
十三、指针
指针变量的声明: 类型名 * 指针变量名; 通过指针变量访问它所指向的普通变量的值
先将普通变量的地址赋值给指针变量,再通过指针运算符* 得到普通变量的值。int *p,x,y;x=3;p=&x;则printf(“%d”,*p);会打印出3即x的值 y=*p;则y的值变为3 *p=5;则x的值变为5 指针变量加上(减去)一个位移的效果
若指针变量存入的是数组元素的地址,则其加一减一得到的是那个数组元素下一个或前一个元素的地址。int a[10];p=&a[3];*p得到的是a[3]的值。
若p++;此时p存放的是a[4]的地址&a[4];*p得到的就是a[4]的值。或p--;此时p存放的是a[2]的地址&a[2],*p得到的就是a[2]的值。
行指针
i.主要是对于二维数组来说的,二维数组每行都有自己的地址,第0行地址用 数组名 表示,第i行地址为 数组名+i;而想要得到二维数组里一个元素的地址,必需先得到其所在行的地址,然后再由那个地址得到元素的地址,比如说 int a[3][4];定义了一个二维数组,该二维数组第0行的地址为a,第1行的地址为a+1,第2行的地址为a+2,想从行的地址得到元素的地址,需在行地址前加上指针运算符“*”,即*a就是第0行首个元素的地址即a[0][0]的地址,而a[0][2]的地址就是在a[0][0]的地址基础上加上位移量2,即*a+2,然后想得到a[0][2]这个元素的值呢就再加上一个指针运算符“*”,即*(*a+2),类似地,想得到a[2][2]这个元素的值呢就是*(*(a+2)+2)ii.定义行指针变量: 类型名
(*变量名)[数组长度];
如int(*p)[4],a[3][4];p=a;此时就可把p当成a来用,用法同上所述。
判断是否合法访问数组元素:若是指针法访问,判断指针后跟的是否地址;若是下标法访问,判断下标有无越界。
函数指针:函数名即为函数的地址(指针)
i.函数指针变量的定义: 类型名(*变量名)(形参列表);如 int(*p)();ii.赋值:指针变量=函数名;设有个函数其函数名为max,则要将该函数的地址给p的话只要执行如下语句即可 p = max;
指针数组:指针数组的数组元素都是指针变量,是用来存放变量的地址的,定义格式为 类型名 * 变量名[数组长度];如int * p[10]; 指向指针的指针:指针变量也是一种变量,故在内存中也有对应的一个地址,而要存放指针变量的地址,就要求助于用来存放指针变量的地址的指针变量,定义格式
类型名 ** 变量名;如 int *p1;int **p2;int a=3;可进行赋值p1=&a;p2=&p1;则a、*p1和 **p2的值都是3.十四、宏定义
无参宏定义 #define 标识符
值
定义后,出现所定义的标识符的地方都将以定义时指定的值来代替。
#define M 2+3 main(){ int x;
x=M*M;则x的值为2+3*2+3=11若想得到的结果是(2+3)*(2+3)则定义时也写成这样 #define M(2+3)} 注意#define、标识符、值之间都要用空格隔开,且宏定义结尾不需加分号。 带参宏定义
#define 标识符(参数表)值
#define S(x,y)x*y main(){ int a=3,b=4,c=5,d=6;
printf(“a*b=%dn”, S(a,b));此时会打印出 a*b=12
printf(“a+b*c+d=%dn” , S(a+b,c+d));此时会打印出a+b*c+d=29,带参宏定义执行时是将a+b这样一个表达式代替x,c+d这样一个表达式代替y,所以S(a+b,c+d)进行的是a+b*c+d的运算,而不是将a+b的值给x,c+d的值给y然后再做x*y,这点跟函数调用传递参数是不一样的。}
自定义类型名typedef:对已存在的类型名取一个外号。
i.基本格式:typedef 原类型名
新类型名;ii.typedef int INTEGER;则int a,b;等价于INTEGER a,b;iii.typedef int NUM[10];则 int a[10];等价于 NUM a;a即为一个有10个元素的数组的数组名。
iv.typedef int * INTEGER;则int *a,*b;等价于INTEGER a,b;
十五、结构体,共用体,枚举类型
结构体
i.结构体类型的定义及变量的定义
struct 结构体名
{类型 成员1;
类型 成员2;
……
类型 成员n;
}变量名;如
struct student { char name[10];long num;int score[4];}st1;定义类型时同时定义变量
struct student st2;定义类型后,用类型名定义变量 还有一种 struct
{ char name[10];long num;int score[4];}st3;不给类型名,直接定义变量
ii.结构体变量所占字节数:各成员各占字节数之和,如以上st1,st2,st3的字节数皆为10+4+2*4=22 iii.结构体数组的定义及初始化
struct student a[3]={{ “zhang”,20030001,89,90,91,92},{“liu”,20030002,68,69,70,71},{“li”,20030003,57,58,59,60} } iv.结构体成员的访问
1.结构体变量名.成员名 如st1.name[2] 2.通过指针访问:struct student *st;st=&st1;(*st).num 或 st->num 共用体
i.共用体类型的定义及变量的定义
union 共用体名 { 类型
成员名1;
…
类型
成员名n;
};
变量的定义与结构体类似,也有三种方法。union data {
int i;char ch;float f;}d1;定义类型时同时定义变量
union data d2;定义类型后,用类型名定义变量
union {
int i;char ch;float f;}d3;不给类型名,直接定义变量
ii.共用体变量所占字节数:各成员所占字节数的最大值,如上d1,d2,d3所占字节数皆为4.(单精度浮点型变量所占字节数最多为4).iii.共用体成员的访问
1.共用体变量名.成员名 如d1.f 2.通过指针访问:union student *d;d=&d1;(*d).num 或 d->num 枚举类型
i.枚举类型的定义:
enum 枚举名{枚举元素名1,枚举元素名2,…,枚举元素名n}; ii.枚举元素的值:
默认值分别为0、1、…、n-1。枚举元素的值也可在定义时重指定,对于没有指定值的元素,按顺序加1
如enum weekday{sun=7,mon=1,tue,wend,thur,fri,sat};则sun值为7,mon值为1,tue值为2,wend值为3,thur值为4,fri值为5,sat值为6
十六、Turbo C的使用
菜单激活: F10
菜单切换:左右方向键在不同菜单间切换,上下方向键在同一个菜单不同选项间切换。
载入文件:两种方法:1.找到源文件所在位置,直接将其拉到Turbo C快捷方式上;2.F3 运行程序: ctrl+F9
看程序运行结果:alt+F5 进入编辑状态:菜单Edit 保存: F2
插入状态切换: Insert键
第二篇:游戏编程入门
游戏编程入门
经常有人问我,没有编程经验的人该如何开始开发游戏。在此之前,我总是一个个的尽力回答。然而,后来提相同问题的人数增长到难以处理的地步。我决定,是时候把我所有的建议写成文章,作为一个大概。
这篇文章是针对那些想要开发自己游戏,但几乎没有编程经验的人。事实上,我假设读者没有任何编程经验。我主要讨论游戏开发的程序和设计方面,而不是艺术性。我也不准备讲述如何进入游戏行业(这方面已经有足够的资料),而只是让你逐步的开始开发自己的游戏。最后,我所指出的这条道路也并不能作为唯一的,或是最好的路径来学习开发游戏,但至少对我和一些人很有用。选择一门语言
你要做的第一件事就是选择一门开发语言。你有很多选择,包括
Basic,Pascal,C,C++,Java,等等。也经常会有人争论对于初学者那一门语言是最好的。对于这一系列流行语言的讨论,你可以参看John Hattan的著作,What Language Do I Use?(我用什么语言?)
我的建议是以C和C++开始。有些人会说这些语言对初学者来说太高级了,但因为我自己就是学C++,我并不同意这一说法。而且,C/C++是当今使用最广泛的语言(译者认为应该是汉语。。),所以你可以找到大量学习资料和帮助。你先学C或C++都无所谓,因为只要学了一个,再学另外一个就很容易。但是,如果你先学C++,请保证在学习面向对象编程之前能理解和使用过程编程(等编程熟练再去学习类)。(译者:C是过程性语言,C++是面向对象语言)
如果你开始学习C/C++,发现太难,那再学一个简单一点的也没关系,比如Basic或Pascal。但是我真的认为,如果你坚持努力,而且有好的资料,学C/C++应该没有太大问题。
你的下一个问题可能会是:“我该怎么学C/C++?”我很高兴你这样问。最好的办法是上课。有老师可以回答你的问题,帮助你产生很大进步,编程练习作业也可以保证你能用到所学的东西。
如果你不觉得上课是个好主意,那最好的办法就是买一些好书。不要花太多时间去选一本什么“超级宝典”或“万用全书”,因为你最终可能会买几本。我建议你去一家书店,然后拿几本比较入眼的C或C++书看,直到找到一本或几本你能看懂,并且可以拿来学习的。同时,你可能会想要一些更深入的,或者一些材料,但是你一旦对于这门语言有了一些了解,我相信你应该有自己更好的选择。在这里,我有必要花一些时间,来说我看到很多初学者所关心的一个事情,特别是年轻人:没有钱买书和其他东西。首先,有很多免费资源可以利用,图书馆,Macmillan Computer Publishing(/personal),有成千上百的编程书籍。但是如果你真的想要成为一个好的程序员,还是应该投入一部分资金。应当想方设法(合法的)帮助你弄到一些钱。
网上也有很多C/C++的学习指南。但是我认为那只能作为补充而不是你自学的主要资源。
选择正确的编译器
你写的程序,或者代码,是以文本方式储存的,你甚至可以用记事本写C/C++程序。但是总需要有东西把他们转换成为可执行文件。对于C和C++,那就是编译器。
可用的编译器有好多种,包括很多免费的。选择一款自己适合的编译器很重要,免费的编译器就有这样的好处,你可以把它们试个遍,然后从中选择自己最喜欢的。然而,免费编译器比起商业版,可能会缺失一些功能和大部分服务。幸运的是,多数商业版编译器也兼售介绍版或学习版,这要便宜得多,通常功能却不见得少,唯一的限制是你不能发布用它编译的程序(短时间内你也根本用不着)。
总之,选择编译器取决于你能花多少钱,用什么操作系统,和为什么平台开发。如果要为windows开发,我强烈推荐Microsoft Visual C++。他强大的开发环境使得很多事做起来更方便,毫无疑问没有其他编译器更适合开发windows应用程序。如果你是个学生,你还可以折价买到。(译者:爽!)如果你在DOS平台开发,你最好的选择可能是DJGPP,免费的哦~。
选择开发平台
尽管最终你很可能为好几个平台开发,总要先选择一个来学。当你在学这门语言,还没有接触到图像的时候,你可能会想使用非图形用户界面的操作系统,比如DOS,Unix.这样可以避免接触高层,比如windows编程,让你集中精力学习语言本身。
一旦你做好开发游戏的准备,那么,应该考虑是否改变平台,让我们来看看每个选项的特征。
windows:如果你想成为游戏行业的专家,或者如果你想让许多人来玩你开发的游戏,那么,这就是你要选择的平台。因为多数你的用户使用windows,而且现在我也看不出有什么改变的迹象。当今大多数的windows游戏都是由一种你可能听说过技术---DirectX---开发的。你可以DirextX这个库直接访问硬件,这意味着你可以开发高性能的游戏。
DOS:DOS过去是占统治地位的游戏平台,但是已经一去不复返了。尽管可能有一些特殊爱好者还在为DOS开发游戏,现在没有一个为DOS开发的商业游戏,他也将继续衰落,直到微软不再支持。如果你只是想开发游戏,还是不要选择DOS,如果你非要这么做,也不要太久。记住:由于存在大量DOS游戏开发的书,可能还有人辩护从这些书中学习DOS游戏开发。但是,windows游戏开发的书越来越多,那些辩解也变得越来越无力。
Linux:Linux是Unix的一种,由于很多原因后来变得流行,包括稳定性,价格,和反微软情绪。尽管Linux用户还是相当少,但是围绕着他的热情和不断增长的市场潜力使其也成为不错的选择。
Macintosh:MAC有大量忠实粉丝并不能说明什么,几乎每一个和我讨论的MAC狂热者都需要更多更好的游戏。我没有见过多少MAC游戏开发资源,但我相信还是有的,因此这也是一个选择。
consoles:console(就是PS,N64,DC等等)的游戏市场十分巨大,当然
console游戏开发的前景也不错。然而以非商业的形式开发console游戏,出于各种原因,在现在似乎行不通。如果你开发console,很可能是在被商业游戏开发组雇用之后。
开始进入主题
现在是时候讨论开发游戏了。简单起见,我假设你选择用C/C++在windows平台开发,可能你选择别的,但大多数我说的还是有用的。
首先,甚至在你打算开始开发游戏之前,你必须很好掌握C和C++.你应该懂指针,数组,结构体,函数,可能还有类。如果你精通他们,就可以开始做游戏了。
这篇文章可能不能教会你所有关于开发游戏的东西。幸运的是,也没有这个必要。这方面有很多书,网上也有很多指南。GameDev.net应该有所有你想要的东西,这里我建议你怎么开始:
找一本或几本书。对于windows游戏开发初学者,Tricks of the Windows Game Programming Gurus是个完美的开始。除此之外,还有许多好书.读透这些书,试试所有的例子,不懂得部分多读几遍。
网上指南作为补充。除了弄清书上读到的,他们还涉及一些书上没有谈及的主题。
向专家寻求帮助。如果你不能在书上或指南找到问题的答案,好好利用我们的论坛和聊天室。那里有好多专家愿意帮助别人。
这并不是要你按照顺序执行的,而是可以同时并且不断的重复执行。
光学习还是不够的,你必须运用你所学到的。从一个小游戏开始,然后在这个基础上前进。你可以看一下Geoff Howlands 的著作: How do I Make Games?
A Path to Game Development.开始,自己独立工作。不要急着加入团队,那样只会减缓学习过程。而且一旦你有了自己的几个游戏,你可以为团队做出更大的贡献。
还有关于书,你应该不仅仅看游戏开发的书。为了能够开发出你看到商店出售的游戏,你应该钻研比大多数游戏开发书籍更高级的一些主题。有一些可以在网上找到,但你也应该选一些图形学,人工智能,网络,物理学等方面的书。计算机科学学位看来唾手可得,但因为你被迫上这些课的时候可能认为他们和游戏开发无关----你错了!
包装
这里有一些提示很有用
不要只积累知识,用它:你永远不会知道会理解一些东西知道你是用他们。用你学的东西作些演示。做作书上的练习。
经常玩游戏:这样做会使你做出更好的游戏。而且可以减轻编程的枯燥。帮助别人:能帮别人的地方尽量帮助别人,教别人的过程中自己会学到更多。有始有终:不要有这样的想法“我能够完成这个游戏了,但是我又有一个新的想法,那就直接做下一个。”你可以学得更多如果你完成他,你也可以用事实证明你不是只会空谈。所以,尽量不要做很大很复杂的游戏,直到你有了一定经验。
开始吧!你现在可以开始准备QUAKE4了。可能你不是不是很了解,但是至少应该知道如何开始这条道路,找多些资料,加上多年努力工作,他一定会实现!
第三篇:powerbuilder编程简单入门(个人总结)
2011-4 by 邵家鑫 From Tsinghua 一种简单的powerbuilder10数据库编程介绍
1、需求分析与数据库建立
进行需求分析(需求分析文档),确定数据关系,建立各种数据表,建立数据库(Access),设置ODBC数据源(控制面板->管理工具->数据源ODBC->“用户DSN”菜单下点“添加”选相应的数据源驱动程序,如果用Access2003建立的,则选第三项“Driver do Microsoft Access(*.mdb),然后点击“完成”->输入数据源名,如mydata,然后点击“选择”按钮选择建好的数据库,最后点“确定”,如下图所示)
2、界面设计(功能界面、重要数据表维护界面)
界面设计主要分为几个部分
(1)按照管理系统所需的功能设计界面。
首先画出所有可能的业务流程(数据的各种可能输入、修改、删除业务,数据的输出、显示业务)
(2)按照需要维护的表设计界面(往往给最高权限管理员直接修改数据用)
3、开始程序编写
(1)新建一个workspace(new->workspace->workspace)(2)在workspace下建立一个目标
(new->Target->application),可取名frame
2011-4 by 邵家鑫 From Tsinghua(3)在目标下建一个主窗口
可取名w_main,窗体名一般以w_开头(new->PB Object->Window),将其Window Type设为“mdihelp!”
(4)为主窗口建一个主菜单
可取名m_frame,菜单名一般以m_开头(new->PB Object->Menu)(5)程序中设置ODB ODBC 点击按钮,选中“ODB ODBC”项,然后单击右边“New”按钮,弹出如下对话框,设置Profile Name和Data Source,如图所示。
(6)建立配置文件
配置文件取名“config.ini”,内容如下:
[MyDB] DBMS=ODBC AutoCommit=False DBParm=ConnectString='DSN=mydata;UID=;PWD='
(7)自动连接数据库与退出程序关闭数据库的编写
2011-4 by 邵家鑫 From Tsinghua 首先建立Global Variables如下: string gs_userid,gs_username //登录用户标识、用户姓名 string gs_root_path,gs_ini_path
//应用路径和主配置文件路径
其次申明Global External Functions如下:
FUNCTION int GetComputerNameA(ref string computername,ref long size)LIBRARY “KERNEL32.DLL” alias for “GetComputerNameA;Ansi” FUNCTION long GetCurrentDirectoryA(long nBufferLength, REF string szBuffer)LIBRARY “KERNEL32.DLL” alias for “GetCurrentDirectoryA;Ansi” FUNCTION long SetCurrentDirectoryA(string szPathName)LIBRARY “KERNEL32.DLL” alias for “SetCurrentDirectoryA;Ansi” //end prototypes 在程序的总入口(进入“”)Open事件中写入以下代码: // Profile moneyandfriends string ls_1
//设置应用根目录
gs_root_path = space(255)GetCurrentDirectoryA(255, gs_root_path)if right(gs_root_path,1)= '' then gs_root_path = left(gs_root_path,len(gs_root_path)1)if pos(ps_sql, “group by ”)> 0 then
ls_end = right(ps_sql, len(ps_sql)pos(ps_sql, “order by ”)+ 1)
ls_where = mid(ps_sql, pos(ps_sql, “where ”)+6, len(ps_sql)-len(ls_front)-len(ls_end)-6)else
ls_where = mid(ps_sql, pos(ps_sql, “where ”)+6, len(ps_sql)-len(ls_front)-6)end if
2011-4 by 邵家鑫 From Tsinghua ls_return = ls_front + “where(” + ls_where +“)and ” + ps_where + “ ” + ls_end else if pos(ps_sql, “group by ”)> 0 then
ls_front = left(ps_sql, pos(ps_sql, “group by ”)pos(ps_sql, “group by ”)+ 1)elseif pos(ps_sql, “order by ”)> 0 then
ls_front = left(ps_sql, pos(ps_sql, “order by ”)pos(ps_sql, “order by ”)+ 1)else
ls_front = ps_sql
ls_end = “" end if ls_return = ls_front + ” where “ + ps_where + ” “ + ls_end end if return ls_return(2)在窗口中声明局部变量用来记录最初的没有where语句的窗口的SQL查询语句 string is_original_sql
(3)声明局部变量ls_old_select, ls_new_select,如下使用 string ls_old_select, ls_new_select ls_old_select = dw_ttxx.GetSQLSelect()if is_original_sql = ”" then is_original_sql = ls_old_select else //避免条件被循环添加
ls_old_select = is_original_sql end if
ls_new_select = f_change_where(ls_old_select, is_conditions)dw_窗口.SetSQLSelect(ls_new_select)
第四篇:编程入门基础知识总结
编程入门基础知识总结
基本知识
程序
= 算法 + 数据结构,算法是对操作的描述,数据结构是对数据的描述。伪代码:pseudo code 程序一般包括:
(1)预处理命令:#include等(2)全局声明部分
(3)函数:函数首部(声明)、函数体(局部声明+执行部分)程序执行过程
源程序-->编译成目标程序obj-->连接目标程序成可执行文件 类:数据成员+成员函数 命名空间
实际上就是一个由程序设计者命名的内存区域。程序员可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其它全局实体分隔开,解决名字冲突,防止全局命名空间污染。
C++库的所有标识符(标准头文件中函数、类、对象、类模版)都是在std命名空间定义的 A 的ASCII码值65
a 的97 1.数据类型
•基本类型:整型、浮点型、字符型、布尔型
•构造类型:枚举、数组、结构体类型(struct)、公用体(union)、类类型 •指针类型 •引用类型 •空类型:null int 4
unsigned int 4
short int 2
unsigned short int 2
long int 4 unsigned long int 4 char 1
uchar 1 float 4
double 8
long double 8 无符号:不用保存符号位,故比有符号多了一位
有符号:数值用补码存放(无论正负),最高位为符号位
VC中,long double与double字节数相同,故long double是无用的 GCC中,long double则有12个字节
无负值的量可以定义为unsigned int,如年龄、学号等,以增大存储范围。short int,long int,unsigned int这些类型后面的int可以省略 整型表示:
十进制,后面加L 或 l 八进制,前面加0 十六进制,前面加0x 浮点数表示:
默认为双精度型double 后面加 f 或 F 则为单精度float 后面加 l 或 L 则为长精度型long double 指数形式 数符
数字部分
指数部分
a = 3.14e2
a=0.314e4
a=31.4e1
a=3140e-1
浮点数,不管是用小数形式还是指数形式表示,在内存中都是以指数形式表示的,且数字部分必须小于1 如3.14159 在内存中表示为
+.314159,数字部分为.314159,是小于1的 字符型
字符型在内存中存储的是ASCII码,也是整型,故而可以把字符型赋给整型 字符串后面,编译系统会加个' '作为结束符 符号常量
用符号代表一个常量,如#define
PI 3.14159 在编译时,系统会把符号常量替换成具体的值
2.变量
变量:程序运行期间,值可变的量
变量名:代表内存中的一个存储单元,在编译连接时由系统给每一个变量分配一个地址 标识符:标识实体名字的有效字符序列,字母、数字、下划线
常变量:定义变量时加上const,运行期间值不可变,也即只读变量 区别#define 定义的符号常量与const定义的常变量 符号常量只是用一个符号代表一个常量,在编译时把所有符号常量替换为指定的值,它没有类型,在内存中不存在以符号常量命名的存储单元 常变量具有变量的特征,具有类型,在内存中有以它命名的存储单元,与一般变量不同的是,常变量代表的存储单元值不可变。
强定义的好处
1.保证变量名使用的正确,不正确会在编译时报错
2.每个变量指定为一确定类型,在编译时就能为其分配存储单元 3.编译时即可检查变量进行的运算是否合法。
3.运算符 二进制位运算 & 二进制 按位与 |
二进制按位或 ^ 按位异或 << 左移位 >> 右移位
++--自加自减运算符 ++i 使用i之前,i先自加 i++ 使用i之后,i再自加 ++--结合方向为自右向左 例:!x++
先取非,再++(i++)+6 先i+6,后i++,不管有无括号,都是先运算,再自加
(++i)+6 先自加,再加6-i++ :i左面是符号运算符,右面是自加运算符,设i等于3,运算过程相当于-(i++),即-i=-3-3+1=-2 a =-i++:a结果为-3,先赋值,再自加; 5-i++ =?
答案2
?待测试
i=1,j=2,则a = i+++j ?
答案:3 因为相当于a=(i++)+j;i=1,j=2,则a=i+(++j)?
答案:4
赋值运算符=的优先级小于++--运算符
示例:
int arr[] = {6,7,8,9,10};sint *ptr = arr;*(ptr++)+= 123;printf(“%d,%d”,*ptr,*(++ptr));解:
*(ptr++)+= 123;相当于 *ptr +=123;*ptr++;故arr[0] = 129;ptr指向arr[1] printf函数从右向左压栈,运算顺序:++ptr;输出结果: 8 8 cout也是自右向左压栈。
逗号运算符
又称顺序求值运算符
a = 3*4,a*5 则
a=? 答案 12 ?
注意逗号运算符优先级最低。注:整个逗号表达式的值为60(a=3*4=12,12*5 =60)x=(a=3,6*3)
则 x=18 x=a=3,6*a
则 x=3
3.内存存储
浮点数在内存里和整数存储方式不同
float a =1.0f;cout<<(int)a==(int&a);(int&a)相当于把该浮点数地址开始的sizeof(int)个字节当成int型数据输出,其值并不为1
(int)a显示转换等于1
4.类型转换
转换本质:按存储单元中的存储形式直接传送
(1)浮点型赋给整型,舍弃小数部分
(2)double型赋给float,防止溢出错误
(3)int,short,long赋给char,原封不动取低八位
(4)signed赋给unsigned,符号位照搬。负数以补码形式存放,-1赋给unsigned int,结果为65536.整数不会变,除非两个长度不同(int,long)发生截断
5.C++输入输出
C++输入输出包含三个方面的内容
(1)对系统指定的标准设备的输入输出。即从键盘输入、输出到显示器屏幕,称标准输入输出,简称标准I/O
(2)以外出磁盘文件为对象进行输入输出,称文件I/O
(3)对内存中指定空间进行输入输出,通常指定一个字符数组作为存储空间,称字符串输入输出,简称串I/O
在C++中,输入输出流被定义为类。C++的I/O库中的类称为流类,用流类定义的对象称流对象。
C++中输入输出是调用输入输出流库中的流对象cin、cout实现的,即I/O不是C++本身定义的,而是编译系统的I/O库中定义的。
I/O控制符#include
setprecision(n)设置精度为n,十进制输出时,n代表有效数字位数包括整数和小数;
fixed(固定小数位数)和scientific(指数)形式输出时,n指小数位数(不包括整数部分)
double a = 123.4567890123456
cout << a;
//十进制输出,输出123.456
默认精度为6
cout< //十进制,输出123.456789 精度为9 cout< //恢复默认精度 cout< //固定位数,123.456789,此时精度表示小数位数,精度为默认的6 6.getchar()和 putchar() cout< //读入的实际是ASCII码,故输出为字符ASCII码,97,而非读入的字符 cout<<(c=getchar());//输出为字符 while((c=getchar())!='n'){} //循环读入字符的控制 7.函数与模版 函数原型:不同具体形参的函数声明 如:float add(float,float) 主要作用:根据函数原型,在程序编译阶段对调用函数的合法性进行全面检查。 函数重载:同一函数名定义的多个函数,这些函数的参数个数,参数类型,参数顺序至少有一项不同,一个函数不能既是重载函数,又是带默认参数的函数。 函数模版:适用于函数个数相同,函数体相同,而只有类型不同的情况 [cpp] view plain copy 01.#include 03.template 05.{ 06.if(b>a)a = b; 07.if(c>a) a = c; 08.return a; 09.} 10.int main() 11.{ 12.int a=1,b=2,c=3; 13.cout< 14.float d=1.1,e=2.2,f=3.3; 15.cout<< T(d,e,f); 16.} 变量作用域:变量有效范围,有四种: 文件作用域 file scope 函数作用域 function scope 块作用域 block scope 函数原型作用域 function prototype scope 递归函数:函数体中,直接或间接调用函数本身的函数。 变量的存储类别:外部、局部(相对于函数而言) 全局变量(也即外部变量) 静态局部变量(static) 自动变量(不加static的局部变量) 寄存器变量(register)存放在CPU中,而非内存中,这样在使用时就省去了从内存中载入寄存器的过程。但只是建议性的,优化编译系统自动识别使用频繁的变量,从而自动将变量放入寄存器中。 extern声明的外部变量 即提前引用申明,表示该变量是将在下面定义的全局变量或在其它文件中定义(本文件中不用extern,引用该变量的外部文件用extern进行声明) static声明的静态外部变量 只能被本文件使用,而不能被外部文件使用的全局变量,这样不同文件中的全局变量不会相互干扰,为程序模块化、通用化提供方便。 注:全局变量也是静态存储的。 内部函数与外部函数 内部函数:static 声明,文件内使用 外部函数:另一个文件里extern声明,表示是其它文件的函数,extern可以省略 宏定义 #define PI 3.14 定义符号常量 #define Area(a,b) a*b //定义函数功能,下面当作函数来用。 #include <> 在系统目录寻找,找不到报错 ' ' 在当前目录寻找,找不到报错 字符数组 (1)char str[] = “i am happy”; 数组长度为11,而非10,因为后面有一个' ' (2)char str[] = {'i','a','m','h','y'} 数组长度为5,系统不会自动为其在后面加' ' 因此,(1),(2)是不同的 输出字符数组:cout< string类 字符数组是C中的处理方式,C++中用string类,#include 字符串变量中不会存放' ',只存放字符串本身,故string str =“hello”;的长度为5,要注意。 字符串变量存储的实际是字符串的指针,4个字节,sizeof(string)= 4; string name[]={“i”,“am”,“happy”}; sizeof(name)= 3*4 = 12; 变量与指针: int *p = &i; //int型指针变量,定义时的*只是表示指针类型 p是指针变量,其值是变量i的地址,*p则是存储单元,*&a与*p同,都表示变量a 指向数组的指针 int a[10] = {}; int *p; p = &a[0];//与下面等价,都指向数组第一个元素,因为数组名本身就是表示数组的地址 p = a;************************* *p++ 相当于*(p++),先得到*p的值,p再++移到下一个元素 (*p)++则是使*p的值+1 二维数组的指针表示: *(*(p+i)+j) 表示 a[i,j] ************************* int(*p)[n] p为指向含n个元素的数组的指针 int *p[n] 定义指针数组P 函数指针 指向函数的指针,主要用作形参 int max(int,int); int(*p)(int,int); p = max;赋值(地址) p(1,2)//调用 引用 int a = 10; int &b = a;b是对a的引用 引用传递,引用型变量作为函数形参 [cpp] view plain copy 01.//值会改变 02.main{ 03.int i=5,j=6; 04.swap(i,j) 05.} 06.void swap(int &a, int &b)//这里的&不是“a的地址”,而是指“a是一个引用型变量”,&是个声明符 07.{ 08.int temp; 09.temp = a; 10.a= b; 11.b=temp; 12.} 传递变量地址:形参是指针变量,实参是变量地址,这种虚实结合的方法仍然是“值传递”方式,只是实参的值是变量地址而已。 [cpp] view plain copy 01.//值会改变 02.main() 03.{ 04.int i=5,j=6; 05.swap(&i,&j) 06.} 07.void swap(int *p1, int *p2)//这里的*号也只表示是指针类型 08.{ 09.int temp; 10.temp = *p1; 11.*p1 = *p2; 12.*p2 = temp; 13.} 结构体变量 struct 作函数参数时有三种形式 (1)用结构体变量名作形参 这时形参要开辟内存单元,实参中全部内容通过值传递方式一一传递给形参,时空开销大,效率低 (2)用指向结构体变量的指针作形参,只有四个字节 void printed(student *p){ cout< num; } (3)用结构体变量的引用变量作形参 Student stu; print(stu); void print(Student &stu){ cout } new delete 动态内存分配 new 类型(初值),返回地址,分配失败返回NULL float *f = new float(3.14); int *i = new int(6); int *k = new int[5][4];//数组 delete 变量 delete f;delete i; 数组 delete [] k; Enum 枚举类型 声明枚举类型 enum weekday{sun,mon,tue,wed,thu,fri,sat};定义枚举变量 weekday workday,week_end;变量赋值: workday = mon; 或 workday = weekday(2);枚举常量对应值从0开始,0,1,2,3..typedef 声明新类型 typedef int INTEGER,相当于为int起了个别名,下面程序中就可以直接用INTEGER作int用了 主要为了方便系统移植,如long int在VC中4个字节,在GCC中占8个字节,直接用int的话可能会溢出,用INTEGER就不用担心了,只要把ypedef int INTEGER 声明语句一改就行 运算符重载 方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现响应运算。即运算符重载是通过定义函数实现的,运算符重载实际上是函数重载。格式: 函数类型 operator 运算符名称(形参表列) {对运算符的重载处理} 例如:将 + 用于Complex类(复数)的加法运算,函数原型如下: Complex operator +(Complex& c1, Complex& c2); 注:operator 是关键字,operator + 就是函数名,可以描述为: 函数operator +重载了运算符+ 整数加可以想象为调用如下函数 int operator +(int a,int b) { return a+b;} [cpp] view plain copy 01.#include 03.class Complex 04.{ 05.public: 06.Complex(){real=0;imag=0;} 07.Complex(double r, double r){real=r;imag=i;} 08.Complex operator +(Complex &c2);//声明重载运算符的函数 09.void display(); 10.private: 11.double rea; 12.double imag; 13.}; 14.Complex Complex::operator +(Complex &c2)//定义重载运算符的函数 15.{ 16.Complex c; 17.c.real = real + c2.real; 18.c.imag = imag + c2.imag; 19.return c; 20.} 21.void Complex::display() 22.{ 23.cout< 24.} 25.int main() 26.{ 27.Complex c1(3,4), c2(5,-10),c3; 28.c3 = c1 +c2; //运算符+ 用于复数运算 29.cout<<“c1=”;c1.display; 30.cout<<“c2=”;c2.display; 31.cout<<“c1+c2=”;c3.display; 32.return 0; 33.} 34.运行结果: 35.c1 =(3,4i) 36.c2 =(5,-10i) 37.c1+c2 =(8,-6i) 重载运算符的规则 (1)C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。 (2)C++允许重载绝大部分的运算符 (3)重载不能改变运算符运算对象的个数 (4)重载不能改变运算符的优先级别 (5)重载不能改变运算符的结合性 (6)重载运算符的函数不能有默认的参数(7)重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少一个是类对象(或类对象的引用)。也就是说参数不能全部是C++的标准类型,以防止用户修改用于标准类型数据的运算符的性质。 (8)用于类对象的运算符一般必须重载,但有两个例外,运算符“=”和“&”不必用户重载 (9)应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能,否则不易使人理解程序 (10)运算符重载函数可以是类的成员函数,也可以是类的友元函数,还是计费成员函数也非友元函数的普通函数。 1、基于MFC对话框程序的框架代码主要由一下几个部分组成: A.应用程序类 B.对话框类 C.资源文件 D.预编译文件 2、Windows是建立在消息驱动机制上的。 3、模态对话框运行机制? 当模态对话框产生后,应用程序没有处理消息,唯一的解释就是模态对话框产生后会屏蔽其他窗体消息。事实也正是如此,创建模态对话框后,应用程序只会响应该对话框的消息,知道应用收到结束模态对话框窗体的消息后,才会把控制权交还给应用程序。 4、非模态对话框 与模态对话框不同,非模态对话框不会垄断用户的输入,用户任然可以使用其他窗体。 5、属性对话框主要分为两个部分: A.属性页 B.属性对话框架 6、属性页只是对话框的一种形式。 7、控件的逻辑顺序决定着软件中需要使用TAB进行焦点切换时的顺序排列。 8、控件按钮有四种基本类型: A.下压按钮 B.复选按钮 C.单选按钮 D.自绘按钮 9、按钮控件会向父窗口发出控件通知消息 A.BN_CLICKED:鼠标单击消息 B.BN_DOUBLECLICKED:鼠标双击击消息 C.BN_SETFOCUS:获取用户输入焦点 D.BN_KILLFOCUS:失去用户输入焦点 10、在MFC环境下,除了使用CButton类本身的成员函数来操作按钮控件,还可以使用窗体相关类的成员函数,使用这些函数可以根据按钮ID直接进行操作。 11、MFC的CEdit类封装了编辑框控件的基本操作。 12、UPPERCASES设置大写,lowerCase设置小写,Number设置只能接受数字,Password设置显示为*。 13、MFC的CListBox类封装了列表框控件的基本操作。 14、AddString:添加字符串列表项 DeleteString:删除字符串列表项 Dir:从当前目录向列表框添加文件名 FindString:在列表框中查找包含指定前缀的第一个列表项 FindStringExact:在列表框中查找与指定字符串匹配的列表项 InsertString:向列表框中插入一个列表项 ResetContentp:清空编辑框和列表框的所有内容 Selectstring:在列表框中查找字符串 15、组合框有三种模式: 简易式 下拉式 下拉列表式 16、组合框有两种形式: Dropdown样式 Drop List样式 17、MFC的CProgressCtrl类封装了进度条控件的基本操作。 18、tist->SetTimer(1,100,NULL) 设置计时器ID为1,每100ms触发一次 19、tist->KillTimer(1) 关闭计时器120、列表控件有四种呈现方式: 图标视图 小图标视图 列表视图 报表视图 21、文档视图结构是使用MFC开发基于文档的应用程序的基本框架,最主要的思想是数据的管理与显示分离。 22视图类CView23、使用AppWizard创建SDI和MDI的过程相似,主要区别是创建SDI时不生成CChildFrame类,CMainFrame的基类为CMainWnd;而创建MDI时会生成两个框架类,一个是CMainFrame类,由CMDIFrameWnd类派生而来,另一个是CChildFrame类,由CMDIChildWnd类派生而来 24、文档与视图体系 一个文档可以对应多个视图,而一个视图只能对应一个文档 文档与视图的结构的优势在于数据的管理与显示分离,在开发文档/视图体系开发应用过程时,涉及到:文档模板、文档、视图、框架窗口 25、MFC的CView类是所有视图类的基类,主要有两大工能: 将与其相关联文档的数据呈现给用户 接受用户对数据的修改,并反馈给文档 26、建立MFC单文档应用程序,实例项目名称为“single”框架会自动生成4个类: CSingleApp类:应用程序类 CMainFrame类:框架类 CSingleDoc文档类 CSingleView类:视图类 27、在MFC中使用GDI 进行绘画操作一般会涉及两类对象: 设备上下文对象 GDI对象 28、设备上下文,是一种windows数据结构,它包含与设备绘制属性相关的信息。 29、主要有一下几种GDI 对象: CPen对象:用来绘制线条 CBrush对象:用来填充绘制对象的内部 CBitmap对象:用来操作位图对象 CFont对象:用来绘制文本 CPalette对象:用于应用程序和色彩输出设备之间的接口 30、使用GDI进行图形绘制的一般流程: 创建GDI对象 创建获取得设备上下文对象 使用SelectObject把GDI对象选入设备上下文 使用图形输出函数在指定上下文中绘制图形 31、画刷其实是一个像素大小为8*8的位图,用多个相同的位图对封图形的内部进行填充 32、位图 位图是描述图形最简单直观的一种形式,把图像横向分为等间距的W列,纵向分为等间距的H列,于是这个图形的大小被定义为分辨率W*H33、键盘上的每一个健都对应一个唯一的扫描码,在windows系统中为实现设备无关的要求,需要使用虚拟键值 34、当有键盘事件发生时,设备驱动器首先获取健的扫描码,并转换为虚拟键值 35、在应用程序中响应键盘消息有两种方式: 响应本进程的键盘消息 响应系统的键盘消息 36、keybd_event只是用于产生键盘事件,至于由谁来处理他并不关心。系统捕捉到键盘事件后,会转化为键盘消息的形式派发给当前系统中拥有键盘输入焦点的应用程序。SendMessage和PostMasseage的区别在于,PostMasseage首先把消息发到指定句柄所在线程的消息队列再由线程派发。SendMessage是把消息直接发送的指定句柄的窗体或控件。而往往很多情况下。指定句柄是个控件。而对控件的消息消息处理一般都是定义在主对话框上的。除非对其进行子类化,如果使用SendMessage,消息就无法到达主对话框因而无法达到预期的效果。 37、TCP协议是一个面向连接的、可靠的协议,UDP协议是一个不可靠的、无连接的协议 38、因特网控制报文协议(Internet Control Message Protocol,ICMP) 39、套接字是一种网络编程接口,提供了一种网络数据发送和接受机制,套接字是网络通信的基础,一个套接字表示通信的一端,使用套接字可以实现数据包在网络上的传输。 40、soket函数,用来根据指定的地址协议簇、套接字类型和协议类型创建一个套接字。 listen函数,监听远程连接 accept函数,用来接受客户端连接。 sendto函数,用来向指定地址发送数据。 recv函数,用来在已建立连接的套接字上接收数据。 recvfrom函数,用来在指定套接字上接收数据。 setsockopt函数,用来设置套接字属性。 41、进程是一个正在运行的程序的实例,有两部分组成: 一个操作系统用来管理进程的内核对象。 创建时系统所分配的资源,主要是内存地址单元。 41、进程地址空间作为一个载体。包含进城的所有数据和代码以及堆和栈。为线程的运行提供保障。 42、进程是静态的43、线程也有两个部分组成: 线程内核对象;线程堆栈。 44、线程是动态的、可执行的、它总是在某个进程的环境中创建的。 45、每个线程都是运行在其所属进程的地址空间,因此线程只能访问本进程的地址空间,而其他进程对其是不可见的46、所谓‘页’,只是操作系统为了更好的管理地址空间所产生的一个逻辑上的概念,把一个固定长度的地址空间作为一个页,通常为4kb,系统在在对地址空间进行管理时,把每4kb的空间作为一个单位,最终形成内存管理的多级索引结构。 47、物理存储器和进程虚拟地址空间的映射是无序的,每一个进程虚拟地址空间也只能由一个物理存储器页来映射。 48、“地址转换机构”就是负责他们彼此之间的关联。 49、虚拟内存也有三种基本状态: 空闲:地址空间没有被占用,不能使用 保留:地址空间没有被占用,但还没有与物理存储器相关联,不能使用。 提交:且已经与物理存储器相关联,可以使用。 50、内存映射文件 内存映射文件可以在进程中保留一个地址空间区域,并把磁盘文件提交给该区域。一旦映射成功,就可以在内存中直接操作文件,而不再需要使用readfile、writefile等文件操作API。 51、情况下会使用内存映射文件: 系统使用内存映射文件加载可执行模块(.exe)和动态链接(DDL) 操作数据文件 共享内存 52、消息传递 消息传递机制并不以进程为界限,处理消息的是窗体,而与是否在同一进程无关。因而在进程间使用消息传递作为通信手段有个前提,即都是窗体应用程序。 53、共享内存的原理 使用内存共享机制,在任何一个进程内创建内存映射,却能够在其他多个进程中使用。这些进程共享的是物理内存器的同一个页面,把这些物理内存映射到虚拟内存时各个进程的虚拟地址不一定相同。当一个进程将数据写入共享内存时,其他进程可以立即获取数据变更情况,显然这种共享内存的方式是完全可以满足在进程间进行大数据快速传输任务要求的。 54、与内存映射磁盘文件一样,共享内存的本质也是内存映射机制。 55、使用系统页文件支持的内存映射文件,及共享内存。 56、进程间通信的三种基本方法:匿名管道、命名管道、邮槽 57、管道是用于进程间通信的共享内存区域。创建管道的进程称为管道服务器,而连接这两个管道的进程称为管道客户端,一个进程向管道写入信息,另外一个进程从管道读取信息 58、匿名管道 匿名管道是基于字符和半双工的,一般用于程序输入输出的重定向。如果需要获取一个基于控制台窗口应用程序的输出,此时就可以是用匿名管道,首先使用CreatePipe函数创建匿名管道。 59、命名管道的特征: 命名管道是双向的,进程间可以使用同一管道进行交互 命名管道不但可以面向字节流,还可以面向消息。所以读取进行可以读取写进程发送的不同长度的消息 多个独立的管道实例可以用同一个名称来命名。 命名管道可以用于网络间两个进程的通信,而其实现过程与本地进程通信完全一致 60、创建命名管道使用CreateNamedPipe函数 61、邮槽是实现单通道的进程间通信的通信方式。创建邮槽的进程称为邮槽服务器,向邮槽发送消息的进程称为邮槽客户端 60、创建邮槽使用CreateMailslot函数 61、windows剪贴板是一种比较简单同时也是开销比较小的进程间通信方式。 62、剪贴板通信机制 windows系统支持剪贴板IPC的基本机制室友系统预留的一块全局共享内存,可用于被各个进程暂时存储数据。写入进程首先穿件一个全局内存块,并将数据写到该内存块;接受数据的进程通过剪贴板机制获取此内存块的句柄,并完成对该内存块数据的读取。 63、剪贴板通信有5种基本情况: 文本剪贴板 位图剪贴板 自定义格式 延迟提交 多项数据 63、进程同步可分为两大类: 访问共享资源,多个进程访问进程共享资源时,需要确保资源不受破坏。 事件通知,一个线程完成某项任务后通知其他线程。 64、原子访问,是指线程对共享资源的独占式访问。 65、关键代码段,是指在执行前首先去的对共享资源的访问权,然后让代码以原子操作方式执行来访问共享资源的一种方法。 66、内核对象等待函数,其所等待的也正是内核对象的受信状态。 67、内核对象本质上只是一个内存块。 68、内核对象是操作系统对资源进行管理的单位。 69、内核对象有两种状态:已通知状态、未通知状态 70、在所有内核对象中,事件内核对象是最基本的对象,事件内核对象有两种状态:已通知状态、未通知状态。在多线程环境先经常使用事件内核对象的这种特性实现线程同步。 71、事件内核对象有两种基本类型:手动重置事件、自动重置事件。 72、等待定时器内核对象是可以在某个指定时间或者以规定的间隔发出通知信号的内核对象,一般在某个线程需要定时执行某项功能时用这种内核对项 73、信标内核对项常用于在多线程环境下控制某类资源的使用,使用信标内核对象可以让系统自动地维护资源的数量,并合理的控制线程对资源的访问情况。 74、信标的出色之处在于它们能够以原子操作方式来执行测试和设置操作,当向信标申请一个资源时,操作系统就要检验是否有这个资源可供使用,同时将可用资源的数量递减,而不让另一个线程加以干扰。只有当资源数量递减后,系统才允许另一个线程申请对资源的访问权。 75、如果线程需要访问该资源就要先获取互斥对象,所有线程都应遵循这个规则。 76、动态链接库(DLL)是Windows操作系统的基础,所有API函数都包含在DLL中。应用程序并不是只有一个可执行程序,而是由一个可执行模块和若干个DLL模块组成。当执行应用程序时,系统会把与可执行模块相链接的DLL模块加载到当前进程地址空间。 77、动态链接库(DLL)的最大特性是支持动态载入。 78、要产生可执行文件有两个步骤: 1)编译过程。编译源码,为每个C/C++源文件生成一个.obj模块,由编译器完成。 2)链接过程。把应用程序的各个.obj模块链接起来产生.exe文件,有链接器完成。 79、DLL隐式链接,是指在链接过程中,把应用程序所需要DLL模块的名字和输入符号都记录下来,使得应用程序在运行时可以动态载入该DLL。 80、与隐式链接相比,显示加载DLL主要有以下几个特性: 1)显示加载的DLL并不会在应用程序初始化时就加载,而是在运行时根据需要调用LoadLibrary或LoadLibraryEx函数来加载。 2)在应用程序输入表中没有记录。 3)隐式链接的前提是需要有DLL所对应的lib文件,如果没有lib文件就无法进行隐式链接。显示加载就没有这个限制。 81、DllMain函数是DLL的可选入口。 82、线程本地存储器(TLS)的主要作用是可以避免多个线程同时访问同一全局或者静态变量时导致的冲突。 83、TLS有两种使用方法:静态TLS和动态TLS。 84、结构异常处理有三种基本的使用方法,分别是结束异常程序、异常处理程序和顶层异常处理。 85结构化异常处理(SEH)是被作为一种系统机制引入到操作系统中的。 86、可执行文件格式(PE),其格式中得分数据结构通常定义在winnt.h中。第五篇:Windows编程知识点总结