第二章
C语言复习及 C++基础知识
2.1.1 C++的起源
2.1.2 C++的特点
*.c C的源程序
以下的文件 C和 C++都可用,
*.h C的 头包含文件
*.cpp C++的源程序
*.hpp C++的 头包含文件
/* */ C的注释
// <CR> C ++的注释
2.1 C++的起源和特点
1
2.2 C++源程序的构成
2.2.1 C++程序的一般格式
〖 例 2.1 〗 说明 C++构造的示例程序
#include <iostream.h> // 系统头文件
int add(int a,int b); //函数原型的说明
int main( ) //主函数
{ int x,y,sum; //定义三个整型变量
cout<<"输入二个数,"<<'\n'; //界面,提示用户输入二个数
cin>>x; //从键盘输入变量 x的值
cin>>y; //从键盘输入变量 y的值
sum=add(x,y); //调用函数 add,将函数返回值赋给变量
sum
cout<<"二数和是,"<<sum<<'\n'; //输出
return 0;
}
int add(int a,int b) //定义函数 add,函数 (返回 )值为整型
{ int c; //定义临时变量 c
c=a+b; //求和
return c; //将 c的值返回,通过 add带回调用处
}
2
2.2.2 C++程序的结构特点
1.注释
2.包含文件及头文件
3.语句
4.标准输入与输出
printf(格式说明,表达式表列 );
scanf(格式说明,地址表列 );
cout<<
cin>>
5.新行
, \n” endl
6.主函数
void main( ) {…….}
7,一般的函数
函数头 int add (int a,int b)
函数体 { int c; //变量定义
c=a+b; //执行部分
return c;
} 3
2.3 C++在非面向对象方面的一些特性
2.3.1 注释行
/* */ C的注释
// <CR> C ++的注释
2.3.2 新的 I/O流
cin是标准输入流,在程序中代表标准输入设备,即键盘。
运算符,>>”表示向右
cout是标准输出流,在程序中代表标准输出设备,即屏幕。
运算符,<<”表示向左
使用 cin或 cout进行 I/O操作时,在程序中必须嵌入头文件 iostream.h
//例 2.2
#include <iostream.h>
int main( )
{ char name[20];
cout<<"Hello,your name:";
cin>>name;
cout<<name<<endl;
return 0;
}
//例 2.3
#include <iostream.h>
void main( )
{ int x=25;
cout<<hex<<x<<?'<<dec<<x<<''<<oct<<
x<<'\n';
} 4
2.3.3 灵活的局部变量说明
int f( )
{ int i;
i=10;
int j;
j=25;
for(int k=5;k>=0;k--) ….,
……,
}
以上的写法在 C程序中都是错误的,但在 C++程序中都是正确的。
5
2.3.4 结构、联合和枚举名可直接作为类型名
定义 枚举类型名,
enum bool {FALSE,TRUE};
定义 结构枚举类型名,
Struct student {
int sno;
char *sneme;
};
C语言中 定义 枚举类型变量,enum bool done;
定义 结构类型变量,struct student s1,s2;
C++语言中 定义 枚举类型变量,bool done;
定义 结构类型变量,student s1,s2;
6
2.3.5 const修饰符
#define LIMIT 100
这里 LIMIT 是一个标志,代表 100
const int LIMIT=100;
这里 LIMIT 是一个常量名,在内存有空间放了 100,因此有地址,
可以用指针指向这空间,但不能修改它。
int i=100;
这里 i 是一个变量名,在内存有空间放了 100,因此有地址,可以
用指针指向这空间,且可以改放别的整数。
(1) 可以用一个指向常量的指针变量指向常量,
const char *name=“chen”;
name[3]=?a?; //错误
name=“zhang”;//正确
(2)指针常量
char *const name=“chen”;
name[3]=?a?; //正确
name=“zhang”; //错误
(3) const char *const name =“chen”;
nam
e
chen 常量
zhang 常量
X
a nam
e
chen
zhang
常量
a
n a
X
7
//例 2.4
#include <iostream.h>
main( )
{ int a=1;
#define T1 a+a
#define T2 T1-T1
cout<<"T2 is "<<T2<<endl;
return 0;
}
cout<<“T2 is,<<a+a-a+a<<endl;
//例 2.5
#include <iostream.h>
main( )
{ int a=1;
const T1=a+a;
const T2=T1-T1;
cout<<"T2 is "<<T2<<endl;
return 0;
}
T2 a+
a
a+
a
T1-T1
8
2.3.6 内置函数
//例 2.6
#include <iostream.h>
int main( ) 3次
{ for(int i=1;i<=3;i++)
cout<<"r="<<i<<" area="<<circle(i)<<endl;
return 0;
}
在函数前加以 inline,成为 内置函数
#include <iostream.h>
int main( ) 代码嵌入
{ for(int i=1;i<=3;i++)
cout<<"r="<<i<<" area="<<circle(i)<<endl;
return 0;
}
float circle(float r)
{ return 3.1416*r*r; }
inline float circle(float r)
{ return 3.1416*r*r; }
9
//例 2.7
#include <iostream.h>
#define doub(x) x*2
int main( )
{ for(int i=1;i<=3;i++)
cout<<i<<" doubled is "<<doub(i)<<endl;
cout<<"1+2 doubled is "<<doub(1+2)<<endl;
return 0;
}
//例 2.8
#include <iostream.h>
inline int doub(int x)
{ return x*2; }
int main( )
{ for(int i=1;i<=3;i++)
cout<<i<<" doubled is "<<doub(i)<<endl;
cout<<"1+2 doubled is "<<doub(1+2)<<endl;
return 0;
} 10
2.3.7 函数原型
返回类型 函数名(参数表) ;
//例 2.9
#include <iostream.h>
void write(char *s); //函数原型或叫函数申明
void main( )
{ write("Hello,world!"); }
void write(char *s)无分号
{ cout<<s<<endl; }
11
2.3.8 带有缺省参数的函数
C++在说明函数原型时,可以为一个或多个参数指定缺省参数值,
以后调用此函数时,若省略其中某一实参,C++自动以缺省值作为
相应參数的值。
int special(int x=5,float y=5.3);
合法的调用;
special();
special(25);
special(100,79.8);
说明,
(1)所有取 缺省值参数都必须出现在不 取 缺省值参数的右边。
int fun(int i,int j=5,int k) 是错误的
int fun(int i,int k,int j=5) 是正确的
(2)调用时,若某个参数 省略,则其后的参数皆应省略。
不合法的调用;
special(,21.5); 12
2.3.9 函数重载
C++中,只要函数的參数的类型不同,或者參数个数不同,或者二
兼有之,几个函数可以用相同的函数名。称为函数重载
//**例 2.10
#include <iostream.h>
int square(int i)
{ return i*i; }
float square(float f)
{ return f*f; }
double square(double d)
{ return d*d; }
void main( )
{ int i=12;
float f=3.4;
double d=5.67;
cout<<i<<'*'<<i<<'='<<square(i)<<endl;
cout<<f<<'*'<<f<<'='<<square(f)<<endl;
cout<<d<<'*'<<d<<'='<<square(d)<<endl;
} 13
//**例 2.11
#include <iostream.h>
int mul(int x,int y)
{ return x*y; }
int mul(int x,int y,int z)
{ return x*y*z; }
void main( )
{ int a=3,b=4,c=5;
cout<<a<<'*'<<b<<'='<<mul(a,b)<<endl;
cout<<a<<'*'<<b<<'*'<<c<<'='<<mul(a,b,c)<<endl;
}
说明,
(1)重载函数应在参数个数或参数类型上有所不同,编译才能识别调
用哪一个重载版本,即使返回类型不同也不行。
如,int mul(int x,int y) ;和 double mul(int x,int y); 是不能重载的。
(2)一般而言,重载函数应对不同的参数情况执行相同的功能。
如,abs(int x); 和 abs(float x);都是求绝对值,一个是整数的绝对值
,一个是实数的。 14
2.3.10 作用域运算符,,
当全局变量和局部变量同名时,函数中不能使用全局变量。
//**例 2.12
#include <iostream.h>
int avar=10; //全局变量
void main( )
{ int avar=25; //局部变量
cout<<"avar is "<<avar<<endl;
} 局部变量
可用作用域运算符,,//**例 2.13
#include <iostream.h>
int avar;
void main( )
{ int avar;
avar=25; //局部变量 avar
,:avar=10; //全局变量 avar
cout<<"local avar = "<<avar<<endl;
cout<<"global avar = "<<::avar<<endl;
} 15
2.3.11 无名联合
C语言的共用体,
union data
{ int i;
char ch;
float f;
}
union data a,b,c;
引用,a.i a.ch a.f 等
C++的无名联合,
union
{ int i;
char ch;
float f;
}
直接可用 i ch f 等
16
a 4字

i
ch
f
2.3.12 强制类型转换
C语言的强制类型转换,
int i=10;
float x=(float)i;
C++的强制类型转换,
int i=10;
float x=float(i);
float y=(float)i;
两种方法 C++都可以。
17
2.3.13 new和 delete
C语言用函数 malloc()和 free()动态分配内存和释放动态分配的
内存。 C++使用运算符 new和 delete能更好、更简单地进行内存的分
配和释放。
如 C语言中用,
int *p;
p=(int *) malloc ( sizeof(int) );
*p=10;
而 C++语言中 //**2.14
#include <iostream.h>
void main( )
{ int *p; //定义一个整型指针变量 p
p=new int; //动态分配一个整型存储区,并把首地址赋给 p
*p=10;
cout<<*p<<endl;
delete p; //释放 p指的空间,撤消指针 p
}
new 和 delete 的优点,
(1)new可以自动计算所要分配内存的类型的大小,而不必用 sizeof
来计算。
p
18
(2)new能够自动返回正确的指针类型,而不必进行类型转换。
(3)可以用 new将分配的对象初始化。
(4)new 和 delete 都可以被重载,允许建立自定义的分配系统。
说明,
(1)使用 new可以为数组动态分配内存空间。
int *pi=new int[10];
int *pi=new int[2][3][4];
(2)new可在为简单变量分配内存空间的同时,进行初始化。
//**例 2.15
#include <iostream.h>
void main( )
{ int *p;
p=new int(99); //动态分配内存,并将 99作为初始值赋给它
cout<<*p<<endl;
delete p;
}
(3)释放动态分配的数组存储区,
delete [ ]p;
19
(4)使用动态分配内存时,分配失败,将返回空指针( NULL)。
因此通常要对内存的动态分配是否成功进行检查。
分配内存失败, p=NULL
//**例 2.16
#include <iostream.h>
void main( )
{ int *p;
p=new int;
if(!p) //若分配内存失败
{ cout<<"allocation failure\n";
return ;
}
*p=20;
cout<<*p<<endl;
delete p;
}
p NULL
20
2.3.14 引用
引用可为变量起别名,主要有变量的引用、函数參数的引用、函数
返回值的引用。
1.引用变量 type &
//**例 2.17
#include <iostream.h>
void main( )
{ int i;
int &j=i; // i 又叫 j i
i=30; j
cout<<"i="<<i<<"j="<<j<<"\n";
j=80;
cout<<"i="<<i<<"j="<<j<<"\n";
cout<<“Address of i,<<&i<<“\n”; //显示 i 的地址
cout<<"Address of j "<<&j<<"\n";
}
(1)定义引用时,必须立即对它进行初始化,不能以后再赋值 。
int i; int &j; //错误 j=i; 21
(2) 引用实际上是一种隐式指针,可以少用, *” 号 //**例 2.18
#include <iostream.h>
void main( )
{ int i=15; //整型变量 i
int *iptr=&i; //iptr指向 i
int &rptr=i; //rptr引用 i
cout<<"i is "<<i<<endl;
cout<<"*iptr is "<<*iptr<<endl;
cout<<"rptr is "<<rptr<<endl;
i=29;
cout<<" After changing i to 29"<<endl;
cout<<"i is "<<i<<endl;
cout<<"*iptr is "<<*iptr<<endl;
cout<<"rptr is "<<rptr<<endl;
}
i is 15 i is 29
*iptr is 15 *iptr is 29
rptr is 15 rptr is 29
iptr
i
rptr
22
(3)引用不可重新赋值,不可使其作为另一个变量的别名。
int i,k;
int &j=i;
j=&k; //错误
(4)引用不同于普通变量。
int &b[3]; //不能建立引用数组
int &*p; //不能建立指向引用的指针
int &&r; //不能建立引用的引用
(5)当使用取地址运算符时 &,取的是被引用变量的地址。
int num=50;
int &ref=num;
int *p=&ref;
则 p中保存的是变量 num的地址。
2,引用參数
引用參数的方法可以代替 C语言中的指针地址调用的方式。
23
//**例 2.19 C语言中的指针地址调用的方式
#include <iostream.h>
void swap(int *m,int *n)
{ int temp;
temp=*m;
*m=*n;
*n=temp;
}
void main( )
{ int a=5,b=10;
cout<<"a="<<a<<" b="<<b<<endl;
swap(&a,&b);
cout<<"a="<<a<<" b="<<b<<endl;
}
a=5 b=10
a=10 b=5
24
m &a
a
tem
n &b
b
//**例 2.20 引用參数的方法
#include <iostream.h>
void swap(int &m,int &n)
{ int temp;
temp=m;
m=n;
n=temp;
}
main( )
{ int a=5,b=10;
cout<<"a="<<a<<" b="<<b<<endl;
swap(a,b);
cout<<"a="<<a<<" b="<<b<<endl;
return 0;
}
a=5 b=10
a=10 b=5 25
m
a
tem
n
b
3,引用返回值
函数可返回一个引用,其目的是可将函数用在赋值运算符的左边。
//**例 2.21
#include <iostream.h>
int a[]={1,3,5,7,9};
int &index(int); //声明返回引用的函数
void main( )
{ index(2)=25; //将 a[2]重新赋值为 25
cout<<index(2)<<endl;
}
int &index(int i)
{ return a[i]; }
26
4,引用举例
例 2.21 //引用参数和引用返回值
#include <iostream.h>
int &max(int &num1,int &num2);
int &min(int &num1,int &num2);
main( )
{ int num1,num2;
cout<<"输入第一个数,";
cin>>num1;
cout<<"输入第二个数,";
cin>>num2;
max(num1,num2)=0;
cout<<"\n把大的数置成 0 后,这两个数是,";
cout<<'\n'<<num1<<" 和 "<<num2<<'\n';
cout<<"\n再一次输入二个数,\n";
cout<<"输入第一个数,";
cin>>num1;
cout<<"输入第二个数,";
cin>>num2; 27
min(num1,num2)=0;
cout<<"\n把小的数置成 0 后,这两个数是,";
cout<<'\n'<<num1<<" 和 "<<num2<<'\n';
return 0;
}
int &max(int &num1,int &num2) //两数中找大数
{ return (num1>num2)?num1:num2; }
int &min(int &num1,int &num2) //两数中找小数
{ return (num1<num2)?num1:num2; }
运行结果,
输入第一个数, 45
输入第二个数, 78
把大的数置成 0 后,这两个数是,
45 和 0
再一次输入二个数,
输入第一个数, 13
输入第二个数, 56
把小的数置成 0 后,这两个数是,
0 和 56 28
2.4 存储类
存储类 类型修饰符 类型 变量名表列 ;
存储类 auto static extern register
类型修饰符 const volatile
2.4.1 自动变量和寄存器变量
2.4.2 静态变量
2.4.3 外部变量
29
2.5 基本运算符和表达式
2.5.1 关系运算符
2.5.2 算术运算符
2.5.3 逻辑运算符
2.5.4 位运算符
2.5.5 条件运算符
2.5.6 逗号表达式
2.5.7sizeof运算符
2.6赋值及运算顺序
2.7 类型转换
30
2.8 语句
2.8.1 表达式语句、空语句和块语句
2.8.2 选择语句
1,if 语句
2,switch 语句
2.8.3 循环
1,while 语句
2,do while 语句
3,for 语句
2.8.4 转移
1,break 与 continue 语句
2,goto 语句
2.8.5 return 语句
31
2.9 函数
2.9.1 函数的基础知识 函数先声明再调用后定义的例子
#include <iostream.h>
void main( )
{ int a,b,c;
int sum(int,int); //先申明 sum()函数
a=25; b=36;
c=sum(a,b); //调用 sum()函数
cout << c << endl;
}
int sum(int x,int y) //定义 sum()函数
{ int temp;
temp=x+y;
return temp;
}
32
//习题 函数 (7.1)
#include <stdio.h>
void main()
{
int m,n,l,s;
int maxj(int a,int b);
int minb(int a,int b);
printf("输入个正整数,");
scanf("%d,%d",&m,&n);
if (m>0 && n>0) {
l=maxj(m,n);
s=minb(m,n);
printf("%d和 %d的最大公约数为
%d\n",m,n,l);
printf("%d和 %d的最小公倍数为
%d\n",m,n,s);
}
else printf("输入了负数 !\n");
return;
}
int maxj(int a,int b)
{ int r,t;
if(a<b) {t=a;a=b;b=t;}
r=a%b;
while(r!=0){
a=b; b=r;
r=a%b;
}
return b;
}
int minb(int a,int b)
{ int r;
r=maxj(a,b);
if (r!=0)
return a*b/r;
else
return 0;
}
s
l
n 78
m 56
t
r
b 78
a 56
r
b 78
a 56
33
//习题 函数 (7.5)
#include <iostream.h>
#include <stdio.h>
#include <string.h>
void main()
{ char a[255];
void convert(char b[]);
printf("请输入一个字符串, \n");
gets(a);
convert(a);
printf("该字符串反序为, \n");
puts(a);
return;
}
void convert(char b[])
{ int l,i;
char c;
l=strlen(b);
for(i=0; i<=l/2 ;i++){
c=b[i]; b[i]=b[l-i-1]; b[l-i-1]=c;}
return ;
} c
a
b
a[1] a[0]
b[1] b[0]
a c b d e f
a[254]
\0
34
m#include <stdio.h>
#include <math.h>
void main()
{ float a,b,c,d,x[2];
void root0(float a,float b,float c,float d,float x[]);
void root1(float a,float b,float c,float x[]);
void root2(float a,float b,float c,float d,float x[]);
printf("请输入一元二次方程的三个系数 a,b,c:\n");
scanf("%f,%f,%f",&a,&b,&c);
if(a<=1e-6) printf("不是一元二次方程 !\n");
else {
printf("方程 (%4.1f)x*x+(%4.1f)x+(%4.1f)=0\n",a,b,c);
d=b*b-4*a*c;
if (d<0){
root0(a,b,c,d,x);
printf("由于 b*b-4*a*c<0 因此有二个虚根,\n");
printf("x1 = %f + %f i\n",x[0],x[1]);
printf("x2 = %f - %f i\n",x[0],x[1]);
}
else if(d==0){
root1(a,b,c,x);
printf("由于 b*b-4*a*c=0 因此有一个重根,\n");
printf("x1 = %f \n",x[0]);
printf("x2 = %f \n",x[1]);
}
x[1]
x[0]
35
void root2(float a,float b,float c,float d,float x[])
{ float r,i;
r=-b/(2*a); i=sqrt(d)/(2*a);
x[0]=r-i; x[1]=r+i;
}
void root1(float a,float b,float c,float x[])
{ x[0]=x[1]==-b/(2*a);
}
void root0(float a,float b,float c,float d,float
x[])
{ x[0]=-b/(2*a); x[1]=sqrt(-d)/(2*a);
}
else{
root2(a,b,c,d,x);
printf("由于 b*b-4*a*c>0 因此有二个实根,\n");
printf("x1 = %f \n",x1);
printf("x2 = %f \n",x2);
}
}
return;
}
36
2.9.2 参数传递及函数返回值
(1) 值传
一般变量
(2) 传地址
结构,数组
(3) 传引用
一般变量,结构,数组
缺省参数
2.9.3 使用 C++系统函数
37
2.10 数组
定义 类型 数组名 [大小 ];
int a[4;];
int b[3][4];
int c[2][3][4];
使用时数组元素 数组名 [表达式 ]
a[0]=10; i=3; a[i]=5;
b[0][3]=20;
初始值 定义时
int a[]={2,4,6,8,10};
int b[][3]={{2,4,6},{8,10,12}};
38
2.11 指针
定义 类型 *指针变量名 ;
2.11.1 使用指针
取地址运算符 &
取内容运算符 *
位移取值 [ ]
#include <iostream.h>
void main( )
{ int a[10]={2,4,6,8,10};
for(int *p=a;p<a+10;p++)
cout << p[+0] <<endl;
}
这里 p[+0] 位移 +0,等价于 *p
p=a; p[+2] 即 *(p+2) p[-i] 即 *(p-i)
39
2.11.2 指针运算
1,赋值
int x,*px,*q;
px=&x; q=px; 表示 q 和 px 同指一个地方 (q跟着 px指 )
2,比较
px= =q q!=px 判断 q 和 px 是否同指一个地方
p < q 判断 p 和 q 指在数组元素的前后
3,移动指针
p=p+3; ++ -- 运算
y=*px++; //y=*(px++);
y=*++px; //y=*(++px);
y=++*px; //y=++(*px);
y=(*px)++;
40
2.11.3 指针和数组
1,指向一维数组的指针 int a[4],*p;
p=a; 或 p=&a[0]; 即 p 指向 a[0];
2,指针数组
许多个指针变量在一起都可用来指向整数
int *pa[2]; char *pc[5][7];
例 #include <iostream.h>
void main( )
{ int a[2][3]={{2,4,6},{8,10,12}};
int *pa[2]; //有二个指针 pa[0] 和 pa[1]
pa[0]=a[0]; pa[1]=a[1];
for (int i=0; i<2; i++)
for(int j=0; j<3; j++,pa[i]++)
cout << "a["<<i<<"]["<<j<<"]=” <<*pa[i]<<endl;
}
41
3,指向整个数组的指针 (行指针 )
如,int (*a)[5];
int b[2][5]={0,1,2,3,4,5,6,7,8,9}
a=b; a b 0 1 2 3 4
5 6 7 8 9
#include <iostream.h>
void main( )
{ int (*a)[5];
int b[2][5]={0,1,2,3,4,5,6,7,8,9};
a=b;
for(int i=0;i<5;i++)
cout << i <<":"<< *(*a+i)<<endl;
a++;
for(int i=0;i<5;i++)
cout << i <<":"<< *(*a+i)<<endl;
}
42
一维数组的地址
int a[4];
a+0 是第 0 列的 地址 a+i 是第 i 列的 地址
*( a+0) 是第 0 列的 数据 *(a+i) 是第 i 列的 数据
地址 a 数据 *a
&a[0] a[0]
一维数组的指针
int a[4],*p;
p=a;
可以 p++
指针 p 数据 *p
a[0]
43
二维数组的地址 *a a[0]
int a[3][4]; *(a+i)+j是第 i 行 第 j 列 地址
*(*(a+i)+j)
a+0 是第 0 行 的 地址
………,
a+i 是第 i 行 的 地址
*( a+0)是第 0 行 第 0 列的 地址 …….,*(a+0)+j是第 0 行 第 j 列的 地址
*(a+i)是第 i 行 第 0 列的 地址 ……..,*(a+i)+j是第 i 行 第 j 列的 地址
*(*(a+0)+0)是第 0行 第 0列的 数据,.(*(a+0)+j) 是第 0行 第 j列的 数据
*(*(a+i)+0)是第 i行 第 0列的 数据 …,*(*(a+i)+j) 是第 i行 第 j列的 数据
行地址 a+0
列地址 *(a+0)
行地址 a+i
44
二维数组的指针 *a a[0]
int a[3][4]; (p+i*4+j)是第 i行 第 j列 地址
(1) int *p;(小指针 )
p=*a;∨
p=a; ㄨ
p=a[0]; ∨ *(p+i*4+j)
p=&a[0][0]; ∨
元素地址, p=*a+j; p+j p++;
元素数据, *p *(p+j) p[j]
*( a+0)是第 0 行 第 0 列的 地址 …….,*(a+0)+j是第 0 行 第 j 列的 地址
*(a+i)是第 i 行 第 0 列的 地址 ……..,*(a+i)+j是第 i 行 第 j 列的 地址
*(*(a+0)+0)是第 0行 第 0列的 数据,.(*(a+0)+j) 是第 0行 第 j列的 数据
*(*(a+i)+0)是第 i行 第 0列的 数据 …,*(*(a+i)+j) 是第 i行 第 j列的 数据
p 当一 维数组名用但可 p=p+i p++ 走 (i)一行
元素地址, *p+j 数据, *(*p+j) (*p)[j]
列地址 *(a+0)
45
struct student {
int num;
float score;
struct student
*next
};
struct student *p;
next num score
结点
#include <stdlib.h>
申请空间函数,malloc(字节数 )
测试字节运算符,sizeof(类型 )
p=(struct student * )malloc(sizeof(struct student));
释放空间函数,free(指针);
free( p );
next num score
结点
p
46
p1=p2=(struct student * )malloc(LEN);
scanf(“%d,%f”,&p1->num,&p1->score);
next num score
结点 p1 p2
20101 89.5
head NULL
n= 0 1
head=p1;
head
next num score
p1
p1=(struct student * )malloc(LEN);
20103 90
2
(n=2) p2->next=p1;
p2=p1;
p
2
scanf(“%d,%f”,&p1->num,&p1->score);
next num score
p
1
0
NULL
p1->num==0
47
p p
01 03 07 08 11 NULL head
p
1
p
2
p1 p2
01 03 07 08 11 NULL head
p
0
05
p
1
p
01 03 08 11 head NULL
p
1 p2
48
2.11.4 引用
引用可为变量起别名,它主要用作函数参数以及函数的返回类
型。有参数引用和返回值引用。
1,引用说明
int num=50;
int& ref=num;
表示放整数 50 的内存空间 可叫 num,又可叫 ref
引用实质上是为另一个变量建立别名。
2,引用参数 (传引用 )
49
3,返回引用的函数
当一个函数的返回值需重新赋值的时候,我们也可对
返回值进行引用,这时函数可出现在赋值号的左边。
这种函数称为返回引用的函数。
形式 类型 & 函数名 (参数 )
#include <iostream.h>
int a[]={2,4,6,8,10,12};
int& index(int i);
void main( )
{ index(3)=16; //index(3) 即返回值 a[i],i=3,a[3]改为 16
cout<<index(3)<<endl; cout <<a[3]<<endl;
}
int& index(int i)
{ return a[i]; }
注意, 返回值是函数内的局部变量时不能引用
50

#include <iostream.h>
int e(int i)
{ return i+1; }
int &f()
{ int i=1;
return ++i;
}
int g(int &i)
{ i=i+1;
return i;
}
main()
{
int r1=e(3);
int &r2=e(4);
int r3=f();
int &r4=f();
int a=0,b=0,c=0,d;
d=g(4);
a+=g(g(c));
b+=g(e(3));
return 1;
}
51
2.11.5 void类型指针
void指针是一个特殊指针,它可以指向任一类型的 C++对象。
void main()
{ void *vp; int i=5; floatf=7.8; char c='A';
int *ip; float *fp; char *cp;
ip=&i; vp=&i;
cp=&c; vp=&c;
fp=&f; vp=&f;
vp=ip; vp=fp; vp=cp;
ip=vp; cp=vp; fp=vp; //错误
}
52
2.12 类型定义
typedef 类型名 标识符
2.13 指针和动态内存分配
C++的基本操作符 new 和 delete
分配内存, 指针变量名 =new 类型 [大小 ];
int *ip;
ip=new int[5];
释放内存
delete ip;
53
2.14 指针和函数
指针变量可以作函数的参数,指针也可作函数的返回值,还有一
种指针可以用来指向函数
2.14.1 指针作为函数的参数
函数中的形参,可以是指针变量。这时实参可以是地址或指针来
调用它
【 例 】 指针作为参数的例子
#include <iostream.h>
void main( )
{ int a[15];
void input(int *s,int n);
input(a,15);
for(int i=0; i<15; i++)
cout<<a[i]<<endl;
}
void input(int *s,int n)
{ cout<<“请输入” <<n<<“个整数
:”<<endl;
for(int i=0; i<n; i++)
cin>>s[i]; //或 cin>>*s++;
}
54
2.14.2 返回指针的函数
C++函数的返回类型,可以是除数组和函数外的任何类型包括指针
【 例 】 指针作为函数的返回值的例子
先问用户要输入多少个实数,然后分配一存储空间保存输入的这
些实数,并把指向这空间的指针返回给用户。
#include <iostream.h>
float *input(int& n);
void main( )
{ int num; float *data;
data = input(num);
if(data)
{ for(int i=0; i<num; i++)
cout<<data[i]<<" ";
delete data;
}
}
float *input(int& n)
{ int num;
cout<<“要输入多少个实数,”;
cin << num;
if(num<=0) return 0;
float *buf=new float[num];
if(buf==0) return;
n = num;
for(int i=0; i<num; i++)
cin>>buf[i];
return buf;
}
55
2.14.3 指向函数的指针变量
C++中函数也有地址,也可以用指针指向它。
这种指针的定义方法, int (*funp)(int a,int b);
表示 funp 是指针,可以用来指向带有两个 int类型参数的函数,
这个函数的返回值是 int
函数 int fun(int a,int b)
{
,.........…
}
funp=fun; funp 指向函数 fun
可以用这种指针调用函数
result=(*funp)(5,10); 或 result=fnup(5,10);
56
在 C++中,字符串被定义为以 '\0'结束的字符数组。
char str[7]={'s','t','r','i','n','g','\0'};
char str[7]="string";
char *ps="string"; 或分成 char *ps; ps="string";
但数组不能分成 char str[7]; str="string"; //错误
串可以作为一个整体输入输出,
#include <iostream.h>
void main( )
{ char str[]="请输入一个字符串,";
char entstr[25];
cout << str;
cin >> entstr;
cout << "\n您输入的字符串是," << entstr;
} 57
习题
2.1
2.3
2.7
2.8
2.9
58