一、语法
标识符:
由字母、数字和下划线三种字符组成,且必须以字母或下划线开头。
关键字不能作为用户定义的标识符。
用户定义标识符:
合法,char2 _abc a3 P1
不合法,int p[i] break 3a a+b class public
常量:
合法,'\n' '\102 ' '\t ' '\72'
不合法,'ABC' 1.2e0.5 M '[]'
运算符和表达式,
?结合性及优先级
例, (1) a+=a*=2 a+=(a=a*2) a=a+(a=a*2)
若初始情况下 a=3,则执行上述运算后 a=?
(2) x=a>b>c
若已知 a=4,b=3,c=5 则 x=?
(3)若已知 int a[5]={0,2,4,6,8},*p=a; 设 a的首地址为 1000,则,
执行 *p++后 表达式的值为 0,p的值为 1004
执行 ++*p后 表达式的值为 1,p的值为 1000
执行 *++p后 表达式的值为 2,p的值为 1004
?对操作数的要求
(1) (i+j)++,3++ (╳ )
++,-- 变量
(2) a%b
a,b必须为整型
12
0
?结果的类型
int n,s=0;
for(n=1;n<=10;n++)
s+=1/n;
上述结果为 1,若要得到正确结果,应用如下形式:
s+=1.0/n
或,s+=1/(float)n
?用逻辑表达式表达某个命题
如, ch<?0?||ch>?9? ch是非数字字符
x>=0&&x<=200&&x%2==0 x是 0到 200之间的偶数
? 用随机函数产生 在某一区间 的数
rand()%101 //产生 0~100之间的数字,若产生 30~100应
如何?
? &&与 ||运算并结合自增、自减运算
已知 a=b= 1; 则执行以下语句 后,各变量的值为?
--a&&++b;
++a||--b;
a=0,b=1
a=2,b=1
初始化与赋值,
错误, int a=b=c=0;
应为, int a=0,b=0,c=0;
或,int a(0),b(0),c(0);
或, int a,b,c;
a=b=c=0;
?引用
int x=5,&y=x;
输入和输出流 cin,cout
例, char c[20];
cin>>c;
若输入 how do you do
则 c的值为 how
gets(c)
则 c的值为,how do you do
改为
void main()
{
char ch=?b?,s[]=“abcde”;
cout<<ch+2; // 输出 100 (?d?的 ASCII码 )
ch=ch+2; // 输出 d
cout<<*(s+2); // 输出 c
cout<<s+2 // 输出 cde
}
cout依据其后表达式类
型决定输出内容
语句,
? if(条件表达式 )
几种等价关系
if(x) 依据 x的类型不同,分别等价于如下形式:
if(x!=0)
if(x!=?\0?)
if(x!=NULL)
if((x=getchar())!=EOF)
?switch语句
switch(a%5)
{case 0,cout<<a++;
case 1,cout<<++a;
case 2,cout<<a--;
case 3,cout<<--a;
}
若 a=2,则输出,2 0
?循环,
(1)do _while 先执行后判断,至少执行一次
for,while 先判断后执行,可能一次也不执行
for循环条件中常使用逗号表达式
void main()
{int i;
for(i=0;i<5;i+=2);
cout<<i;
}
void main()
{int i;
for(i=0;i<5;i+=2)
cout<<i<<? ?;
}
int k=3; while(k=0) k++;
for(int k=1;k==3;k++);
6
0 2 4
注意区分空循环
执行次数?
(2)break语句
x=0;
for(j=4;j<=6;j++)
{if(j%2)break;
x+=j;
}
cout<<x;
4
退出 switch语句或本层循环,
在双重循环中使用时,注意退
出的是哪一层。
数组
避免下面错误:
char s[5]={“This is a book"};
char s[10];
s = "I am fine";
不要越界
数组名是地址常量,不可被赋值
只有字符数组可整体操作
数组名做函数形参时,一维数组省略长度说明,二维数组
省略第一维的长度说明。如:
void sort(int x[ ],int n)
void fun(char[ ][10],int n)
? CString类
CString s1=“abc”,s2=def”; +,= afx.h
char a1[]=“xyz”,a2[]=“uvw”;
s1,MakeUpper(); s1=s2;
strupr(a1); strcpy(a1,a2); string.h
函数
定义,
? 函数头的末尾无分号
? 若函数类型为非 void 类型,则函数中应有 return语句
返回同类型的数据。
? 参数一一说明类型
调用,
以语句的形式调用(函数类型为 void)
以表达式形式调用(函数类型非 void)
说明,
函数定义在后调用在前时需要。
参数传递,
值参数 ——单向
地址参数 (数组名或指针变量 )-------参数本身单向传递,
但指针变量所指内容或数组元素的改变是双向的
引用参数 ————形参的改变影响实参 。
参数缺省,
void fun(int i,int j,int k,int m=3,int n=4)
假设函数调用语句为:
fun(1,2); //错误, 至少应有三个实参
fun(10,20,30,,50); //错误, 只能从左至右匹配
函数重载要求:
?参数个数不同
?参数类型不同
函数名相同
变量的作用域和存储类别
静态变量只初始化一次,而动态变量每调用一次函数,便初
始化一次。
test()
{int i=0;static int j=0;
i++;j++;
cout<<i<<j<<endl;
}
main()
{int i;
test();
test();
}
i=1,j=1
i=1,j=2
当全局变量和局部变量同名时,局部变量起作用
int m=10;
void a(int n)
{n=15/n;m=m/2;}
main()
{int n=3;
a(n);
printf("n=%d,m=%d\n",n,m);
}
n=3,m=5
void cube(int x)
{x=x*x*x;}
void main()
{int x=5;cube(x);
cout<<x<<endl; }
void cube(int *x)
{*x=(*x)*(*x)*(*x); }
void main()
{int x=5;cube(&x);
cout<<x<<endl; }
void cube(int x)
{x=x*x*x; return(x);}
void main()
{int x=5; x=cube(x);
cout<<x<<endl;
}
void int x=5;
void cube( )
{x=x*x*x;}
void main()
{cube();
cout<<x<<endl; }
例,分析下面程序
传值调用
结果为 5
传址调用
结果为 125
虽为传值调用,但
返回值赋值给 x,故
结果为 125
无参函数,使用
的全局变量,故
结果为 125
#include "iostream.h"
void cube(int &x)
{x=x*x*x;}
void main()
{int x=5; cube(x);
cout<<x<<endl;}
引用调用
结果为 125
指针
运算
float *p,*q;
若已知 p=1000,则 q=1004 则, q-p的值为 1
p+2的值为 1008
int a=3,*p=&a,*q,&b=a;
q=new int(6); // *q的值为 6,注意与 q=new int[6]的区别
delete p; (?)
delete q;
p是指向变
量 a的指针 b是变量 a的引用
指针和数组
若,int a[5]={1,3,5,7,9},*p=a+1;
则,*p+1的值为 4
*(p+1)的值为 5
注意一些概念的区别:
若有函数,void fun(int *p,int &q)
则相应的函数调用语句:
void main()
{int a,b;
……
fun(&a,b);
……}
指针变量做形参 变量的引用做形参
变量的地址做实参
变量做实参
?例,分析下面程序
#include,stdio.h”
void f(float *p1,float *p2,float *s)
{s=new float;
*s=*p1+*p2;
}
void main()
{float a=1.0,b=2.0,*s=&a;
f(&a,&b,s);
cout<<*s<<endl;
}
1.0
形参的指向已变,与实参
不再指向相同的内容
返回指针值的函数
求一维数组 a中的最大值 。
int a[8]={45,6,35,-12,100,11,3,-40};
void main()
{int *p,____(1)____;
p=max( );
cout<<*p;
}
int *max( ) //函数的返回值为指针
{int i,k=0; int t=a[0];
for(i=1;i<8;i++)
if(t<a[i])
{t=a[i]; k=i; }
return(___(2)___);
}
*max()
&a[k]
函数定义在调用之后
故需函数说明
void maxmin(int a[],int n,int *p,int *q)
{int i,max=a[0],min=a[0];
for(i=1;i<n;i++)
{ if (a[i]>max)max=a[i];
if (a[i]<min) min=a[i]; }
*p=max; *q=min;
}
void main()
{ int i,n,a[100],max,min;
cin>>n;
for (i=0;i<n;i++)
cin>>a[I];
maxmin(a,n,&max,&min);
cout<<"max= "<<max<< " min= " <<min<<endl;
}
结构体
struct student{
int num;
char name[20];
float score;
}st={123456L,”zhang san”,88},stclass[30],*p=&st,st1;
st.score=78; strcpy(stclass[5].name,”li si”);
p->score=78; strcpy(p->name,”li si”);
st1=st;(结构变量之间可整体赋值)
I/O流类
?打开文件的方式:
创建流类对象的同时打开文件
ofstream outfile("abc.dat");
fstream outfile("abc.dat",ios::out);
先创建流类对象, 再打开文件
ofstream outfile;
outfile.open("abc.dat");
?几个读写成员函数
ifstream
ofstream
fstream
get,getline,put,write,read
char s[10]=“abcdefg”;
cout.write(s,2).put(?a?);
文件打开时,默认
的模式为文本文件
二进制文件需显式
地打开:
ios::binary
常用内部函数:
?字符串处理函数
需使用 #include,string.h”
?strlen(str) 如,strlen(,\nabcd,)的结果为 5(不包含对‘ \0?的统计)
?strlwr(str)
?strupr(str)
?strcpy(str1,str2) 如:
char s1[30]=“abcd”;
strcpy(s1+2,“123”);
cout<<s1;
输出结果为,ab123
?strcat(str1,str2)
?strcmp(str1,str2)
需使用 #include,stdio.h”
gets,puts()
需使用 #include,math.h”
sqrt,fabs
面向对象程序设计基础
三个特性
封装性
继承性
多态性
类定义形式:
?包括成员函数的两种实现方式
?数据成员、成员函数通常的访问权限
?类体中不允许对数据成员初始化
访问权限
public,可以被外部程序访问
private:只能被该类的成员函数访问
protected,能被该类和派生类的成员函数访问。
对象的成员表示形式
数据成员,<对象名 >, <成员名 >
或,<对象指针名 >-><成员名 >
成员函数,<对象名 >, <成员名 >( <参数表 >)
或,<对象指针名 >-><成员名 >(<参数表 >)
#include <iostream.h>
class Cpoint
{private:
int X,Y;
public:
Cpoint(int x,int y)
{X=x; Y=y;}
void print()
{cout<<X<<Y; }
};
void main()
{
Cpoint p1(3,5),*p2;
p1.print();
p2=new Cpoint(8,10);
p2->print();
}
对象初始化
构造函数和析构函数的特点
缺省构造函数自动生成的条件
派生类的继承关系,
如:
在公有继承中,基类的私有成员将成为其派生类的什么成员?
派生类的定义形式、继承关系、构造函数
虚函数和抽象类的概念
二、算法
1.求级数和
2,素数
(1)
int isprime(int m)
{int i;
for(i=2;m%i!=0;i++);
return(i= =m);
}
(2)
#include,math.h”
........
for(i=2;i<=sqrt(m);i++)
if(m%i= =0)break;
if(i= =k+1)
......
else
......
3,最大公约数和最小公倍数
int gcd(int m,int n)
{int h;
while(h=m%n)
{m=n;n=h;}
return (n);
}
4,判断回文
( 1) 判断输入的字符串是不是回文
#include“stdio.h”
#include“string.h”
void main()
{ char s[80],*p=s,ch,s1[80]; int i,j=0;
gets(s); strcpy(s1,s);
while(*p++!=?\0?)j++;
for(i=0;i<j/2;i++)
{ ch=s[i]; s[i]=s[j-i-1]; s[j-i-1]=ch; }
if(strcmp(s,s1)==0)
cout<<“yes”<<endl;
else
cout<<“no”<<endl;
}
( 2)判断输入的整数是不是回文数
void main()
{int a,b,c=0,c1;
cin>>a;
c1=a;
while(a!=0)
{b=a%10;
c=c*10+b;
a/=10;
}
if(c1==c)
cout<<“yes”;
else
cout<<“no”;
}
构造 a的逆序数
a:123 c:321
5.数组
(1)冒泡法排序
for(i=0;i<n-1;i++) /*从小到大排序 */
for(j=0;j<n-1-i;j++)
if(a[j]>a[j+1])
{temp=a[j];a[j]=a[j+1];a[j+1]=temp;}
(2)选择法排序
for(i=0;i<n-1;i++)
{k=i;
for(j=i;j<n;j++)
if(a[k]<a[j])k=j;
if(i==k){w=a[i];a[i]=a[k];a[k]=w;}
}
( 3)插入、删除、平移
(程序略,请参阅教材及习题 )
( 4), 查找
二分法查找
?二分法查找
int find(a,n,x)
int a[],n,x;
{int i,mid,bot=0,top=n-1;
for(i=0;i<n;i++)
{mid=(bot+top)/2;
if (x == a[mid])
break;
else if (x>a[mid])
bot = mid+1;
else
top = mid-1;}
if(i<n) return 1;else return 0;
}
7,字符串
(1) 求长度 strlen函数
long len(char s[])
{long i=0;
while(s[i]!='\0')i++;
return i;
}
(2) 复制 strcpy函数
void copy_string(from,to)
char *from,*to;
{while(*from!='\0')
*to++=*from++;
*to='\0';
}
(3) 复制前 n个字符
(4)连接 strcat函数
#define SIZE 20
char *strcat1(s1,s2)
char *s1,*s2;
{char *p;
p=s1;
while(*p++);/*空循环 */
--p;
while(*p++=*s2++ );/*空循环 */
return(s1);
}
(5)比较字符串 strcmp函数
int cmp(char s1[],char s2[])
{int i=0,r;
while(s1[i]= =s2[i]&&s1[i]!='\0')i++;
if(s1[i]= ='\0'&&s2[i]= ='\0')
r=0;
else
r=s1[i]-s2[i];
return (r);
}
(6)查找
#define NULL 0
char *match(s,c)
char s[],c;
{int i=0;
while(c!=s[i]&&s[i]!='\0')i++;
if(s[i]!='\0')return(&s[i]); else return(NULL);
}