C语言经典面试题100道(校对详解版) 您所在的位置:网站首页 酒店案例分析题100条及答案大全 C语言经典面试题100道(校对详解版)

C语言经典面试题100道(校对详解版)

2024-07-09 08:44| 来源: 网络整理| 查看: 265

题目非本人整理,转载于https://blog.csdn.net/qq_42613510/article/details/81225935 做了校对与详解,方便大家参考。最后编程答案自己做的,还没写完,可能不全,需要自己百度答案。 有什么问题请评论,会及时修改,避免误导大家。

1.请填写bool , float, 指针变量 与“零值”比较的if语句。 提示:这里“零值”可以是0, 0.0 , FALSE 或者“空指针”。 例如int 变量 n 与“零值”比较的 if 语句为: if ( n = =0 ) if ( n != 0 ) 以此类推。 (1)请写出bool flag 与“零值”比较的if 语句:

答案:if ( flag ) ; if ( !flag )

(2)请写出float x 与“零值”比较的if 语句:

答案: const float EPSINON = 0.00001; if ((x >= - EPSINON) && (x =” 或“ long i; int k[5]; char c; } DATA; struct data { int cat; DATA cow; double dog; } too; DATA max; 则语句printf("%d",sizeof(struct data)+sizeof(max)); 的执行结果是:_____

答案:DATA是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20,data 是一个struct, 每个变量分开占用空间. 依次为int4 + DATA20 + double8 = 32.所以结果是20 + 32 = 52. 当然… 在某些16位编辑器下, int 可能是2字节,那么结果是int2 + DATA10 + double8 = 20 2022-12-28:这道题比较有争议,重新解释一下。 32位下: sizeof(DATA) = 20 sizeof(struct data) = 32 执行结果:52 解析: DATA中最大内存变量为数组k,占用20个字节,超出了32位下操作系统基本字节单位(4),所以4字节对齐,但是对齐后还是20。struct data中int占用4个字节,DATA占用20个字节,double占用8个字节,一共32个字节,刚好也可以4字节对齐,所以最终为32。它们相加为52。 64位下: sizeof(DATA) = 24 sizeof(struct data) = 40 执行结果:64 DATA中最大内存变量为数组k,占用20个字节,超过了64位下操作系统基本字节单位(8),所以8字节对齐,最后为24。truct data中int占用8个字节,DATA占用20个字节,double占用8个字节,一共36个字节,8字节对齐后为40,其中补齐的4个字节在DATA后面。最终它们相加等于64。 另外,以上是在ubuntu18.04下使用系统自带GCC编译器实验的。实际我在windows10下使用x86_64-w64-mingw32指定 -m64 编译64位程序仍旧和 -m32 下一样,可能还是和编译器有关。

6.请问以下代码有什么问题: int main() { char a; char *str=& a; strcpy(str,"hello"); printf(str); return 0; }

答案:没有为str分配内存空间,将会发生异常问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。

7.请问以下代码有什么问题: char * s ="AAA"; printf("%s",s); s[0]='B'; printf("%s",s); 有什么错?

答案:“AAA” 是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。cosnt char * s =“AAA”;然后又因为是常量,所以对是s[0] 的赋值操作是不合法的。

8.int (*s[10])(int) 表示的是什么

答案:int (*s[10])(int) 函数指针数组,每个指针指向一个int func ( int param) 的函数。(或一个有10个指针的数组,每个指针指向一个函数,该函数有一个整型参数并返回一个整型数)

9.c和c++ 中的struct有什么不同?

答案:c和c++ 中struct的主要区别是c中的struct不可以含有成员函数,而c++ 中的struct可以。c++ 中struct和class的主要区别在于默认的存取权限不同,struct默认为public ,而class默认为private

10.void getmemory(char *p) { p=(char *) malloc(100); strcpy(p,“hello world”); } int main( ) { char *str=NULL; getmemory(str); printf(“%s/n”,str); free(str); return 0; } 会出现什么问题?

答案:程序崩溃,getmemory中的malloc 不能传递动态内存,所以str一直是NULL,free ()对str操作很危险。

11.char szstr[10]; strcpy(szstr,"0123456789"); 产生什么结果?为什么?

答案:长度不一样,出现段错误。字符串多一个’\0’结束符。

12.数组和链表的区别?

答案: 数组:数据顺序存储,固定大小; 链表:数据可以随机存储,大小可动态改变。

13.void main() { char aa[10]; printf(“%d”,strlen(aa)); } 会出现什么问题?打印结果是是多少?

答案:sizeof()和初不初始化没有关系,strlen()和初始化有关,打印结果值未知。

14.给定结构 struct A { char t:4; char k:4; unsigned short i:8; unsigned long m; }; 问sizeof(A) = ?

答案:8 详解:char t:4;是代表使用位域结构,表示使用char的其中四位,char k:4;刚好可以把剩下四位用掉(假如不够则要重新使用一个char),所以一共是char(1)+short(2)+long(4)=7,字节对齐(char和short占一个字节,long占一个字节)后为8。

15.struct name1 { char str; short x; int num; } ;求sizeof(name1)?

答案:8 详解:char(1)+short(2)+int(4)=7,字节对齐(char和short占一个字节,int占一个字节)后为8。

16.struct name2 { char str; int num; short x; }; 求sizeof(name2)?

答案:12 详解:char(1)占第一个字节中的1,第一个字节剩下3不够int(4),所以为了对齐,重新用一个字节,int(4)刚好占满这第二个字节,所以short(2)又要重新用一个字节(其实只用了前2),一共是4+4+4=12。

17.程序哪里有错误 wap( int *p1,int *p2 ) { int *p; *p = *p1; *p1 = *p2; *p2 = *p; }

答案:申请p的时候没有初始化,所以p为野指针。

19.(void *)ptr 和(*(void**))ptr 的结果是否相同?其中ptr为同一个指针。

答案:(void )ptr 和((void**))ptr 值是相同的 详解:个人理解,void前面的*是取该地址内容的,所以本质一样。

20.要对绝对地址0x100000赋值,我们可以用 (unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?

答案:((void ()( ))0x100000 ) ( );首先要将0x100000强制转换成函数指针,即: (void (*)())0x100000 然后再调用它: ((void ()())0x100000)();

27.关键字volatile有什么含意? 并给出三个不同的例子。

答案:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: 1). 并行设备的硬件寄存器(如:状态寄存器) 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量

28.嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。

答案:这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast )为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下: int * ptr; ptr= (int *)0x67a9; *ptr = 0xaa66;

29.头文件中的ifndef/define/endif 干什么用?

答案:防止该头文件被重复引用。

30.#include 和 #include “filename.h” 有什么区别?

答案:对于#include ,编译器从标准库路径开始搜索filename.h ; 对于#include “filename.h” ,编译器从用户的工作路径开始搜索filename.h 。

31.const 有什么用途?(请至少说明两种)

答案:(1)可以定义const 常量(2)const 可以修饰函数的参数、返回值,甚至函数的定义体。被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

32.static有什么用途?(请至少说明两种)

答案: 1 限制变量的作用域(static全局变量); 2 设置变量的存储域(static局部变量)。

33.堆栈溢出一般是由什么原因导致的?

答案:没有回收垃圾资源。

34.如何引用一个已经定义过的全局变量?

答案:可以用引用头文件的方式,也可以用extern 关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern 方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

35.全局变量可不可以定义在可被多个.C 文件包含的头文件中?为什么?

答案:可以,在不同的C 文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。

36.队列和栈有什么区别?

答案:队列先进先出,栈后进先出。

37.Heap与stack的差别。

答案:Heap是堆,stack是栈。Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。Stack空间有限,Heap是很大的自由存储区C 中的malloc 函数分配的内存空间即在堆上,C++中对应的是new 操作符。程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行。

38.用宏定义写出swap(x,y),即交换两数。

答案: #define swap(x, y) (x)=(x)+(y);(y)=(x)–(y);(x)=(x)–(y);

39.写一个“标准”宏,这个宏输入两个参数并返回较小的一个。

答案: #define Min(X, Y) ((X)>(Y)?(Y):(X))// 结尾没有 ;

40.带参宏与带参函数的区别(至少说出5点)?

答案:

带参宏 带参函数

处理时间------编译时------- 运行时

参数类型 ----- 无-------------需定义

程序长度 ------变长----------不变

占用存储空间-否 ----------- 是

运行时间-------不占运行时间–调用和返回时占

41.关键字volatile有什么含意?

答案:提示编译器对象的值可能在编译器未监测到的情况下改变。

42.int main() { int x=3; printf("%d",x); return 1; } 问函数既然不会被其它函数调用,为什么要返回1?

答案:mian中,c标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息。

43.已知一个数组table ,用一个宏定义,求出数据的元素个数。

答案: #define NTBL(table) (sizeof(table)/sizeof(table[0]))

44.A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题? 这两个static变量会保存到哪里(栈还是堆或者其他的)?

答案:static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。他们都放在静态数据区,但是编译器对他们的命名是不同的。如果要使变量在其他模块也有意义的话,需要使用extern 关键字。

45.static全局变量与普通的全局变量有什么区别?

答案: 作用域不同,static全局变量只初使化一次,防止在其他文件单元中被引用。

46.static局部变量和普通局部变量有什么区别?

答案:static局部变量只被初始化一次,下一次依据上一次结果值。

47.static函数与普通函数有什么区别?

答案:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。 参考:https://blog.csdn.net/qq_22238021/article/details/79533711

48.程序的局部变量存在于()中,全局变量存在于 ()中,动态申请数据存在于()中。

答案:程序的局部变量存在于栈(stack) 中,全局变量存在于静态数据区中,动态申请数据存在于堆(heap)中。

49.什么是预编译,何时需要预编译?

答案: 1、总是使用不经常改动的大型代码体。 2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

50.用两个栈实现一个队列的功能?要求给出算法和思路!

答案:设2个栈为A,B, 一开始均为空. 入队: 将新元素push入栈A; 出队: (1)判断栈B 是否为空; (2)如果不为空,则将栈A中所有元素依次pop 出并push到栈B; (3)将栈B 的栈顶元素pop 出; 详解:队列:先进先出,栈:先进后出

51.对于一个频繁使用的短小函数,在C 语言中应用什么实现,在C++ 中应用什么实现?

答案:c用宏定义,c++ 用inline

52.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)

答案:#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 详解:UL无符号长整形

53.Typedef 在C 语言中频繁用以声明一个已经存在的数据类型的同义字。 也可以用预处理器做类似的事。例如,思考一下下面的例子: #define dPS struct s* typedef struct s* tPS; 以上两种情况的意图都是要定义dPS 和tPS 作为一个指向结构s指针。 哪种方法更好呢?(如果有的话)为什么?

答案:第二种更好,因为在实际替换中可能出现意想不到的问题。 如: dPS p1,p2; tPS p3,p4; 第一个扩展为struct s * p1, p2;上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。

54.在 C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?

答案:extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言(而不是C++)的方式进行编译。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。

56.语句for( ; 1 ;) 有什么问题?它是什么意思?

答案:死循环,和while(1)相同。

57.do……while和while……do有什么区别?

答案:前一个循环一遍再判断,后一个判断以后再循环。

58.请写出下列代码的输出内容 #include int main() { int a,b,c,d; a=10; b=a++; c=++a; d=10*a++; printf("b,c ,d:%d,%d,%d",b,c,d ); return 0; }

答案:10,12,120 详解: b=a++;可以拆解为 b=a; a++; 所以这一句运行后b=10;a=11; c=++a;可以拆解为 ++a; c=a; 所以这一句运行后b=10;a=12;c=12; d=10a++;可以拆解为 d=10a; a++; 所以最后a=13;b=10;c=12;d=120;

59.unsigned char *p1; unsigned long *p2; p1=(unsigned char *)0x801000; p2=(unsigned long *)0x810000; 请问p1+5= ; p2+5= ;

答案: p1+5=0x801005; p2+5=0x810014;

60.main() { int a[5]={1,2,3,4,5}; int * ptr=(int*)(&a+1); printf(“%d,%d”,*(a+1),*(ptr-1)); } 请问输出:

答案:2,5 详解:a代表数组首地址,即* a=1,* (a+1)=2 &a代表数组指针,其类型为int (*)[5],所以&a+1可以理解为在数组指针的基础上偏移为5,然后强制转换为int类型的指针赋给ptr,所以是下个数组的首地址,ptr-1即为上个数组的最后一位,所以是a[4]=5

61.请问下面程序有什么错误? int a[60][250][1000],i,j,k; for(k=0;k ......; } } 这段代码执行有什么问题?

答案:死循环,因为unsigned char 的取值范围在0~255之间,所以ucCmdNum永远小于Max_CB。

64.嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。

答案:while(1);或者for ( ;1;) ;

67. int x; int modifyvalue() { return(x+=10); } int changevalue(int x) { return(x+=1); } void main() { int x =10; x++; changevalue(x); x++; modifyvalue(); printf("First output:%dn",x); x++; changevalue(x); printf("Second output:%dn",x); modifyvalue(); printf("Thirdoutput:%dn",x); }输出?

答案:12,13,13 详解:modifyvalue()里面的x相当于全局变量x,而不是main()函数内的局部变量x。而changevalue()函数我们可以理解为: int changevalue( int x) { int a; a=x; return(a+=1); } 函数内部参与运算的是形参,所以实参没有改变。

68.不能做switch()的参数类型是:

答案:switch 的参数不能为实型。

69.请写出下列代码的输出内容 #include main() { int a,b,c,d; a=10; b=a++; c=++a; d=10*a++; printf("b,c ,d:%d,%d,%d",b,c,d ); return 0; }

答案:10,12,120

71.一语句实现x是否为2 的若干次幂的判断。

答案: void main() { int a; scanf(“%d”,&a); printf(“%c”,(a)&(a-1)?’n’:’y’); // 若是打印y,否则n } 详解:(a)&(a-1)?‘n’:‘y’;意思是(a)&(a-1)结果为1则输出n,结果为0则输出y

72.中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C 支持中断。具代表事实是,产生了一个新的关键字__interrupt 。下面的代码就使用了__interrupt 关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_area (double radius) { double area = PI * radius * radius; printf(" Area = %f", area); return area; }

答案: (1)中断不能有入参和返回值; (2)在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额外的寄存器入栈,有些处理器/编译器就是不允许在ISR 中做浮点运算。此外,ISR 应该是短而有效率的,在ISR 中做浮点运算是不明智的; (3)与第三点一脉相承,printf() 经常有重入和性能上的问题。

73.下面的代码输出是什么,为什么? void foo(void) { unsigned int a = 6; int b = -20; (a+b> 6)? puts("> 6") : puts("


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有