您的位置:首页 > 运维架构 > Linux

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

2013-10-19 21:31 337 查看
一、基本题

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命令是查看网络连接的详细状态的命令
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: