本人30有余,从业IT行业已经有10载,经历过不少的面试和笔试。下面是整理出之前笔试和面试常见题。
(1)i++和++i有啥区别? (出现过1次)
i++是先返回i,再自加;
++i是先自加,再返回i;
注:++i的效率比i++的效率要高 (面试员会问到这个)
(2)写一个求数组有多少元素的宏 (出现过2次)
#define ARRAY_NUM(A) (sizeof(A)/sizeof(A[0]))
(3)写一个求两个数最小值的的宏 (出现过2次)
#define MIN_NUM(a,b) (a>b?b:a)
(4)编写实现strlen功能的函数 (出现过1次)
int SStrlen(char *str)
{
int len=0;
char *ptr=str;
if(ptr==NULL)
{
return 0;
}
while(*ptr!='\0')
{
len++;
ptr++;
}
return len;
}
(5)编写函数,将“1234”(数字字符串,不包含小数名)转成对应整数 (出现过2次)
int str_to_int(char *str)
{
char *ptr=NULL;
int sum=0;
ptr=str;
while(*ptr!='\0')
{
sum=(10*sum)+(*ptr-'0');
ptr++;
}
return sum;
}
(6)在一个文件a.c中有个全局的变量int sum=0,我要在b.c文件想使用该变量,该怎么处理? (出现过1次)
在b.c文件中这样来写,
extern int sum;
(7) (出现过1次)
struct AA
{
char b;
int a;
};
union BB
{
char b;
int a;
};
sizeof(struct AA)=8 ;
sizeof(union BB)=4;
(8)static和const区别 (每次笔试必见)
const就是只读的意思,只在声明中使用;
对于全局变量,就为只读的全局变量,其值不可修改;
对于函数,const,返回只读变量的函数;
/*=========================================*/
static一般有2个作用,规定作用域和存储方式。
对于局部变量,static规定其为静态存储方式,每次调用的初始值为上一次调用的值,调用结束后存储空间不释放;
对于全局变量,如果以文件划分作用域的话,此变量只在当前文件可见;对于static函数也是在当前模块内函数可见。
(9)什么是大小端? (出现过3次)
在小端模式下,数据的 低位 存在内存的低地址中,而高位 存在内存的高地址中。而大端模式刚好反过来。
(10)为什么要内存对齐? (出现过1次)
原因1:不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
原因2:CPU读数据,不是一个个字节来读的,这样读取的速度会很慢,比如读一个int(占用4个字节),如果一个字节来读的话,这样要读4次,这样就很浪费时间,所以CPU读数据, 是按块来读取的 ,这个块可能是2,4,8,16个字节来读,所以是按2的N次方来读。这个时候就要用到内存对齐的了。也就是加快CPU的内存访问的速度。
(11) 什么是死锁? (经常被问到)
所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。
(12)面向对象编程特征或者C++特征 (出现2次)
封装性,继承性,多态性。
(13)指针数组和数组指针的区别? (出现过3次)
这个太容易混淆了。为了区分这两个,我是通过这样来记忆的,指针数组和字符数组(数组的元素为字符)我看为同一个类型,也就是数组的元素为指针。
指针数组:表示的是一个由指针变量组成的数组,也就是说其中的元素都是指针变量。 例如: int *p[5];
数组指针:表示的是这是个指向数组的指针,那么该指针变量存储的地址就必须是数组的首地址,得是个指向行的地址,如 a[2][3] 数组中的 a,a+1 等,不能是具体的指向列的地址,如 &a[0][1], &a[1][1] 这类地址。例如:int (*p2)[5];
int arr[5]={1,2,3,4,5};
int (*p1)[5] = &arr; //正确的赋值
/*下面是错误的*/
int (*p2)[5] = arr;
(14)填空题 (出现过1次)
int a=4;
char c='A';
char *p=NULL;
sizeof(a)=4;
sizeof(c)=1
sizeof(p)=4
(15)自已编写个函数,实现c语言的字符串连接的功能strcat (出现过2次)
char *strcat1(char *dest,const char *src)
{
char * ret = dest;
//对接受到的两个指针进行断言
assert(dest);
assert(src);
//将dest遍历至\0
while(*dest)
{
dest++;
}
//将src内容复制在dest之后
while(*src)
{
*dest++ = *src++;
}
//在dest后面追加\0
*dest = '\0';
return ret;
}