12 Interesting C Interview Questions and Answers
2012-09-02 10:11
363 查看
英文原文来自:http://www.thegeekstuff.com/2012/08/c-interview-questions/
本篇只是简要摘录和翻译:
----------------------------------------------------------------分割线-------------------------------------------------------------------------------
在这片文章中,我们将讨论一些有趣的C语言问题,以帮助同学们复习他们的C语言技能、帮助他们准备C语言面试。
1.gets()函数
问题:在下面的代码中,有一个潜在的问题,你能看出来么?
2.strcpy()函数
问题:下面是一段密码检测程序,你能在不知道密码的情况下破译它么?
因此你能看到尽管密码输入错误,但是仍能打破密码安全机制通缓冲区溢出。
为了避免这类问题,strncpy()函数推荐使用。
3.main()函数的返回值
问题:下面这段代码能编译通过么?如果能,这段代码有其他的问题么?
答案:这段代码没有编译问题但是对于main函数的返回值问题会有警告(对于大多数编译器来说)。main函数的返回值应该是int而不是void。这是因为int型返回值要求程序返回一个状态值。这在程序作为脚本的一部分运行的时候显得特别重要,因为它要反映程序运行的正确与否。
4.内存泄漏
问题:下面这段代码将导致内存泄漏么?
答案:虽然给‘ptr’分配的内存并没有被释放,但是这仍然不会导致内存泄漏,因为随着进程终止程序也就退出了。由于程序终止,程序分配的内存会被自动释放。但是如果上述代码处在一个while循环里边,那么将会导致严重的内存泄漏。
5.free()函数
问题:当用户输入"freeze"时,下面的程序会出现段错误。但是输入"zebra"时,程序正常,为何?
6.atexit 和 _exit
问题:在下面这段代码中,atexit()函数不会被调用,这是为什么?
答案:这是因为_exit函数的使用。如果我们需要调用atexit的话,应该使用exit() 或者 'return'而不是_exit().
7.void* 和 C structures
问题:你能设计一个能接受任何类型的参数并且返回整形的函数么?那如果是有不同数量的参数呢?
答案:能接受任何类型的参数的函数应该是这样:
对于第二个问题,我们可以构造一个结构体。
8.*和++ 操作符
问题:下面这段程序的输入结果是什么,为何?
答案:输入结果是:
由于‘++’和‘*’的优先级相同,所以‘*ptr++’按照从右向左的顺序执行。按照这个逻辑,ptr++先执行,然后才是*ptr。这两个操作符都将是运算结果为'L'。但由于后置算子'++',所以下一行的输出是'i'。
9.操作只读存储区
问题:下面这段代码会导致段错误,你能说出为什么么?
答案:这是因为,'*ptr'='T'这句代码想要改变只读存储区中的内容。这种操作是无效的,并且会出现段错误。
10.你能写一个程序改变,在运行时改变它自己的程序名么?
答案:
11.返回局部变量的地址:
问题:下面这段代码有问题么?如果有,该如何调整?
答案:
本篇只是简要摘录和翻译:
----------------------------------------------------------------分割线-------------------------------------------------------------------------------
在这片文章中,我们将讨论一些有趣的C语言问题,以帮助同学们复习他们的C语言技能、帮助他们准备C语言面试。
1.gets()函数
问题:在下面的代码中,有一个潜在的问题,你能看出来么?
#include<stdio.h> int main(void) { char buff[10]; memset(buff,0,sizeof(buff)); gets(buff); printf("\n The buffer entered is [%s]\n",buff); return 0; }答案:上面的代码的潜在的问题在于gets()函数的使用。此函数从stdin中接受字符串,但并没有检测buffer拷贝值的能力。这可能导致buffer溢出。在这些情况下,使用fgets()要好一些,推荐使用。
2.strcpy()函数
问题:下面是一段密码检测程序,你能在不知道密码的情况下破译它么?
#include<stdio.h>
int main(int argc, char *argv[])
{
int flag = 0;
char passwd[10];
memset(passwd,0,sizeof(passwd));
strcpy(passwd, argv[1]);
if(0 == strcmp("LinuxGeek", passwd))
{
flag = 1;
}
if(flag)
{
printf("\n Password cracked \n");
}
else
{
printf("\n Incorrect passwd \n");
}
return 0;
}
答案:能够破译。我们可以依靠strcpy()函数的缺陷来解决这个问题。这个程序将用户输入的内容拷贝到passwd中而没有检查输入密码的长度是否超过了passwd的承受范围。因此,如果用户输入了长度超过passwd承受范围的随机密码,就有可能造成buffer溢出,并且重写包含有flag的值的那块内存。最后,即使检测到密码输入错误,但是这时flag的值是非0的,因而能正确破译这个密码保护程序。
举个例子:
$ ./psswd aaaaaaaaaaaaa Password cracked
因此你能看到尽管密码输入错误,但是仍能打破密码安全机制通缓冲区溢出。
为了避免这类问题,strncpy()函数推荐使用。
3.main()函数的返回值
问题:下面这段代码能编译通过么?如果能,这段代码有其他的问题么?
#include<stdio.h> void main(void) { char *ptr = (char*)malloc(10); if(NULL == ptr) { printf("\n Malloc failed \n"); return; } else { // Do some processing free(ptr); } return; }
答案:这段代码没有编译问题但是对于main函数的返回值问题会有警告(对于大多数编译器来说)。main函数的返回值应该是int而不是void。这是因为int型返回值要求程序返回一个状态值。这在程序作为脚本的一部分运行的时候显得特别重要,因为它要反映程序运行的正确与否。
4.内存泄漏
问题:下面这段代码将导致内存泄漏么?
#include<stdio.h> void main(void) { char *ptr = (char*)malloc(10); if(NULL == ptr) { printf("\n Malloc failed \n"); return; } else { // Do some processing } return; }
答案:虽然给‘ptr’分配的内存并没有被释放,但是这仍然不会导致内存泄漏,因为随着进程终止程序也就退出了。由于程序终止,程序分配的内存会被自动释放。但是如果上述代码处在一个while循环里边,那么将会导致严重的内存泄漏。
5.free()函数
问题:当用户输入"freeze"时,下面的程序会出现段错误。但是输入"zebra"时,程序正常,为何?
#include<stdio.h>
int main(int argc, char *argv[])
{
char *ptr = (char*)malloc(10);
if(NULL == ptr)
{
printf("\n Malloc failed \n");
return -1;
}
else if(argc == 1)
{
printf("\n Usage \n");
}
else
{
memset(ptr, 0, 10);
strncpy(ptr, argv[1], 9);
while(*ptr != 'z')
{
if(*ptr == '')
break;
else
ptr++;
}
if(*ptr == 'z')
{
printf("\n String contains 'z'\n");
// Do some more processing
}
free(ptr);
}
return 0;
}
答案:这段程序的问题在于它在while循环中改变了存放在'ptr'中的地址值(通过'ptr'自增)。当'zebra'作为输入值的时候,while内部连一次都没有执行过就被终止了。所以free时,ptr的值和malloc后,ptr的值是相同的。但是当输入'freeze'时,ptr的值在while循环中会发生变化,这样,在free的时候,就会出现段错误。
6.atexit 和 _exit
#include<stdio.h> void func(void) { printf("\n Cleanup function called \n"); return; } int main(void) { int i = 0; atexit(func); for(;i<0xffffff;i++); _exit(0); }
答案:这是因为_exit函数的使用。如果我们需要调用atexit的话,应该使用exit() 或者 'return'而不是_exit().
7.void* 和 C structures
问题:你能设计一个能接受任何类型的参数并且返回整形的函数么?那如果是有不同数量的参数呢?
答案:能接受任何类型的参数的函数应该是这样:
int func(void *ptr)
对于第二个问题,我们可以构造一个结构体。
8.*和++ 操作符
问题:下面这段程序的输入结果是什么,为何?
#include<stdio.h> int main(void) { char *ptr = "Linux"; printf("\n [%c] \n",*ptr++); printf("\n [%c] \n",*ptr); return 0; }
答案:输入结果是:
[L] [i]
由于‘++’和‘*’的优先级相同,所以‘*ptr++’按照从右向左的顺序执行。按照这个逻辑,ptr++先执行,然后才是*ptr。这两个操作符都将是运算结果为'L'。但由于后置算子'++',所以下一行的输出是'i'。
9.操作只读存储区
问题:下面这段代码会导致段错误,你能说出为什么么?
#include<stdio.h> int main(void) { char *ptr = "Linux"; *ptr = 'T'; printf("\n [%s] \n", ptr); return 0; }
答案:这是因为,'*ptr'='T'这句代码想要改变只读存储区中的内容。这种操作是无效的,并且会出现段错误。
10.你能写一个程序改变,在运行时改变它自己的程序名么?
答案:
#include<stdio.h> int main(int argc, char *argv[]) { int i = 0; char buff[100]; memset(buff,0,sizeof(buff)); strncpy(buff, argv[0], sizeof(buff)); memset(argv[0],0,strlen(buff)); strncpy(argv[0], "NewName", 7); // Simulate a wait. Check the process // name at this point. for(;i<0xffffffff;i++); return 0; }
11.返回局部变量的地址:
问题:下面这段代码有问题么?如果有,该如何调整?
#include<stdio.h> int* inc(int val) { int a = val; a++; return &a; } int main(void) { int a = 10; int *val = inc(a); printf("\n Incremented value is equal to [%d] \n", *val); return 0; }答案:虽然这段程序有时能正常运行,但是在inc()函数中有严重的缺陷。这段程序返回局部变量值的地址。因为局部变量的生存时间在inc()中。所以,一旦inc()函数销毁,使用局部变量的地址会造成不可预知的结果。这种情况能够被避免,通过将变量a的地址传入inc()函数中,在inc()中,在保持地址不变的情况下,对值进行改变。
12. 处理printf()的参数:
问题:下面这段代码的输出结果是什么?#include<stdio.h> int main(void) { int a = 10, b = 20, c = 30; printf("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2)); return 0; }
答案:
110..40..60这是因为参数的处理是从右向左的,但是打印却是从左向右。
相关文章推荐
- 12 Interesting C Interview Questions and Answers
- 12 Interesting C Interview Questions and Answers
- 12 Interesting C Interview Questions and Answers
- 11 Basic Linux Interview Questions and Answers
- Technical Interview Questions, Answers, and Tips
- Java Multi-Threading and Concurrency Interview Questions with Answers
- Servlet JSP Tutorial -- 1.15 50 Servlet Interview Questions and Answers
- Data Structures Interview Questions and Answers
- [译]Node.js Interview Questions and Answers (2017 Edition)
- iOS interview questions and Answers
- 69 Spring Interview Questions and Answers – The ULTIMATE List--reference
- mysql interview questions and answers
- 115 Java Interview Questions and Answers – The ULTIMATE List--reference
- 一家外企公司完整面试题和答案 Basic C/C++ (CC++ Programming interview questions and answers)
- Core Java Interview Questions and Answers
- Java Thread Interview Questions And Answers
- Java Exception Interview Questions and Answers
- JSP Interview Questions and Answers
- C++ Interview Questions and Answers - Part 01
- SQL Server Interview Questions and Answers – Part 2