C语言面试专用题库

1.为了判断两个字符串s1和s2是否相等,应当使用___ D_____

A. if(s1==s2)      B. if(s1=s2)        C. if(*s1==*s2)      D. if(strcmp(s1,s2)==0)

解答: 字符串的比较只能用库函数: strcmp(),在C++中可以通过重载操作符来达到字符串的比较.

2.若a为二维数组,它有m列,则a[i][j]在数组中的位置是____ D____

A.i*m+j       B. j*m+1         C. i*m+j-1       D.i*m+j+1

解答: :如果i和j的同时为零的情况下,则a[0][0]在数组中的位置是第一个,所以可以先排除A和C

   a[i][j]中, i为一维的番号也就是列号,所以i成指数增长.

3.非空的循环单链表head的尾结点(由p所指向)满足___C_____

A.p->next == NULL   B. p == NULL      C. p->next== head    D.p == head

解答: :尾结点的下一个结点应该指向头结点.这样才可以构成循环链表.

4.函数foo的声明如下

intfoo(int *element1, int element2);

p是指向foo的函数指针,正确的声明是____A____

A.int (*p)(int * ,int);           B. int *p(int * ,int);    

C.(int *)p(int * ,int);                D. (int *p)(int * ,int);   

解答: :正确是函数指针的申明方法是选项A, B是指针函数,函数的返回值是指针.选项CD的申明是错误的.

5.若a为二维数组,则a[5][6]等价于____B____

A.*((a+5)+6)        B. *(a[5]+6)          C. (*(a+5)+6)       D. &a[5]+6

解答: : a是二维数组的首地址,也可以把他看成是二维数组的列指针.a[5]等价于*(a+5),二维数组的场合, a[5]就变成了行指针了. 所以a[5][6]就等于*(*(a+5)+ 6),所以B是对的.

   选项A, (a+5)是先把指针移动到第五列的首地址,然后在加六的时候,该指针就已经越界了.

选项C, *(a+5)就是第五列的首地址对应的值,然后加六,行指针指向第五列的第六个元素,但是它是一个地址,不等于地址里面的值.

选项D, a[5]二维数组的行指针,然后加上地址符后就是二维数组的行指针的地址.

6.执行for(j=1; j++ < 5; );语句后变量j的值是___ C_____

A.4            B. 5             C. 6           D. 不定

解答: : 这道题考的是先加加和后加加的区别, j++ < 5是先比较大小,再加1,而条件语句j=5的时候,不成立而退出循环

7.设有int a[]={3,4,5},*p=&a[0];则执行完*p++;*p+=1;后a[0],a[1],a[2]的值依次是__B____

A.3,4,5        B. 3,5,5    C. 4,5,5         D.4,4,5

解答: *p=&a[0]等于*p=a;就是把数组的首地址赋值给指针. *p++使指针指向4, *p+=1使指针指向的4加1等于5。*p++中,先执行++操作,移动位置,然后再将星号作用与上面。

8.下列main函数,哪些是正确的___BC_____

A.int main(int arge, char* argv);       B.int main(int arge, char* argv[]);  

C.int main(int arge, char** argv);      D.int main(int arge, char** argv[]);

解答: : main函数必须有一个返回值int,有0个或者2个参数.第2个参数是字符串数组.选项A第2个参数只是字符串的首地址,选项D第2个参数相当与int main(int arge,char*** argv).所以也不对.

9.对以下声明:

  const int*cip;

  int* constcpi;

  int i;

  int *ip;

  允许下面哪些赋值?________

A.cip = ip;          B. cpi= ip;             C. *cip = i;        D.*cpi = i;

解答: : const int *cip;是指针指向的值是只读的,选项C改变了指针所指向的值,所以不对.

    int* const cpi;是指针是只读的,而指针指向的值是可以改变的, 选项B改变了指针的值,所以不对.

ip只是对指针进行了声明,故而它只是野指针。野指针赋值给cip,cpi,都会出现运行时错误。所以A和B都不对

i的值也是一样,没有进行初始化,所以给赋值的时候,也会报出运行时错误。所以C和D也都不对

10.对以下结构体:

  struct S{

     char name[10];

     doublevalue;

};

在32位机器(假设char类型占用1字节,double占用8字节)上进行sizeof(S)的运算,以下哪些值是可能的___ABC_____

A.18           B. 20                C. 24               D.9

解答: : #pragma pack (1)按照1字节对齐的时候, sizeof(S)的值等于18

#pragmapack (2)按照1字节对齐的时候,sizeof(S)的值等于18

     #pragma pack (4)按照1字节对齐的时候, sizeof(S)的值等于20

#pragmapack (8)按照1字节对齐的时候,sizeof(S)的值等于24

11.以下说法正确的有____C____

  A.一个数组能够存储许多不同类型的值。

  B.如果初始化值列表中的初始化值的个数少于数组元素个数,

    编译器会自动把剩余的元素初始化为初始化值列表中的最后一个值。

  C.函数fscanf不能从标准输入流读取数据。

  D.函数fprintf能够把数据写入标准输入流。

解答: :选项A,一个数组是不能够存储许多不同类型的值的.

选项B,如果初始化值列表中的初始化值的个数少于数组元素个数,这个时候编译器会自动把剩余的元素初始化为0,当然不同的编译期可能会有不一样的情况.

选项D,fprintf函数的作用是传送格式化输出到一个文件中,写入应该不是输入流而是输出流.

12.vp的类型是void *,ip的类型是int *,下列哪些赋值语句是有效的____A____

A.vp = ip;     B. *vp = ip;              C. *vp = *ip;       D. *ip = *vp;

解答: : 选项A,把一个int型的指针的地址赋值给一个空指针是可以的,但是反过来的时候,就不行了. 反过来的时候必须要先把空指针强制转化一下.

    选项BC,是错误的.把指针变量赋给*vp空指针指向的东西,空指针指向的地址是什么类型都不知道,是不能赋给他一个指针或者一个值的

选项D,是错误的.给*vp空指针指向的东西是什么值还不知道,32位系统下,如果是4个字节,如果是2个字节,他们所对应的值是不一样的.所以编译的时候会在这里报错.

13.以下释放单向链表所有结点一和内存的操作,正确的是___C_____

  head为链表头结点的指针,p及t均是指向链表结点的指针。

A.for(p = head ; p ; p = p->next){

  free(p);

}

B.p = head;

   do{

  free(p);

}while(p= p->next);

C.for(p = head ; p ; ){

   t = p->next;

  free(p);

p = t;

}

D.p = head;

   while(p = p->next){

  free(p);

}

答:: 选项D是错误的,因为它没有释放(free)he ad 指针所指向地址.

14.以下指针使用正确的是____BCF____

  intAllocMemory(char** lppMem)

  {

char*lpTemp = (char*)malloc(100);

if(lpTemp== NULL){

*lppMem= NULL;

return1;

}else{

*lppMem= lpTemp;

return0;

}

}

  A. char*lpMemAlloc;

     AllocMem(lpMemAlloc);

  B. char**lpMemAlloc;

     AllocMem(lpMemAlloc);

  C. char*lpMemAlloc;

     AllocMem(&lpMemAlloc);

  D. charMemAlloc[10];

     AllocMem(MemAlloc);

E.char* MemAlloc[10];

     AllocMem(MemAlloc[0]);

F.char* MemAlloc[10];

     AllocMem(&(MemAlloc[0]));

G.char* MemAlloc[10];

    AllocMem(*(MemAlloc[0]));

解答:: 选项A是错误的, AllocMemory的参数是指针的指针,所以MemAlloc应该也是指针的指针.

选项B是指针的指针,所以没有什么大问题

选项C中lpMemAlloc是指针,但是在引用函数的时候加了地址符,所以没有什么问题

选项D 不行,因为他的实参是一个一维函数的首地址.

选项E 不对,因为MemAlloc[0]就变成了行地址的指针了

选项F 是正确的

选项G 不对,因为*MemAlloc[0 ] 已经是二维数组的第一个元素.

15.以下程序段正确的有____ B____

A.int f1(int val)

  {

int *ptr;

int val;

if(val == 0){

    val =5;

    ptr =&val;

}

return(*ptr + 1);

}

  B. int ints[11],*ptrs[10],i;

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

    ptrs[i] = &ints[i];   

  C. int a;

     scanf(“d%”, a);

  D. typedef PCHAR char*;

解答:选项A,如果val重定义了.还有如果val等于0的时候,会返回栈指针.

选项C 少加了一个地址符.

    选项D typedef char* PCHAR;才是正确的.位置放错了.

选项B是正确的,但是int ints[11]最好也要初始化一下.

16.以下程序在Big-endian和Little endian的机器上输出分别是____D____

 #include<stdio.h>

  main(){

inti = 0x12345678;

if(*(char*)&i == 0x12)

     printf(“Hello”);

elseif(*(char *)&i == 0x78)

     printf(“Welcome”);

}

A.Hello和Hello       B. Welcome和Welcome    C. Hello和Welcome      D.Welcome和Hello

解答: big endian是指低地址存放最高有效字节(MSB),而little endian则是低地址存放最低有效字节(LSB)

big endian:最高字节在地址最低位,最低字节在地址最高位,依次排列。
little endian:最低字节在最低位,最高字节在最高位,反序排列。

17.以下程序的输出是什么____-1____。(3分)

  int a = 0;

  if(--a)

      printf(“d%”,a++);

  else

      printf(“d%”,a--);

解答:这题目就是考C语言++和--,--a是先执行减减操作后,IF语句就成立,于是走了if分支

    a++是先执行输出,然后再执行++,所以输出是-1

当然这题目还是有错误的.

错误: printf(“d%,a--);

正确: printf(“%d,a--);

18.下列程序执行完毕后,sum的值是___3_____。(3分)

  int i ,sum= 0;

  for(i = 0; i < 12; i++){

      switch(i){

case0: case 1: case 3: case 5: sum++;

default:continue;

case4: break;

}

break;

}

解答:这题目就是考C语言表达式的执行顺序.当循环中i等于0,1,3的时候,sum会加1.由于没有break,所以0,1,3的时候都是会执行到default:continue的.当循环中i等于2的时候, sum的值不会改变.当循环中i等于4的时候,循环终了.所以这个时候sum等于3.

19.有以下函数:

intfoo(int m)

{

intvalue;

if(m== 0) value = 4;

else value =foo(m - 1) + 10;

  return value;

}

执行语句printf(“d%\n” ,foo(6));的结果是____64____。(3分)

解答:这道题目考的是递归.

    m = 0 的时候foo的返回值是4

    m = 1 的时候foo的返回值是14

m = 2 的时候foo的返回值是24

    m = 3 的时候foo的返回值是34

    m = 4 的时候foo的返回值是44

m = 5 的时候foo的返回值是54

m = 6 的时候foo的返回值是64

20.POSIX线程库中创建线程的函数是___pthread_create()_____。(2分)

解答:函数的原形

int pthread_create( pthread_t* thread, const pthread_attr_t* attr, void*(*start_routine)(void* ), void* arg );

21.写出下列语句返回的x值

  ① x = fabs(-7.5);                           ___7.5_____。(2分)

② x = ceil(fabs(-8 + floor(7.5)) + 2.5);    ____4.0____。(2分)

解答:函数名double fabs( double x );

  用法:#include<math.h>

  功能:求浮点数x绝对值

函数名: floor

  功 能: 返回小于或者等于指定表达式的最大整数

  用 法: double floor(double x);

  函数名:ceil

  用 法:double ceil(double x);

  功 能: 返回大于或者等于指定表达式的最小整数

22.fp是文件指针,写出将fp定位到文件末尾的语句_______fseek(fp,0L,SEEK_END);_________________。

23.下列gcd函数计算两个正整数的最大公约数,请完成程序。

  unsigned gcd(unsigned x, unsigned y)

{

while(y!= 0){

    unsigned temp = y;

    y = ___ x % temp_____;

x= temp;

}

    return x;

}

解答:这道题目考的是算法, x % temp是取余, 取余剩下的数Y如果不等于零,则一直进行循环,

24.以下函数用来打印输出斐波那契数列,请完成程序。

#include<stdio.h>

#defineMAX 65000

voidfibonacci(int max)

{

intv1 = 0, v2 = 1,cur, ix;

if(max< 2) return;

    printf(“0 1 ”);

for(ix= 3; ix <= max; ++ix){

    cur = v1 + v2;

    if(cur > MAX) break;

    printf(“d% ”,cur);

    v1 = v2;

____v2 = cur;____________;

    if(ix %12 == 0) printf(“\n ”);

}

     }

}

解答:这道题目考的是算法, 这个数列从第三项开始,每一项都等于前两项之和。

25.reverse_bits函数的返回值是把value的二进制位模式从左到右变化一下后的值。例如,在32位机器上,89这个值包含下列各个位:

  00000000000000000000000001011001

  函数的返回值应该是2,583,691,264,它的二进制位模式是:

10011010000000000000000000000000。(6分)

unsignedint reverse_bits(unsigned int value)

{

unsignedint answer;

unsigned inti;

 

answer = 0;

for(i= 1; i != 0; ______){

answer<<= 1;

   if(value& 1)

       answer= 1;

       value______;

}

returnanswer;

}

unsignedint reverse_bits(unsigned int value)

{

  unsigned int answer;

  unsigned int i;

  answer = 0;

  for(i = 1; i != 0; i<<= 1){i向左移动一位,因为初始值是1,所以当移动了32次以后,就变成0了,也就可以退出循环

       answer <<= 1;

       if(value & 1){

            answer +=1;  这里是原来的题目错了,原来的题目是没有正确结果的

       }

       value >>=1; 移动一位,把value从最低位开始一位一位的确认.

  }

  return answer;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的横打

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值