标题: 嵌入式开发—C语言面试题 [打印本页] 作者: Hh0203 时间: 2016-5-9 14:47 标题: 嵌入式开发—C语言面试题 嵌入式开发—C语言面试题 s, Z7 P1 J$ M/ [% Q1 i/ Q2 y
1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)6 R7 C) B! M4 i, P
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL+ T1 Q3 j, \* ?1 _6 C, L
我在这想看到几件事情: 7 \- H" X) Y' N, M9 ~) h1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)( d8 I6 W6 o& w5 _. t" [% H
2). 懂得预处理器将为你计算常数表达式的值 ,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。 ( b: j" r8 u. E. e) I3). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。4 p0 U5 Q Q% ]# G; B( A) D9 U
4). 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。* P/ |% p9 Y# Y) j% n' j. B4 {0 N
7 n( E' G0 g5 B4 e- R4 K0 U2. 写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。 g- g# `7 s9 m, c1 M0 d7 N
#define MIN(A,B) ((A) <= (B) (A) : )) / o9 p$ [4 G* X, u8 [1 z0 {7 ~1 ]& h
这个测试是为下面的目的而设的:! ^$ a' V/ u6 ^, B! s3 r& L1 z# T4 B
+ B3 h. D8 K4 [( R/ a5 q
1). 标识#define在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准C的一部分,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。0 R! [0 r; P" t* C9 H$ I8 ?
2). 三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。 / r8 x8 H6 m( v! m3). 懂得在宏中小心地把参数用括号括起来 3 D/ S% ?% a) |# }' ^5 G ~, ]. W4). 我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?! L( p9 |! h7 n% a( o5 B
least = MIN(*p++, b); 9 ~2 a. [# x: Z - P7 D! _" |2 t) W3. 预处理器标识#error的目的是什么?/ B* L8 H d! @
# d% Y* r+ B& i: A2 W
如果你不知道答案,请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种( O" {/ ^0 W5 d# V ?0 X
问题的答案。当然如果你不是在找一个书呆子,那么应试者最好希望自己不要知道答案。5 W9 ]8 t t$ ^$ U" a
& _4 a1 N/ \4 l0 P6 X; u3 S7 Q
死循环(Infinite loops) 5 C+ f, c x" v5 @- H- V, e6 Q, F4 h" ]6 {: o/ e `3 n; x& U
4. 嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?1 W$ o& @9 B |) A M2 M# u
. U, K( h4 K y( o- g. m, k9 N
这个问题用几个解决方案。我首选的方案是:' ~ k6 U- X7 a) c+ `' ^9 q
while(1) { }* `: i* H, \3 n8 H Z
一些程序员更喜欢如下方案:1 x. A* z p v( u0 P, k( q
for(;;) { } 7 W( `( M% o1 |) w0 V* n% f这个实现方式让我为难,因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案,我将用这个作为一个机会去探究他们这样做的 $ D0 I9 W/ `1 \基本原理。如果他们的基本答案是:“我被教着这样做,但从没有想到过为什么。”这会给我留下一个坏印象。, R7 l2 m: P: Q) K# u
第三个方案是用 goto 3 u/ p0 u: ^( e0 \0 U' lLoop:/ r( o: ?; d) Z! l8 q8 W
... ! O& V7 c' X" U, X" Z- r! Rgoto Loop; C, T8 B- ^3 Y* X应试者如给出上面的方案,这说明或者他是一个汇编语言程序员(这也许是好事)或者他是一个想进入新领域的BASIC/FORTRAN程序员。- [) k" W9 j. `' C" N
* x4 U$ B7 C1 ]# w% [. R数据声明(Data declarations)' j5 `7 Z8 O' L, M3 D2 |
; C: @$ G2 o1 M: g$ X
5. 用变量a给出下面的定义 $ W& u# \0 _7 p- o: v$ za) 一个整型数(An integer) ' j) Q. t3 R# T9 \. Wb) 一个指向整型数的指针(A pointer to an integer)9 _3 P2 s6 ]0 v% {; [ x1 F
c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer) 4 D5 I! r, m( b8 I/ Ad) 一个有10个整型数的数组(An array of 10 integers) 6 w2 P* Y' g0 t! k* Qe) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)6 e6 S* E, P- p! A( v- Y$ n' I# ?
f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers) ( s8 V4 [7 m2 w" q0 yg) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)' \& ]- H+ M5 l2 j: T; g: D
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer ) 2 }" O3 D; v& K 6 O+ N9 [/ H( y0 ?答案是: ; }9 }; c; P5 A9 |7 f( G- ra) int a; // An integer * u# U' S4 i6 h; C) I* Rb) int *a; // A pointer to an integer . x0 F6 H' Z3 {; C. p! a9 I% w% Oc) int **a; // A pointer to a pointer to an integer % S8 _0 Y/ [" ld) int a[10]; // An array of 10 integers 6 p1 Q1 o( ^5 je) int *a[10]; // An array of 10 pointers to integers: b1 e. _& ^$ {
f) int (*a)[10]; // A pointer to an array of 10 integers" Z' [" {5 W2 i5 a. W6 ]; z1 c! r; U
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer. k% E/ u: q$ x$ p2 z$ }4 w3 a
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer " x; I/ ]; j# t ( g4 v' y2 t: k人们经常声称这里有几个问题是那种要翻一下书才能回答的问题,我同意这种说法。当我写这篇文章时,为了确定语法的正确性,我的确查了一下书。 & e8 t# a n9 }$ g2 c f! I$ W4 y但是当我被面试的时候,我期望被问到这个问题(或者相近的问题)。因为在被面试的这段时间里,我确定我知道这个问题的答案。应试者如果不知道 4 u/ v x: ?2 N6 R$ t' M所有的答案(或至少大部分答案),那么也就没有为这次面试做准备,如果该面试者没有为这次面试做准备,那么他又能为什么出准备呢? j1 e2 Y; J. |
' f- b6 a+ v( wStatic5 x4 ~+ T9 C1 m' `% \
E/ d3 h# a. e: o' v
6. 关键字static的作用是什么? / w* X7 O/ d3 a( L! ?( A4 j( v. I; ?0 K- O7 W# m
这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:* A% c( X" q1 s* }2 Z: }2 E
1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 ( S% g4 q: f/ U* ^/ x8 ]3 x2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。 * n; H% b! {' b% d0 f" R+ b3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。$ j/ Y2 w& L3 b+ m6 b. m
大多数应试者能正确回答第一部分,一部分能正确回答第二部分,同是很少的人能懂得第三部分。这是一个应试者的严重的缺点,因为他显然不懂得本地化数据和代码范围的好处和重要性。0 \7 W& v" o2 r, l- | f
! _! a0 q" p) g x
Const * ?( _" T) I6 C1 H ! O |# i, c' @) C( |1 [1 W7.关键字const是什么含意?) m0 z7 D2 Y' {: _# M
我只要一听到被面试者说:“const意味着常数”,我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.. ]/ Q/ K" b7 j( r; a
如果你从没有读到那篇文章,只要能说出const意味着 “只读”就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。)如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思?1 u3 T% ~. A" q
+ @& R' `+ x. t3 x+ w3 tconst int a;4 u4 I) Y; | k1 x5 j5 \8 |- v
int const a;; G* T: i: {* H1 H
const int *a; 4 C6 o* I* U- Y0 ^; Bint * const a;& ?* |7 q' m. c p. X
int const * a const;: j: s* {$ f6 g) t- y
* ~9 w3 h p/ e% L, y+ y7 h- h2 o前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字 const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由: 2 g" w/ d7 P, F* `7 P2 |1). 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)6 u: I* M; T9 k7 F! P3 G) K
2). 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。 # t0 y2 ]' k, b6 g' [3). 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。; d9 S' v0 e: Z: d
6 B; J: N9 K6 _7 a) p5 r! q}9 U5 @# R1 ^' Q# M- o0 K4 ?" l
% T/ g! G6 ?5 `- J3 [9 U0 W
Answer:empty string. 6 H6 W; u# m% A 0 I I' w& ~7 Y T5 f1 Q4 D" HWhat will be printed as the result of the operation below: " F q+ Y1 J% H* N1 i# O/ d3 Y' T# S3 p1 h
main()! n7 R Z S2 E( ~2 W
{ int x=20,y=35;' e3 }$ _; d% ], `+ ]% u
x=y++ + x++;. t; f; d" c7 E( @" i+ f6 B, |
y= ++y + ++x; 4 T/ J# I1 x) _# Vprintf(“%d%dn”,x,y); 1 v5 T' Z, k' s) D}7 d0 E9 u8 `* ?5 s' t
' W. u8 {4 V6 h& L; [Answer : 5794 6 u* V! Y" t, u! [3 C( t' h0 D, _( r+ ]+ j
What will be printed as the result of the operation below:+ _( N2 {3 _# Y8 o) b4 m
$ P& N, v/ U+ h: v& k$ _8 kmain()! W- l; G- M } b7 ~
{ int x=5; ' F# j; O9 G" |& r1 b. ? c$ E& u/ Jprintf(“%d,%d,%dn”,x,x< <2,x>>2);3 C: a2 t( h, ?3 b: V
} 4 ]2 d. |$ C$ \2 g& p 5 X1 Q* G8 N9 Y- A" @( D% ]Answer: 5,20,19 E5 E7 Q. ^- A* Y$ K& {
8 b) T# Z) N3 @
What will be printed as the result of the operation below: ( k+ z+ r* M2 l% _$ v2 O# U% f! i$ z0 Y c
#define swap(a,b) a=a+b;b=a-b;a=a-b;! K' |+ \& Q! v( t9 Y: E; l% n
void main() y) w4 H; W: ]+ h% X* S" ^{ int x=5, y=10; 2 z3 [) d: ^- @6 e6 Zswap (x,y);3 R* v1 n/ r: j3 k; B }1 v
printf(“%d %dn”,x,y);+ R" K7 m) S$ u
swap2(x,y); % Q9 c, h4 R4 n, [& o, {' Eprintf(“%d %dn”,x,y); 7 _& n3 T4 i( a. P: P7 o* q4 L}0 b+ R6 `1 y. @; g0 G, z. Y' l4 z9 c
% r2 j5 e' c) E' o6 Z- i' jint swap2(int a, int b) ; r" x; r" z6 m P; V' P) k1 T{ int temp;4 G5 M8 j% o- d
temp=a;" ]% _& y$ a2 j( f
b=a;: [1 t: y+ B* E
a=temp;( E$ ]. q: k& i& v) x
return 0; " y% ?$ [7 J9 f& [# h) q$ _/ J / h/ p. n/ K6 W}, L, t, z/ R3 m' }
3 Z" |; |- h, E& X7 ]
Answer: 10, 5 $ n7 ~5 v; P# {0 b6 I10, 5 / _; i% c3 H- d ; ], l- o/ c- {$ k, u# }What will be printed as the result of the operation below: & S5 r4 s: Y& A; ~: `2 A+ [2 B( C5 T, j" C+ i
main(); r. X' D. E" r! N- `
{ char *ptr = ” Cisco Systems”;! E) V b9 a" g+ d! \8 |, g
*ptr++; printf(“%sn”,ptr);7 t: e2 l1 u" }. s
ptr++;; \3 v' G9 ^3 r+ a# ]0 R" E# }
printf(“%sn”,ptr); ! ?2 J5 R* j; g. V5 M/ `} 8 {. ~4 Z3 {5 E1 q: r+ [1 A* _ ] f: b4 }7 s% ~6 }' m
Answer:Cisco Systems # h3 L' k! f* `& P# Uisco systems- N. [- F: |6 p Y: k8 ]
1 N( o; V; Z$ g9 z5 WWhat will be printed as the result of the operation below:. p4 D5 A; W$ S# I8 q' x* \5 B
2 Z$ |' c( K1 z8 U2 T3 X# c
main() - w& C7 @3 _$ i4 m6 ^ T{ char s1[]=“Cisco”;1 _4 ]2 U: D6 {5 a
char s2[]= “systems”;0 [: e$ U8 {/ A
printf(“%s”,s1); + [6 k+ G9 m4 U, g1 H} Answer: Cisco+ v' o* A8 H y4 ?; \8 a! M
( d+ ~# Z& A! S1 V2 ?' }What will be printed as the result of the operation below: d5 B' Y: d) e( U+ T$ a
4 x+ e! A2 j6 X( G& }* x
main() ' u. }* r- Z- a2 e9 K% M{ char *p1; 7 e) x1 I- e0 ?" [: Qchar *p2;2 M. R6 T1 x {6 ?! L
p1=(char *)malloc(25); , `- E! W# x# ?* L* ~4 Jp2=(char *)malloc(25);) a6 J) C% i1 E, Z! z6 W& R; m- \) Q
) m0 W# I9 ^" R T9 {
strcpy(p1,”Cisco”); 9 E6 q( H9 A/ _- Lstrcpy(p2,“systems”);- v- M' O) e: ^1 v# F+ Q" ?
strcat(p1,p2); + a$ W9 J2 B: q- H- R* h4 X( S% r h- ^, h$ ]# x
printf(“%s”,p1); 9 M7 R6 E5 [! r0 S1 x# u+ m0 u/ |* D6 L1 _
} 4 f1 B5 R A1 o ^ ; }4 _1 Y9 X, z, v- pAnswer: Ciscosystems/ o( I: T1 B2 u$ `+ B3 [2 e( X
9 R" S4 c/ Y& K8 u9 h
The following variable is available in file1.c, who can access it?: E3 p* {2 }- H% F" {8 N9 n0 A @$ f
static int average;1 l5 \! X% l3 D0 h7 Q
: b( S$ k) V) V
Answer: all the functions in the file1.c can access the variable. " p! s1 }& {1 [) g9 N5 D: F8 P: ^* Z1 O2 x& a5 J8 g6 L" G% n
WHat will be the result of the following code? 3 n8 ]0 H- u$ ?/ [0 A; M8 i( M q0 @. R, |: D$ G- n; o5 y
#define TRUE 0 // some code ; N! w3 j2 W2 ]/ j! B8 s- `! T$ awhile(TRUE) " H% W, y4 E) G1 z/ i) }{ 5 p3 @7 ^ m3 K9 y+ ] " M0 z, C( U& o7 u1 G( _// some code+ f! _# J7 d" A4 I# l
9 q; z& u- Q2 ]} ! |$ Z! A! B1 i+ O/ T% m) ~; f5 A/ l
Answer: This will not go into the loop as TRUE is defined as 0.4 a& N' x" Z* \: f' `! r
: Y6 e" \8 K+ rWhat will be printed as the result of the operation below: 7 V* W3 n2 U3 W- p5 p) U $ H4 S3 J/ y$ u, K( P! {9 Aint x; - f5 A: ^* W; X( n3 S1 Rint modifyvalue()2 p. S5 u" e0 O# D6 c8 d
{ return(x+=10); m6 N# Z/ E1 W1 U' O* I} int changevalue(int x) " v+ b9 Q3 V6 j% p# S{ return(x+=1);) B* a2 \. a) @ j# Q; S
}6 F9 a* A$ c, D# v N5 N
; F! v: q& j/ \" R
void main() ( n* P4 a/ y2 w+ T% I: f{ int x=10;) K$ b" x* Q; T$ U
x++;7 O0 i6 H# L3 K& r H% w4 c/ _
changevalue(x);0 O9 {! S) Z/ T1 }
x++; " j, q3 r F9 B9 e# S+ ?4 jmodifyvalue();4 x% \, c# O6 U* p4 s6 v! H2 W
printf("First output:%dn",x); : s1 o& i, c1 s1 e ) S% [# N3 g! q6 ?: `3 Ox++; ; r5 Y- T1 A, k/ w. e Y& b, h4 H( wchangevalue(x);8 x: c% E% U) N% ^; m. F% I
printf("Second output:%dn",x); , y! L" N! R0 N3 s' K% gmodifyvalue(); j1 _/ H' v7 p. ^5 E1 uprintf("Third output:%dn",x);% U" s% M3 b, W! }0 v7 x- i
9 [$ G2 Q5 c: O, `# [% X2 b}7 a# t. X4 P1 \3 F, G0 m( L
+ d2 c9 S. Y# @8 {, wAnswer: 12 , 13 , 13 % M3 q) k# I% W+ Q: _3 m8 ^ 2 u2 @+ K% \, k, d! k& EWhat will be printed as the result of the operation below:3 }! g# H/ d2 I# e/ X- ~+ X/ ]
3 o2 R5 M, v$ `1 Q2 w8 rmain()- k/ p8 T6 U+ [/ l+ e Y$ b
{ int x=10, y=15; 0 ?8 `* R, \6 L( D6 l& J6 Ix = x++; & L/ [4 [' h, A8 Uy = ++y;2 d8 H$ b) D; z- ^
printf(“%d %dn”,x,y);& g+ G0 E# a+ }: E
} `9 W0 h3 m- T& l5 p l$ x, u1 @