⾯试常问的16个C语⾔问题,你能答上来⼏个?
作者:绯⽉蓝茵
const的作用最近把基础知识点总结了⼀遍,专门针对⾯试的知识点,⾦三银四不少⼩伙伴在⼯作,这⾥我给⼤家分享⼀下⾯试中经常会遇到的⼀些嵌⼊式C语⾔问题,你看看能答上来⼏个呢? 1
⽤预处理指令#define 声明⼀个常数,⽤以表明1年中有多少秒(忽略闰年问题)
# defineSEC_YEAR (365*24*60*60)UL
考察点:
1.
#define 语法的基本知识(例如:不能以分号结束,括号的使⽤,等等)
2.
懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算⼀年中有多少秒⽽不是计算出实际的值,是更清晰⽽没有代价的。
3.
意识到这个表达式将使⼀个16位机的整型数溢出-因此要⽤到长整型符号L,告诉编译器这个常数是的长整型数
4.
如果你在你的表达式中⽤到UL(表⽰⽆符号长整型),那么你有了⼀个好的起点。记住,第⼀印象很重要。
2
写⼀个"标准"宏MIN ,这个宏输⼊两个参数并返回较⼩的⼀个。
# defineMIN(a,b) ((a)<=(b)?(a):(b))
考察点:
1.
标识#define在宏中应⽤的基本知识。这是很重要的。因为在嵌⼊(inline)操作符变为标准C的⼀部分之
前,宏是⽅便产⽣嵌⼊代码的唯⼀⽅法,对于嵌⼊式系统来说,为了能达到要求的性能,嵌⼊代码经常是必须的⽅法。
2.
懂得在宏中⼩⼼地把参数⽤括号括起来
3.
我也⽤这个问题开始讨论宏的副作⽤,例如:当你写下⾯的代码时会发⽣什么事?
least = MIN(*p++, b);
宏定义的作⽤结果 MIN(*p++,b) ((*p++)<(b)?(*p++),b) 指针p会做两次⾃增操作
如何消除宏的副作⽤
# include<stdio.h>
# definemin_i(x,y) ((x)<=(y)?(x):(y)) //(1)
# definemin_t(type,x,y) ({type _x = x;\ //(2)
# definemin_t(type,x,y) ({type _x = x;\ //(2)
type _y = y;\
_x<_y?_x:_y;\
})
# definemin(x,y) {const typeof(x) _x = (x);\ //(3)consttypeof(y)_y = (y);\
( void)(&_x=&_y);\ //(4)
_x<_y?_x:_y;\
})
intmain
{
inta = 10;
intb = 20;
printf( "min_i(a++,b++)=%d\n",min_i(a++,b++)); //11 printf( "a=%d\n",a); //12
printf( "b=%d\n",b); //21
a= 10;
b= 20;
printf( "min_t(int,a++,b++)=%d\n", min_t( int,a++,b++)); //10 printf( "a=%d\n",a); //11
printf( "b=%d\n",b); //21
a= 10;
b= 20;
printf( "min(a++,b++)=%d\n",min(a++,b++)); //10
printf( "a=%d\n",a); //11
printf( "b=%d\n",b); //21
}
1.
这个定义计算x和y分别两次(x和y中的⼩者被计算两次),当参数由副作⽤时,将产⽣不正确的结果
2.
使⽤语句表达式只计算参数⼀次,避免了可能的错误,语句表达式通常⽤于宏定义
3.
typeof(x)表⽰x的值类型
4.
检查参数x和y的类型是否相同(如果x和y的类型不同编译器将会发出warning,并不影响后⾯语句的运⾏
3
预处理器标识#error的⽬的是什么?
编译程序时,只要遇到 #error 就会跳出⼀个编译错误,既然是编译错误,要它⼲嘛呢?其⽬的就是保证程序是按照你所设想的那样进⾏编译的。
下⾯举个例⼦:程序中往往有很多的预处理指令
# ifdefXXX
...
# else
...
# endif
当程序⽐较⼤时,往往有些宏定义是在外部指定的(如makefile),或是在系统头⽂件中指定的,当你不太确定当前是否定义了 XXX 时,就可以改成如下这样进⾏编译:
# ifdefXXX
...
# error"XXX has been defined"
# else
# endif
这样,如果编译时出现错误,输出了 XXX has been defined ,表明宏 XXX 已经被定义了。
4
嵌⼊式系统中经常要⽤到⽆限循环,你怎么样⽤C编写死循环呢?
while( 1)
{}
for(;;)
{}
loop:...
gotoloop;
5
⽤变量a给出下⾯的定义
a) ⼀个整型数(An integer)
b)⼀个指向整型数的指针( A pointer to an integer)
c)⼀个指向指针的的指针,它指向的指针是指向⼀个整型数( A pointer to a pointer to an intege)
d)⼀个有10个整型数的数组( An array of 10 integers)
e) ⼀个有10个指针的数组,该指针是指向⼀个整型数的。(An array of 10 pointers to integers)
f) ⼀个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
g) ⼀个指向函数的指针,该函数有⼀个整型参数并返回⼀个整型数(A pointer to a function that takes an integer as
an argument and returns an integer)
h) ⼀个有10个指针的数组,该指针指向⼀个函数,该函数有⼀个整型参数并返回⼀个整型数( An array of ten
pointers to functions that take an integer argument and return an integer )
a) inta;
b) int*a;
c) int**a;
d) inta[ 10]
e) int*a[ 10]
f) int(*a)[ 10]
g) int(*a)( inta)
h) int(*a[ 10])( int)
6
关键字static的作⽤是什么?
在C语⾔中,关键字static有三个明显的作⽤:
第⼀、在修饰变量的时候,static修饰的静态局部变量只执⾏⼀次,⽽且延长了局部变量的⽣命周期,直到程序运⾏结束以后才释放。
第⼆、static修饰全局变量的时候,这个全局变量只能在本⽂件中访问,不能在其它⽂件中访问,即便是extern外部声明也不可以。
第三、static修饰⼀个函数,则这个函数的只能在本⽂件中调⽤,不能被其他⽂件调⽤。Static修饰的局部变量存放在全局数据区的静态变量区。初始化的时候⾃动初始化为0;
(1)不想被释放的时候,可以使⽤static修饰。⽐如修饰函数中存放在栈空间的数组。如果不想让这个数组在函数调⽤结束释放可以使⽤static修饰
(2)考虑到数据安全性(当程想要使⽤全局变量的时候应该先考虑使⽤static)
-------------------------------------------------------------------------
在C++中static关键字除了具有C中的作⽤还有在类中的使⽤在类中,static可以⽤来修饰静态数据成员和静态成员⽅法静态数据成员
(1)静态数据成员可以实现多个对象之间的数据共享,它是类的所有对象的共享成员,它在内存中只占⼀份空间,如果改变它的值,则各对象中这个数据成员的值都被改变。
(2)静态数据成员是在程序开始运⾏时被分配空间,到程序结束之后才释放,只要类中指定了静态数据成员,即使不定义对象,也会为静态数据成员分配空间。
(3)静态数据成员可以被初始化,但是只能在类体外进⾏初始化,若为对静态数据成员赋初值,则编译器会⾃动为其初始化为0
(4)静态数据成员既可以通过对象名引⽤,也可以通过类名引⽤。
静态成员函数
(1)静态成员函数和静态数据成员⼀样,他们都属于类的静态成员,⽽不是对象成员。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。