赞
踩
如下为牛客网C/C++专项刷题:python
一、下面程序会输出什么:ios
static int a=1;
void fun1(void){ a=2; }
void fun2(void){ int a=3; }
void fun3(void){ static int a=4; }
int main(int argc,char** args){
printf(“%d”,a);
fun1( );
printf(“%d”,a);
fun2( );
printf(“%d”,a);
fun3( );
printf(“%d”,a);
}
KEY:1 2 2 2c++
解析:静态局部变量只对定义它的函数体始终可见,函数体执行完事后虽然还存在,可是没法被其余的使用了。数组
二、下面程序会输出什么:缓存
int main()
{
bool first=true;
int sum=0;
int value;
unsigned short i=0xFFFF;
for (;i>=0;--i)
{
if (first)
{
value=65536;
sum+=value%3;
first=false;
}
else{
sum+=--value%3;
if (value<=0)
{
cout<
break;
}
}
}
return 0;
}
KEY:65536,65535ide
解析:for(;i>=0;--i)因为是i是unsigned无符号,因此并非i<0退出循环,是当i=0后下一个i的值从最初的0xffff(65535)从头再开始(没法表示-1),也就是说若是for循环里没有break即死循环。-1 = 1000 0000 0000 0001B = 补码:1111 1111 1111 1111 = 无符号则为0xffff,存储方式为补码形式。函数
三、下面有关C++的类和C里面的struct的描述,正确的有?大数据
在C++中,来自class的继承默认按照private继承处理,来自struct的继承默认按照public继承处理优化
class的成员默认是private权限,struct默认是public权限this
c里面的struct只是变量的聚合体,struct不能有函数
c++的struct可有构造和析构函数
KEY:A、B、C、D
四、如下正确的说法是( ),在C语言中。
实参和与其对应的形参各占用独立的存储单元
实参和与其对应的形参共占用一个存储单元
只有当实参和与其对应的形象同名时才共占用存储单
形参是虚拟的,不占用存储单元
KEY:A
解释:形参在编译时是不会分配存储容间,在调用时才在栈里分配,在调用结束时,即刻释放所分配的内存单元。
五、程序运行后的输出结果是?
#include
main(){
int i=0;
i=~i;
printf("%d\n",i);
}
KEY:-1
解释:0 = 00000000000000000000000000000000 ,取反11111111111111111111111111111111,就是-1在计算机的存储形式。
计算机内, 负数以反码形式存储, 符号位不变, 源码求反加1, 就是反码。
11111111111111111111111111111111就是
10000000000000000000000000000001求反
11111111111111111111111111111110 加1
就是 11111111111111111111111111111111。
六、程序运行后的输出结果是?
enum {
a, b=5, c, d=4, e
} k;
k =c;
KEY:6
解释:enum中:首元素不赋值的话,默认为0;后一个元素不赋值的话比前一个元素大1。
七、关于“深拷贝”,下列说法正确的是:
会拷贝动态分配的成员对象
会拷贝成员数据的值
会拷贝静态分配的成员对象
KEY:A
解释:
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另一个对象形成影响;
浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不一样(名称不一样)。对其中任何一个对象的改动都会影响另一个对象。
B和C都算错在了一个地方,没有考虑静态成员。类的静态成员是全部类的实例共有的,存储在全局(静态)区,只此一份,无论继承、实例化仍是拷贝都是一份。
八、有哪几种状况只能用intialization list 而不能用assignment?
当类中含有const成员变量
基类无默认构造函数时,有参的构造函数都须要初始化。
当类中含有reference成员变量
当类中含有static成员变量
KEY:A、B、C
解析:由于const对象以及引用只能初始化而不能赋值,因此只能使用成员初始化列表。
对于非内置类型,在进入函数体以前,若是没有提供显式初始化,会调用默认构造函数进行初始化。若没有默认构造函数,则编译器尝试调用默认构造函数将会失败,因此若是没有默认构造函数,则必须在初始化列表中显示的调用构造函数。
static 成员在执行构造函数前就已经构造好了,即便不存在类对象,也能够被使用,不须要初始化列表。
九、如有说明:int*p,m=5,n;则如下正确的程序段是()。
p=&n;scanf("%d",&p);
p=&;scanf("%d",*p)
scanf("%d”,&n); *p=n;
p=&n;*p=m;
KEY:D
解释:因p是指针变量,在scanf中不能再使用&p或*p来接收键盘的输入值,应直接用p便可。
十、在下列关于类型转换的描述中,错误的是( )。
任何形式的构造函数均可以实现数据类型转换。
带非默认参数的构造函数能够把基本类型数据转换成类类型对象。
类型转换函数能够把类类型对象转换为其余指定类型对象。
类型转换函数只能定义为一个类的成员函数,不能定义为类的友元函数。
KEY:A
解析:转换构造函数的做用是将一个其余类型的数据转换成一个类的对象。注意:转换构造函数只能有一个参数。若是有多个参数,就不是转换构造函数。缘由是显然的,若是有多个参数的话,到底是把哪一个参数转换成类的对象呢?
类型转换函数是类中定义的一个成员函数。operator和“转换后的类型”一块儿构成转换函数名。该函数不能带有参数,也不能指定返回值类型。由于它的返回值类型就是“转换后的类型”。转换函数的做用就是将对象内的成员数据转换成某种特定的类型。类型转换函数只能定义为一个类的成员函数,不能定义为类的友元函数。
十一、哪一个选项能够将t初始化为当前程序的运行时间?
time_t t;
t = clock();
time( &t );
time( t );
t = localtime();
KEY:A
解释:clock()就是该程序从启动到函数调用占用CPU的时间;time( &t );为获取系统时间;localtime(&t); 将一个UTC时间转为本地时间。
十二、从运行层面上来看,从四个选项选出不一样的一个。
JAVA
Python
objectC
C#
KEY:B
解释:Java,C,C#是静态语言,须要编译;python时动态语言,不须要编译。
1三、一个C语言程序是由()。
一个主程序和若干子程序组成
函数组成
若干过程组成
若干子程序组成
KEY:B
解释:C语言程序是由函数构成的,所谓函数是指功能相对独立的能够反复执行的。一段程序,在某些程序设计语言中也称为过程,但C语言中叫函数。
1四、正确的输入语句是______。
int b;
char c[10];
scanf("%d%s",&b,&c);
scanf("%d%s",&b,c);
scanf("%d%s",b,c);
scanf("%d%s",b,&c);
KEY:A、B
解释: "c" 实际上有两种含义 : 一个指向十个char类型元素的数组、一个char* 类型的指针。
对于第一种状况:
scanf("%s", &c); //这里c是一个指向十个char元素的数组的指针
对于第二种状况:
scanf("%s", c); //这里c是一个char* 类型的指针,数组名就是一个地址
1五、若给定条件表达式(M)?(a++):(a--),则其中表达式 M()。
和(M==0)等价
和(M==1)等价
和(M!=0)等价
和(M!=1)等价
KEY:C
解释:在C语言中非零数表明true,零表明false。而B选项,只是判断是否等于1,对于二、3等数就不视做真了。
1六、假设有说明 int a=0; double x=5.16;,则在如下语句中,( )属于编译错误。
x=a/x;
x=x/a;
a=a%x;
x=x*a;
KEY:C
1七、这段程序的运行结果为:
#include
using namespace std;
class A
{
public:
virtual void print()
{
cout << "A::print()" << "\n";
}
};
class B: public A
{
public: virtual void print()
{
cout << "B::print()" << "\n";
}
};
class C: public A
{
public: virtual void print()
{
cout << "C::print()" << "\n";
}
};
void print(A a)
{
a.print();
}
int main()
{
A a, *aa, *ab, *ac;
B b;
C c;
aa = &a;
ab = &b;
ac = &c;
a.print();
b.print();
c.print();
aa->print();
ab->print();
ac->print();
print(a);
print(b);
print(c);
}
KEY:A::print() B::print() C::print() A::print() B::print() C::print() A::print() A::print() A::print()
解释:虚函数会具备动态绑定功能,会按照实际类型调用相关的函数。而动态绑定(多态)只有在指针和引用时才有效,其余状况下无效!
a.print(); b.print(); c.print(); 虽然是虚函数,但不是指针,无效!分别输出A::print() B::print() C::print();
aa->print(); ab->print(); ac->print(); 虚函数,指针,因此输出实际对象类型对应的print,所以输出A::print() B::print() C::print();
void print(A a){ a.print();} 函数声明的形参为A类型的,至关于强制类型转换,所以调用print(A a)函数的输出都是A::print()。
1八、重写(override)与重载(overload)的区别:
函数重写是子类和父类之间的继承关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系;
重写须要子类和父类中的两个函数的函数原型彻底相同;重载要求两个函数参数列表不一样;
在重写关系中,调用具体调用哪个函数是根据(对象对应存储空间的实际类型)为准的,这涉及到动态绑定和静态绑定的问题,也就是虚函数的调用机制,而函数重载主要是靠形参列表的不一样来区分具体调用哪一个函数的。
1九、这段程序的运行结果为:
int func()
{
int i,j,k=0;
for(i=0,j=-1;j=0;i++,j++)
{
k++;
}
return k;
}
int main()
{
cout<
}
KEY:0
解释:先看循环断定条件 ,true则执行,在执行循环体内以前进行的条件判断。而本题的判断条件时j=0。这是什么意思呢?
实际上能够将赋值语句去掉,好比说if语句:if(i=1)实际上就是 i=1; if(1)。
20、下列说法错误的有( )
在类方法中可用this来调用本类的类方法
在类方法中调用本类的类方法时可直接调用
在类方法中只能调用本类中的类方法
在类方法中绝对不能调用实例方法
KEY:A、C、D
解释:首先明确一点,成员方法又称为实例方法,静态方法又称为类方法。
a,静态方法中没有this指针
c,能够经过类名做用域的方式调用Class::fun();
d,太绝对化了,在类中申请一个类对象或者参数传递一个对象或者指针均可以调用;
2一、这段程序的运行结果为:
int func(int a)
{
int b;
switch (a)
{
case 1: b = 30;
case 2: b = 20;
case 3: b = 16;
default: b = 0;
}
return b;
}
KEY:0
解析:func(1)=0,由于没有break语句,switch中会一直计算到b=0。这是提醒咱们不要忘了break。
2二、这段程序的运行结果为:
#include "iostream"
#include "vector"
using namespace std;
int main(void)
{
vectorarray;
array.push_back(100);
array.push_back(300);
array.push_back(300);
array.push_back(500);
vector::iterator itor;
for(itor=array.begin();itor!=array.end();itor++)
{
if(*itor==300)
{
itor = array.erase(itor);
}
}
for(itor=array.begin();itor!=array.end();itor++)
{
cout<
}
return 0;
}
KEY:100 300 500
解析:vector erase之后,itor已经指向下一个元素了,不该该执行itor++,不然会跳过下一个元素,即连续两个300时跳过了第二个300.
2三、这段程序中,str1和str2的地址相同么?p1和p2指向的地址相同么?
const char str1[] = "abc";
const char str2[] = "abc";
const char *p1 = "abc";
const char *p2 = "abc";
KEY:str1和str2地址不一样,P1和P2指向的地址相同
解释: str1和str2是栈空间中的两个字符数组,地址不一样;p1和p2指向的位置在常量区,值都是“abc”因此是同一常量,地址相同。
2四、在64位系统中,有以下类,那么sizeof(C)的数值是()
class C
{
public:
char a;
static char b;
void *p;
static int *c;
virtual void func1();
virtual void func2();
};
KEY:24
解释:sizeof(类)计算的是类中存在栈中的变量的大小,而类中的b和*c都是static静态变量,存在全局区中,所以不在计算范围以内。因而只剩下char a,void *p和两个virtual虚函数,a是char类型,占用一个字节,p是指针,在64位系统的指针占用8个字节,而两个虚函数只须要一个虚函数表指针,也是八个字节,加上类中的对齐方式(char a对齐时后面补上7个字节),故答案为24。
本题中的虚函数属于同一个类,故只须要一个指针指向虚函数表,因此在64位系统中占用8个字节。就算本题有100个虚函数,那么也只占用8个字节。类与结构同样,都有字节对齐的问题。类中普通的函数不占用类的大小。子类的大小等于子类新增的加上父类的大小。
2五、C++语言中,有关类的初始化叙述正确的是()
静态函数中不能出现this指针
能够在类定义时,对对象直接初始化
通常数据类型能够在类的外部进行初始化
静态数据类型能够在类的外部进行初始化
KEY:AD
解释:静态成员变量必须在类外初始化,静态成员常量在类中初始化。
2六、这段程序的运行结果为:
int main(int argc,char**argv){
int a[4]={1,2,3,4};
int*ptr=(int*)(&a+1);
printf(“%d”,*(ptr-1));
}
KEY:4
解释:指针的实质为:地址+步长。指针的类型决定了步长。定义了数组a[4],其中a,&a,&a[0]都是数组的起始地址。可是步长有区别,也就是指向的类型不一样。
a等同于a+0等同于&a[0],是指向数组第一个元素的指针,步长为指向的元素所占用的地址空间为sizeof(int) ;
&a也是指向数组第一个元素的指针,但其意义是指向整个数组的首地址,指向的类型为整个数组,因此其步长为4*sizeof(int)。
也就是说,&a+1移动了4个int的长度,指向4后面的那个数的地址;ptr-1,移动1个int的长度,指向4。
2七、请问下面的程序一共输出多少个“-”?
#include
#include
#include
int main(void) {
int i;
for (i=0; i<2; i++) {
fork();
printf("-\n");
}
return 0;
}
KEY:6
解释:fork()系统调用是Unix下以自身进程建立子进程的系统调用,一次调用,两次返回,若是返回是0,则是子进程,若是返回值>0,则是父进程(返回值是子进程的pid),这是众为周知的。
还有一个很重要的东西是,在fork()的调用处,整个父进程空间会原模原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲区,等等。
i=0时,父进程A产生一个子进程A1,此时输出两行“-”;
i=1时,fork使父进程A产生子进程A2,A1产生子进程A3,此时A-A3共产生4行“-”(由于如今A,A1的输出行缓冲均为空);
总数为6:2(A)+2(A1)+1(A2)+1(A3)=6;
但若是题目改为:
#include
#include
#include
int main(void) {
int i;
for (i=0; i<2; i++) {
fork();
printf("-");
}
return 0;
}
结果就是8个了。这是由于printf(“-“);语句有buffer,因此,对于上述程序,printf(“-“);把“-”放到了缓存中,并无真正的输出,在fork的时候,缓存被复制到了子进程空间,因此,就多了两个,就成了8个,而不是6个。
程序遇到“\n”,或是EOF,或是缓中区满,或是文件描述符关闭,或是主动flush,或是程序退出,就会把数据刷出缓冲区。须要注意的是,标准输出是行缓冲,因此遇到“\n”的时候会刷出缓冲区,但对于磁盘这个块设备来讲,“\n”并不会引发缓冲区刷出的动做,那是全缓冲,你可使用setvbuf来设置缓冲区大小,或是用fflush刷缓存。
2八、在32位机器上,下列代码中,sizeof(a)的值是()。
class A
{
int i;
union U
{
char buff[13];
int i;
}u;
void foo() { }
typedef char* (*f)(void*);
enum{red, green, blue} color;
}a;
KEY:24
解释:联合表示若干数据成员取其一,故以叠加方式分配内存,所占字节数为最大数据成员所占的字节数。 还要字节对齐:
空函数 不占字节。
int i占4个字节;
union U实例化为u占取16个字节(char数组占13个字节,但由于最大类型为int,因此占取只能为4字节的整数倍即最小16字节);
空函数不占取字节;
未实例化指针不占取字节;
枚举类型占取4个字节;
因此4+16+0+0+4=24。
2九、下列关于bool,int,float,指针类型的变量a 与“零”的比较语句正确的有?
bool : if(!a)
int : if(a == 0)
float: if(a == 0.0)
指针: if(a == nullptr)
KEY:A、B、D
解释:因为计算机二进制表示浮点数有精度的问题,0.0(浮点double)实际上不是0,而是很是接近零的小数,因此C错!
30、程序运行后的输出结果是( )。
#include
main()
{int
a[]={1,2,3,4,5,6,7,8,9,10,11,12,},*p=a+5,*q=NULL;
*q=*(p+5);
printf("%d %d\n",*p,*q);
}
KEY:运行后报错。
解释:*q=NULL,q是野指针,对q操做可能会引发程序崩溃,首先编译器就不容许他的存在。
3一、选择填空:
#include
void test(void *data) {
unsigned int value = (此处应填入)
printf("%u", value);
}
using namespace std;
int main() {
unsigned int value = 10;
test(&value);
return 0;
}
*data
(unsigned int)(*data)
(unsigned*)data
*((unsigned int *)data)
KEY:D
解释:实际上只要是*data,咱们就知道了它是指针,若是是32位机器,该指针就指着内存中的某个地址,用32位表示,记住这个32位只是初始地址,任何指针都是的。而前面的void 或者int 类型是定义一次读几个字节,若是是int则读4个字节,也就是从*data存的地址开始从内存日后读4个字节就行,而void是空,没有指定要读多少个字节,因此要用指针类型(unsigned int *)强制转化为知道要读几个字节的int指针,而后再用*从开始地址,读取unsigned int个字节出来!
参数是 void*, 编译器不知道它的具体数值类型,不能直接取值,B错。
3二、运行时的输出结果是()
#include
using namespace std;
class MyClass
{
public:
MyClass(int i = 0)
{
cout << i;
}
MyClass(const MyClass &x)
{
cout << 2;
}
MyClass &operator=(const MyClass &x)
{
cout << 3;
return *this;
}
~MyClass()
{
cout << 4;
}
};
int main()
{
MyClass obj1(1), obj2(2);
MyClass obj3 = obj1;
return 0;
}
KEY:122444
解释:注意区分实现拷贝功能的构造函数、赋值运算符的重载的区别,也就是:
A a ;
A b;
a = b;
这里是赋值操做。
A a;
A b = a;
这里是拷贝的构造函数操做。
因此 MyClass obj3 = obj1; 调用的是拷贝构造函数。
3三、关于抽象类和纯虚函数的描述中,错误的是:
纯虚函数的声明以“=0;”结束
有纯虚函数的类叫抽象类,它不能用来定义对象
抽象类的派生类若是不实现纯虚函数,它也是抽象类
纯虚函数不能有函数体
KEY:D
解释:纯虚函数能够有函数体!!!函数体必须定义在类的外部!!!(C++ Primer)。
3四、设有如下说明语句,则下面的叙述不正确的是().
struct stu
{
int a;
float b;
} stutype;
struct是结构体类型的关键字
struct stu是用户定义的结构体类型
stutype是用户定义的结构体类型名
a和b都是结构体成员名
KEY:C
解释:struct为结构体关键字,stu为结构体类型名,a、b为结构体成员名,stutype为结构体变量名。
3五、写出下面程序的输出结果:
class A
{
public:
void FuncA()
{
printf( "FuncA called\n" );
}
virtual void FuncB()
{
printf( "FuncB called\n" );
}
};
class B : public A
{
public:
void FuncA()
{
A::FuncA();
printf( "FuncAB called\n" );
}
virtual void FuncB()
{
printf( "FuncBB called\n" );
}
};
void main( void )
{
B b;
A *pa;
pa = &b;
A *pa2 = new A;
pa->FuncA();
pa->FuncB();
pa2->FuncA();
pa2->FuncB();
delete pa2;
}
KEY:FuncA called
FuncBB called
FuncA called
FuncB called
解释:pa->FuncA(); //pa=&b动态绑定可是FuncA不是虚函数,因此FuncA called
pa->FuncB(); //FuncB是虚函数因此调用B中FuncB,FuncBB called
pa2->FuncA(); //pa2是A类指针,不涉及虚函数,调用的都是A中函数,因此FuncA called FuncB called
pa2->FuncB()
也就是说,须要知足三点要求:动态绑定、指针或引用、虚函数。即必须使用基类类型的指针变量,使该指针指向不一样派生类的对象,并经过调用指针所指向的虚函数才能实现动态的多态性。
3六、若MyClass为一个类,执行语句时会自动调用该类构造函数的次数是:
MyClass a[4],*p[5];
KEY:4
解释:把MyClass a[4],*p[5];分开写;
MyClass a[4];
MyClass *p[5];
则a[4]是类数组,有4个对象,调用构造函数4次;
*p[5]是指针数组,也就是5个元素存放的是指向MyClass类型的对象的指针,没有初始化的指针为空,不指向任何对象,也不调用构造函数。
3七、下面一段程序的输出结果是?
#define product(x) ((x)*(x))
int main()
{
int i = 3, j, k;
j = product(i++);
k = product(++i);
printf("%d %d", j, k);
return 0;
}
KEY:12 42
3八、若执行如下程序段,则z的二进制值是______。
int x=3,y=6,z; z=x^y<<2;
KEY:00011011
解析:须要注意的是:“^”为异或的意思,而不是指数运算的标志。其次“<
3九、当free释放内存以后,指针还指向原来的那块地址,须要咱们设置 p = NULL;若是不手动设置 p = NULL,此时P就变成了野指针。也就是说:野指针是指向未分配或者已经释放的内存地址。
40、关于C语言中volatile关键字,下面的说法哪个是错误的?
编译器会禁止对volatile修饰的变量进行读写优化
用volatile修饰的变量,读取速度会更快
每一次读取volatile修饰的变量都会从内存中读取
KEY:B
解释:volatile修饰的变量表示该变量为“易变的”。为保证正确性,禁止编译器进行读写优化,必须每次都从内存中读取。
使用volatile关键字声明的变量,系统老是从新从它所在的内存中读取数据,即便它前面的指令刚刚从该处读取过数据,并且读取的数据马上被保存;相反,若没有使用volatile,编译器可能会作优化处理,可能暂时使用寄存器中的值,而若是该变量由别的程序更新了的话,将会出现不一致的现象!!
总结起来就是:
编译器会禁止对 volatile 修饰的变量作读写优化,A 正确;
每次使用该变量时,系统都会从新从它所在内存中读取数据,C 正确;
这相对于作了读取优化的变量来讲,速度固然是慢了一些啦, B 错误。
4一、下列代码试图打印数字1-9的全排列组合。其中run函数中缺失的部分应该依次为:
#include "stdio.h"
#define N 9
int x[N];
int count = 0;
void dump() {
int i = 0;
for (i = 0; i < N; i++) {
printf("%d", x[i]);
}
printf("\n");
}
void swap(int a, int b) {
int t = x[a];
x[a] = x[b];
x[b] = t;
}
void run(int n) {
int i;
if (N - 1 == n) {
dump();
count ++;
return;
}
for (i = ___; i < N; i++) {
swap(___, i);
run(n + 1);
swap(___, i);
}
}
int main() {
int i;
for (i = 0; i < N; i++) {
x[i] = i + 1;
}
run(0);
printf("* Total: %d\n", count);
}
KEY:n, n, n
4二、已知:int x,y;double z;如下语句中错误的函数调用是()。
scanf(“%d,%1x,%1e",&x,&y,&z);
scanf(“%2d*%d%1f”,&x,&y,&z);
scanf(“%x%*d%o”,&x,&y);
scanf(“%x%o%6.2f",&x,&y,&z);
KEY:D
解释:%m.nf只能用于输出时指定精度。输入时只能用%f,不能用%m.nf指定输入精度!
也就是说:scanf中的格式控制符不能指明浮点数的精度。
4三、如下选项中非法的C语言字符常量是?
'\007'
'\b'
'a'
"\09"
KEY:D
解答:转义字符分三种,通常转义字符,八进制转移字符和十六进制转移字符:
通常转义字符,如‘\b’,由两个字符表示,其实表明一个字符,这个表明退格字符;
八进制转义字符,如‘\007’,三位数字是八进制的,ASCII码为7的表示响铃,此处的0开头能够省略,写成'\7'也是正确的;
十六进制,如'\x09',一样后面数字是所表示意思的Ascii码的十六进制表示,注意必定要有x,大小写都行。而且,后面的取值范围必须在0-255之间。
D选项是双引号,因此错误。
4四、若char是一字节,int是4字节,指针类型是4字节,代码以下:
class CTest
{
public:
CTest():m_chData(‘\0’),m_nData(0)
{
}
virtual void mem_fun(){}
private:
char m_chData;
int m_nData;
static char s_chData;
};
char CTest::s_chData=’\0’;
问:若按4字节对齐sizeof(CTest)的值是多少?若按1字节对齐sizeof(CTest)的值是多少?
KEY:十二、9
解释:在类中,若是什么都没有,则类占用1个字节,一旦类中有其余的占用空间成员,则这1个字节就不在计算以内,如:一个类只有一个int则占用4字节而不是5字节;
若是只有成员函数,则仍是只占用1个字节,由于类函数不占用空间;
虚函数由于存在一个虚函数表,须要4个字节,数据成员对象若是为指针则为4字节,注意有字节对齐,若是为13字节,则进位到16字节空间。
4五、这段程序的输出结果为:
char ch=-1;
printf("%02x,%02x",ch,(unsigned char)ch);
KEY:ffffffff,ff
解释:%02x表示输出最少2位,不足补0。这是一道关于符号扩展的问题。
短数据类型扩展为长数据类型:
要扩展的数据类型为有符号类型,用短数据的符号位填充长数据多出来的高字节 ,-1 (11111111)扩展为int(方便转换为十六进制)即(符号位是1)11111111 11111111 11111111 11111111(ffffffff);
要扩展的数据类型为无符号的(unsigned char) ,用0来填充长数据类型的高字节,此时-1在内存的二进制存储(11111111 )扩展为int即00000000 00000000 00000000 11111111(ff)。
4六、如下函数用法正确的个数是:
void test1()
{
unsigned char array[MAX_CHAR+1],i;
for(i=0;i<=MAX_CHAR;i++){
array[i]=i;
}
}
char*test2()
{
char p[] = "hello world";
return p;
}
char *p =test2();
void test3(){
char str[10];
str++;
*str='0';
}
KEY:0
解释:第一个问题:
重点不在于CHAR_MAX的取值是多少,而是在于i的取值范围是多少。
通常char的取值范围是-128到127,而u char 则是0~255,因此i的取值范围是0~255.因此当CHAR_MAX常量大于255时,执行i++后,i不能表示256以上的数字,因此致使无限循环。
第二个问题:
重点在于函数中p的身份,它他是一个指针,仍是数组名。若是是指针p,则p指向存放字符串常量的地址,返回p则是返回字符串常量地址值,调用函数结束字符串常量不会消失(是常量)。因此返回常量的地址不会出错;若是是数组p,则函数会将字符串常量的字符逐个复制到p数组里面,返回p则是返回数组p,可是调用函数结束后p被销毁,里面的元素不存在了。
例子中p是数组名,因此会出错,p所指的地址是随机值。如果把char p[]="hello";改为char *p="hello";就能够了。
第三个问题:
重点在于str++;这实际的语句就是str=str+1;而str是数组名,数组名是常量,因此不能给常量赋值(能够执行str+1,可是不能str=)。
4七、执行这个程序的结果是()
#include
using namespace std;
class TestClass{
char x;
public:
TestClass() { cout << 'A'; }
TestClass(char c) { cout << c; }
~TestClass() { cout << 'B'; }
};
int main() {
TestClass p1, *p2;
p2 = new TestClass('X');
delete p2;
return 0;
}
KEY:AXBB
解释:类指针的声明,是不会调用构造函数的;可是指向一个类实例(new)就会调用构造函数。 可是类的声明,会调用默认构造函数。
TestClass p1, *p2; //只为p1调用默认构造——A
p2 = new TestClass('X'); //调用构造函数,由p2指向——X
delete p2; //释放内存空间,p2所指实例调用析构函数——B
return 0; //程序结束,p1调用析构——B
4八、有以下模板定义,在下列对fun的调用中,错误的是()
template
T fun(T x,T y){
return x*x+y*y;
}
fun(1, 2)
fun(1.0, 2)
fun(2.0, 1.0)
fun(1, 2.0)
KEY:B
解释:模板定义就至关于泛型,类型必需要相同,且不会自动强制转换。用进行声明,后面的实参会强制类型转换为float,因此也是类型一致的。
4九、下列 C 代码中,不属于未定义行为的有:______。
int i=0;i=(i++);
char *p=”hello”;p[1]=’E’
char *p=”hello”;char ch=*p++
int i=0;printf(“%d%d\n”,i++,i--)
KEY:C
解释:未定义行为(Undefined Behavior)是指C语言标准未作规定的行为。同时,标准也从没要求编译器判断未定义行为,因此这些行为有编译器自行处理,在不一样的编译器可能会产生不一样的结果,又或者若是程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另外一个系统上,甚至是在另外一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情均可能发生”,也许什么都没有发生。一句话,未定义行为就是运行结果不肯定。
例如:变量便是左边结果,又是右边的操做数,如a+=a++,a %= b ^= a ^= b ^= a;使用越界数组也是C的一个“未定义行为”;容许一个随便指的指针的读写;使用未初始化的变量等等。
A选项,不知道编译器会怎么选择自增和赋值的顺序,因此这是由编译器决定的,属于未定义行为。
B选项,”hello“这个字符串属于一个字符串常量了,指针p指向了这个字符串常量,经过这个指针来直接修改常量第二个字符,这也属于未定义行为。
C选项,只是经过指针找到第二个字符并将它赋值给一个字符变量,并无改变这个字符串常量,因此不属于未定义行为。
D选项,在printf语句中,i++和i–谁先执行由编译器决定,这是未定义行为。
仍是不了解的能够参考连接:C语言未定义行为一览。
50、下面选项中的程序段,没有编译错误的是()
char* sp, s[10]; sp = "Hello";
char* sp, s[10]; s = "Hello";
char str1[10] = "computer", str2[10]; str2 = str1;
char mark[]; mark = "PROGRAM";
KEY:A
解释:数组就是数组,不是指针。数组名表明被分配的内存的首地址,是一个地址常量,是右值;而指针做为变量,倒是一个左值。数组名不是常量指针,由于他们的类型不同。
也就是说,数组名为常量指针, 不能做为左值。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。