以下为牛客网C/C++专项刷题:

1、下面程序会输出什么:

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 2

解析:静态局部变量只对定义它的函数体始终可见,函数体执行完过后虽然还存在,但是无法被其他的使用了。

2、下面程序会输出什么:

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<<sum<<","<<i;break;}}}return 0;
}

KEY:65536,65535

解析: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,存储方式为补码形式。

3、下面有关C++的类和C里面的struct的描述,正确的有?

在C++中,来自class的继承默认按照private继承处理,来自struct的继承默认按照public继承处理

class的成员默认是private权限,struct默认是public权限

c里面的struct只是变量的聚合体,struct不能有函数

c++的struct可有构造和析构函数

KEY:A、B、C、D

4、以下正确的说法是(        ),在C语言中。

实参和与其对应的形参各占用独立的存储单元

实参和与其对应的形参共占用一个存储单元

只有当实参和与其对应的形象同名时才共占用存储单

形参是虚拟的,不占用存储单元

KEY:A

解释:形参在编译时是不会分配存储容间,在调用时才在栈里分配,在调用结束时,即刻释放所分配的内存单元。

5、程序运行后的输出结果是?

#include <stdio.h>
main(){int i=0;i=~i;printf("%d\n",i);
}

KEY:-1

解释:0 = 00000000000000000000000000000000 ,取反11111111111111111111111111111111,就是-1在计算机的存储形式。

计算机内, 负数以反码形式存储, 符号位不变, 源码求反加1, 就是反码。

11111111111111111111111111111111就是

10000000000000000000000000000001求反

11111111111111111111111111111110 加1

就是 11111111111111111111111111111111。

6、程序运行后的输出结果是?

enum {a, b=5, c, d=4, e
} k;
k =c;

KEY:6

解释:enum中:首元素不赋值的话,默认为0;后一个元素不赋值的话比前一个元素大1。

7、关于“深拷贝”,下列说法正确的是:

会拷贝动态分配的成员对象

会拷贝成员数据的值

会拷贝静态分配的成员对象

KEY:A

解释:

  • 深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响;
  • 浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。

B和C都算错在了一个地方,没有考虑静态成员。类的静态成员是所有类的实例共有的,存储在全局(静态)区,只此一份,不管继承、实例化还是拷贝都是一份。

8、有哪几种情况只能用intialization list 而不能用assignment?

当类中含有const成员变量

基类无默认构造函数时,有参的构造函数都需要初始化。

当类中含有reference成员变量

当类中含有static成员变量

KEY:A、B、C

解析:因为const对象以及引用只能初始化而不能赋值,所以只能使用成员初始化列表。

对于非内置类型,在进入函数体之前,如果没有提供显式初始化,会调用默认构造函数进行初始化。若没有默认构造函数,则编译器尝试调用默认构造函数将会失败,所以如果没有默认构造函数,则必须在初始化列表中显示的调用构造函数。

static 成员在执行构造函数前就已经构造好了,即使不存在类对象,也可以被使用,不需要初始化列表。

9、若有说明: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即可。

10、在下列关于类型转换的描述中,错误的是( )。

任何形式的构造函数都可以实现数据类型转换。

带非默认参数的构造函数可以把基本类型数据转换成类类型对象。

类型转换函数可以把类类型对象转换为其他指定类型对象。

类型转换函数只能定义为一个类的成员函数,不能定义为类的友元函数。

KEY:A

解析:转换构造函数的作用是将一个其他类型的数据转换成一个类的对象。注意:转换构造函数只能有一个参数。如果有多个参数,就不是转换构造函数。原因是显然的,如果有多个参数的话,究竟是把哪个参数转换成类的对象呢?

类型转换函数是类中定义的一个成员函数。operator和“转换后的类型”一起构成转换函数名。该函数不能带有参数,也不能指定返回值类型。因为它的返回值类型就是“转换后的类型”。转换函数的作用就是将对象内的成员数据转换成某种特定的类型。类型转换函数只能定义为一个类的成员函数,不能定义为类的友元函数。

11、哪个选项可以将t初始化为当前程序的运行时间?

time_t t;

t = clock();

time( &t );

time( t );

t = localtime();

KEY:A

解释:clock()就是该程序从启动到函数调用占用CPU的时间;time( &t );为获取系统时间;localtime(&t);  将一个UTC时间转为本地时间。

12、从运行层面上来看,从四个选项选出不同的一个。

JAVA

Python

objectC

C#

KEY:B

解释:Java,C,C#是静态语言,需要编译;python时动态语言,不需要编译。

13、一个C语言程序是由()。

一个主程序和若干子程序组成

函数组成

若干过程组成

若干子程序组成

KEY:B

解释:C语言程序是由函数构成的,所谓函数是指功能相对独立的可以反复执行的。一段程序,在某些程序设计语言中也称为过程,但C语言中叫函数。

14、正确的输入语句是______。

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* 类型的指针,数组名就是一个地址

15、若给定条件表达式(M)?(a++):(a--),则其中表达式 M()。

和(M==0)等价

和(M==1)等价

和(M!=0)等价

和(M!=1)等价

KEY:C

解释:在C语言中非零数代表true,零代表false。而B选项,只是判断是否等于1,对于2、3等数就不视作真了。

16、假设有说明 int a=0; double x=5.16;,则在以下语句中,(   )属于编译错误。

x=a/x;

x=x/a;

a=a%x;

x=x*a;

KEY:C

17、这段程序的运行结果为:

#include <iostream>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()。

18、重写(override)与重载(overload)的区别:

  • 函数重写是子类和父类之间的继承关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系;
  • 重写需要子类和父类中的两个函数的函数原型完全相同;重载要求两个函数参数列表不同;

在重写关系中,调用具体调用哪一个函数是根据(对象对应存储空间的实际类型)为准的,这涉及到动态绑定和静态绑定的问题,也就是虚函数的调用机制,而函数重载主要是靠形参列表的不同来区分具体调用哪个函数的。

19、这段程序的运行结果为:

int func()
{ int i,j,k=0;for(i=0,j=-1;j=0;i++,j++){k++;}
return k;
}
int main()
{cout<<(func());
}

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,太绝对化了,在类中申请一个类对象或者参数传递一个对象或者指针都可以调用;

21、这段程序的运行结果为:

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。

22、这段程序的运行结果为:

#include "iostream"
#include "vector"
using namespace std;  int main(void)
{  vector<int>array;  array.push_back(100);  array.push_back(300);  array.push_back(300);  array.push_back(500);  vector<int>::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<<*itor<<" ";  }  return 0;
} 

KEY:100    300     500

解析:vector erase以后,itor已经指向下一个元素了,不应该执行itor++,否则会跳过下一个元素,即连续两个300时跳过了第二个300.

23、这段程序中,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”所以是同一常量,地址相同。

24、在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个字节。类与结构一样,都有字节对齐的问题。类中普通的函数不占用类的大小。子类的大小等于子类新增的加上父类的大小。

25、C++语言中,有关类的初始化叙述正确的是()

静态函数中不能出现this指针

可以在类定义时,对对象直接初始化

一般数据类型可以在类的外部进行初始化

静态数据类型可以在类的外部进行初始化

KEY:AD

解释:静态成员变量必须在类外初始化,静态成员常量在类中初始化。

26、这段程序的运行结果为:

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。

27、请问下面的程序一共输出多少个“-”?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>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 <stdio.h>
#include <sys/types.h>
#include <unistd.h>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刷缓存。

28、在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。

29、下列关于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 <stdio.h>
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操作可能会引起程序崩溃,首先编译器就不允许他的存在。

31、选择填空:

#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错。

32、运行时的输出结果是()

#include<iostream>
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; 调用的是拷贝构造函数。

33、关于抽象类和纯虚函数的描述中,错误的是:

纯虚函数的声明以“=0;”结束

有纯虚函数的类叫抽象类,它不能用来定义对象

抽象类的派生类如果不实现纯虚函数,它也是抽象类

纯虚函数不能有函数体

KEY:D

解释:纯虚函数可以有函数体!!!函数体必须定义在类的外部!!!(C++ Primer)。

34、设有以下说明语句,则下面的叙述不正确的是().

struct stu
{
int a;
float b;
} stutype;

struct是结构体类型的关键字

struct stu是用户定义的结构体类型

stutype是用户定义的结构体类型名

a和b都是结构体成员名

KEY:C

解释:struct为结构体关键字,stu为结构体类型名,a、b为结构体成员名,stutype为结构体变量名

35、写出下面程序的输出结果:

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()

也就是说,需要满足三点要求:动态绑定、指针或引用、虚函数。即必须使用基类类型的指针变量,使该指针指向不同派生类的对象,并通过调用指针所指向的虚函数才能实现动态的多态性。

36、若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类型的对象的指针,没有初始化的指针为空,不指向任何对象,也不调用构造函数。

37、下面一段程序的输出结果是?

#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

38、若执行以下程序段,则z的二进制值是______。

int x=3,y=6,z; z=x^y<<2;

KEY:00011011

解析:需要注意的是:“^”为异或的意思,而不是指数运算的标志。其次“<<”的优先级较高,先计算。

39、当free释放内存之后,指针还指向原来的那块地址,需要我们设置 p = NULL;如果不手动设置 p = NULL,此时P就变成了野指针。也就是说:野指针是指向未分配或者已经释放的内存地址。

40、关于C语言中volatile关键字,下面的说法哪一个是错误的?

编译器会禁止对volatile修饰的变量进行读写优化

用volatile修饰的变量,读取速度会更快

每一次读取volatile修饰的变量都会从内存中读取

KEY:B

解释:volatile修饰的变量表示该变量为“易变的”。为保证正确性,禁止编译器进行读写优化,必须每次都从内存中读取。

使用volatile关键字声明的变量,系统总是重新从它所在的内存中读取数据,即使它前面的指令刚刚从该处读取过数据,而且读取的数据立刻被保存;相反,若没有使用volatile,编译器可能会做优化处理,可能暂时使用寄存器中的值,而如果该变量由别的程序更新了的话,将会出现不一致的现象!!

总结起来就是:

编译器会禁止对 volatile 修饰的变量做读写优化,A 正确;

每次使用该变量时,系统都会重新从它所在内存中读取数据,C 正确;

这相对于做了读取优化的变量来说,速度当然是慢了一些啦, B 错误。

41、下列代码试图打印数字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

42、已知: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中的格式控制符不能指明浮点数的精度。

43、以下选项中非法的C语言字符常量是?

'\007'

'\b'

'a'

"\09"

KEY:D

解答:转义字符分三种,一般转义字符,八进制转移字符和十六进制转移字符:

  • 一般转义字符,如‘\b’,由两个字符表示,其实代表一个字符,这个代表退格字符;
  • 八进制转义字符,如‘\007’,三位数字是八进制的,ASCII码为7的表示响铃,此处的0开头可以省略,写成'\7'也是正确的;
  • 十六进制,如'\x09',同样后面数字是所表示意思的Ascii码的十六进制表示,注意一定要有x,大小写都行。并且,后面的取值范围必须在0-255之间。

D选项是双引号,所以错误。

44、若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:12、9

解释:在类中,如果什么都没有,则类占用1个字节,一旦类中有其他的占用空间成员,则这1个字节就不在计算之内,如:一个类只有一个int则占用4字节而不是5字节;

如果只有成员函数,则还是只占用1个字节,因为类函数不占用空间;

虚函数因为存在一个虚函数表,需要4个字节,数据成员对象如果为指针则为4字节,注意有字节对齐,如果为13字节,则进位到16字节空间。

45、这段程序的输出结果为:

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)。

46、以下函数用法正确的个数是:

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=)。

47、执行这个程序的结果是()

#include<iostream>
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

48、有如下模板定义,在下列对fun的调用中,错误的是()

template <class T>
T fun(T x,T y){return x*x+y*y;
}

fun(1, 2)

fun(1.0, 2)

fun(2.0, 1.0)

fun<float>(1, 2.0)

KEY:B

解释:模板定义就相当于泛型,类型必须要相同,且不会自动强制转换。用<float>进行声明,后面的实参会强制类型转换为float,所以也是类型一致的。

49、下列 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

解释:数组就是数组,不是指针。数组名代表被分配的内存的首地址,是一个地址常量,是右值;而指针作为变量,却是一个左值。数组名不是常量指针,因为他们的类型不一样。

也就是说,数组名为常量指针, 不能作为左值。

【牛客网】C/C++牛客网专项刷题(01)相关推荐

  1. 【牛客网】C/C++牛客网专项刷题(02)

    以下为牛客网C/C++专项刷题: 1.虚函数不可以内联,因为虚函数是在运行期的时候确定具体调用的函数,内联是在编译期的时候进行代码展开,两者冲突,所以没有一起使用的做法. 2.C++中构造函数和析构函 ...

  2. 【牛客网】C/C++牛客网专项刷题(00)

    以下为牛客网C/C++专项刷题: 1.若要打开A盘上user子目录下名为abc.txt的文本文件进行读.写操作,符合此要求的函数调用是( ). KEY:fopen("A:\\user\\ab ...

  3. 【牛客网】C/C++牛客网专项刷题(03)

    以下为牛客网C/C++专项刷题: 1.阅读以下程序,当输入数据的形式为12a345b789↙,正确的输出结果为(). void main() {char c1,c2;int a1,a2;c1=getc ...

  4. 牛客网《剑指offer》专栏刷题练习之双指针算法的使用

    ✅作者简介:C/C++领域新星创作者,为C++和java奋斗中 ✨个人社区:微凉秋意社区

  5. 牛客网《剑指offer》专栏刷题练习之数组专精

    ✅作者简介:C/C++领域新星创作者,CSDN内容合伙人 ✨个人社区:微凉秋意社区

  6. 手把手带你刷好题(牛客刷题⑤)

    作者:月亮嚼成星~ 博客主页:月亮嚼成星~的博客主页 专栏:手把手带你刷牛客 工欲善其事必先利其器,给大家介绍一款超牛的斩获大厂offer利器--牛客网 点击免费注册和我一起刷题吧 1.类中的数据域使 ...

  7. sql里查询一个组和组的用户数怎么查?_【牛客网SQL刷题】留存率怎么算?

    抽空刷了牛客网SQL实战72题,最后几道以牛客网为例的题目还挺有挑战性,在此记录 统计时间段新用户次日留存率 每日的次日留存率 每日的新用户数 每日新用户的次日留存 求新登录用户次日留存 表login ...

  8. 牛客网Java刷题知识点之关键字static、static成员变量、static成员方法、static代码块和static内部类...

    不多说,直接上干货! 牛客网Java刷题知识点之关键字static static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个"伪全局"的概 ...

  9. 洛谷、牛客网、AcWing 刷题(python版)

    牛客网python专项练习整理(一) https://blog.csdn.net/weixin_41913008/article/details/87203468 牛客网剑指offer--python ...

最新文章

  1. android receiver 通知,android – 来自BroadcastReceiver的呼叫通知
  2. 构造 ---- 最小没出现过的数(逆向构造) D. Replace by MEX
  3. openpyxl模块介绍
  4. 映射Mapper.xml文件的几种方式
  5. 生成指定序列的前一字典序序列(洛谷P2525题题解,C++语言描述)
  6. linux 字符设备和块设备的区别
  7. python装饰器举例_Python学习笔记:装饰器(Decorator)
  8. 计算机无法识别打印机usb,win10电脑不识别打印机usb设备怎么回事_win10无法识别usb打印机如何处理-win7之家...
  9. 在edge浏览器找不到internet选项?
  10. matlab 输出 syms,matlab中latex和syms的完美结合
  11. N MOSFET VGS(th)和管子导通的关系
  12. Number of Operations to Decrement Target to Zero - 滑动窗口
  13. STM32模拟USB多点触控屏
  14. Hive on Hbase
  15. Linux 如何挂载nas盘
  16. Python自制恶搞virus
  17. Oracle-数据库组件invalid问题处理
  18. python xlwings实例_Python与Excel交互——Xlwings
  19. 计算机网络笔记Part2 物理层(Physical Layer)
  20. 专项职业能力考核计算机,专项职业能力考核项目指定试题汇编教材用书表(信息技术类)...

热门文章

  1. SA738GrB核电钢板
  2. 11个SEO人员必须知道的Chrome扩展插件
  3. 看移动认证一键登录如何为用户提供便捷认证登录体验
  4. 一种工厂内人车防撞解决方案
  5. 我院与湖南农大初步达成合作办学意向
  6. xlabel 用法 matlab,matlab关于使用m语言设计gui设置xlabel出错
  7. python字体大小_python 设置xlabel,ylabel 坐标轴字体大小,字体类型
  8. makefile 语法 /usr/bin/ld: cannot find -lxxxx
  9. win10突然出现蓝屏,终止代码:BAD_POOL_CALLER
  10. OpenGL扩展库基本介绍以及配置(搜集)