Linux下的C和C++面试题(10/19自己整理小结)

来源:互联网 发布:英语单词书写软件 编辑:程序博客网 时间:2024/06/05 18:52


一、基本题            
1、头文件中的 ifndef/define/endif 干什么用?
答:防止多重编译,重复引用该头文件。#ifndef和#endif是配套使用的条件编译指令,若#ifndef后的宏没有定义则编译#idndef---#endif之间的代码,否则不编译。

2、#include<> 和 #include “” 有什么区别?
答:<>这种方式用于标准或系统提供的头文件,到保存系统标准头文件的目录下寻找。
而“”则通常是展开自己定义的头文件,编译器先查找当前目录,在查找标准目录。

3、在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”声明?
答:C和C++的编译器对函数名的修饰不同,为了保证在C\C++中编写的函数能够相互调用,需要加这个链接提示符。
在C++调用时,加上这个告诉C++编译器不要对函数名再进行修饰。
(这个后面单独补充,应该在C和C++的混合编程中会经常使用)。

二、有关内存的思考题
1、
void GetMemory(char *p)
{
  p = (char *)malloc(100);
}


void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}


请问运行Test函数会有什么样的结果?
答:出现段错误。涉及到函数的参数传递,要想改变str指向的内容,需要把指向str指针的指针传递给函数。
(修改的方法跟上次总结的一样)。

2
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}


void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}


请问运行Test函数会有什么样的结果?
答:打印出乱码。因为hello world是字符串常量。保存在静态存储区,而定义的字符数组则是局部变量,保存在栈中,进行赋值操作,相当于hello world在栈中也保存了一份,而在函数返回时,栈空间该内存就被释放了,所以str指向该内存打印出的是乱码。解决方法是在局部变量前加static关键字,使其维持到程序结束再进行释放。

3、
Void GetMemory2(char **p, int num)
{
  *p = (char *)malloc(num);
}


void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}


请问运行Test函数会有什么样的结果?
答:能够正确输出结果。但是应该函数体内增加对malloc函数返回指针的判断。


4、
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str != NULL)
{
strcpy(str, “world”);
printf(str);
}
}


请问运行Test函数会有什么样的结果?
答:输出world。Free函数的使用将str指针指向的内存块释放了,在没有对str指针进行附空的情况下,str成了野指针,野指针的指向是不明确的,应该避免使用。

       
5、自己写一个函数,实现strcpy的功能
(strcpy函数实现字符串的拷贝,使用指针操作最为简便)


Char* mystrcpy(char *dest,const char *src) //最好在这边加const限定符,意义很明显
{
//注意进行入口参数检查
If(dest == NULL || src ==NULL)
{
Printf(“Invalid arguments\n”);
Return NULL;
}
Char *temp = dest;//定义一个中间指针变量
While(*src!=’\0’)
{
*temp = *src;
Temp++;
Src++;
}
*temp=’\0’;
Return dest;
}


6、分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)
答:bool类型,任何非零值都是真,记做TRUE,零值记做假,FLAUSE。与零值比较通常使用if(var)和if(!var)。
Int型与零值比较很简单,if(var==0)和if(var!=0).
Flaot型变量。应该注意精度限制。它和double变量一样,不能使用“==”或者“!=”,正确的使用是const float EPSINON=0.00001;if(var>=-EPSINON)&&(var<=EPSION)
指针变量,if(p==NULL)和if(p!=NULL).


7、编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefg”
答:
Char *fun(char *src,int steps)
{
If(src==NULL)
{
Return NULL;
}
Int n = strlen(src)-steps;
Char tmp[20];
Strcpy(tmp,src+n);
Strcpy(tmp+steps,src);
*(tmp+strlen(src)=’\0’);
Strcpy(src,tmp);
}


8、下面的声明都是什么意思?
const int a; 声明一个整形常量
int const a; 声明一个整形常量
const int *a; 同int const *a,表示声明指针指向的变量是常量,不能通过*a来修改其值
int * const a; 表明,a是常量,表明指针指向固定不变
int const * a const;表明,指针a是常指针,指向一个常量

三、有关类的
1、为什么需要拷贝构造函数?
答:对于类对象,相同类型的类对象是通过拷贝构造函数完成复制的。
2、类成员函数的重载、覆盖和隐藏的区别?
答:重载:相同的范围在同一个类中,函数名相同,参数不同,virtual关键字可省略
覆盖:不同的范围(分布基于派生类和基类),函数名相同,参数相同,基类中一定要有virtual关键字。
隐藏:是指派生类的函数屏蔽了和他同名的基类函数。隐藏的规则:(1)派生类的函数与基类的函数同名,但是参数不同。基类的函数将被隐藏,此时不管有无关键字(注意别与重载混淆)。 
(2)派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆) 


四、网络
1、TCP和UDP的区别
答:略,这个后面再补充。 
2、简述TCP的三段握手

五、LINUX下线程、进程、同步对象
1、创建进程的函数是?创建线程的函数是?
答:略

2、进程间通讯机制有哪些?
答:linux下使用的进程间通信的方式主要有:管道和有名管道,信号,消息队列,共享内存,信号量,套接字。
3、线程同步对象有哪些?
答:略

六、其他
1、LINUX下查看进程的命令?查看系统资源使用情况的命令?netstat是作什么用的?
答:linux下查看进程的命令,ps命令
使用free-m命令
Netstat命令是查看网络连接的详细状态的命令
原创粉丝点击