当前位置:文档之家› 第12章C语言

第12章C语言

第12章C语言
第12章C语言

第12章运算符重载

?12.1 什么是运算符重载

在第10章中曾介绍过函数重载,已经接触到重载(overloading)这个名词。所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之实现新的功能。因此,同一个函数名就可以代表多个不同功能的函数,也就是一名多用。

运算符也可以重载。运算符重载的概念,其实并不陌生,只是此前没有做进一步的讲解。如“+”加法运算符,在C语言中已经用的很多了。在C++中,若对数值型数据进行“+、-、*、/”等操作,可写出如下程序

int a,b,c;

c=a+b; //对整型变量执行算术的加法运算。

float f1,f2,f3;

f3=f1+f2; //对实型变量执行算术的加法运算。

从中可以看出,运算符“+”既可以实现整型变量的加法,又可以实现实型变量的加法。这说明运算符“+”具有双重功能,它能够根据表达式中运算符两侧的数据类型自动调整该类型所需的数据操作方法。这样,就可以将同一运算符用于不同的数据类型上实现功能相同的操作。这就是C++中的运算符重载。

编译系统已经为基本数据类型定义(重载)了一些运算符。如为数值型数据,定义有“+、-、*、/”等运算符;为关系运算定义了“>、>=、<、<=、!=、==”等运算符;为系统输入输出定义了“>>、<<”操作符。但对于用户自定义的结构体及类只定义了赋值运算符“=”、成员访问运算符“.”和指针运算符“->”这三种运算符。换句话说,编译系统在语法中赋予了这些运算符或操作符相应的功能。编译源程序时,系统遇到什么操作符就执行什么操作。

若用户要对自定义类型数据进行算术、关系、或其他运算,就不能使用这些未加定义(重载)的运算符或操作符,如以下自定义类型数据的“+”运算。

struct fraction //定义表示分数(fraction)的结构体,为完成如(1/2)+(2/3)+(1/3)的加法{int numerator; //分子

int denominator; //分母

};

fraction num1,num2,num3;

num3= num1+ num2; //试图执行两个分数的加法运算,编译错误error C2676:

num1= num3- num2; //试图执行两个分数的减法运算,编译错误error C2676:

编译时提示error C2676:binary '+' : 'struct main::fraction' does not define this operator or a con- version to a type acceptable to the predefined operator错误。显然,编译系统不知道对num1, num2,num3变量应进行怎样的“+”和“-”操作?

若要实现结构体变量的加法或减法运算,可采用以下两种方法,一种是按照一般函数的定义规则分别定义一个用于完成加法功能的函数和一个用于完成减法功能的函数。另一种是按照运算符重载函数的定义规则分别对现有运算符“+”和“-”进行重载。

例12.1 -1用函数方法(方法一)来实现结构体变量的加法

#include

struct fraction //定义表示分数(fraction)的结构体,为完成如(1/2)+(2/3)+(1/3)的加法{int numerator; //分子

int denominator; //分母

};

fraction num1,num2,num3;

fraction Add(const fraction &num1,const fraction &num2) //定义函数

{fraction temp_num; //定义临时工作变量

int n,m,k;

n=num1.numerator*num2.denominator;

m=num2.numerator*num1.denominator;

temp_num.numerator=n+m; //计算分子

temp_num.denominator=num1.denominator*num2.denominator; //计算分母

n=temp_num.numerator;

m=temp_num.denominator;

/*将计算结果化简为最简分数*/

k=m%n;

while(k)

{m=n;

n=k;

k=m%n;

}

temp_num.numerator/=n;

temp_num.denominator/=n;

/*化简完毕*/

return temp_num;

}

void main()

{fraction num1,num2,num3;

cin>>num1.numerator>>num1.denominator; //输入第一个分数的分子和分母

cin>>num2.numerator>>num2.denominator; //输入第二个分数的分子和分母

num3=Add(num1,num2); //将两个分数相加

cout<

运行结果:

2 3↙

4 5↙

22/15

程序说明

?运行时,从键盘输入2 3↙表示2/3,4 5↙表示4/5。

?对Add()函数的参数,使用常引用的方法,其目的是为防止在函数中改变该参数的值,以保证被引用的实参不会发生变化。

运算符重载的定义格式

运算符重载分为单目运算符的重载和双目运算符的重载。它是由关键字operator后跟一个运算符来实现的。一般格式为

单目运算符的重载格式

返回值类型operator 单目运算符(一个用户类型的参数声明){}

双目运算符的重载格式

返回值类型operator 双目运算符(第一个参数声明,第二个参数声明){}

格式说明

?运算符的重载格式有些象函数的形式。即可以把operator运算符看作是一个函数名。因此,运算符重载又称作运算符重载函数。operator和后面的运算符之间有无空格均可。

?运算符重载必须带有参数,并且至少要有一个用户自定义类型的参数。

?对于单目运算符的重载来说,其参数表中只有一个用户自定义类型的参数。

?对于双目运算符的重载来说,其参数表中第一个参数为双目运算符左边的对象,第二个参数为双目运算符右边的对象。且二者中必须有一个是用户自定义类型。

?对于单目运算符的后增1或后减1运算符,在重载时参数表中要增加一个整型参数,以便与前增1前减1区别,该整型参数是虚设的,可以只列出类型。

如fraction operator ++( fraction &num,int);

例12.1 -2重载运算符“+”(方法二)实现结构体变量的加法

#include

struct fraction

{int numerator; //分子

int denominator; //分母

};

fraction num1,num2,num3;

fraction operator +( const fraction &num1,const fraction &num2)//重载运算符“+”

{…//同前例略

…}

void main()

{fraction num1,num2,num3;

cin>>num1.numerator>>num1.denominator;

cin>>num2.numerator>>num2.denominator;

num3=num1+num2; //可以使用重载的“+”运算符将两个分数相加

cout<

运行结果:

2 3↙

4 5↙

22/15

由此,我们实现了使用“+”运算符对自定义数据类型变量的加法运算。它同函数实现的方法是一样的,但所表达的语义不同。可以看出,使用重载的运算符后,比函数调用更简单,更能说明程序的意图。该结构的减法运算请读者自己设计完成。

?注意

? C++中的运算符除了成员运算符“.”、条件运算符“?:”和作用域运算符“::”以外,其它全部可以重载,而且只能重载已有的运算符。

?重载之后运算符的优先级、操作对象个数和结合性都不会改变。

?运算符重载是针对新类型数据的实际需要,对原有运算符所能处理的数据类型范围进行扩大,使之能够对新的数据类型执行功能相同的运算。一般来讲,重载的功能应当与原有功能相类似,同时至少要有一个操作对象是用户自定义类型。

运算符重载实际上就是函数重载。对于运算符将其视为一个函数,只不过形式有点特殊。如,程序中遇有11+12的表达时,C++编译器将此表达式当作一次函数调用,即int operator+(11,12)

该函数给出2个整型数的加法操作,并返回一个整数;

而对于程序中遇有11.1+12.2时,C++编译器也将此表达式当作一次函数调用,即

int operator+(11.1,12.2)

该函数给出2个实型数的加法操作,并返回一个实型数。

以上2个函数很相似,不同之处是:第1个函数原型为int operator+(int a,int b);第2个函数原型为int operator+(float a,float b)。如果将“operator+”理解为一个函数名,则与一般函数没有什么区别。

运算符重载一般采用2种形式,一种为成员函数形式,另一种为友元函数形式。

?12.2 运算符重载为类的成员函数形式

将运算符重载为类的成员函数,一般格式为

类型operator 运算符(形参表)

{

函数体;

}

其中类型是指重载运算符的返回值类型;operator是定义运算符重载的关键字;运算符是指要重载的运算符名称。形参表:在表中列出了重载运算符所需要的参数和参数类型。表中参数个数与重载运算符操作数的个数有关,即运算符重载函数的参数比原来的操作数少一个(后置++、--除外)。具体地说,单目运算符参数表无参数,双目运算符参数表中只有一个参数。也就是说,调用该参数的对象为第1个操作数,参数表中的参数为第2个操作数。

例12.2-1 运算符重载:复数四则运算与求负

分析:复数c1=a+bi,c2=x+yi。其中a,b,x,y均为实数;

c=c1+c2=(a+x)+(b+y)i

c=c1-c2=(a-x)+(b-y)i

c=c1*c2=(a+bi)*(x+yi)= (ax-by)+(bx+ay)i

c=c1/c2=(a+bi)/(x+yi)= ((ax+by)/(x2+y2))+((bx-ay)/( x2+y2))i

c= - c1=-a-bi

c= - c2=-x-yi

//complex.h文件

#include

class complex //定义复数类

{public:

complex(float r=0.0,float i=0.0) //构造函数

{real=r;imag=i;}

complex operator+(complex &c); //运算符“+”重载成员函数

complex operator-(complex &c); //运算符“-”重载成员函数

complex operator*(complex &c); //运算符“*”重载成员函数

complex operator/(complex &c); //运算符“/”重载成员函数

complex operator-(void); //运算符“求负”重载成员函数

void show(); //显示输出复数

private:

float real,imag; //复数实部real,复数虚部imag };

//complex.cpp文件

#include

#include “complex.h”

complex complex::operator+(complex &c) //重载运算符“+”函数实现{complex p;

p.real=real+c.real;

p.imag=imag+c.imag;

return p;}

complex complex::operator-(complex &c) //重载运算符“-”函数实现{complex p;

p.real=real-c.real;

p.imag=imag-c.imag;

return p;}

complex complex::operator*(complex &c) //重载运算符“*”函数实现{complex p;

p.real=real*c.real-imag*c.imag;

p.imag=real*c.imag+imag*c.real;

return p;}

complex complex::operator/(complex &c) //重载运算符“/”函数实现{complex p;

p.real=(real*c.real+imag*c.imag)/(c.real*c.real+c.imag*c.imag);

p.imag=(imag*c.real-real*c.imag)/( c.real*c.real+c.imag*c.imag);

return p;}

complex complex::operator-(void) //重载“求负”操作函数实现{complex p;

p.real=-real;

p.imag=-imag;

return p;}

void complex::show()

{if(imag<0) cout<

else cout<

//Ex12_2_1.cpp文件

#include

#include “complex.h”

void main()

{complex a(6,8); //定义复数类的对象a

cout<<”a=”;

a.show();

complex b(2,4); //定义复数类的对象b

cout<<”b=”;

b.show();

complex c1; //定义复数类的对象c1

c1=a+b; //使用重载运算符完成复数加法

cout<<”a+b=”;

c1.show();

c1=a-b; //使用重载运算符完成复数减法

cout<<”a-b=”;

c1.show();

c1=a*b; //使用重载运算符完成复数乘法

cout<<”a*b=”;

c1.show();

c1=a/b; //使用重载运算符完成复数除法

cout<<”a/b=”;

c1.show();

c1=-a; //使用重载运算符完成复数“求负”

cout<<”-a=”;

c1.show();

c1=-b; //使用重载运算符完成复数“求负”

cout<<”-b=”;

c1.show();}

运行结果:

a=6+8i

b=2+4i

a+b=8+12i

a*b=-20+40i

a/b=2.2+(-0.4)i

-a=-6+(-8)i

-b=-2+(-4)i

程序说明

?把复数的四则运算(+、-、*、/)和“求负”重载为复数类的成员函数。只在函数说明和实现时用了关键字operator。在运算过程中,成员函数形式的运算符重载函数与类的一般成员函数完全相似,可以直接通过运算符、操作数来实现函数的调用。运算符+、-、*、/和“求负”的功能没有变,对整型和实型等基本类型数据的运算仍遵循C++的基本语法规则,但是增加了对复数运算的功能。

?程序中出现的为双目运算符,一般情况为:

a运算符b。如

a+b,编译器将解释为

a.operator运算符(b),即

a.operator+(b)。其中a和b为类的对象。若运算符“+”被重载为复数运算的加法运算符,其中a为第1个操作数,b为第2个操作数,则它们都是complex的对象。

对于单目运算符,一般情况为:a运算符或运算符a。编译器将解释为

a.operator运算符()

?本程序有3个文件构成:头文件complex.h,扩展名为.h,类的成员函数形式的运算符重载在头文件中进行说明;与头文件同名的源文件complex.cpp,扩展名为.cpp,类的成

员函数形式的运算符重载函数在这个文件中定义(实现);文件Ex12_2_1.cpp,扩展名为.cpp,是主函数文件。将3个文件组合在一个项目中,这个程序才能运行,并得到结果。

例12.2-2 运算符重载:单目运算符++进行复数运算

//complex1.h文件

#include

class complex //定义类complex

{public: //公有成员函数,外部接口

complex(float a=0.0,float b=0.0) //构造函数

{real=a;imag=b;}

void operator++(); //前置单目运算符重载

void operator++(int); //后置单目运算符重载

complex operator+(complex &c); //运算符“+”重载成员函数

void show(); //显示输出复数

private: //私有数据成员

float real,imag; //复数实部real,复数虚部imag };

//complex1.cpp文件

#include

#include “complex1.h”

void complex::operator++() //前置单目运算符重载函数实现

{real++;imag++;}

void complex::operator++(int) //后置单目运算符重载函数实现

{real++;imag++;}

complex complex::operator+(complex &c) //重载运算符“+”函数实现

{complex p; //定义复数类的对象

p.real=real+c.real;

p.imag=imag+c.imag;

return complex(p.real,p.imag);}

void complex::show()

{cout<<”a+b=”;

if(imag<0) cout<

else cout<

//Ex12_2_2.cpp文件

#include

#include “complex1.h”

void main()

{complex a(-1,8); //定义复数类的对象a

complex b(2,-11); //定义复数类的对象b

complex c; //定义复数类的对象c

cout<<”first output(a,b):”<

c=a+b;

c.show();

++a;

++b;

cout<<”second output(++a,++b):”<

c=a+b;

c.show();

a++;

b++;

cout<<”third output(a++,b++):”<

c=a+b;

c.show();}

运行结果:

first output(a,b):

a+b=1+(-3)i

second output(++a,++b):

a+b=3+(-1)i

third output(a++,b++):

a+b=5+1i

程序说明

?本程序由头文件complex1.h、同名的源文件complex1.cpp、和源文件Ex12_2_2.cpp 这3个文件组合在一个项目中。

?程序中把复数实部和虚部自增的前置++和后置++运算符重载为复数类的成员函数。前置++和后置++单目运算符的重载的主要区别就是函数的形参:前置++单目运算符重载函数无形参,后置++单目运算符重载函数有一个整数形参。这个整数形参只是用于区分前置和后置,因此参数表中无参数名,只是给出了类型名。

例12.2-3 赋值运算符“=”,“+=”,“-=”重载

#include

class point

{public:

point(){}

point(int aa,int bb)

{a=aa;b=bb;}

void show()

{cout<<”(”<

point operator=(point &);

point operator+=(point &);

void operator-=(point c)

{a-=c.a;

b-=c.b;}

private:

int a,b;

};

point point::operator=(point &c)

{a=c.a;b=c.b;

return *this;}

point point::operator+=(point &c)

{a+=c.a;b+=c.b;

return *this;}

void main()

{point s(4,5),r(6,8),t;

t=s;

cout<<”t=”;

t.show();

cout<<”s:”;

s.show();

cout<<”r:”;

r.show();

s+=r;

cout<<”s+=r:”;

s.show();

s-=r;

cout<<”s-=r:”;

s.show();}

运行结果:

t=(4,5)

s:(4,5)

r:(6,8)

s+=r:(10,13)

s-=r:(4,5)

程序说明

?赋值运算符“=”是双目运算符,赋值运算符的重载函数的一般格式为

A operator=(A &) 或着A& operator=(A &c)

其中A为类;operator为关键字;“=”为重载运算符;重载憾事有一个参数为类A的引用;函数返回值是类A的引用。在主函数中的表达式t=s;,其中s和t是类point的2个对象。s为已初始化的对象,将s的值赋给对象t;“=”为被重载的运算符,编译器将表达式解释为t.operator=(s),其含义是调用重载的赋值运算符函数来实现上述操作。

?使用成员函数方式重载双目运算符,参数是对象本身的数据,不需要用参数输入,而是通过隐含的this指针传入的,即指向该成员函数的对象的指针。如果是单目运算符,操作数由对象的传入,也就不需要任何参数了。

?本程序在类中,用point operator=(point &);声明“=”运算符重载

point operator+=(point &);声明“+=”运算符重载而“-=”运算符重载使用了无返回值运算符重载函数的形式,即void operator-=(point c) {……}。由此可见C++编程的灵活性。

?12.3 运算符重载为类的友元函数形式

运算符重载为类的友元函数的形式,就可以自由地访问此类的任何数据成员。当运算

符重载为友元函数时,函数的参数个数与原操作数个数相同。因为友元函数对某个对象的数据进行操作,必须通过该对象的名称进行,因此使用到的参数都要进行传递,操作数的个数与函数原型相同。若重载为类的成员函数(前面介绍的),函数参数比函数原型少一个。这就是两种形式的不同之处。

一般情况下,单目运算符重载为成员函数,而双目运算符重载为友元函数。这样的操作被认为是一种比较好的选择。

运算符重载为类的友元函数的一般格式为

friend 类型operator 运算符(形参表)

{

函数体;

}

在形参表,形参从左到右的顺序即为运算符操作数的顺序。

例12.3-1 用运算符重载为类的友元函数的形式,重做例12.2-1的复数四则运算

“+、-、*、/”

//complex2.h文件

#include

class complex //定义复数类

{public:

complex(float r=0.0,float i=0.0) //构造函数

{real=r;imag=i;}

friend complex operator+(complex &c1, complex &c2);//运算符“+”重载友元函数

friend complex operator-(complex &c1, complex &c2);//运算符“-”重载友元函数

friend complex operator*(complex &c1, complex &c2);//运算符“*”重载友元函数

friend complex operator/(complex &c1, complex &c2);//运算符“/”重载友元函数

void show(); //显示输出复数的成员函数

private:

float real,imag; //复数实部real,复数虚部imag };

//complex2.cpp文件

#include

#include “complex2.h”

complex operator+(complex &c1, complex &c2) //重载运算符“+”函数实现

{return complex(c1.real+c2.real,c1.imag+c2.imag);}

complex operator-(complex &c1, complex &c2) //重载运算符“-”函数实现

{return complex(c1.real-c2.real,c1.imag-c2.imag);}

complex operator*(complex &c1, complex &c2) //重载运算符“-”函数实现

{return complex(c1.real*c2.real-c1.imag*c2.imag, c1.real*c2.imag+c1.imag*c2.real);}

complex operator/(complex &c1, complex &c2) //重载运算符“-”函数实现

{return complex((c1.real*c2.real+c1.imag*c2.imag)/

(c2.real*c2.real+c2.imag*c2.imag),

(c1.imag*c2.real-c1.imag*c2.imag)/

(c2.real*c2.real+c2.imag*c2.imag));}

void complex::show() //成员函数(显示输出)的实现

{if(imag<0) cout<

else cout<

//Ex12_3_1.cpp文件

#include

#include “complex2.h”

void main()

{complex a(6,8),b(2,4),c; //定义复数类的对象a、b、c

c=a+b;

cout<<”a+b=”;

c.show();

c=a-b;

cout<<”a-b=”;

c.show();

c=a*b;

cout<<”a*b=”;

c.show();

c=a/b;

cout<<”a/b=”;

c.show();}

运行结果:

a+b=8+12i

a-b=4+4i

a*b=-20+40i

a/b=2.2+(-0.4)i

程序说明

?程序有3个文件构成:头文件complex2.h是类complex的定义;同名的源文件complex2.cpp,是类的成员函数及友元运算符重载函数的实现(定义);Ex12_3_1.cpp是主函数main()文件。

?在头文件complex2.h,定义了4个友元函数形式的类的运算符重载,即

friend complex operator+(complex &c1, complex &c2)

friend complex operator-(complex &c1, complex &c2)

friend complex operator*(complex &c1, complex &c2)

friend complex operator/(complex &c1, complex &c2)

重载后的运算符用于对复数进行四则运算,运算符的2个操作数为友元函数形式的运算符重载函数,对双目运算符所具有的2个参数。将运算符重载为友元函数,就必须把操作数通过形参方式传给运算符重载函数。

?例12.3-1与例12.2-1中主函数没有变化,程序运行结果相同(指复数四则运算部分,在例12.3-1中复数求负部分未做)。

?主函数main()中表达式a+b 中,运算符“+”是被重载后的复数加法运算。编译器将该式解释为operator+(a,b),调用程序中下列函数求值,即

complex operator+(complex &c1, complex &c2)

?12.4 插入运算符和提取运算符的重载

前面介绍过运算符的重载,定义了一个类就相当于定义了一个新的数据类型,如复数、集合、向量、矩阵在数学上已有规范的运算,运算符重载功能使得新类型的使用非常方便。C++I/O流类库(第15章介绍)支持对用户定义新的数据类型的输入/输出。本节介绍插入运算符“<<”和提取运算符“>>”的重载。重载后,使编程十分便捷。

下面用例题说明通过友元函数的形式重载插入运算符“<<”和提取运算符“>>”的方法。

例12.4-1 使用重载“+”运算符进行复数运算,使用重载插入运算符“<<”和提取运算符“>>”进行复数的输入/输出

#include

class complex

{public:

complex(double r=0.0,double i=0.0)

{real=r;imag=i;}

friend complex operator+(complex &c1,complex &c2); //说明”+”重载为类友元函数

friend ostream& operator<<(ostream &str,complex &c);//说明”<<”重载为类友元函数

friend istream& operator>>(istream &str,complex &c); //说明”>>”重载为类友元函数

private:

double real,imag; //复数实部与虚部

};

complex operator+(complex &c1,complex &c2) //”+”重载为类成员函数的实现

{return complex(c1.real+c2.real,c1.imag+c2.imag);}

ostream& operator<<(ostream& str, complex &c) //”<<”重载为类成员函数的实现

{str<

return str;}

istream& operator>>(istream &str,complex &c) //”>>”重载为类成员函数的实现

{str>>c.real>>c.imag;

return str;}

void main()

{complex a1,a2,a3; //定义类complex的对象a1,a2,a3

cout<<”Input complex number(a1 and a2): ”<

cin>>a1>>a2;

a3=a1+a2;

cout<

运行结果:

Input complex number(a1 and a2):

10 20 30 40

40+60i

程序说明

?程序在类complex中,通过友元函数的形式重载了加法、插入运算符和提取运算符。重载后可以对复数这种类型的数据进行“+”运算和输入/输出。

?定义重载插入运算符“<<”时,使用类ostream的对象引用作为返回值,因为流类对象cout是类ostream的对象。

?定义重载提取运算符“>>”时,使用类istream的对象引用作为返回值,因为流类对

象cin是类istream的对象。

?将重载运算符说明为complex类的友元函数,其目的是为了访问类中的私有成员。

运算符重载的几点说明

?大多数运算符都可以重载,诸如:

+ - * / % ^ & | ~ !

=< > += -= *= /= %= ^= &= |=

<< >> || ++ -- ->* . -> [ ] ( )

new new[ ] delete delete[ ]

不能重载的运算符有4个:

:: 作用域分辨符;

. 成员选择符;

.* 通过函数指针选择成员;

?: 三目运算符。

?重载之后的运算符的优先级和结合性不发生变化。

?重载不改变原运算符的操作对象个数。

?如果重载运算符的定义比较简单,则把它们定义成内联函数更便捷。使用运算符重载可能使可读性降低。一般使用原则是:当使用原有的运算符有困难时,才选择使用重载运算符。

?习题

《C语言程序设计》第12章在线测试

《C 语言程序设计》第12章在线测试 《C 语言程序设计》第12章在线测试 剩余时间: 54:28 答题须知:1、本卷满分20分。 2、答完题后,请一定要单击下面的“交卷”按钮交卷,否则无法记录本试卷的成绩。 3、在交卷之前,不要刷新本网页,否则你的答题结果将会被清空。 第一题、单项选择题(每题1分,5道题共5分) 1、若有说明语句“int a[10],*p=a;”,对数组元素的正确引用是: A 、a[p] B 、p[a] C 、p+2 D 、*(p+2) 2、在C 语言中,关于文件存取方式,: A 、只能顺序存取 B 、只能随机存取(也称直接存取) C 、可以顺序存取,也可以随机存取 D 、只能从文件开头存取 3、已知定义“int x = 1, *p”,则合法的赋值表达式是( )。 A 、p = &x B 、p = x C 、*p = &x D 、*p = *x 4、执行“char a[10]={"abcd"},*p =a;”后,*(p+4)的值是( )。 A 、字符ˊdˊ B 、转义符ˊ\0ˊ C 、常量"abcd" D 、不能确定 5、若有int a[10],*p =a;,则( )。 A 、p++可以使p 指向下一个字节 B 、p+=2 相当于p =sizeof(a)/10 C 、p++可以使p 指向下一个元素,即a[1]的首地址 D 、p+=2可以使p 指向下一个元素,即a[1]的首地址 第二题、多项选择题(每题2分,5道题共10分) 1、C 语言中的文件分类是: A 、文本文件和数据文件 B 、文本文件和二进制文件 C 、数据文件和二进制文件

D、顺序文件和随机文件 2、已有char s[10][10]={0};int i=10;。在下列表达式中,没有意义的表达式是: A、s[i][i] B、*(*(s+i)+i) C、*(&(s+i)+i) D、*(*(s+i-1)+i-1) 3、若有int x=3,*px; float y=3,*py;,则正确的赋值表达式是 ( )。 A、px=&x B、py=&x C、px=&y D、py=&y 4、设有定义语句“int x=10, *p=&x”,则表达式的值为10的有()。 A、p B、*p C、*&x D、*p=x E、x=*p 5、设有定义语句“struct {int a;float b;char c;}abc,*p;”,则对结构体成员a的引用可以是( )。 A、abc.a B、abc->a C、(*p).a D、p->a 第三题、判断题(每题1分,5道题共5分)

江苏大学大一c语言期末复习题汇总

选择题1.下列字符序列中,不可用作C语言标识符的是()。 A.abc123 B.C._123_ D._ok 2.请选出可用作C语言用户标识符的一组标识符()。 A.void B.a3_b3 C.For D.2a define _123 -abc DO WORD IF Case sizeof 3.不属于C语言关键字的是()。 A.int B.break C.while D.character 4.以下不能定义为用户标示符的是()。 A.scanf B.Void C._3com_ D.int 5.C语言程序的基本单位是()。 A.程序行B.语句C.函数D.字符 6.以下说法中正确的是()。 A.C语言程序总是从第一个定义的函数开始执行 B.在C语言程序中,要调用的函数必须在main( )函数中定义 C.C语言程序总是从main( )函数开始执行 D.C语言程序中的main( )函数必须放在程序的开始部分 7.以下选项中,合法的用户标识符是()。 A.long B._2abc C.3dmax D. 8.已知大写字母A的ASCII码值是65,小写字母a的ASCII码是97,则用八进制表示 的字符常量’\101’是()。 A.字符A B.字符a C.字符c D.非法的常量 9.以下选项中,正确的字符常量是()。 A.”F”B.’\\’’C.’W’D.’’ 10.下列变量定义中合法的是 A.short _a=; B.double b=1+; C.long do=0xfdaL; D.float 2_and=1-e-3; 11.为了避免嵌套的if-else语句的二义性,C语言规定else总是与()组成配对关系。 A.缩排位置相同的if B.在其之前未配对的if C.在其之前未配对的最近的if D.同一行上的if 12.下列运算符中优先级最高的是()。 A.< B.&& C.+ D.!= 13.判断char型变量s是否为小写字母的正确表达式是()。 A.’a’ <= s<=’z’B.(s>=’a’) & (s<=’z’) C.(s>=’a’) && (s<=’z’) D.(’a’<=s) and (’z’>=s)

c语言第8章编译预处理及位运算习题答案.doc

编译预处理习题 一.单项选择题 1.在宏定义#define A 3.897678中,宏名A代替一个()。 A)单精度数 B)双精度数 C)常量 D)字符串 2.以下叙述中正确的是 A)预处理命令行必须位于源文件的开头 B)在源文件的一行上可以有多条预处理命令C)宏名必须用大写字母表示D)宏替换不占用程序的运行时间 3.C语言的编译系统对宏命令的处理()。 A)在程序运行时进行的 B)在程序连接时进行的 C)和C程序中的其它语句同时进行的 D)在对源程序中其它语句正式编译之前进行的 4.在文件包含预处理语句的中,被包含文件名用“< >”括起时,寻找被包含文件的方式 是()。 A)直接按系统设定的标准方式搜索目录 B)先在源程序所在目录搜索,再按系统设定的标准方式搜索 C)仅仅在源程序所在目录搜索 D)仅仅搜索当前目录 5.以下说法中正确的是 A)#define和printf都是C语句 B)#define是C语句,而printf不是 C)printf是C语句,但#define不是D)#define和printf都不是C语句 6.#define A 3.897678 #include main( ) { printf(“A=%f ”,A); } 程序运行结果为()。 A) 3.897678=3.897678 B) 3.897678=A C) A=3.897678 D)无结果7.有宏定义:#define LI(a,b) a*b #define LJ(a,b) (a)*(b) 在后面的程序中有宏引用:x=LI(3+2,5+8); y=LJ(3+2,5+8); 则x、y的值是()。 A) x=65,y=65 B) x=21,y=65 C) x=65,y=21 D)x=21,y=21 8.有以下程序 # define f(x) (x*x) main() { int i1, i2; i1=f(8)/f(4) ; i2=f(4+4)/f(2+2) ; printf("%d, %d\n",i1,i2); } 程序运行后的输出结果是

C语言程序设计(第3版)何钦铭 颜 晖 第12章 文件

第12章文件 【练习12-1】读出例12-1学生成绩文件f12-1.txt内容,输出最高分和最低分及相应的学号和姓名。 解答: #include #include struct student{ long num; char stname[20]; int score; }; int main(void) { FILE *fp; int i,max,min,j=0,k=0; struct student students[5]; if((fp=fopen("f12-1.txt","r"))==NULL) { printf("File open error!\n"); exit(0); } fscanf(fp,"%ld%s%d",&students[0].num,students[0].stname,&students[0] .score); max=min=students[0].score; for(i=1;i<=4;i++){ fscanf(fp,"%ld%s%d",&students[i].num,students[i].stname,&students[i]. score); if(maxstudents[i].score){ min=students[i].score; k=i; } } printf("Max score: %d,num:%d,name:%s\n",students[j].score,students[j].num,&studen ts[j].stname); printf("Min

C语言程序设计1-4、12章习题解答

第1章C语言程序设计概述 1.1一个C程序的执行是从 A 。 A.从main()函数开始,直到main()函数结束 B.第一个函数开始,直到最后一个函数结束 C.第一个语句开始,直到最后一个语句结束 D.main()函数开始,直到最后一个函数结束 1.2在C程序中,main()的位置 C 。 A.必须作为第一个函数B.必须作为最后一个函数 C.可以任意D.必须放在它所调用的函数之后 1.3C语言源程序的基本单位是 B 。 A.过程 B.函数 C.子程序 D.标识符 1.4一个C源程序有且仅有一个一个函数和__零个或多个_____个其他函数。 1.5C语言源程序的语句分隔符是__分号___。 1.6C语言开发的四个步骤是_编辑源程序→对源程序进行编译→与库函数连接→运行 目标程序__ 。 1.7C语言有哪些主要特点? C主要特点有: 1.C语言简洁、紧凑,使用方便、灵活; 2.运算符丰富; 3.数据类型丰富; 4.C语言是结构化语言; 5.语法限制不太严格,程序设计自由度大; 6.可直接与机器硬件打交道,直接访问内存地址; 7.生成的目标代码质量高,程序执行效率高; 8.C语言适用范围广,可移植性好。 1.8简述C编译和运行的基本方法。 略。 1.9常用的集成开发工具有哪些?各有什么特点? 略。 1.10编写一个程序,在屏幕上输出以下内容: *************************** * You are welcome! * *************************** #include void main( ) /*主函数 */ { /*函数体开始*/ printf ("***************************\n"); /*输出语句*/ printf ("* You are welcome! *\n"); printf ("***************************\n"); } 1.11 编写一个C程序,输入a、b、c 3个值,输出其中最大者。

大一C语言期末考试题

大一C语言期末考试题 悬赏分:40 |解决时间:2010-6-29 14:28 |提问者:345387547 1. 数组int a[3][5]; 共定义了______15__个元素。 2. 有float f= 3.1415927; 则printf(“%5.4f”, f );输出的结果是___3.1416__。 3. 下面程序的功能是:输出100以内(不包含100)能被3整除且个位数为6的所有整数,请填空。 main( ) { int i; for(i=1; __i<100 ___; i++) if (_(i%3==0)&&(i%10==6)_) printf("%d", i); } 4. 设有“int x=2, y”说明,则逗号表达式“y=x+5,x+y”的值是____7____ 5. 以下是使用指针,进行字符串复制的程序,请填空。 main() { char a[]= “Tsinghua University”, b[30], *p1,*p2; p1=a; p2=b; for(; *p1!= __'\0'____; p1++, p2++) *p2 _=_*p1; *p2= ___'\0'______; printf(“string a is:%s\n”,a); printf(“string b is:%s\n”,b); } 6. 下面程序用冒泡法对数组a进行降序排序,请填空。 main() { int a[5]={4,7,2,5,1}; int i,j,m; for(i=0;i<4;i++) for(j=0;j<____4____;j++) if( a[j]

C语言程序设计第十二章

第12章文件 1.fopen()函数 (1)调用形式:fopen(文件名,文件使用方式) 函数返回一个指向FILE类型的指针。若函数调用成功,则返回一个FILE 类型的指针,赋给文件指针变量fp,从而把指针fp与文件联系起来,在此调用之后,指针fp就指向了文件。 无论哪种使用方式,当打开文件时出现了错误,fopen函数都将返回NULL。 (2)最常用的文件使用方式及其含义: ●“r”:为读而打开文本文件。当指定这种方式时,对打开的文件只能进行“读”操作。若指定的文件不存在,则会出错。另外一些情况,比如企图去读一个不允许读的文件时,也会出错。 ●“rb”:为读而打开一个二进制文件。其余功能与“r”相同。 ●“w”:为写而打开文本文件。这时,如果指定的文件不存在,系统将用在fopen调用中指定的文件名建立一个新文件;如果指定的文件已存在,则将从文件的起始位置开始写,文件中原有的内容将全部消失。 ●“wb”:为写而打开一个二进制文件。其余功能与“w”相似,但从指定位置开始写。 ●“a”:为在文件后面添加数据而打开文本文件。这时,如果指定的文件不存在,系统将用在fopen调用中指定的文件名建立一个新文件;如果指定的文件已存在,则文件中原有的内容将保存,新的数据写在原有内容之后。 ●“ab”:为在文件后面添加数据而打开一个二进制文件。其余功能与“a”相同。 ●“r+”:为读和写而打开文本文件。用这种方式时,指定的文件应当已经存在。既可以对文件进行读,也可以对文件进行写,在读和写操作之间不必关闭文件。只是对于文本文件来说,读和写总是从文件的起始位置开始。在写新的数据时,只覆盖新数据所占的空间,其后的原数据并不丢失。 ●“rb+”:为读和写而打开一个二进制文件。功能与“r+”相同。只是

大学C语言期末考试习题集(带详解答案)

一、单项选择题 1.(A)是构成C语言程序的基本单位。 A、函数 B、过程 C、子程序 D、子例程 2.C语言程序从 C开始执行。 A) 程序中第一条可执行语句 B) 程序中第一个函数 C) 程序中的main函数 D) 包含文件中的第一个函数 3、以下说法中正确的是(C)。 A、C语言程序总是从第一个定义的函数开始执行 B、在C语言程序中,要调用的函数必须在main( )函数中定义 C、C语言程序总是从main( )函数开始执行 D、C语言程序中的main( )函数必须放在程序的开始部分 4.下列关于C语言的说法错误的是(B)。 A) C程序的工作过程是编辑、编译、连接、运行 B) C语言不区分大小写。 C) C程序的三种基本结构是顺序、选择、循环 D) C程序从main函数开始执行 5.下列正确的标识符是(C)。 A.-a1 B.a[i] C.a2_i D.int t 5~8题为相同类型题 考点:标识符的命名规则 (1)只能由字母、数字、下划线构成 (2)数字不能作为标识符的开头 (3)关键字不能作为标识符 选项A中的“-”,选项B中“[”与“]”不满足(1);选项D中的int为关键字,不满足(3) 6.下列C语言用户标识符中合法的是( B)。 A)3ax B)x C)case D)-e2 E)union 选项A中的标识符以数字开头不满足(2);选项C,E均为为关键字,不满足(3);选项D中的“-”不满足(1); 7.下列四组选项中,正确的C语言标识符是(C)。 A) %x B) a+b C) a123 D) 123 选项A中的“%”,选项B中“+”不满足(1);选项D中的标识符以数字开头不满足(2) 8、下列四组字符串中都可以用作C语言程序中的标识符的是(A)。 A、print _3d db8 aBc B、I\am one_half start$it 3pai

C语言程序设计 位运算

一、选择题 1、读程序片段: int x=20; printf(“%d\n”, ~x); 上面程序片段的输出结果是( ). A)02 B)–20 C)-21 D)-11 2、表达式~0x13的值是( ). A)0xFFEC B)0xFF71 C)0xFF68 D)0xFF17 3、在位运算中,操作数每右移一位,其结果相当于( ). A)操作数乘以2 B)操作数除以2 C)操作数除以4 D)操作数乘以4 4、在位运算中,操作数每左移一位,其结果相当于( ). A)操作数乘以2 B)操作数除以2 C)操作数除以4 D)操作数乘以4 5、设有以下语句: char x=3,y=6,z; z=x^y<<2; 则z的二进制值是( ). A)00010100 B)00011011 C)00011100 D)00011000 6、请读程序: struct bit {unsigned a_bit:2; unsigned b_bit:2; unsigned c_bit:1; unsigned d_bit:1; unsigned e_bit:2; unsigned word:8; }; main() {struct bit *p; unsigned int modeword; printf(“Enter the mode word (HEX):”); scanf(“%x”,&modeword); p=(struct bit *)&modeword; printf(“\n”); printf(“a_bit: %d\n”,p ->a_bit); printf(“b_bit: %d\n”,p ->b_bit); printf(“c_bit: %d\n”,p ->c_bit); printf(“d_bit: %d\n”,p ->d_bit); printf(“e_bit: %d\n”,p ->e_bit);} 若运行时从键盘输入: 96<回车> 则以上程序的运行结果是( ). A)a_bit: 1 B) a_bit: 2 C)a_bit: 2 D) a_bit: 1

C语言位运算符

C语言位运算符 位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。 C语言提供的位运算符列表: 1、“按位与”运算符(&) 按位与是指:参加运算的两个数据,按二进制位进行“与”运算。如果两个相应的二进制位都为1, 则该位的结果值为1;否则为0。这里的1可以理解为逻辑中的true,0可以理解为逻辑中的false。按位与其 实与逻辑上“与”的运算规则一致。逻辑上的“与”,要求运算数全真,结果才为真。若,A=true,B=true,则A∩B=true 例如: 3&5 3的二进制编码是11(2)。(为了区分十进制和其他进制,本文规定,凡是非十进制的数据均在数据后面加上括号,括号中注明其进制,二进制则标记为2)内存储存数据的基本单

位是字节(Byte),一个字节由8个位(bit)所组成。位是用以描述电脑数据量的最小单位。二进制系统中,每个0或1就是一个位。将11(2)补足成一个字节,则是00000011(2)。5的二进制编码是101(2),将其补足成一个字节,则是00000101(2)。 按位与运算: 00000011(2) &00000101(2) 00000001(2) 由此可知3&5=1 c语言代码: 按位与的用途: (1)清零 若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件: 原来的数中为1的位,新数中相应位为0。然后使二者进行&运算,即可达到清零目的。例: 原数为43,即00101011(2),另找一个数,设它为148,即10010100(2),将两者按位与运算: 00101011(2)&10010100(2)

C语言程序设计第11.12章测试答案

第一题、单项选择题(每题1分,5道题共5分) 1、设有定义“int a=3,b,*p=&a;”,则下列语句中,使b不为3的语句是: A、b=*&a; B、b=*p; C、b=a; D、b=*a; 2、在C语言中,关于文件存取方式,: A、只能顺序存取 B、只能随机存取(也称直接存取) C、可以顺序存取,也可以随机存取 D、只能从文件开头存取 3、fp 是文件指针,str 是一个字符串,n是一个整数,向文件中输出数据的正确格式是: A、fprintf("%s,%d\n",str,n,fp); B、fprintf(fp,"%s,%d\n",str,n); C、fprintf("fp %s,%d\n",str,n); D、fprintf("%s,%d fp\n",str,n); 4、若有int a=3,*pa; float f=4.5,*pf=&f;,则下列表述中,错误的是 ( )。 A、pa=&a B、pa=&f C、pf=&f D、*pf=a+f 5、若有int a[10],*p=a;,则( )。 A、p++可以使p指向下一个字节 B、p+=2 相当于p=sizeof(a)/10 C、p++可以使p指向下一个元素,即a[1]的首地址 D、p+=2可以使p指向下一个元素,即a[1]的首地址 第二题、多项选择题(每题2分,5道题共10分) 1、C语言中的文件分类是: A、文本文件和数据文件 B、文本文件和二进制文件 C、数据文件和二进制文件 D、顺序文件和随机文件 2、以读写方式打开一个二进制文件fil2,fopen函数的正确的调用方式是: A、FILE *FP; FP=fopen("fil2","r"); B、FILE *FP; FP=fopen("fil2","rb");

江苏大学大一c语言期末复习题汇总

选择题 1.下列字符序列中,不可用作C语言标识符的是()。 A.abc123 B.no.1 C._123_ D._ok 2.请选出可用作C语言用户标识符的一组标识符()。 A.void B.a3_b3 C.For D.2a define _123 -abc DO WORD IF Case sizeof 3.不属于C语言关键字的是()。 A.int B.break C.while D.character 4.以下不能定义为用户标示符的是()。 A.scanf B.V oid C._3com_ D.int 5.C语言程序的基本单位是()。 A.程序行B.语句C.函数D.字符 6.以下说法中正确的是()。 A.C语言程序总是从第一个定义的函数开始执行 B.在C语言程序中,要调用的函数必须在main( )函数中定义 C.C语言程序总是从main( )函数开始执行 D.C语言程序中的main( )函数必须放在程序的开始部分 7.以下选项中,合法的用户标识符是()。 A.long B._2abc C.3dmax D.A.dat 8.已知大写字母A的ASCII码值是65,小写字母a的ASCII码是97,则用八进制表示 的字符常量’\101’是()。 A.字符A B.字符a C.字符c D.非法的常量 9.以下选项中,正确的字符常量是()。 A.”F”B.’\\’’C.’W’D.’’ 10.下列变量定义中合法的是 A.short _a=1-.le-1; B.double b=1+5e2.5; C.long do=0xfdaL; D.float 2_and=1-e-3; 11.为了避免嵌套的if-else语句的二义性,C语言规定else总是与()组成配对关系。 A.缩排位置相同的if B.在其之前未配对的if C.在其之前未配对的最近的if D.同一行上的if 12.下列运算符中优先级最高的是()。 A.< B.&& C.+ D.!= 13.判断char型变量s是否为小写字母的正确表达式是()。 A.’a’ <= s<=’z’B.(s>=’a’) & (s<=’z’) C.(s>=’a’) && (s<=’z’) D.(’a’<=s) and (’z’>=s) 14.已知x=45, y=’a’, z=0; 则表达式(x>=z && y<’z’ || !y)的值是()。 A.0 B.语法错 C.1 D.“假”

数据结构(C语言版)9-12章练习 答案 清华大学出版社

9-12章数据结构作业答案 第九章查找 选择题 1、对n个元素的表做顺序查找时,若查找每个元素的概率相同,则平均查找长度为( A ) A.(n+1)/2 B. n/2 C. n D. [(1+n)*n ]/2 2. 下面关于二分查找的叙述正确的是 ( D ) A. 表必须有序,表可以顺序方式存储,也可以链表方式存储 B. 表必须有序且表中数据必须是整型,实型或字符型 C. 表必须有序,而且只能从小到大排列 D. 表必须有序,且表只能以顺序方式存储 3. 二叉查找树的查找效率与二叉树的( (1)C)有关, 在 ((2)C )时其查找效率最低 (1): A. 高度 B. 结点的多少 C. 树型 D. 结点的位置 (2): A. 结点太多 B. 完全二叉树 C. 呈单枝树 D. 结点太复杂。 4. 若采用链地址法构造散列表,散列函数为H(key)=key MOD 17,则需 ((1)A) 个链表。 这些链的链首指针构成一个指针数组,数组的下标范围为 ((2)C) (1) A.17 B. 13 C. 16 D. 任意 (2) A.0至17 B. 1至17 C. 0至16 D. 1至16 判断题 1.Hash表的平均查找长度与处理冲突的方法无关。 (错) 2. 若散列表的负载因子α<1,则可避免碰撞的产生。(错) 3. 就平均查找长度而言,分块查找最小,折半查找次之,顺序查找最大。(错) 填空题 1. 在顺序表(8,11,15,19,25,26,30,33,42,48,50)中,用二分(折半)法查找关键码值20, 需做的关键码比较次数为 4 . 算法应用题 1. 设有一组关键字{9,01,23,14,55,20,84,27},采用哈希函数:H(key)=key mod 7 ,表长 为10,用开放地址法的二次探测再散列方法Hi=(H(key)+di) mod 10解决冲突。要求:对该关 键字序列构造哈希表,并计算查找成功的平均查找长度。 2. 已知散列表的地址空间为A[0..11],散列函数H(k)=k mod 11,采用线性探测法处理冲 突。请将下列数据{25,16,38,47,79,82,51,39,89,151,231}依次插入到散列表中,并计算出在 等概率情况下查找成功时的平均查找长度。 3、对长度为20 的有序表进行二分查找,试画出它的一棵判定树,并求等概率情况下的平均 查找长度。 4、设散列表的长度为15,散列函数H(K)=K%13,给定的关键字序列为20,16,29,82,37,02,06,28,55,39,23,10,试写出分别用拉链法和线性探测法解决冲突时所构造的散 列表,并求出在等概率情况下,这两种方法查找成功时的平均查找长度。

大一c语言期末试题及参考答案word版本

2004级信息学院《C语言设计》考试试题 一、判断下列语句或程序的对错。 10分√ 1 int x=y=z=’0’; (×) y,z没有定义 2 #include ; (×)不能有分号,#开头的结尾均不能有分号; 3 printf(“%s\n”,”c language”); (√) 4 float a[100]; int *p=a; (×)数据类型不匹配 5 char str[20]; 6 int data[4]={0,1,2,3,4}; (×)五个元素,但是只有四个单元 7 float x=1.45e+310L; (×)数值越界 8 int xyz-1=2; (×) 9 int x=‘\xae’ ; (√) 10 int *p,a[2][3] ; p=a ; (×)数据类型不匹配 二计算下列表达式的值 10分 设 unsigned int a=10,b=17,c=5,d=3; float f ; (1)f=b/c ( 3.0 ) (2)!(a+b)+c-1&&b+c/2 ( 1 ) (3)(a^b)+(c>>1+d) ( 0x1b ) (4)a+=b%=a=b ( 17 ) (5)a=2,b=a*++b ( 2 ) 三程序改错 10分 (1)求两个浮点数的平方和及平方差 #include float calculate (float x,float y,float *sub);添加函数原型声明 main () { float a,b; float add_reasult, sub_result; scanf (“%f,%f”,a,b); add_result=calculate(a,b,&sub_result); printf( “a*a+b*b=%d,a*a-b*b=%d\n”,add_result,sub_result); } float calculate (float x,float y,float *sub) 添加函数类型 { float *temp; 应该直接定义为变量float temp; sub=a*a-b*b ; *sub=a*a-b*b;

C语言位运算符(附例题讲解)

C语言提供了六种位运算符: & 按位与 | 按位或 ^ 按位异或 ~ 取反 << 左移 >> 右移 12.1.1按位与运算 按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0。参与运算的数以补码方式出现。 例如:9&5可写算式如下: 00001001 (9的二进制补码) &00000101 (5的二进制补码) 00000001 (1的二进制补码) 可见9&5=1。 按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清0 ,保留低八位,可作a&255运算( 255 的二进制数为0000000011111111)。 【例12.1】 main(){ int a=9,b=5,c; c=a&b; printf("a=%d\nb=%d\nc=%d\n",a,b,c); } 12.1.2按位或运算 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。 例如:9|5可写算式如下: 00001001 |00000101 00001101 (十进制为13)可见9|5=13 【例12.2】 main(){ int a=9,b=5,c; c=a|b; printf("a=%d\nb=%d\nc=%d\n",a,b,c); } 12.1.3按位异或运算

按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如9^5可写成算式如下:00001001 ^00000101 00001100 (十进制为12) 【例12.3】 main(){ int a=9; a=a^5; printf("a=%d\n",a); } 12.1.4求反运算 求反运算符~为单目运算符,具有右结合性。其功能是对参与运算的数的各二进位按位求反。例如~9的运算为: ~(0000000000001001)结果为:1111111111110110 12.1.5左移运算 左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。 例如: a<<4 指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。 12.1.6右移运算 右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。例如: 设a=15, a>>2 表示把000001111右移为00000011(十进制3)。 应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定。Turbo C和很多系统规定为补1。 【例12.4】 main(){ unsigned a,b; printf("input a number: "); scanf("%d",&a); b=a>>5;

C语言程序设计第11.12章测试答案

1、设有定义“int a=3,b,*p=&a;”,则下列语句中,使b不为3的语句是: A、b=*&a; B、b=*p; C、b=a; D、b=*a; 语言中,关于文件存取方式,: A、只能顺序存取 B、只能随机存取(也称直接存取) C、可以顺序存取,也可以随机存取 D、只能从文件开头存取 是文件指针,str是一个字符串,n是一个整数,向文件中输出数据的正确格式是: A、fprintf("%s,%d\n",str,n,fp); B、fprintf(fp,"%s,%d\n",str,n); C、fprintf("fp%s,%d\n",str,n); D、fprintf("%s,%d fp\n",str,n); 4、若有int a=3,*pa;float f=4.5,*pf=&f;,则下列表述中,错误的是()。 A、pa=&a B、pa=&f C、pf=&f D、*pf=a+f 5、若有int a[10],*p=a;,则()。 A、p++可以使p指向下一个字节 B、p+=2相当于p=sizeof(a)/10 C、p++可以使p指向下一个元素,即a[1]的首地址 D、p+=2可以使p指向下一个元素,即a[1]的首地址

1、函数调用语句fseek(fp,-10L,2)的含义是将文件位置指针从当前位置向文件头方向移10个字节。 正确错误 与p一样。 正确错误 正确错误

正确错误 正确错误 测试结果如下: 1.1[单选][对]设有定义“int a=3,b,*p=&a;”,则下列语句中,使b不为3的语句是:1.2[单选][对]在C语言中,关于文件存取方式,: 1.3[单选][对]fp是文件指针,str是一个字符串,n是一个整数,向文件中输出数据的正确格式是: 1.4[单选][对]若有int a=3,*pa;float f=4.5,*pf=&f;,则下列表述中,错误的是()。 1.5[单选][对]若有int a[10],*p=a;,则()。 2.1[多选][对]C语言中的文件分类是: 2.2[多选][对]以读写方式打开一个二进制文件fil2,fopen函数的正确的调用方式是:2.3[多选][对]下列关于C语言数据文件的叙述中,不正确的叙述是: 2.4[多选][对]若有int*px;float*pf;char*pc;,下列关于指针的正确描述为()。 2.5[多选][对]设有定义语句“struct{int a;float b;char c;}abc,*p;”,则对结构体成员a的引用可以是()。 3.1[判断][对]函数调用语句fseek(fp,-10L,2)的含义是将文件位置指针从当前位置向文件头方向移10个字节。 3.2[判断][对]*&p与p一样。 3.3[判断][对]&*p与p一样。 3.4[判断][对]单目运算符“*”是取地址运算符。 3.5[判断][对]双目运算符“*”是指针运算符。

大学C语言期末考试试题及答案

大学C语言期末考试试题 一选择题(7分,每小题0.5分) 1。C语言源程序的基本单位是()。 A 过程B函数C子程序D标识符 2.下列程序的输出结果是()。 main( ) { inta=7,b=5; printf("%d\n",b=b/a); } A 5 B 1 C0 D不确定值 3.假设变量a,b均为整型,表达式(a=5,b=2,a>b?a++:b++,a+b)的值是()。 A7 B8 C9 D 2 4.设a为int型变量,执行下列赋值语句后,a的取值分别是()。 a=125.534;a=(int)125.521%4;a=5<<2; A125,31,1 B125,1,20 C 125,31,20D125.534,2,20 5。设有如下程序段,下面描述中正确的是( )。 int k=10;while(k=0)k=k—1; A循环执行一次B循环是无限循环C循环体语句一次也不执行D循环体语句执行一次 6。以下程序的输出结果为( ). int i; void prt() { for(i=5;i<8;i++) printf(”%c”,'*’); printf("\t"); } main( ) { for(i=5;i<=8;i++)prt( ); } A *** B ************ C *** *** D * ** 7。在C语言程序中,以下说法正确的是()。 A函数的定义可以嵌套,但函数的调用不可以嵌套 B函数的定义不可以嵌套,但函数的调用可以嵌套 C函数的定义和函数的调用都不可以嵌套 D函数的定义和函数的调用都可以嵌套 8。以下函数调用语句中含有( )个实参. func((e1,e2),(e3,e4,e5)); A 2 B3 C5 D语法错误 9.以下程序的输出结果为(). #defineADD(x)x*x main( ) {int a=4,b=6,c=7,d=ADD(a+b)*c; printf(”d=%d",d);

《C语言程序设计》第12章在线测试

A B C D 、若有说明语句“ A B C D 语言中,关于文件存取方式,: A B C D 、已知定义“int x A B C D int a=3,*pa; float f,则下列表述中,错误的是 A B C D

2、以读写方式打开一个二进制文件fil2,fopen函数的正确的调用方式是: A、FILE *FP; FP=fopen("fil2","r"); B、FILE *FP; FP=fopen("fil2","rb"); C、FILE *FP; FP=fopen("fil2","wb+"); D、FILE *FP; FP=fopen("fil2","rb+"); 3、已有char s[10][10]={0};int i=10;。在下列表达式中,没有意义的表达式是: A、s[i][i] B、*(*(s+i)+i) C、*(&(s+i)+i) D、*(*(s+i-1)+i-1) 4、若有int x,*px=&x; float y, *pf=&y;char c,*pc=&c;,下列正确的为()。 A、px=(int *)pf; B、pc=(int *)px; C、px=(int *)pc; D、pf=(int *)px; E、pf=(float *)pc; 5、设有定义语句“int x=10, *p=&x”,则表达式的值为10的有()。 A、p B、*p C、*&x D、*p=x E、x=*p 第三题、判断题(每题1分,5道题共5分) 1、单目运算符“&”是指针运算符。

正确错误 、函数中的形参若为指针,则调用时对应位置上的实参不能是数组名。 正确错误一样。正确错误、单目运算符“*正确错误、共用体变量的存储单元长度是最长分量的存储长度。正确错误 《C 语言程序设计》第12章在线测试 恭喜,交卷操作成功完成!你本次进行的《C 语言程序设计》第12章在线测试的得分为 20分(满分20分),本次成绩已入库。若对成绩不满意,可重新再测,取最高分。 测试结果如下: ? 1.1 [单选] [对] 若执行fopen 函数时发生错误,则函数的返回值是() ? 1.2 [单选] [对] 若有说明语句“int a[10],*p =a;”,对数组元素的正确引用是: ? 1.3 [单选] [对] 在C 语言中,关于文件存取方式,: ? 1.4 [单选] [对] 已知定义“int x = 1, *p ”,则合法的赋值表达式是( )。 ? 1.5 [单选] [对] 若有int a =3,*pa; float f =4.5,*pf =&f;,则下列表述中,错误的是 ( )。 ? 2.1 [多选] [对] C 语言中的文件分类是: ? 2.2 [多选] [对] 以读写方式打开一个二进制文件fil2,fopen 函数的正确的调用方式是: ? 2.3 [多选] [对] 已有char s[10][10]={0};int i =10;。在下列表达式中,没有意义的表达式是: ? 2.4 [多选] [对] 若有int x,*px =&x; float y, *pf =&y;char c,*pc =&c;,下列正确的为( )。 ? 2.5 [多选] [对] 设有定义语句“int x =10, *p =&x ”,则表达式的值为10的有( )。 ? 3.1 [判断] [对] 单目运算符“&”是指针运算符。 ? 3.2 [判断] [对] 函数中的形参若为指针,则调用时对应位置上的实参

大学大一C语言程序设计期末考试试卷及答案

XX 师X 大学计算机科学学院 2012~2013学年度第二学期期末考试 C 语言程序设计试卷 试卷A 答卷说明: 1、 本试卷共6页,答题纸3页,4个大题,35个小题,满分100分,120分钟 完卷。 2、 闭卷考试,所有的答案都必须写在答题纸上,判卷以答题纸上答案为准。 3、 本试卷适用于2011级1、2、3班。 壱、 单项选择题(在每小题的四个备选答案中,选出一个正确答案,并将正确答案的序号填在题干的括号内。每小题1分,共20分) 1、 在C 语言中,下列标识符中合法的是( ) A). -int B). in1_3 C). A_B!D D). const 2、 不属于C 语言基本数据类型的是( ) A). int B). union C). char D). unsigned 3、 下面是对宏定义的描述。不正确的是( ) A). 宏不存在类型问题,宏名无类型,它的参数也无类型 B). 宏替换不占用运行时间 C). 宏替换只是字符串的简单替代 D). 宏替换时先检查类型,类型一致时才可以替换 4、 C 语言中,″\\xfds ″在内存中占用的字节数是( ) A).3 B).4 C).5 D).6 5、 设int x;则执行printf(″%x\n ″,~x^x);的结果是( ) A). ffffffff B). ff C). 0 D). 1 6、 对于while 语句,错误的说法是( ) A).用条件控制循环体的执行次数 B).循环体至少要执行一次 C).循环体有可能一次也不执行 D).循环体中可以包含若干条语句 __________________学院__________级___________班 X X _______________ 学号_______________ ………………………………(密)………………………………(封)………………………………(线)……………………………… 密 封 线 内 答 题 无 效

相关主题
文本预览
相关文档 最新文档