C语言基础类错题

(1.3)基础知识类

(1.1)库函数类

引用标准库时,下面的说法你认为哪个是正确的:
#include “stdlib.h”是正确的,而且程序编译速度比#include <stdlib.h>要快
语句#include <stdlib.h>是正确的,而且程序编译速度比#include “stdlib.h”要快
语句#include <stdlib.h>和#include “stdlib.h”都是正确的,程序编译速度没有区别
语句#include “stdlib.h”是错误的
#inlcude <> 首先 只搜索系统目录,不会搜索本地目录.比如你自己写一个头文件,你用#include <>会出错.  
#inlude ""首先搜索本地目录,如果本地目录没有才会搜索系统目录.
可以把系统的文件 放到当前目录下 改成 ""   可以优先使用


你认为可以完成编写一个C语言编译器的语言是()
  • 汇编
  • C语言
  • :VB
  • 以上全可以




下面哪些调用转换支持可变长度参数
  • cdecl
  • stdcall
  • pascal
  • fastcal


以下哪个函数可以在源地址和目的地址的位置任意的情况下,在源地址和目的地址的空间大小任意的情况下实现二进制代码块的复制?
  • memcpy()
  • memmove()
  • memset()
  • strcpy()



定义网络传输数据包为 
1
2
3
4
class packet{
      int size;
      void data[ 0 ];
}
其中data的作用是?
  • 维护数据包空间的连续性
  • 数据分割位
  • 指向独立的数据空间
  • 无任何作用
1.这个叫柔性数组,它的作用跟指针差不多,但是指针占空间,而它不占空间,这就意味着可以节省空间。
2.该数组的内存地址就和它后面的元素地址相同,意味着无需初始化,数组名就是后面元素的地址,直接就能当指针使用。例如,制作动态buffer,可以这样分配空间malloc(sizeof(structXXX) + buff_len); 直接就把buffer的结构体和缓冲区一块分配了。这样使用释放一次即可,如果使用指针,则需要释放两次。
3.也可以写成data[1]或data[],是考虑到可移植性的原因,因为有些编译器不支持0数组。





1
time_t t;
哪个选项可以将t初始化为当前程序的运行时间?
  • t = clock();
  • time( &t );
  • time( t );
  • t = localtime();
  • None of the above
clock() 就是该程序从启动到函数调用占用CPU的时间
time( &t );为获取系统时间
localtime(&t);   将一个UTC时间转为本地时间



下面的函数中哪个是系统调用而不是库函数?
  • printf
  • scanf
  • fgetc
  • read
  • print_s
  • scan_s





在 C 语言中下面那个语句的结果是 1 ?
  • main 函数正常结束的返回值
  • return 7&1;
  • char *p="hello"; return p == "hello";
  • 上面都不对
main 函数正常结束的返回值是0   ps:全局变量在main前构造,main结束后,程序关闭前析构



程序的完整编译过程分为是:预处理,编译,汇编等,如下关于编译阶段的编译优化的说法中不正确的是()?
  • 死代码删除指的是编译过程直接抛弃掉被注释的代码
  • 函数内联可以避免函数调用中压栈和退栈的开销
  • For循环的循环控制变量通常很适合调度到寄存器访问
  • 强度削弱是指执行时间较短的指令等价的替代执行时间较长的指令
死代码的含义是指永远不会被执行到的代码段,而不是直接抛弃被注释的代码
比如while(false){}


下面哪些属于使用"常引用"的原因?
  • 提高程序的效率
  • 节省存储空间
  • 保护传递给函数的数据不在函数中被改变
  • 以上都不正确



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

  • 会拷贝动态分配的成员对象
  • 会拷贝成员数据的值
  • 会拷贝静态分配的成员对象
  • B和C都对
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。
浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。
静态成员的数据只有一份为大家共享,所以不能深拷贝

1
"My salary was increased by 15%!"
下列哪个选项可以准确的显示出上述语句?
  • printf("\"My salary was increased by 15/%\!\"\n");
  • printf("My salary was increased by 15%!\n");
  • printf("My salary was increased by 15'%'!\n");
  • printf("\"My salary was increased by 15%%!\"\n");
%因为%d  %s比较特殊
A: 没\!这转义符,编译时报错
B,C: 一看前面输出时就少了双引号
D是对的,里面%%是输出的%,虽然有些编译器\%也能输出%,但貌似标准c不支持


1
2
3
4
5
6
7
8
9
10
11
12
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;
}
则func(1) = 0
因为没有break语句,switch中会一直计算到b=0
如果匹配到某个case,则从该case处开始顺序执行,否则就从default处开始执行,一直向下,直到出现break语句为止


1
2
3
4
5
6
7
8
9
10
11
12
int func( int a)
{
     int b;
     switch (a)
     {
  
            default: b = 0;
         case 1 : b =  30 ;
         case 2 : b =  20 ;
         case 3 : b =  16 ;
        
     }
     return b;
}
则func(1) = 16



若有以下程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
main()
     int  s= 0 ,n;
     for (n= 0 ; n< 4 ; n++)
    
         switch (n)
        
             default :s+= 4 ;
             case1:s+= 1 ;
             case2:s+= 2 ;
             case3:s+= 3 ;
         }
     }
     printf ( "%d\n" ,s);
}

则程序的输出结果是?

24
第一次循环for循环,n的值为0,所以从default后面的语句开始执行,s+=4,s+=1,s+=2,s+=3,s的值为10。在进入第二次for循环,n的值为1,所以执行的s+=1,s+=2,s+=3,s的值为16。在进入第三次for循环,n的值为2,所以执行s+=2,s+=3,s的值为21。在进入第四次for循环,n的值为3,所以执行s+=3,s的值为24。





void recursive(int n, int m, int o)
{
    if (n <= 0)
    {
        printf("%d,%d\n", m, o);
    }
    else
    {
        recursive(n - 1, m + 1, o);
        recursive(n - 1, m, o + 1);
    }
}
以上函数的时间复杂度()
时间复杂度只与n有关,m和o只是打酱油的。
n会递归两次n-1
n-1会递归两次n-2
n-2会递归两次n-3
所以,是一个完全二叉树,总共是2^n-1次,时间复杂度O(2^n)


头文件中的 ifndef/define/endif 干什么用?
  • 定义常量
  • 标记为特殊的头文件
  • 防止头文件被重复引用
  • 注释头文件


下面描述中,错误的是()
  • 基类定义的public成员在公有继承的派生类中可见,也能在类外被访问
  • 基类定义的public和protected成员在私有继承的派生类中可见,在类外可以被访问
  • 基类定义的public和protected成员在保护继承的派生类中不可见
  • 基类定义的protected成员在protected继承的派生类中可见,也能在类外被访问


有哪几种情况只能用intialization list 而不能用assignment?
  • 当类中含有const成员变量
  • 基类无默认构造函数时,有参的构造函数都需要初始化表。
  • 当类中含有reference成员变量
  • 当类中含有static成员变量
因为const对象以及引用只能初始化而不能赋值,所以只能使用成员初始化列表。
对于非内置类型,在进入函数体之前,如果没有提供显式初始化,会调用默认构造函数进行初始化。若没有默认构造函数,则编译器尝试调用默认构造函数将会失败,所以如果没有默认构造函数,则必须在初始化列表中显示的调用构造函数。

(1.2)基础类型与计算类

函数
1
2
3
fun( char * p) {
     return p;
}
的返回值是 行参p中存放的地址值



若有定义语句: char a ='\82'; 则变量a
  • 说明不合法
  • 包含1个字符
  • 包含2个字符
  • 包含3个字符
有一个‘\’,那么首先想到的是转义字符常量,‘\ddd’  是用八进制数的ASCII码表示一个字符,但是本题中'\82',有一个8,显然已经不是八进制,那么这个时候实际上就'\82'中包含3个字符,分别是‘\’,'8','2',赋值时是将字符'2'给了a,实际上这个题和 char a = 'fdz'变量a的值是‘z’是一个道理,只是\具有迷惑作用而已,可以试验把‘\82’换成‘\zz’,则a的值为z,因此这道题选择包含一个字符。




c++中,声明const int i,是在哪个阶段做到 i只可读的?
  • 编译
  • 链接
  • 运行
  • 以上都不对
const int i = 10; 编译时候  就和 变量i做了对应,后面程序用到i的时候,直接从编译器的符号表中取10,不会再查找内存...


已知一函数中有下列变量定义,其中属于自动变量的有()。
  • double k;
  • register int i;
  • static char c;
  • auto long m;
普通的变量,不管是否声明为auto,都是自动型变量
A,普通变量,是auto的
B,寄存器变量,不是
C,静态变量,不是
D,声明为auto,是




引用可以是void类型吗?
  • 不可以
  • 可以
引用为对象起了另外的一个名字,该对象是已经存在的对象,引用必须初始化,有类型



下面关于迭代器失效的描述哪个是错误的()
vector的插入操作不会导致迭代器失效
map的插入操作不会导致迭代器失效
vector的删除操作只会导致指向被删除元素及后面的迭代器失效
map的删除操作只会导致指向被删除元素的迭代器失效
选A,因为由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是快速失败的 :如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的 remove 或 add 方法之外的任何其他方式),则迭代器将抛出 ConcurrentModificationException。


若有以下程序

1
2
3
4
5
6
7
8
9
#include <stdio. h>
main( )
     int  a =  0 ,b =  0 ,c =  0 ,d; 
     c = (a + = b,,b + = a);     / * 第 4 行 * /
     d = c;        / * 第 5 行 * /
     ;         / * 第 6 行 * /
     ;printf( "%d,%d,%d\n" ,a,b,c);/ * 第 7 行 * /
}

 编译时出现错误,你认为出错的是

第4行逗号表达式中间的第二个表达式为空,是不合法的,可以去掉写成a + = b,b + = a,也可以在里面补一个表达式,如a + = b,a,b + = a。所以选择A选项。


有函数定义: 
1
2
void test( int a){} 
void test( float a){} 
则以下调用错误的是:
  • test(1);
  • test(‘c’);
  • test(2+’d’)
  • test(0.5)
C++中默认的类型转换是从下到上的,就是int ,float可能系统会转成double,但不会将double转化成int,char
test(0.5) 中的0.5在运算时是double类型的


已知x>=y and y>=z 为真,那么x>z or y=z 值为
  • 无法确定
  • x y z同为正数时为真
这题选c没有问题。首先要注意的是y=z是赋值,不是判断。 而后,x>=y>=z,当x=y=z的时候后面第一项x>z就不成立了,关键看第二项。当x=y=z=0,第二项为false,整个表达式为false。其他情况表达式是true



假设在n进制下,下面的等式成立,n值是() 567*456=150216
  • 9
  • 10
  • 12
  • 18
567*456=150216 -》 (5*n 2+5*n+7) * (4*n 2+5*n+6) = n  5 +5*n 4+2*n 2+n+6 解方程可得n=18
1735*1392=2415120



已有变量定义和函数调用语句,
1
2
int a= 25 ;
print_value(&a);
则下面函数的正确输出结果是______。
1
2
3
4
void print_value( int * x)
{
     printf(“%x\n”,++*x);
}

  • 25
  • 26
  • 19
  • 1a
%x是按十六进制输出,++*x = 26 = 0x1a


给定3个int类型的正整数x,y,z,对如下4组表达式判断正确的选项()
1
2
3
4
int a1=x+y-z;  int b1=x*y/z;
int a2=x-z+y;  int b2=x/z*y;
int c1=x<<y>>z;  int d1=x&y|z;
int c2=x>>z<<y;  int d2=x|z&y;
  • a1一定等于a2
  • b1一定等于b2
  • c1一定等于c2
  • d1一定等于d2
A
【解析】
由于整数除法的截断,b1和b2不一定相等
由于移位会丢弃超出位,c1和c2不一定相等
d1是(x&y)|z而d2是x|(y&z),不一定相等






1
2
3
4
5
void swap_int( int *a, int *b){
   *a=*a+*b;
   *b=*a-*b;
   *a=*a-*b;
}
以下说法正确的是:
  • 结果不正确,因为会溢出,用位与的方式就没问题
  • 结果正确,即使会溢出
  • 结果正确,不会溢出
  • 其他选项都不对
加减法可能会溢出。其实不然,第一步的加运算可能会造成溢出,但它所造成的溢出会在后边的减运算中被溢出回来


对以下程序,正确的输出结果是()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#define SUB(x,y) x-y
#define ACCESS_BEFORE(element,offset,value) *SUB(&element, offset) = value
int main() {
     int array[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     int i;
     ACCESS_BEFORE(array[5], 4, 6);
     printf ( "array: " );
     for (i = 0; i < 10; ++i) {
         printf ( "%d" , array[i]);
     }
     printf ( "\n" );
     return (0);
}
  • array: 1 6 3 4 5 6 7 8 9 10
  • array: 6 2 3 4 5 6 7 8 9 10
  • 程序可以正确编译连接,但是运行时会崩溃
  • 程序语法错误,编译不成功
“赋值号的左边操作数需要一个左值”。其原因是调用宏的那句被预处理器替换成了:
*&array[5]-4 =6; 
由于减号比赋值优先级高,因此先处理减号;由于减号返回一个数而不是合法的左值,所以编译报错



下列代码的输出为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#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;  
}  
  • 100 300 300 500
  • 100 300 500
  • 100 500
  • 程序错误
vector在erase之后,指向下一个元素的位置,其实进行erase操作时将后面所有元素都向前移动,迭代器位置没有移动。itor=array.erase(itor) erase返回下一个元素的地址,相当于给itor一个新值。


以下STL的容器存放的数据,哪个肯定是排好序的()
  • vector
  • deque
  • list
  • map
关联式容器是排好序的




int func(unsigned int i)
{
    Unsigned int temp = i;
    temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> 1);
    temp = (temp & 0x33333333) + ((temp & 0xccccccccc) >> 2);
    temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0 >> 4));
    temp = (temp & 0xff00ff) + ((temp & 0xff00fff00) >> 8);
    temp = (temp & 0xffff) + ((temp & 0xffff0000) >> 16);
    Return temp;
}
请问 func(0x11530828)的返回值是:8
求数的二进制表示中1的个数的“平行算法”,思路就是先将n写成二进制形式,然后相邻位相加,重复这个过程,直到只剩下一位。8

在c++中,
1
2
3
4
const int i =  0
int *j = ( int *) &i; 
*j =  1
printf( "%d,%d" , i, *j)
输出是多少?
  • 0,1
  • 1,1
  • 1,0
  • 0,0
const 修饰符表示i为常量,值不可改变,但是通过指针可以改变内存中i所在地址中的值,所以输出*j的值变为1。但是通过编译器优化,i的值不再是每次都在内存中读取,而是见到i编译器就可自动赋值为最初的值0,所以输出i的值时为0,答案为A 0,1。
如果将i更改为volatile const int类型的,编译器就不会对变量i做优化,printf输出的结果就为1。



下面描述正确的是
1
2
int *p1 =  new int [ 10 ];  // 10个未初始化int        new student
int *p2 =  new int [ 10 ]();// 10个值初始化为0的int    new Student()
  • p1和p2申请的空间里面的值都是随机值
  • p1和p2申请的空间里的值都已经初始化
  • p1申请的空间里的值是随机值,p2申请的空间里的值已经初始化
  • p1申请的空间里的值已经初始化,p2申请的空间里的值是随机值


1
2
3
signed char a=0xe0;
unsigned  int b=a;
unsigned  char c=a;
下面说法正确的是:
  • (a>0 )&&(b>0)为真
  • c==a 为真
  • b的16进制为0xffffffe0
  • 都不对
a-------1110 0000-----因为是有符号数,负数-----取反+1  0010 0000----- -32
b-------高位按符号位补齐-------ff ff ff e0
c-------224


x y t 均为 int 型变量,则执行语句: t=3; x=y=2; t=x++||++y;  后,变量 t y 的值分别为 ____ 1,2
||返回0或者1



在一个64位的操作系统中定义如下结构体:
1
2
3
4
5
6
struct st_task
{
     uint16_t id;
     uint32_t value;
     uint64_t timestamp;
};
同时定义fool函数如下:
1
2
3
4
5
6
7
void fool()
{
     st_task task = {};
     uint64_t a =  0x00010001 ;
     memcpy(&task, &a, sizeof(uint64_t));
     printf( "%11u,%11u,%11u" , task.id, task.value, task.timestamp);
}
上述fool()程序的执行结果为()
  • 1,0,0
  • 1,1,0
  • 0,1,1
  • 0,0,1
考点:字节对齐,低地址到高地址
    因为字节对齐的原因,所以id占用4个字节,value和timestamp分别是4个字节、8个字节。虽然id占用四个字节的地址,但是只有低两位地址的数值有效(字节对齐的机制,即value存储时的地址对4(自身对齐值)求余应为0)。所以id为 0001 0001,高四位无效,所以为0001,value与timestamp分别为0.
    比如:地址从0x0000开始,id存储地址本来为0x0000-0x0001,但value存储地址要从0x0004开始,因为0x0004%4==0,所以id存储地址为0x0000-0x0003, value存储地址为0x0004-0x0007, timestamp存储地址为0x0008-0x000F. 所以id == 0x00010001,去掉高4位,id=0x0001,其余为0.




经验:1、表示为习惯意义上的从高向低位写   高---》低    0010=2
           2、小端机从右向左读,读的时候   元素间的字节外从右向左    元素内的字节内还是从左向右


nt main()
{
  long long a=1;
  long long b=2;
  long long c=3;
  printf("%d,%d,%d",a,b ,c);
  return 0;
}
输出结果是什么?(32位环境,cpu为小端模式,所有参数用栈传递)
1、printf从右向左,压栈顺序c,b,a,栈从高向低,c在高位。
2、我们先表示为平常理解的方式高-->低,例如:1001   正常大端机器上:
【00 00 00 00 00 00 00 03】【00 00 00 00 00 00 00 02】【00 00 00 00 00 00 00 01】
大端机器读取,从左向右,%d为4字节,读取为0,3,0
小端机相当于从右向左读取,每次读取4个字节,1,0,2



unsigned int a= 0x1234;
unsigned char b=*(unsigned char *)&a;
在32位大端模式处理器上变量b= ?。
高--->低     00 00 12 34   大端机从左向右读取1个字节 00 


x86 的机器上, int a=0xabcd1234 char b= (( char* &a [0] 请问 b 是多少  0x34
高向低   ab  cd 12  34
X86小端机、1字节



在小端序的机器中,如果 
1
2
3
4
union X{
     int x;
     char y[4];
};
如果:
X a;
a.x=0x11223344;//16 进制 则:______
  • a.y[0]=11
  • a.y[1]=11
  • a.y[2]=11
  • a.y[3]=11
  • a.y[0]=22
  • a.y[3]=22
union类型,数据时重叠在同一块内存区域上的,这个内存区域的大小为对其后的最大长度,这里就是4
高--->低   11 22 33 44
  小端从左向右取 y[3]=11


1
写出下列程序在X86上的运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct mybitfields
{
     unsigned  short a : 4;
     unsigned  short b : 5;
     unsigned  short c : 7;
} test
 
void main( void )
{
     int i;
     test.a = 2;
     test.b = 3;
     test.c = 0;
 
     i = *(( short *)&test);
     printf ( "%d\n" , i);
}
这个题的为难之处呢,就在于前面定义结构体里面用到的冒号,如果你能理解这个符号的含义,那么问题就很好解决了。这里的冒号相当于分配几位空间,也即在定义结构体的时候,分配的成员a 4位的空间, b 5位,c 7位,一共是16位,正好两个字节。下面画一个简单的示意:
变量名  位数
test    15 14 13 12 11 10 9 |8 7 6 5 4 |3 2 1 0
test.a                  |       |0 0 1 0
test.b                  |0 0 0 1 1 |
test.c   0  0  0  0 0 0 0 |        |
高--->低,从右读,每次都一个字节
在执行i=*((short *)&test); 时,取从地址&test开始两个字节(short占两个字节)的内容转化为short型数据,即为0x0032,再转为int型为0x00000032,即50



1
2
3
4
5
6
7
8
9
10
11
union Test
  {
     char  a[ 4 ];
     short  b;
  };
  Test test;
  test.a[ 0 ]= 256 ;
  test.a[ 1 ]= 255 ;
  test.a[ 2 ]= 254 ;
  test.a[ 3 ]= 253 ;
  printf( "%d\n" ,test.b);
问题:在80X86架构下,输出什么值?
  • -128
  • -256
  • 128
  • 256
char类型的取值范围是-128~127,unsigned char的取值范围是0~256
这里a[0]=256,出现了正溢出,将其转换到取值范围内就是0,即a[0]=0;
同理,a[1]=-1, a[2]=-2, a[3]=-3,在C语言标准里面,用补码表示有符号数,故其在计算机中的表示形式如下:
a[0]=0,     0000 0000
a[1]=-1,    1111 1111
a[2]=-2,    1111 1110
a[3]=-3,    1111 1101
小端机器中:     1111 1101  1111 1110  1111 1111  0000 0000 
short是2字节(a[0]和a[1]),由于80X86是小端模式,即数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,在本例中,a[0]中存放的是b的低位,a[1]中存放的是b的高位,即b的二进制表示是:1111 1111 0000 0000,表示-256,故选B。


在32位小端的机器上,如下代码输出是什么:
1
2
3
4
5
char array[ 12 ] = { 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 };     
  short *pshort = ( short *)array;     
  int *pint = ( int *)array;     
  int64 *pint64 = (int64 *)array;     
  printf( "0x%x , 0x%x , 0x%llx , 0x%llx" , *pshort , *(pshort+ 2 ) , *pint64 , *(pint+ 2 ));

  • 0x201 , 0x403 , 0x807060504030201 , 0x0
  • 0x201 , 0x605 , 0x807060504030201 , 0x0
  • 0x201 , 0x605 , 0x4030201 , 0x8070605
  • 0x102 , 0x506 , 0x102030405060708 , 0x0
小端机器的数据高位字节放在高地址,低位字节放在低地址。x86结构为小端模式。
pshort占用2个字节,在内存中的16进制为0x01 0x02,对应的16进制数为0x0201。
pshort + 2指向array数组的下标为4的元素,占用2个字节,在内存中的16进制为0x05 0x06,对应的16进制数为0x0605。 
pint64的int64类型不确定,但根据名字可以看出占用8个字节,对应的16进制形式为0x807060504030201。
pint  + 2占用4个字节,指向的array数组的下标为8的元素,8-11个元素没有指定数组的初始化值,默认为0,因此*(pint + 2)对应的16进制为0。





以下代码执行后,val的值是___:
1
2
3
4
unsigned  long val = 0;
char a = 0x48;
char b = 0x52;
val = b << 8 | a;
  • 20992
  • 21064
  • 72
  • 0
b << 8 = 0x5200
val = 0x5200 | 0x48 = 0x5248 = 21064 

写出一下程序的输出
1
2
3
4
5
6
7
8
int main( void )
{
  char num;
  for (num =  0 ; num <  255 ; )
  num += num;
  printf( "%d\n" ,num);
  return 0 ;
}
  • 254
  • 255
  • 256
  • 死循环
选D
这里num值一直是0,num < 255一直是成立的,程序进入死循环



下面这个程序执行后会有什么错误或者效果:
1
2
3
4
5
6
7
#define MAX  255
int main()
{
      unsigned  char A[MAX], i;
      for (i =  0 ; i <= MAX; i++)
          A[i] = i;
}

  • 数组越界
  • 死循环
  • 栈溢出
  • 内存泄露


1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int main()
{
     uint32_t a =  100 ;
     while (a >  0 )
     {
         --a;
     }
     printf( "%d" , a);
     return 0 ;
}
-1
100
0
死循环
Unsigned int型数字最小为0,因此不是死循环,a到0就跳出循环,最后输出0



使用printf函数打印一个double类型的数据,要求:输出为10进制,输出左对齐30个字符,4位精度。以下哪个选项是正确的?
  • %-30.4e
  • %4.30e
  • %-30.4f
  • %-4.30f    f: double精度浮点数    e: 科学计数法


  • 用C++语法来看,下列的哪个赋值语句是正确的?
  • char a=12
  • int a=12.0
  • int a=12.0f
  • int a=(int)12.0
A项在赋值为0-127时无警告,但B/C/D均有损失精度的警告,编译还是能通过的。B、C、D项的区别是:B 项的默认为double型转向int型,C项因等号后“12.0f”的  ‘f’使其转换为folate型,D项直接通过在等号的右边加“(int)”强制类型转换,与B项相同的是:是从默认的double型转换为int型。A项会对应的ASCII字符,但在大于127时会发生常量截断会有警告。

以下程序的输出结果为 
#include "stdio.h"
int func(int x, int y)
{
    return (x + y);
}
int main()
{
    int a = 1, b = 2, c = 3, d = 4, e = 5;
    printf(" % d\n", func((a + b, b + c, c + a), (d, e)));
    
    return 0;
}
9
主要知识点是C++中的逗号操作符! C++ Primer第4版中145页关于逗号操作符论述如下:
逗号表达式的结果是其最右边表达式的值,但是是从左向右计算




以下选项中合法的实型常量是?
  • 0
  • 3.13e-2.1
  • .914
  • 2.0*10
A选项为整型数据。B选项中e后面必须为整数。D选项是表达式,不是常量,所以选择C。


有如下程序段:
1
2
3
4
5
6
7
8
9
int i, n = 0;
float x = 1, y1 = 2.1 / 1.9, y2 = 1.9 / 2.1;
for ( i = 1; i < 22; i++ )
  x = x * y1;
while ( x != 1.0 )
{
  x = x * y2; n++;
}
printf( “ %d / n ”, n );
请问执行结果是: 无限循环
浮点数有精确度的限制吧。所以肯定不能除尽,不能使用==和!=,以及位运算



下面两段代码中for循环分别执行了多少次?
1
2
3
4
5
6
7
8
9
1 .
unsigned  short i,j;
for (i= 0 , j= 2 ; i!=j; i+= 5 , j+= 7 )
{}
 
2 .
unsigned  short i,j;
for (i= 3 ,j= 7 ;i!=j;i+= 3 ,j+= 7 )
{}

32767 16383
答案分析:unsigned short能表示216个数,其范围为0~216-1,j在i前2个位置,i以5的速度增长,j以7的速度增长,当增长到unsigned short表示的最大值又会返回0(以一个圈的形式循环)开始重新走直到i、j相遇,所以就是7t - 5t + 2 = 216,所以为32767次
第二个类似 (7t + 7)-(5t - 3) = 216,所以为16383次



下面有关C++的类和C里面的struct的描述,正确的有?
  • 来自class的继承按照private继承处理,来自struct的继承按照public继承处理
  • class的成员默认是private权限,struct默认是public权限
  • c里面的struct只是变量的聚合体,struct不能有函数
  • c++的struct可有构造和析构函数


有变量int i = 0; int a = i++; int b=++a; int c = a+b; 请问表达式 a?b:c 的值是
  • 0
  • 1
  • 2
  • 3
a=i++. a----0 
b=++a. b----1. a----1
 c=a+b. c-----2
a?b:c     a为1取b  也就是1


当参数*x==1, *y==1, *z==1时,下列不可能是函数add的返回值的( )?
1
2
3
4
5
6
int add( int *x,  int *y,  int *z){
     *x += *x;
     *y += *x;
     *z += *y;
     return *z;
  }

  • 4
  • 5
  • 6
  • 7
开始不知道啥意思,后经牛客网的大神指点才知道这题要考虑的是,x,y,z三个参数是否指向同一地址(或者说调用该函数时是否实参相同),如:当a=b=c=1时,add(&a,&a,&a),add(&a,&b,&c)。
通过写程序测试得出结果,不可能得到答案7。
有以下5种情况
C语言基础类错题_第1张图片 




1
2
3
4
5
6
7
enum string{    
     x1,    
     x2,    
     x3= 10 ,    
     x4,    
     x5,    
} x;
问x等于什么?
  • 5
  • 12
  • 0
  • 随机值
如果是函数外定义那么是0
如果是函数内定义,那么是随机值,因为没有初始化


数字字符0的ASCII值为48,若有以下程序:
1
2
3
4
5
6
main()
{
     char a=’1’,b=’2’;
     printf(“%c,”,b++);
     printf(“%d\n”,b-a);
}
程序运行之后的输出结果是:
注意初始化时的数据类型,为char型,即此时int(a)=49,int(b)=50。第一条输出变量b的char类型,即char(b)=2,输出后int(b)自增=51,第二条输出整形即int(b-a)=51-49=2。

(1.3)函数类



从下列函数原形看,用GCC编译时,返回值类型为int的函数有?
  • char F1(int n);
  • int F2(char n);
  • F3(int n);
  • int *F4(int n);
函数原型格式:
函数返回值 函数名([形参表]);
A:返回char类型
C:默认返回类型为int类型
D:返回整型指针类型
如果没有返回值,必须声明为void类型


设有以下函数void fun(int n,char *s)(......),则下面对函数指针的定义和赋值均是正确的是:()
  • void (*pf)(int,char); pf=&fun;
  • void (*pf)(int n,char *s); pf=fun;
  • void *pf(); *pf=fun;
  • void *pf(); pf=fun;
B. 函数指针只需要把fun 改成(*pf) ,赋值 直接 pf = fun;即可 函数名赋值.指针函数赋值时候,可以直接用函数名赋值(书上一般都是这样赋值的) .但是也可以用&fun ,取地址操作符复制给函数指针.   pf = &fun;也是可以的.亲测过



程序出错在什么阶段__?
1
2
3
4
int main( void ) {
     http: //www.taobao.com
     cout <<  "welcome to taobao" << endl; 
}
  • 预处理阶段出错
  • 编译阶段出错
  • 汇编阶段出错
  • 链接阶段出错
  • 运行阶段出错
  • 程序运行正常
http相当于一个label,//www.taobao.com是注释,所以答案错误,可以运行



(1.3.1)重载类


不能作为重载函数的调用的依据是:
  • 参数个数
  • 参数类型
  • 函数类型
  • 函数名称



std::vector::iterator重载了下面哪些运算符?
  • ++
  • >>
  • *(前置)
  • ==

在重载运算符函数时,下面()运算符必须重载为类成员函数形式()
  • +
  • -
  • ++
  • ->
只能使用成员函数重载的运算符有:=、()、[]、->、new、delete。  

如果友元函数重载一个运算符时,其参数表中没有任何参数则说明该运算符是:
  • 一元运算符
  • 二元运算符
  • 选项A)和选项B)都可能
  • 重载错误
友元函数重载时,参数列表为1,说明是1元,为2说明是2元
成员函数重载时,参数列表为空,是一元,参数列表是1,为2元




类成员函数的重载、覆盖和隐藏区别描述正确的有?
  • 覆盖是指在同一个类中名字相同,参数不同
  • 重载是指派生类函数覆盖基类函数,函数相同,参数相同,基类函数必须有virtual关键字
  • 派生类函数与基类函数相同,但是参数不同,会"隐藏"父类函数
  • 函数名字相同,参数相同,基类无virtual关键字的派生类的函数会"隐藏"父类函数

a.成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(2)函数名字相同;

(3)参数不同;

(4)virtual 关键字可有可无。

b.覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同;

(3)参数相同;

(4)基类函数必须有virtual 关键字。

c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)




(1.3.2)静态类

关于static用途说法正确的是?
  • 声明静态外部类
  • 声明静态外部全局变量
  • 声明静态外部函数
  • 声明静态局部变量

下面对静态成员的描述中,正确的是:
静态数据成员可以在类内初始化
静态数据成员不可以被类对象调用
静态数据成员不能受private控制符的作用
静态数据成员可以直接用类名调用

1、静态数据成员同样受 private,public,protected 等权限符限制
2、静态数据成员由于是属于整个类的,静态数据成员存储在静态数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义(即初始化),对它们的初始化一般在类外,但是,当类型为const static时的整形时可以在类体内进行初始化。
3、可以通过累的对象,指针,类名等直接调用静态成员
4、类的静态成员函数可以在类内进行定义,也可以在类外,类的静态成员函数只能直接调用静态成员,如果想调用非静态成员只能通过间接的方式,而非静态成员可以直接访问静态成员。



Fill the blanks inside class definition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Test
{
     public:
         ____ int a;
         ____ int b;
     public:
         Test::Test(int _a , int _b) : a( _a )
         {
              b = _b;
         }
};
int Test::b;
int main(void)
{
     Test t1(0 , 0) , t2(1 , 1);
     t1.b = 10;
     t2.b = 20;
     printf( "%u %u %u %u" ,t1.a , t1.b , t2.a , t2.b);
     return 0;
}
Running result : 0 20 1 20
  • static/const
  • const/static
  • --/static
  • conststatic/static
  • None of above
对于成员变量a,若它为const类型,那么必须要使用Test::Test(int _a , int _b) : a( _a )这种初始化形式,若它为普通成员变量,也可以采取Test::Test(int _a , int _b) : a( _a )这种形式,所以a可以为const或者普通类型,由于b没有采取Test::Test(int _a , int _b) : b( _b )这种形式,所以b一定不是const类型,有main()中的t1.b和t2.b的输出都是20可以知道,b是静态变量。






(1.3.3)宏、抽象、内联、构造函数类

内联函数在编译时是否做参数类型检查?
做类型检查,因为内联函数就是在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来代替。



以下叙述中错误的是?
  • 数值型常量有正值和负值的区分
  • 常量可以用一个符号名来代表
  • 定义符号常量必须用类型名来设定常量的类型
  • 常量是在程序运行过程中值不能被改变的量
可以使用红定义来确定一个常量,宏定义不需要指定类型名,宏定义是一个符号名



若有定义 
1
2
typedef  char T[ 10 ] ; 
T * a ; 
上述定义中a的类型与下面选项中完全相同的是?


  • char a [ 10 ] ;
  • char ( *A) [ 10 ] ;
  • char * a ;
  • char *a [ 10 ] ;
T b;
相当于 char b[10];
相信大家对这个没啥意见吧
那么,
T *a;
也就是一个指针a指向了一片空间,空间连续,并且以T为基本单位


以下代码的输出结果是?

1
2
3
4
5

你可能感兴趣的:(C语言基础类错题)