C语言面试题

来源:互联网 发布:mac电脑怎么打顿号 编辑:程序博客网 时间:2024/06/05 03:27

一、华为面试题

1.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值

int a = 4;

(A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++);

a = ?

答:C错误,左侧不是一个有效变量,不能赋值,可改为(++a) += a;

改后答案依次为9,10,10,11

2.某32位系统下, C++程序,请计算sizeof 的值

char str[] = "HelloWorld";

char *p = str;

int n = 10;

请计算:

sizeof(str) = ?    (1)

sizeof(p) = ?      (2)

sizeof(n) = ?      (3)

void Foo(char str[100])

{

请计算:

sizeof(str) = ?    (4)

}

void *p = malloc(100);

请计算:

sizeof(p) = ?    (5)

答:(1)11 (2)4 (3) 4 (4)4 (5)4

3.回答下面的问题

(1).#include<filename.h> 和 #include"filename.h" 有什么区别?

答:尖括号表示:先在系统目录查找所包含的文件,一般在要包含系统头文件时使用

双引号表示:先在当前程序所在的目录查找所包含的文件,一般在要包含自己写的文件时使用       

再具体点就是:

      <>搜索顺序为:系统目录 -->环境变量目录-->用户自定义目录

     而"" 则是 用户自定义目录-->系统目录-->环境变量目录

(2).在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”声明?

答:函数和变量被C++编译后在符号库中的名字与C语言的不同,被extern "C"修饰的变量和函数是按照C语言方式编译和链接的。

  由于编译后的名字不同,C++程序不能直接调用C函数。C++提供了一个C链接交换指定符号extern "C"来解决这个问题。 

4.回答下面的问题

(1). void GetMemory(char **p,int num)
{
*p = (char*)malloc(num);
}

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

请问运行Test函数会有什么样的结果?

答:输出"hello"

(2). void Test()
{
char* str =(char*)malloc(100);
strcpy(str,"hello");
free(str);
if(str != NULL)
{
strcpy(str,"world");
printf(str);
}
}

请问运行Test函数会有什么样的结果?

答:输出"world"

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

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

请问运行Test函数会有什么样的结果?

答:无效的指针,输出不确定。

5.编写strcat函数

已知strcat函数的原型是char *strcat (char *strDest, const char *strSrc);

其中strDest 是目的字符串,strSrc 是源字符串。

(1)不调用C++/C 的字符串库函数,请编写函数 strcat

答:

VC源码:

char * __cdecl strcat (char * dst, const char * src)

{

char * cp = dst;

while( *cp )

cp++; /* find end of dst */

while( *cp++ = *src++ ) ; /* Copy src to end of dst */

return( dst ); /* return dst */

}

(2)strcat能把strSrc 的内容连接到strDest,为什么还要char * 类型的返回值?

答:方便赋值给其他变量。

6.C++中为什么用模板类?

解答:

(1)可用来创建动态增长和减小的数据结构

(2)它是类型无关的,因此具有很高的可复用性。

(3)它在编译时,而不是运行时检查数据类型,保证了类型安全

(4)它是平台无关的,可移植性

(5)可用于基本数据类型

7.程序什么时候应该使用线程,什么时候单线程效率高?

解答:

(1)耗时的操作使用线程,提高应用程序响应

(2)并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求

(3)多CPU系统中,使用线程提高CPU利用率

8.C++中什么数据分配在栈或是堆中?

解答:

栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理

堆:程序运行时动态申请,new 和malloc申请的内存就在堆上

9. TCP/IP建立连接的过程?(3-way shake)

解答:在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

第一次握手:建立连接时,客户端发送syn包(syn = j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack = j +1),同时自己也发送一个SYN包(syn = k),

即SYN + ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN + ACK包,向服务器发送确认包ACK(ack = k + 1),此包发送完毕,

客户端和服务器进入ESTABLISHED状态,完成三次握手。

10. winsocket建立连接的主要实现步骤是什么?

解答:

服务器端:socker()建立套接字,绑定(bind)并监听(listen),用accept() 等待客户端连接

客户端:socker()建立套接字,连接(connect) 服务器,连接上后使用send()  和 recv(),在套接字上写读数据,

直至数据交换完毕,closesocket() 关闭套接字。

服务器端:accept() 发现有客户端连接,建立了一个新的套接字,自身重新开始等待连接。该新产生的套接字使用

send() 和 recv() 写读数据,直至数据交换完毕,closesocket() 关闭套接字。

11.动态链接库的两种方式?

解答:

调用一个DLL中的函数有两种方法:

(1)载入是动态链接(load-time dynamic linking),模块非常明确调用某个导出函数,使得他们就像本地函数一样。这需要

链接时链接那些函数所在DLL的导入库,导入库向系统提供了载入DLL时所需的信息及DLL函数定位。

(2)运行时动态链接(run-time dynamic linking),运行时可通过LoadLibrary 或 LoadLibraryEx函数载入DLL。DLL载入后,模块

可以通过调用GetProcAddress获取DLL函数的出口地址,然后就可以通过返回的函数指针调用DLL函数了。如此即可避免

导入库文件了。





0 0
原创粉丝点击