📄 c语言.txt
字号:
当 x 输入值为9999时,函数返回值为多少?
int fun ( unsigned int x )
{
int count = 0;
while(x)
{
x = x & (x-1);
count++;
}
return count;
}
答案:此函数是在计算 x 中含有1的个数,所以返回值为8。
1. 以下三条输出语句分别输出什么?[C易] (视编译器而定)
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char* str5 = "abc";
const char* str6 = "abc";
cout << boolalpha << ( str1==str2 ) << endl; // 输出什么?
cout << boolalpha << ( str3==str4 ) << endl; // 输出什么?
cout << boolalpha << ( str5==str6 ) << endl; // 输出什么?
答:分别输出false,false,true。str1和str2都是字符数组,每个都有其自己的存储区,它们的值则是各存储区首地址,不等;str3和str4同上,只是按const语义,它们所指向的数据区不能修改。str5和str6并非数组而是字符指针,并不分配存储区,其后的“abc”以常量形式存于静态数据区,而它们自己仅是指向该区首地址的指针,相等。
12. 以下代码中的两个sizeof用法有问题吗?[C易]
void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母
{
for( size_t i=0; i if( 'a'<=str[i] && str[i]<='z' )
str[i] -= ('a'-'A' );
}
char str[] = "aBcDe";
cout << "str字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;
UpperCase( str );
cout << str << endl;
答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组,因此其大小为6,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4个字节,因此返回4。
[color=#DC143C]13. 非C++内建型别 A 和 B,在哪几种情况下B能隐式转化为A?[C++中等]
答:
a. class B : public A { ……} // B公有继承自A,可以是间接继承的
b. class B { operator A( ); } // B实现了隐式转化为A的转化
c. class A { A( const B& ); } // A实现了non-explicit的参数为B(可以有其他带默认值的参数)构造函数
d. A& operator= ( const A& ); // 赋值操作,虽不是正宗的隐式类型转换,但也可以勉强算一个[/color]
4. 以下代码有什么问题?[C++易]
struct Test
{
Test( int ) {}
Test() {}
void fun() {}
};
void main( void )
{
Test a(1);
a.fun();
Test b();
b.fun();
}
答:变量b定义出错。按默认构造函数定义对象,不需要加括号。
5. 以下代码有什么问题?[C++易]
cout << (true?1:"1") << endl;
答:三元表达式“?:”问号后面的两个操作数必须为同一类型。
8. 以下代码能够编译通过吗,为什么?[C++易]
unsigned int const size1 = 2;
char str1[ size1 ];
unsigned int temp = 0;
cin >> temp;
unsigned int const size2 = temp;
char str2[ size2 ];
答:str2定义出错,size2非编译器期间常量,而数组定义要求长度必须为编译期常量。
2. 以下反向遍历array数组的方法有什么错误?[STL易]
vector array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 3 );
for( vector::size_type i=array.size()-1; i>=0; --i ) // 反向遍历array数组
{
cout << array[i] << endl;
}
答:首先数组定义有误,应加上类型参数:vector array。其次vector::size_type被定义为unsigned int,即无符号数,这样做为循环变量的i为0时再减1就会变成最大的整数,导致循环失去控制。
[color=#DC143C]9. 以下代码中的输出语句输出0吗,为什么?[C++易]
struct CLS
{
int m_i;
CLS( int i ) : m_i(i) {}
CLS()
{
CLS(0);
}
};
CLS obj;
cout << obj.m_i << endl;
答:不能。在默认构造函数内部再调用带参的构造函数属用户行为而非编译器行为,亦即仅执行函数调用,而不会执行其后的初始化表达式。只有在生成对象时,初始化表达式才会随相应的构造函数一起调用。[/color]
[color=#DC143C]10. C++中的空类,默认产生哪些类成员函数?[C++易]
答:
class Empty
{
public:
Empty(); // 缺省构造函数
Empty( const Empty& ); // 拷贝构造函数
~Empty(); // 析构函数
Empty& operator=( const Empty& ); // 赋值运算符
Empty* operator&(); // 取址运算符
const Empty* operator&() const; // 取址运算符 const
};[/color]
[color=#DC143C]3. 以下两条输出语句分别输出什么?[C++难]
float a = 1.0f;
cout << (int)a << endl;
cout << (int&)a << endl;
cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?
float b = 0.0f;
cout << (int)b << endl;
cout << (int&)b << endl;
cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?
答:分别输出false和true。注意转换的应用。(int)a实际上是以浮点数a为参数构造了一个整型数,该整数的值是1,(int&)a则是告诉编译器将a当作整数看(并没有做任何实质上的转换)。因为1以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等。对b的两种转换意义同上,但是0的整数形式和浮点形式其内存数据是一样的,因此在这种特殊情形下,两者相等(仅仅在数值意义上)。
注意,程序的输出会显示(int&)a=1065353216,这个值是怎么来的呢?前面已经说了,1以浮点数形式存放在内存中,按ieee754规定,其内容为0x0000803F(已考虑字节反序)。这也就是a这个变量所占据的内存单元的值。当(int&)a出现时,它相当于告诉它的上下文:“把这块地址当做整数看待!不要管它原来是什么。”这样,内容0x0000803F按整数解释,其值正好就是1065353216(十进制数)。
通过查看汇编代码可以证实“(int)a相当于重新构造了一个值等于a的整型数”之说,而(int&)的作用则仅仅是表达了一个类型信息,意义在于为cout<<及==选择正确的重载版本。
[/color]
6. 以下代码有什么问题?[STL易]
typedef vector IntArray;
IntArray array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 2 );
array.push_back( 3 );
// 删除array数组中所有的2
for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor )
{
if( 2 == *itor ) array.erase( itor );
}
答:同样有缺少类型参数的问题。另外,每次调用“array.erase( itor );”,被删除元素之后的内容会自动往前移,导致迭代漏项,应在删除一项后使itor--,使之从已经前移的下一个元素起继续遍历。
[color=#DC143C]11. 写一个函数,完成内存之间的拷贝。[考虑问题是否全面]
答:
void* mymemcpy( void *dest, const void *src, size_t count )
{
char* pdest = static_cast( dest );
const char* psrc = static_cast( src );
if( pdest>psrc && pdest {
for( size_t i=count-1; i!=-1; --i )
pdest[i] = psrc[i];
}
else
{
for( size_t i=0; i pdest[i] = psrc[i];
}
return dest;
}[/color]
原题如下:
#i nclude
struct bit
{
int a:3;
int b:2;
int c:3;
};
int main(int argc, char* argv[])
{
bit s;
char *c = (char*)&s;
*c = 0x99;
cout < return 0;
}
Output:?
答案:
此题在在X86 little-endian 下是 1 -1 -4
在powerPC等big endian机器下,还要重新考虑
因为0x99在内存中表示为 100 11 001 , a = 001, b = 11, c = 100
当c为有符号数时, c = 100, 最高位1表示c为负数,负数在计算机用补码表示,所以c = -4;同理
b = -1;当c为有符合数时, c = 100,即 c = 4,同理 b = 3
位域的概念
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:
struct 位域结构名
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度
例如:
struct bs
{
int a:8;
int b:2;
int c:6;
};
位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:
struct bs
{
int a:8;
int b:2;
int c:6;
}data;
说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明:
1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:
struct bs
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*从下一单元开始存放*/
unsigned c:4
}
在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:
struct k
{
int a:1
int :2 /*该2位不能使用*/
int b:3
int c:2
};
从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。
二、位域的使用位域的使用和结构成员的使用相同,其一般形式为: 位域变量名·位域名 位域允许用各种格式输出。
main(){
struct bs
{
unsigned a:1;
unsigned b:3;
unsigned c:4;
} bit,*pbit;
pbit = new bs;
bit.a=1;
bit.b=7;
bit.c=15;
pbit->a = 1;
pbit->b = 2;
pbit->c = 3;
printf("%d, %d, %d",bit.a, bit.b, bit.c);
printf("%d, %d, %d",pbit->a, pbit->b, pbit->c);
}
四
一、 单项选择题(从四个备选答案中选择一个正确答案,每小题1分,共20分)
1. C++中,关键字struct和class的区别仅仅在于( C )。
(A)struct 用来定义结构体, 而class用来定义类;
(B)struct 用来定义类, 而class用来定义类结构体;
(C)struct定义的类的缺省成员为公有的,而class定义的类的缺省成员为私有的;
(D)struct定义的类的成员须全部为公有的,而class定义的类的成员可以为私有的;
2. 以下程序执行后,输出结果为( C ).
#i nclude
int Var=3 ;
void main(void)
{ int Var=10;
::Var++;
cout<<”Var=”<
}
(A)Var=11, ::Var=11 (B)Var=11, ::Var=3
(C)Var=10, ::Var=4 (D)Var=4, ::Var=10
3. 抽象基类是指( C )。
(A)嵌套类 (B)派生类
(C)含有纯虚函数 (D)多继承类
4.如果有#define AREA(a,b)a+b 则语句int s=AREA(3,4)*AREA(3,4)执行后变量s值为( D )。
(A) 24 (B)49 (C)144 (D)19
5. C++中条件表达式的值为( C )。
(A)–1或者+1 (B)–231~231 –1 (C)0或者1 (D) 0~231–1
6. 现在有以下语句:
struct MyBitType
{ int a:3;
unsigned b:3;
unsigned c:20;
int d;
};
int sz=sizeof(MyBitType);
则执行后,变量sz的值将得到( B )。
(A)2 (B)8 (C)28 (D)58
7. 假设有一个C++类名为Country, 则此类的析构函数为( C ).
(A)::Country() (B)void ~Country(void)
(C)~Country() (D)void ~Country()
8. 如果定义一个C++类CDate, 语句“CDate *p = new CDate;”的含义是( A )。
(A)调用CDate类的缺省构造函数从内存中分配一个CDate类型的对象,并将该对象地址赋值给指针p;
(B)调用CDate类的拷贝构造函数从内存中分配一个CDate类型的对象,并将该对象地址赋值给指针p;
(C)调用CDate类的析构函数从内存中分配一个CDate类型的对象,并将该对象地址赋值给指针p;
(D)从内存中释放指针p所指向的CDate类的对象;
9.如果有一个类CRect及语句“CRect x1, x2;” 要使语句 “x1=x2;”合法,可在类中定义成员函数( C )。
(A) int operator(x2) (B)int operator=(x2)
(C) void operator=(CRect &); (D) void operator=()
10. 结构体变量S实际所占内存的大小为( A )字节。
(A)sizeof(S) (B)strlen(S)
(C)结构体中最长成员的长度 (D)结构体中最短成员的长度
11.在C++中,下列算符( D )不能重载。
(A)<< (B)>> (C)delete (D)::
12.下列正确的是( D )
(A)结构不能有构造函数、析构函数; (B)缺省时类的成员是公有的;
(C)类中如果定义了析构函数,则必须定义构造函数;
(D)缺省时结构的成员是公有的;
13. 下列关于静态数据成员正确的是( B )
(A)可以通过this指针访问静态数据; (B)可以用类名和作用域访问静态数据;
(C)静态数据在类内声明并初始化; (D)只能由该类的静态成员函数访问;
14. 下列关于友元正确的说法是( D )
(A)友元只能在类的public区声明;(B)友元具有this指针;
(C)类的成员函数不能声明为另一个类的友元;
(D)一个函数如果被声明为一个类的友元,则该函数具有访问该类私有成员的权利。
15. 基类的( A )在派生类内不能被访问。
(A)私有成员 (B)保护成员
(C)公有数据成员 (D)公有静态数据成员
16. 下列关于运算符重载的描述中正确的是( D )
(A)运算符重载可以改变该运算符的优先级;
(B)运算符重载可以改变该运算符目数,即该算符运算的操作数个数;
(C)运算符重载函数只能在类中定义;
(D)new和delete允许重载;
17.左值是指( A )
(A)赋值算符左边的变量; (B)赋值算符左边的表达式的值;
(D)出现在赋值算符右边的表达式的值;
(E)二元算符左边表达式的值;
18. 下列为纯虚函数的正确声明的是( B )
(A)void virtual print()=0; (B)virtual void print()=0;
(C)virtual void print(){ }; (D)virtual void print();
19. 如果在类对象a的类中重载运算符“+”,则a+5的显示调用方式为( C )
(A)a.operator(5) (B)a->operator+(5);
(C)a.operator+(5) (D)5.operator+(a)
20.一个类如果有一个以上的基类就叫做( B )。
(A)循环继承 (B)单继承
(C)非法继承 (D)多继承
二、 多项选择题(从五个备选答案中选择2~5个正确答案,每小题2分,共10分)
1. 如果已定义了一个C++类CMyList并有以下语句:
CMyList list(3);
以下说法正确的是( AC )。
(A)该语句会创建一个CMyList类的一个对象;
(B)该语句会创建一个CMyList类的3个对象;
(C)必须为类CMyList定义一个构造函数;
(D)必须为类CMyList定义一个析构函数;
(E) 必须定义函数CMyList list(int);
2. 以下说法正确的是( ABCDE )。
(A)内联(inline)函数改善了函数调用的执行效率。
(B)类A的友元(friend)函数可以访问类A的私有成员。
(C)类A的友元(friend)类B可以访问类A的私有成员。
(D)类A的静态数据成员为类A的所有对象所共享。
(E)类A的静态成员函数没有传递this 指针作为参数。
3.类B从类A派生,则类B可以访问类A中的( AC )成员。
(A)public成员 (B)private成员 (C)protected成员
(D)数据成员 (E)函数成员
4. 面向对象的程序设计语言具有( ABE )等共同特性。
(A)封装性 (B)多态性 (C)简单性 (D)复杂性
(E)继承性
5. 现有一个程序如下:
#i nclude
class A
{ public:
void f(){ cout<< "A::f()"<
};
class B
{ public:
void f(){ cout<< "B:f()"<
void g(){ cout<< "B:g()"<
};
class C:public A, public B
{ public:
void g(){ cout<<"C::g()"<
void h()
{ cout<<"C::h()"<
f(); //语句1
}
};
void main()
{ C obj;
obj.f(); //语句2
obj.A::f(); //语句3
obj.B::f(); //语句4
obj.g(); //语句5
}
则编译时会产生错误的语句有( AB )。
(A)语句1 (B)语句2 (C)语句3
(D)语句4 (E)语句5
三、 判断分析题(正确的画上√,错误的画上×,每小题1分,共10分)
1.如果一个类的所有对象都共享某一个变量,则应当将该变量定义为该类的static成员。 ( √ )
2.语句“ typedef struct _MYSTRUC { int x; int y; double z; } MYSTRUC; ”是非法语句。 ( × )
3.语句“ int (*p)(int x, int y);”说明了p是一个指向整数的指针。 ( × )
4.Visual C++集成开发环境中,一个Workspace中只能创建一个Project。 ( × )
5.能访问一个类CMyClass中的private成员的可以是类CMyClass的成员函数,友元函数和友元类中的函数。 ( √ )
6. 所有的MFC应用程序都必须有一个且只有一个CWinApp对象。 ( √ )
7.C++中的多态性就是指在编译时,编译器对同一个函数调用,根据情况调用不同的实现代码。 ( × )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -