C/C++ 笔试易错题汇集

以下定义中,哪一个是指向数组的指针P:

正确答案: A 你的答案: 空 (错误)
int(*p)[5]
int * p[5]
(int * )p[5]
int *p[]

A:数组指针
B:指针数组
C:强制类型转换
D:定义错误
所以选A

()的优先级大于[ ],所以这个表达式其实是在定义一个指针,本质是*p,而[5]在(*p)后面作用是修饰这个指针,补充说明这个指针指向的是一个包含5个元素的数组(行指针)

下列说法正确的是( )

#include “stdio.h”
#include “string.h”

void fun( char *s)
{
char t[7];
s=t;
strcpy(s, “example”);
}

int main()
{
char *s;

fun(s);
printf("%s",s);

return 0;
}

正确答案: D 你的答案: C (错误)
输出结果为"example"
输出结果为"烫烫烫烫"
程序编译时出现错误
程序运行时出现错误

如果s没有分配内存空间, strcpy(s, “hello”)就会导致内存访问的异常。 可以用 s = (char*)malloc(10);分配10字节的内存给s, 或 s = new char[10];
主函数里的s没有被初始化,即使初始化了,传到fun函数里,也会存在溢出的情况,程序终止。即使s初始化了,也不会输出"example",这只是值传递。

下面程序的输出是什么?

int main(void)
{
int a[5] = {1, 2, 3, 4, 5};
int *ptr = (int *)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
return 0;
}

2 5

a是数组首元素的地址,a+1的步长是int,所以是2
&a是数组的首地址,&a+1步长是int[5]
ptr是int类型的指针,指向a数组的尾后位置,ptr-1的步长是int,所以是a数组的最后一个元素 5

若调用fputc函数输出字符成功,则其返回值是()。

输出的字符

有以下程序

#include
main()
{int a=2,b=3,c=4,d=0;
if(a==2 &&b++==3)
if(b!=3 || c–==4)
printf("%d,%d,%d\n",a,b,c);
else printf("%d,%d,%d\n",a,b,c);
else printf("%d,%d,%d\n",a,b,c);
}
程序运行后的输出结果是( )

2,4,4

注意里面的陷阱:if(b!=3 || c–==4),因为b不等于3,所以if语句直接返回true,不执行c-- = = 4操作,所以c还是等于4

float 类型(即 IEEE754 单精度浮点数格式)能表示的最大整数是( )。

2^ 128-2^ 104

float指数位8位,指数范围-128至127 。小数位23位。。则最大数为1.11111111111111111111111*2^ 127=(2-2^ -23)*2^ 127=2^ 128-2^104

请声明一个指针,其所指向的内存地址不能改变,但内存中的值可以被改变。

正确答案: B 你的答案: C (错误)
const int const *x = &y;
int * const x = &y;
const int *x = &y;
int const *x = &y;
const int * const x = &y;

若const限定符在 * 之前,则const限定的是ptr而不限定ptr。也就是说,ptr可以改变其所指向的对象,但不能通过该指针修改其所指向对象的值。
若const限定符在 * 之后,则const限定的是ptr而不限定
ptr。也就是说,ptr不可以改变其所指向的对象,但能通过该指针修改其所指向对象的值。
若在之前有const限定符且在之后也有const限定符,则ptr与*ptr都被限定。也就是说,ptr既不可以改变其所指向的对象,也不能通过该指针修改其所指向对象的值。
另外:只要 在 * 之后有 const限定符,则该指针在声明时必须初始化。

有以下程序

main()
{ int i;

for(i=0;i<3;i++)

switch(i)
{

case 0:printf("%d",i);

case 2:printf("%d",i);

default:printf("%d",i);
}
}
程序运行后的输出结果是( )。

000122

switch语句中没有break会执行满足条件的和之后的所有条件,i=0,case0,2,default均会执行;i=1,执行default;i=2,执行case2和default.综上,000 1 22

下列代码运行出错,可能会是哪一行引起的?

复制代码
void getMemory(char *p)
{
p = (char *)malloc(100); // 1
}

int main(int argc, char const *argv[])
{
char *str = NULL;
getMemory(str);
strcpy(str,“hello wrold”); //2
printf("%s\n", str); //3
free(str); //4
}

答案:2

GetMemory(str); //把str传进去,str是一个指针,而他实际上是一个int
void GetMemory(char *p) // p是str的一个副本
{
p=(char *)new char[100]; // p的值改变,但是str的值并没有改变。
}
而双重指针为什么就可以了呢:
GetMemory(&str); //把str的地址传进去
void GetMemory(char ** p) // p是str地址的一个副本
{

*p = (char *)new char[100]; // p指向的值改变,也就是str的值改变。
}

有以下结构体,请问在64位系统中,sizeof(struct B)的大小为

struct A
{
    
    
 int a;
 union
 {
    
    
     long b;
     short c;
 };
};
struct B
{
    
    
 char e;
 struct A d;
 int f;
};

解答:
结构体在C中是一种集合,而不是一种新的数据类型!
B相当于
struct B
{
char e;
int a;
union
{
long b;
short c;
};
int f;
};
1.union共享内存取最长的long 8(windows 64位系统中vs2019实测long是4,可能这里是linux);
2.所有类型对齐(char e)+7,(int a)+4, (int f)+4, 4*8 = 32;

请阅读以下程序,其运行结果是()

void main()
{
char c=‘A’;
if(‘0’<=c<=‘9’) printf (“YES”);
else printf(“NO”);
}

正确答案: A 你的答案: 空 (错误)
YES
NO
YESNO
语句错误

if(‘0’<=c<=‘9’) 等价于if((‘0’<=c)<=‘9’) ,因为0的ASCII码为048,A的ASCII码为065大于’0’,所以结果为true,不过我有一个疑惑点,就是当前面为true时,后面就不进行比较了吗?
拓展ASCII的大小比较:小写字母(a~z)大于大写字母(A~Z)大于字符(`0’~’9’)。

int a=4,则对于表达式++(a++)的结果说法正确的是()

正确答案: D 你的答案: B (错误)
结果为5
结果为6
结果为7
以上不都是

a++的结果是4,然后进行++4是不对的,++运算只是针对于变量的,a++是右值,不能对常量来进行++运算。

单选】下面的程序会打印几个hello?

int main(void)
{
fork();
printf(“hello\n”);
fork();
printf(“hello\n”);
while(1);
return
}
正确答案:
6

每次fork后,子进程将获得与父进程一样的环境。假设原始进程为P,第一次fork后,多了一个P0,接着P,P0各自打印一次。再fork一次,P,P0分别fork出来P1,P00。这时4个进程都打印一次。加起来一共是6次。

假定CSomething是一个类,执行下面这些语句之后,内存里创建了____个CSomething对象。

CSomething a();
CSomething b(2);
CSomething c[3];
CSomething &ra = b;
CSomething d=b;
CSomething *pA = c;
CSomething *p = new CSomething(4);

6

CSomething a(); 只是个函数声明
CSomething b(2); +1
CSomething c[3]; +3,对象数组
CSomething &ra = b; 引用,没有新构造
CSomething d=b; +1,调用拷贝构造函数
CSomething *pA = c; 只是给指针赋值
CSomething *p = new CSomething(4); +1,构造并给指针赋值
总共6个

注意区别:
CSomething a();
CSomething a;
前者是一个函数的声明,与默认构造函数区分;//返回类型为CSomething,形参表为空
后者是一个对象的定义;

class A { int a; short b; int c; char d; }; class B { double a; short b; intc; char d; }; 在32位机器上用gcc编译以上代码,求sizeof(A),sizeof(B)分别是多少。

16 24

原则有3条(楼上已经说了),讲一下自己的理解:

  1. 结构体变量的首地址 必须 是内部最宽数据类型的倍数(虽然和做题没什么关系)
  2. 按顺序一个变量一个变量看,要求current变量的首地址 必须是自己大小的倍数。
  3. 到了最后一个变量,要求整个结构体的大小的最宽数据类型的倍数。

那么看一下 这道 题:
A: int a (4个字节) 4
short b (2个字节,起始地址4是2的倍数,不补) 4+2
int c (4个字节,4+2不是4的倍数,被2个 ) 4+2+2(补)+4
char d (1个字节,4+2+2+4是1的倍数,不补) 4+2+2(补)+4 +1
最后补3个字节,让整体大小为4的倍数 4+2+2(补)+4+1+3(补) =16

B: double a (8个字节) 8
short b (2个字节,起始地址8是2的倍数,不补) 8+2
int c (4个字节,8+2不是4的倍数,被2个 ) 8+2+2(补)+4
char d (1个字节,8+2+2+4是1的倍数,不补) 8+2+2(补)+4 +1
最后补7个字节,让整体大小为8的倍数 8+2+2(补)+4+1+7(补) =24

【单选】下面函数输出结果是什么:

int main() {
int k = 12345;
printf("%2d\n", k);
return 0;
}

12345

%d就是普通的输出了,%d 是输出十进制整数 d是decimal的缩写
% 2d是将数字按宽度为2,采用右对齐方式输出,如果数据位数不到2位,则左边补空格。
%02d:默认情况下,数据数据宽度不够2位是用空格填补的,但是因为2d前面有0,表示,数据宽度不足时用0填补。

“%2d” 指定数据输出为2列,输出的数据显示在此2列区域的右侧, 如果超出,则按实际输出

若变量已正确的定义为float类型,要通过输入函数scanf(“%f%f%f”,&a,&b,&c)给a赋值10,b赋值22,c赋值33,以下不正确的输入形式是( )

正确答案: B C 你的答案: A D (错误)
10
22
33

10.0,22.0,33.0

10.0
22.0,33.0

10 22
33

如果scanf中%d是连着写的如“%f%f%f”,在输入数据时,数据之间不可以用逗号分隔,只能用空白字符、空格、tab键、回车键 分隔。
若是“%f,%f,%f”,则在输入数据时需要加“,”,如“2,3,4”。

函数是一种特殊的数据类型,这句话是否正确?

正确

看到题目我想到的就是函数指针,比如说int (*p)(int ,int),p是个函数指针变量,它的类型其实就是函数类型,而且也可以赋值

请将B类的构造函数补充完整,要求用x初始化a.请为横线处选择合适的程序( )

class A
{ int a;
public:
A(int x=0) { a=x; } };
class B: public A {
int b;
public:
B(int x): ______________
{ b=x+1; } };

正确答案: B 你的答案: B (正确)
a(x)
A(x)
B(x)
a=x

公共继承派生类”只能通过“”基类的成员函数”去访问“”基类的私有成员

C语言中,设a=3,b=4,执行语句“printf("%d,%d",(a,b),(b,a));”的输出结果是()

正确答案: C 你的答案: 空 (错误)
3,4
(3,4),(4,3)
4,3
不确定

注意 (a ,b)并不是一个数对,而是一种运算–逗号表达式。
运算方法:从左往右逐个计算表达式,整个表达式的值为最后一个表达式的值(右括号左侧)。
故:( a,b ) = b, ( b, a ) = a.

unsigned short A = 10;

printf("~A = %u\n", ~A);
char c = 128;
printf(“c=%d\n”, c);
输出多少?

4294967285 -128

反码 = 源码除了符号位以外按位取反。补码 = 反码+1。

关于符号扩展

一、短数据类型扩展为长数据类型

1、要扩展的短数据类型为有符号数的

       进行符号扩展,即短数据类型的符号位填充到长数据类型的高字节位(即比短数据类型多出的那一部分),保证扩展后的数值大小不变

如1:char x=10001001b;   short y=x;   则 y 的值应为 11111111 10001001b ;

    2 : char x=00001001b;   short y=x;  则 y 的值应为 00000000 00001001b ;

2、要扩展的短数据类型为无符号数的

     进行零扩展,即用零来填充长数据类型的高字节位

如1:unsigned char x=10001001b;   short y=x;   则 y 的值应为 00000000 10001001b ;

    2 : unsigned char x=00001001b;   short y=x;  则 y 的值应为 00000000 00001001b ;

shor和char的无符号和有符号形式都会先转换为int型。
unsigned short A=10转换为int型类0x0000000a,按位取反为0xfffffff5,若按%d形式输出,由于是补码形式存储的,所以0xfffffff5的原码为0x8000000b,也就是-11;此时是按%u无符号形式输出,结果为15167+15166+15*165+15164+15*163+1516^2+1516+5=4294967285;
char c=128先转化为int类型,为0xffffff80,以%d输出,转换为原码为0x80000080,也就是-16*8=-128

以 下 程 序 段 的 输 出 结 果 是 ()。(在vs环境下编译)

int a=21,b=11;
printf("%d\n",–a+b,–b+a);

30

printf()从右到左压栈,从左到右输出。
是从右往左计算表达式的,所以计算两个表达式:
–b+a, b=10, a=21, 结果31(前缀自加自减,先自加自减再参与运算)
–a+b, a=20, b=10, 结果30
但输出时是从左往右输出的即输出–a+b的结果,30

若有定义语句:char s[3][10],(*k)[3],*p;则以下赋值语句错误的是()

1.p=s;
2.p=k;
3.p=s[0];
4.k=s;

124

这道题主要就考指针类型是否一样。
char s[3][10] s 是数组指针,类型为char (*)[3],所指向的每个数组长度为10;
char (k)[3] 很明显k就是一个数组指针,类型也为 char ()[3],但是所指向的每个数组的长度未知;
char *p 类型为char * 指针。
因此,在没有强制类型转换的情况下,只有类型完全相同的指针才能相互复制。
答案:1,2,4
—— —— —— ——3为什么正确?—— —— ——
s[0] 是指向第一行数组的首元素的地址,即s[0] == &s[0][0],指针类型为char *,因此可以与char * p进行复制操作。

对一个指针变量int *p赋值,下面哪一个赋值是正确的?

正确答案: D 你的答案: B (错误)
float f;p=b&f;
int k; *p=&k;
p=0x3000
int k;p=&k;

声明过的指针,再将其赋值的时候不需要写出*,否则就是对该指针解引用

In C++, what does “explicit” mean? what does “protected” mean?

正确答案: A B 你的答案: 空 (错误)
explicit-keyword enforces only explicit casts to be valid
Protected members are accessible in the class that defines them and in classes that inherit from that class.
Protected members only accessible within the class defining them.
All the above are wrong

A.explicit关键字强制仅有显式调用有效 ,正确,C++提供关键字explicit,用于阻止不应该允许的经过转 换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。
B.保护成员可以在定义它的类中使用,也可以在派生类中使用,正确。保护类就是为了继承产生的
C.保护成员仅可以在定义它的类中使用。错误,见B

下面哪些运算符不能被重载?()

正确答案: A B C 你的答案: 空 (错误)
三目运算符“?:”
作用域运算符“::”
对象成员运算符“.”
指针成员运算符“->”

不能被重载的运算符只有五个,分别是

  1. . (成员访问运算符)
  2. *(成员指针访问运算符)
  3. :: (域运算符)
  4. sizeof (长度运算符)
  5. ?: (条件运算符)

前两个运算符不能重载是为了保证访问成员的功能不被改变 ,域运算符和sizeof运算符的运算对象是类型而不是变量或者一般表达式,不具备重载的特征。

关于变量及其作用范围描述正确的是( ):

正确答案: A B 你的答案: B C D (错误)
实例变量是类的成员变量
静态变量用关键字static声明
在方法体中定义的局部变量在该方法被执行时创建
局部变量在使用前可不用初始化

不是局部变量在该方法被执行/调用时创建,而是应该为在该变量被声明并赋值时创建,可以理解为“当代码执行到该变量被赋值的代码时才被创建”。
实例变量是指非静态成员变量,也就是需要通过实例化对象才能访问的变量 当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动对其初始化。

在c语言中,非零为真,零为假;但在c++中,1为真,0为假

参加位运算的数据可以是任何类型的数据。请问这句话的说法是正确的吗?

错误

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作,而浮点数是无法精确的转化为二进制表示的,所以是无法进行位运算的

设有如下定义:

struct ss
{ char name[10];int age; char sex;}std[3],*p=std;

下面各输入语句中错误的是____________

正确答案: B 你的答案: A (错误)
scanf(“%d”,&(*p).age);
scanf(“%s”,&std.name);
scanf(“%c”,&std[0].sex);
scanf(“%c”,&(p->sex));

scanf的第二个参数是一个地址,数组名本身就是一个地址,scanf函数以字符串形式输入字符串,同时将输入的字符串赋值数组时,直接引用数组名即可,不用加取地址运算符

以下字符中不是转义字符的是()。

正确答案: C 你的答案: A (错误)
‘\a’
‘\b’
‘\c’
‘\’

在这里插入图片描述

int main(){

int a;float b,c;
scanf("%2d%3f%4f",&a,&b,&c);
printf("\na=%d,b=%d,c=%f\n",a,b,c);
}
若运行时从键盘上输入9876543210l,则上面程序在gcc编译器下的输出结果是

a=98,b=0,c=0.000000

printf函数执行的时候,会先把这三个数字压入栈里,然后再执行打印。压入栈的时候按照数据本身的长度来,首先把c和b压入,并且每一个都是8个字节(printf自动转化为double)。然后再压入a是4个字节。然后再执行打印。打印的时候按照用户指定的格式来出栈。首先打印a,a打印正常。然后又打印4个字节长度的b,在栈里面由于b长度是八个字节,并且b目前是64位的表示方式,数据的后面全是0.(float 变double),电脑是小端存储方式,0存储在距离a近的地方。打印b的时候,打印的4个字节都是0.然后再打印c,c用正常的方式打印,会一下子读取8个字节,正好,读出来的八个字节前面四个字节全是0,自己可以算一下,实在太小了,因此为0.
栈底 栈顶
高字节。。。。。。。。。。。低字节
4321 0000 765 0000 98
4字节 4字节 4字节 4字节 4字节
打印c 打印b 打印a
附:浮点数(单精度的float和双精度的double)在内存中以二进制的科学计数法表示,表达式为N = 2^E * F;其中E为阶码(采用移位存储),F为尾数。
float和double都由符号位、阶码、尾数三部分组成,float存储时使用4个字节,double存储时使用8个字节。各部分占用位宽如下所示:

         符号位     阶码      尾数     长度

float      1         8         23      32

double     1         11        52       64

参考:https://blog.csdn.net/weixin_34665627/article/details/117103748

有以下函数,该函数的功能是( )

int fun(char *s)
{char *t=s;
while(*t++);
return(t-s);
}
正确答案: B 你的答案: B C (错误)
比较两个字符的大小
计算s所指字符串占用内存字节的个数
计算s所指字符串的长度
将s所指字符串复制到字符串t中

t++ 最后会在\0后一个位置停止 \0后一个位置为此时指针指向 尾部减去头部包括\0就是字节数
而c答案字符串长度不包括最后的\0,因为
t++中的t一定是先用后加。先*t,后t=t+1。

正确答案: A D 你的答案: A D (正确)

包含虚函数的类有this指针
包含虚函数的类没有this指针
包含虚函数的类不能被继承
包含虚函数的类能被继承

纯虚函数:只提供一个接口,具体实现方法需要派生类自己去实现
虚函数:提供接口,并提供默认的实现方法,派生类也可以根据自己需求去重载
非虚函数:提供接口,强制实现方法
“pure virtual函数必须在derived class中重新声明,但是它们也可以拥有自己的实现。”-------《Effective C++》

已有定义:char a[]=“xyz”,b[]={‘x’,‘y’,‘z’};,以下叙述中正确的是 ( )。

a数组长度大于b数组长度

#include
#include
using namespace std;
int main()
{
char a[]=“xyz”,b[]={‘x’,‘y’,‘z’};
cout << strlen(a) << endl;
cout << strlen(b)<< endl;
cout << sizeof(a)<< endl;
cout << sizeof(b)<< endl;
return 0;
//输出3 3 4 3
}

输出以下结果

#define add(a,b) a+b
int main() {
printf("%d\n",3 * add(4,7));
return 0;
}

19

在 C/C++ 中,宏定义只是做简单的字符替换;
在 #define add(a,b) a+b 中, a+b 没有括号,所以 3* add(4,7) 实际的替换情况是: 34+7=19 ;若 a+b 有括号, #define add(a,b) ( a+b )则结果为: 3 ( 4+7 ) =33 ;

若有int i=10,j=0;则执行完语句

if (j=0)i++; else i–; i的值为11.
说法是否正确?

错误

j=0 所以 是if(0)

下面选择中正确的赋值语句是()。

(设 chara[5],*p=a;)
正确答案: A 你的答案: 空 (错误)
p=“abcd”;
a=“abcd”;
*p=“abcd”;
*a=“abcd”;

A p=“abcd”; P是字符型指针,将“abcd”的地址给了P,也就是P指向“abcd"的首地址,也就是 指向‘a’的地址;
B a=“abcd”;a是字符数组的地址,不可赋值;
C *p=“abcd”; P是字符,不能将字符串赋给它,若是p=‘a’,则正确.

下面关于 “EOF” 的叙述,正确的是()

正确答案: B 你的答案: B (正确)
EOF的值等于0
EOF是在库函数文件中定义的符号常量
文本文件和二进制文件都可以用EOF作为文件结束标志
对于文本文件,fgetc函数读入最后一个字符时,返回值是EOF

【解析】在 C 语言中,或更精确地说成 C 标准函数库中表示文件结束符( end of file )。在 while 循环中以 EOF 作为文件结束标志,这种以 EOF 作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的 ASCII 代码值的形式存放。我们知道, ASCII 代码值的范围是 0~255 ,不可能出现 -1 ,因此可以用 EOF 作为文件结束标志。

const在定义的时候必须初始化

在for语句中,循环次数只由变量来控制的.说法是否正确?

错误

除了变量以外,for中的break语句也可以控制控制次数, 如果题目是 只 由变量来控制的 ,那就是错误啦。
再补充一点,break语句只用于for和switch,在if语句中不能使用,因为if不是循环语句,所以不能用break来结束。

该函数参数为1时返回值为:

int GetResult(int a){
int b = 0;
__try{
if ( a != 0 ){
b++;
}
return b;
}
__finally{
–b;
}
return b;
}

1

在这里插入图片描述
转自《Windows核心编程》
本题中:
finally块中的代码会执行,但是try中已经返回了,所以返回b=1;
返回后,执行finally中的代码–b,b=0;
但是finally后面的代码return b不执行。所以返回还是1;但是此时b=0;

表达式(short)10/10.2*2运算后结果是什么类型?

double

强制类型转换的优先级高于+ - * /

现在机器cpu都是GHz,每次需要若干个指令,大约在1秒。执行1条语句约1ns即10的-9次方秒,1G=1024M=10241024k=102410241024byte,每次赋值1byte都要执行一次语句,故至少花费10241024102410^-9=1.073741824s

下列描述,正确的一共有多少个?

1)const char *p,这是一个常量指针,p的值不可修改
2)在64位机上,char *p= “abcdefghijk”; sizeof§大小为12
3)inline会检查函数参数,所以调用开销显著大于宏
4)重载是编译时确定的,虚函数是运行时绑定的;

1

A. 常量指针,p指向的值的大小不变 B. sizeof()测的是类型大小,指针类型在64位机中是8 C. 内联函数以空间换时间,直接嵌入函数,不存在普通函数的调用开销。 D. 正确

在c语言中,非零为真,零为假;但在c++中,1为真,0为假

参加位运算的数据可以是任何类型的数据。请问这句话的说法是正确的吗?

错误

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作,而浮点数是无法精确的转化为二进制表示的,所以是无法进行位运算的

设有如下定义:

struct ss
{ char name[10];int age; char sex;}std[3],*p=std;

下面各输入语句中错误的是____________

正确答案: B 你的答案: A (错误)
scanf(“%d”,&(*p).age);
scanf(“%s”,&std.name);
scanf(“%c”,&std[0].sex);
scanf(“%c”,&(p->sex));

scanf的第二个参数是一个地址,数组名本身就是一个地址,scanf函数以字符串形式输入字符串,同时将输入的字符串赋值数组时,直接引用数组名即可,不用加取地址运算符

以下字符中不是转义字符的是()。

正确答案: C 你的答案: A (错误)
‘\a’
‘\b’
‘\c’
‘\’

在这里插入图片描述

int main(){

int a;float b,c;
scanf("%2d%3f%4f",&a,&b,&c);
printf("\na=%d,b=%d,c=%f\n",a,b,c);
}
若运行时从键盘上输入9876543210l,则上面程序在gcc编译器下的输出结果是

a=98,b=0,c=0.000000

printf函数执行的时候,会先把这三个数字压入栈里,然后再执行打印。压入栈的时候按照数据本身的长度来,首先把c和b压入,并且每一个都是8个字节(printf自动转化为double)。然后再压入a是4个字节。然后再执行打印。打印的时候按照用户指定的格式来出栈。首先打印a,a打印正常。然后又打印4个字节长度的b,在栈里面由于b长度是八个字节,并且b目前是64位的表示方式,数据的后面全是0.(float 变double),电脑是小端存储方式,0存储在距离a近的地方。打印b的时候,打印的4个字节都是0.然后再打印c,c用正常的方式打印,会一下子读取8个字节,正好,读出来的八个字节前面四个字节全是0,自己可以算一下,实在太小了,因此为0.
栈底 栈顶
高字节。。。。。。。。。。。低字节
4321 0000 765 0000 98
4字节 4字节 4字节 4字节 4字节
打印c 打印b 打印a
附:浮点数(单精度的float和双精度的double)在内存中以二进制的科学计数法表示,表达式为N = 2^E * F;其中E为阶码(采用移位存储),F为尾数。
float和double都由符号位、阶码、尾数三部分组成,float存储时使用4个字节,double存储时使用8个字节。各部分占用位宽如下所示:

         符号位     阶码      尾数     长度

float      1         8         23      32

double     1         11        52       64

参考:https://blog.csdn.net/weixin_34665627/article/details/117103748

有以下函数,该函数的功能是( )

int fun(char *s)
{char *t=s;
while(*t++);
return(t-s);
}
正确答案: B 你的答案: B C (错误)
比较两个字符的大小
计算s所指字符串占用内存字节的个数
计算s所指字符串的长度
将s所指字符串复制到字符串t中

t++ 最后会在\0后一个位置停止 \0后一个位置为此时指针指向 尾部减去头部包括\0就是字节数
而c答案字符串长度不包括最后的\0,因为
t++中的t一定是先用后加。先*t,后t=t+1。

正确答案: A D 你的答案: A D (正确)

包含虚函数的类有this指针
包含虚函数的类没有this指针
包含虚函数的类不能被继承
包含虚函数的类能被继承

纯虚函数:只提供一个接口,具体实现方法需要派生类自己去实现
虚函数:提供接口,并提供默认的实现方法,派生类也可以根据自己需求去重载
非虚函数:提供接口,强制实现方法
“pure virtual函数必须在derived class中重新声明,但是它们也可以拥有自己的实现。”-------《Effective C++》

已有定义:char a[]=“xyz”,b[]={‘x’,‘y’,‘z’};,以下叙述中正确的是 ( )。

a数组长度大于b数组长度

#include
#include
using namespace std;
int main()
{
char a[]=“xyz”,b[]={‘x’,‘y’,‘z’};
cout << strlen(a) << endl;
cout << strlen(b)<< endl;
cout << sizeof(a)<< endl;
cout << sizeof(b)<< endl;
return 0;
//输出3 3 4 3
}

输出以下结果

#define add(a,b) a+b
int main() {
printf("%d\n",3 * add(4,7));
return 0;
}

19

在 C/C++ 中,宏定义只是做简单的字符替换;
在 #define add(a,b) a+b 中, a+b 没有括号,所以 3* add(4,7) 实际的替换情况是: 34+7=19 ;若 a+b 有括号, #define add(a,b) ( a+b )则结果为: 3 ( 4+7 ) =33 ;

若有int i=10,j=0;则执行完语句

if (j=0)i++; else i–; i的值为11.
说法是否正确?

错误

j=0 所以 是if(0)

下面选择中正确的赋值语句是()。

(设 chara[5],*p=a;)
正确答案: A 你的答案: 空 (错误)
p=“abcd”;
a=“abcd”;
*p=“abcd”;
*a=“abcd”;

A p=“abcd”; P是字符型指针,将“abcd”的地址给了P,也就是P指向“abcd"的首地址,也就是 指向‘a’的地址;
B a=“abcd”;a是字符数组的地址,不可赋值;
C *p=“abcd”; P是字符,不能将字符串赋给它,若是p=‘a’,则正确.

下面关于 “EOF” 的叙述,正确的是()

正确答案: B 你的答案: B (正确)
EOF的值等于0
EOF是在库函数文件中定义的符号常量
文本文件和二进制文件都可以用EOF作为文件结束标志
对于文本文件,fgetc函数读入最后一个字符时,返回值是EOF

【解析】在 C 语言中,或更精确地说成 C 标准函数库中表示文件结束符( end of file )。在 while 循环中以 EOF 作为文件结束标志,这种以 EOF 作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的 ASCII 代码值的形式存放。我们知道, ASCII 代码值的范围是 0~255 ,不可能出现 -1 ,因此可以用 EOF 作为文件结束标志。

const在定义的时候必须初始化

在for语句中,循环次数只由变量来控制的.说法是否正确?

错误

除了变量以外,for中的break语句也可以控制控制次数, 如果题目是 只 由变量来控制的 ,那就是错误啦。
再补充一点,break语句只用于for和switch,在if语句中不能使用,因为if不是循环语句,所以不能用break来结束。

该函数参数为1时返回值为:

int GetResult(int a){
int b = 0;
__try{
if ( a != 0 ){
b++;
}
return b;
}
__finally{
–b;
}
return b;
}

1

在这里插入图片描述
转自《Windows核心编程》
本题中:
finally块中的代码会执行,但是try中已经返回了,所以返回b=1;
返回后,执行finally中的代码–b,b=0;
但是finally后面的代码return b不执行。所以返回还是1;但是此时b=0;

表达式(short)10/10.2*2运算后结果是什么类型?

double

强制类型转换的优先级高于+ - * /

现在机器cpu都是GHz,每次需要若干个指令,大约在1秒。执行1条语句约1ns即10的-9次方秒,1G=1024M=10241024k=102410241024byte,每次赋值1byte都要执行一次语句,故至少花费10241024102410^-9=1.073741824s

下列描述,正确的一共有多少个?

1)const char *p,这是一个常量指针,p的值不可修改
2)在64位机上,char *p= “abcdefghijk”; sizeof§大小为12
3)inline会检查函数参数,所以调用开销显著大于宏
4)重载是编译时确定的,虚函数是运行时绑定的;

1

A. 常量指针,p指向的值的大小不变 B. sizeof()测的是类型大小,指针类型在64位机中是8 C. 内联函数以空间换时间,直接嵌入函数,不存在普通函数的调用开销。 D. 正确

在c语言中,非零为真,零为假;但在c++中,1为真,0为假

参加位运算的数据可以是任何类型的数据。请问这句话的说法是正确的吗?

错误

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作,而浮点数是无法精确的转化为二进制表示的,所以是无法进行位运算的

设有如下定义:

struct ss
{ char name[10];int age; char sex;}std[3],*p=std;

下面各输入语句中错误的是____________

正确答案: B 你的答案: A (错误)
scanf(“%d”,&(*p).age);
scanf(“%s”,&std.name);
scanf(“%c”,&std[0].sex);
scanf(“%c”,&(p->sex));

scanf的第二个参数是一个地址,数组名本身就是一个地址,scanf函数以字符串形式输入字符串,同时将输入的字符串赋值数组时,直接引用数组名即可,不用加取地址运算符

以下字符中不是转义字符的是()。

正确答案: C 你的答案: A (错误)
‘\a’
‘\b’
‘\c’
‘\’

在这里插入图片描述

int main(){

int a;float b,c;
scanf("%2d%3f%4f",&a,&b,&c);
printf("\na=%d,b=%d,c=%f\n",a,b,c);
}
若运行时从键盘上输入9876543210l,则上面程序在gcc编译器下的输出结果是

a=98,b=0,c=0.000000

printf函数执行的时候,会先把这三个数字压入栈里,然后再执行打印。压入栈的时候按照数据本身的长度来,首先把c和b压入,并且每一个都是8个字节(printf自动转化为double)。然后再压入a是4个字节。然后再执行打印。打印的时候按照用户指定的格式来出栈。首先打印a,a打印正常。然后又打印4个字节长度的b,在栈里面由于b长度是八个字节,并且b目前是64位的表示方式,数据的后面全是0.(float 变double),电脑是小端存储方式,0存储在距离a近的地方。打印b的时候,打印的4个字节都是0.然后再打印c,c用正常的方式打印,会一下子读取8个字节,正好,读出来的八个字节前面四个字节全是0,自己可以算一下,实在太小了,因此为0.
栈底 栈顶
高字节。。。。。。。。。。。低字节
4321 0000 765 0000 98
4字节 4字节 4字节 4字节 4字节
打印c 打印b 打印a
附:浮点数(单精度的float和双精度的double)在内存中以二进制的科学计数法表示,表达式为N = 2^E * F;其中E为阶码(采用移位存储),F为尾数。
float和double都由符号位、阶码、尾数三部分组成,float存储时使用4个字节,double存储时使用8个字节。各部分占用位宽如下所示:

         符号位     阶码      尾数     长度

float      1         8         23      32

double     1         11        52       64

参考:https://blog.csdn.net/weixin_34665627/article/details/117103748

有以下函数,该函数的功能是( )

int fun(char *s)
{char *t=s;
while(*t++);
return(t-s);
}
正确答案: B 你的答案: B C (错误)
比较两个字符的大小
计算s所指字符串占用内存字节的个数
计算s所指字符串的长度
将s所指字符串复制到字符串t中

t++ 最后会在\0后一个位置停止 \0后一个位置为此时指针指向 尾部减去头部包括\0就是字节数
而c答案字符串长度不包括最后的\0,因为
t++中的t一定是先用后加。先*t,后t=t+1。

正确答案: A D 你的答案: A D (正确)

包含虚函数的类有this指针
包含虚函数的类没有this指针
包含虚函数的类不能被继承
包含虚函数的类能被继承

纯虚函数:只提供一个接口,具体实现方法需要派生类自己去实现
虚函数:提供接口,并提供默认的实现方法,派生类也可以根据自己需求去重载
非虚函数:提供接口,强制实现方法
“pure virtual函数必须在derived class中重新声明,但是它们也可以拥有自己的实现。”-------《Effective C++》

已有定义:char a[]=“xyz”,b[]={‘x’,‘y’,‘z’};,以下叙述中正确的是 ( )。

a数组长度大于b数组长度

#include
#include
using namespace std;
int main()
{
char a[]=“xyz”,b[]={‘x’,‘y’,‘z’};
cout << strlen(a) << endl;
cout << strlen(b)<< endl;
cout << sizeof(a)<< endl;
cout << sizeof(b)<< endl;
return 0;
//输出3 3 4 3
}

输出以下结果

#define add(a,b) a+b
int main() {
printf("%d\n",3 * add(4,7));
return 0;
}

19

在 C/C++ 中,宏定义只是做简单的字符替换;
在 #define add(a,b) a+b 中, a+b 没有括号,所以 3* add(4,7) 实际的替换情况是: 34+7=19 ;若 a+b 有括号, #define add(a,b) ( a+b )则结果为: 3 ( 4+7 ) =33 ;

若有int i=10,j=0;则执行完语句

if (j=0)i++; else i–; i的值为11.
说法是否正确?

错误

j=0 所以 是if(0)

下面选择中正确的赋值语句是()。

(设 chara[5],*p=a;)
正确答案: A 你的答案: 空 (错误)
p=“abcd”;
a=“abcd”;
*p=“abcd”;
*a=“abcd”;

A p=“abcd”; P是字符型指针,将“abcd”的地址给了P,也就是P指向“abcd"的首地址,也就是 指向‘a’的地址;
B a=“abcd”;a是字符数组的地址,不可赋值;
C *p=“abcd”; P是字符,不能将字符串赋给它,若是p=‘a’,则正确.

下面关于 “EOF” 的叙述,正确的是()

正确答案: B 你的答案: B (正确)
EOF的值等于0
EOF是在库函数文件中定义的符号常量
文本文件和二进制文件都可以用EOF作为文件结束标志
对于文本文件,fgetc函数读入最后一个字符时,返回值是EOF

【解析】在 C 语言中,或更精确地说成 C 标准函数库中表示文件结束符( end of file )。在 while 循环中以 EOF 作为文件结束标志,这种以 EOF 作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的 ASCII 代码值的形式存放。我们知道, ASCII 代码值的范围是 0~255 ,不可能出现 -1 ,因此可以用 EOF 作为文件结束标志。

const在定义的时候必须初始化

在for语句中,循环次数只由变量来控制的.说法是否正确?

错误

除了变量以外,for中的break语句也可以控制控制次数, 如果题目是 只 由变量来控制的 ,那就是错误啦。
再补充一点,break语句只用于for和switch,在if语句中不能使用,因为if不是循环语句,所以不能用break来结束。

该函数参数为1时返回值为:

int GetResult(int a){
int b = 0;
__try{
if ( a != 0 ){
b++;
}
return b;
}
__finally{
–b;
}
return b;
}

1

在这里插入图片描述
转自《Windows核心编程》
本题中:
finally块中的代码会执行,但是try中已经返回了,所以返回b=1;
返回后,执行finally中的代码–b,b=0;
但是finally后面的代码return b不执行。所以返回还是1;但是此时b=0;

表达式(short)10/10.2*2运算后结果是什么类型?

double

强制类型转换的优先级高于+ - * /

现在机器cpu都是GHz,每次需要若干个指令,大约在1秒。执行1条语句约1ns即10的-9次方秒,1G=1024M=10241024k=102410241024byte,每次赋值1byte都要执行一次语句,故至少花费10241024102410^-9=1.073741824s

下列描述,正确的一共有多少个?

1)const char *p,这是一个常量指针,p的值不可修改
2)在64位机上,char *p= “abcdefghijk”; sizeof§大小为12
3)inline会检查函数参数,所以调用开销显著大于宏
4)重载是编译时确定的,虚函数是运行时绑定的;

1

A. 常量指针,p指向的值的大小不变 B. sizeof()测的是类型大小,指针类型在64位机中是8 C. 内联函数以空间换时间,直接嵌入函数,不存在普通函数的调用开销。 D. 正确

若一个类中含有纯虚函数,则该类称为( )。

抽象类

抽象类可以不包含抽象方法,包含抽象方法的类一定是抽象类,抽象方法必须在子类中实现。

short a[10] = {0};sizeof(a)返回:()

20

机器平台:X86_64 处理器
Size of char is: 1
Size of int is: 4
Size of short is: 2
Size of long is: 8
Size of long int is: 8

Size of float is: 4
Size of double is: 8
Size of long double is: 16
Size of (所有指针) is: 8

机器平台: X86_32 处理器
区别:
Size of long is: 4
Size of long int is: 4
Size of long double is: 8
Size of (所有指针) is: 4

请找出下面程序中有哪些错误:

int main()
{
int i=10;
int j=1;
const int *p1;//(1)
int const *p2=&i; //(2)
p2=&j;//(3)
int *const p3=&i;//(4)
*p3=20;//(5)
*p2=30;//(6)
p3=&j;//(7)
return 0;
}

6 7

  • const int * a; 表示a是一个指针,可以任意指向int常量或者int变量,它总是把它所指向的目标当作一个int常量。也可以写成int const* a;含义相同。
  • int * const a; 表示a是一个指针常量,初始化的时候必须固定指向一个int变量,之后就不能再指向别的地方了。

字符串题目

c风格字符串的两种形式:
1、char a[] = {‘a’, ‘b’,‘v’, ‘\0’}; 手动添加结束符‘\0’
2、char a[] = “abv”; 默认添加’\0’

c/c++中基本类型只有整型、实型和字符型,不存在字符串类型;字符串是由字符组成的数组

综合题

空白符,包括空格、制表符、换行符,只是用来占位,没有实际内容。对于编译器来说,有的会被忽略(一般是在()中);有的不会被忽略(一般是在“”中)
标识符在C语言 中一般是8字符,在C++中一般是32字符,在Java中则没有限制

以下对一维数组a的定义正确的是( )。

const int N = 5; int a[N];

1、定义数组,中括号内必须是常量。
2、int a(5)等价于 int a = 5;不是数组

下面程序段的运行结果是:

char C[5]={‘a’,’b’,’\0’,’c’,’\0’};
printf(“%s”,C);

答:ab
%s格式符意为输出字符串,输出字符串时,遇到 “\0”表示结束,所以结果是ab;

若有以下语句:

int a[4][5],(*p)[5];
p=a;
下面哪个选项表示a数组中的元素?

正确答案: D
a: p+1
b:(p+3)
c:
(p+1)+3
d:*( * p+2)

a是一个二维数组,p是一个指向有5个元素的数组指针,所以最多只能访问。
A:表达式是一个指针,不是对数组元素的引用。(p+1)等于&a[1],即(p+1)指向a的第二行的首元素。
B:(p+3)是一个指针,指向第4行的首元素。
C:
(p+1)指向a的第二行的首元素;(p+1)+3则指向第二行的第3个元素。
D:
( *p+2)是对数组元素的正确引用,它等价于a[0][2]。
所以对a数组元素的正确引用的选项是D。

程序运行中需要从键盘上输入多于一个数据时,各数据之间默认应使用( )符号作为分隔符。

TAB、空格或逗号

1.这里的“从键盘上输入多于一个数据”,应该专门指的是一次性从键盘上输入多于一个数据。这样子,代码中就不能出现循环,必须在所有输入的结束处刷新缓存。默认情况下,回车会刷新输入缓存。排除含有回车的选项。
2. 分号通常当作普通字符处理。排除含有分号的选项。
3. 如果逗号作分割符,存在中英文字符不同、输入内容错误等几个问题。

以下对选择语句描述错误的是()

正确答案: A 你的答案: D (错误)
a根据某一条件重复执行一部分代码直到满足终止条件为止
b可以根据条件控制程序流程,改变程序执行的顺序
c选择语句可以嵌套使用
d当条件满足时就会执行相应的语句

流程控制语句分类:
顺序结构
选择结构:if语句、switch语句
循环结构:while语句、for语句

变量类型推断

int i=0;
const int ci=i;
auto b=ci; //(1)
int *p=&i;
decltype(*p) c=i;//(2)
以上(1)(2)中变量b,c类型为()

正确答案: B 你的答案: D (错误)
const int ,int
int,int&
const int,int*
int,int*

decltype和auto都可以用来推断类型,但是二者有几处明显的差异:
1.auto忽略顶层const,decltype保留顶层const;
2.对引用操作,auto推断出原有类型,decltype推断出引用;
3.对解引用操作,auto推断出原有类型,decltype推断出引用;
4.auto推断时会实际执行,decltype不会执行,只做分析。总之在使用中过程中和const、引用和指针结合时需要特别小心。

Guess you like

Origin blog.csdn.net/weixin_44576259/article/details/120583711
C++