当前位置:学者斋 >

计算机 >C语言 >

C语言面试实例操作

C语言面试实例操作

引导语:面试程序员少不了考验对语言操作的熟练性,以下是本站小编分享给大家的C语言面试实例操作,欢迎阅读!

C语言面试实例操作

 实例:编写一个函数,实现把C/C++程序代码中的注释去掉,并把结果返回。

解析:

解答本题的基本步骤如下:

一次读取一行,分两种情况,因为有两种注释:

(1)在读取到的一行中查找“//”,如果找到,则把“//”及其后的部分扔掉。

(2)在读取到的一行中查找“/*”,记录位置pos1,然后再在这行中查找“*/”,如果找到,也记录位置pos2,扔掉它们与其中的内容;以pos2开始,继续查找“/*”,如果在当前行中没有找到,则去掉当前行中“/*”及其后的内容,读取新的一行,查找“*/”,如没有查找,去掉读取到的这一行,再读一行,查找“*/”,如找到,记录位置pos2,去掉这一行的0到pos2之间的字符。

(3)进行步骤1、步骤2,直到程序结束。

编程时要考虑的特殊情况如下:

“”中的“//”和“/*”

‘’中的“//”和“/*”

“//”与“/*”的嵌套关系,比如:

///*

/* //*/……

一、我们要明确,需要我们去掉注释的代码,是一段正确的C/C++代码,编译连接可以通过。

二、首先,这个题目答案自带的解析,跟附带程序不太对照,两种注释之注释(1)没有什么问题,程序中也是按照这样的思想处理的。但是仔细分析了程序之后,发现,注释(2)就写的有点问题了:其实在处理/*……*/时候,并没有严格的分行处理,而是读取到的一行中查找/*,记录位置pos1,然后继续查找*/,找到之后,删除它们之间的代码(包括注释符号本身)。

三、特殊情况中,这一条:‘’中的“//”和“/*”让人想不明白,单引号我们一般在里面放一个字符,也即是'a',不考虑放置两个字符的`情况,也就是不会出出现‘//’‘/*’,所以,我很费解,题目中为什么来了这么一条需要注意的特殊情况:‘’中的“//”和“/*”(题目问题吗???),即便出现单引号中‘//’‘/*’同样可以处理,本程序同样可以处理。

四、转义字符的处理,'''注意代表一个单引号字符,第一个单引号与第三个单引号结合。"""代表了一个双引号字符串,注意此处有三个双引号,第一个和第三个结合。

// 5_8_remove_ : Defines the entry point for the console application.

/********************************************************

功能:去除C/C++代码中的注释

输入:指向C/C++程序代码的指针,代码的长度

注意:①要考//和/*,//和/*的嵌套关系。

如://*、/*//*/等

②要注意处理''," "中的字符,字符串,包括转义字符。

如:'''注意代表一个单引号字符,第一个单引号与第三个单引号结合

"//****"引号内的当做字符串处理、"""代表了一个双引号字符串,注意此处有三个双引号,第一个和第三个结合

*********************************************************/

//#include "stdafx.h"

#include

#include

#include

#include

#include

void remove_comment(char *buf, size_t size)

{

char *p, *end, c;//p-动态移动的字符指针,end-指向文件末尾的字符指针,c-代表一个p指向的字符

char *sq_start, *dq_start;//sq_start-单引号(single quotes)开始位置指针,dq_start-双引号(double quotes)开始位置指针

char *lc_start, *bc_start;//lc_start-//的开始位置指针,bc_start-/*的开始位置指针

size_t len;//记录某符号结束和开始的位置之差(长度,偏移量)

p = buf;

end = p + size;

sq_start = NULL;

dq_start = NULL;

lc_start = NULL;

bc_start = NULL;

while (p < end) //当指针没有到达文件末尾

{

c = *p;

switch (c)

{

case ''': /* 单引号 */

if (dq_start || lc_start || bc_start)

{

/*当遇到过双引号、//或/*的时候,忽略字符串与注释中的单引号 */

p++;

continue;//继续下一个,对while而言的

}

if (sq_start == NULL) //如果之前未遇到单引号

{

sq_start = p++;//sq_start指向单引号的开始位置(p),p指向下一个字符(p+1)

}

else //如果之前遇到过单引号,sq_start已经保存了单引号开始位置,p指向当前单引号

{

len = (p++) - sq_start;//len = p-sq_start; p=p+1;两个单引号之间字符长度,'a':len=2

if (len == 2 && *(sq_start + 1) == '') //处理'''这种情况,''表示一个反斜杠字符

{

/* 忽略后面的的单引号 */

continue;

}

sq_start = NULL;

}

break;

case '"': // 双引号

if (sq_start || lc_start || bc_start)

{

/*当遇到过单引号、//或/*的时候,忽略字符串与注释中的双引号 */

p++;

continue;

}

if (dq_start == NULL)//如果之前未遇到双引号

{

dq_start = p++;//dq_start指向双引号的开始位置(p),p指向下一个字符(p+1)

}

else //如果之前遇到过双引号

{

if (*((p++) - 1) == '')//''表示一个反斜杠字符

{

// 处理这种"""代表了一个双引号字符串,忽略后面的的双引号

continue;

}

dq_start = NULL;

}

break;

case '/': /* 斜杆 */

if (sq_start || dq_start || lc_start || bc_start) {

//如果是单引号、双引号、斜杠//、/*的后面,忽略此处的单斜杠

p++;

continue;

}

c = *(p+1);//否则,C指向斜杠后的字符

if (c == '/') //两个//情况

{

lc_start = p;

p += 2;

}

else if (c == '*') // /*的情况

{

bc_start = p;

p += 2;

}

else//其他

{

p++;

}

break;

case '*': /* 星号 */

if (sq_start || dq_start || lc_start || bc_start == NULL) {

//如果是单引号、双引号、斜杠、的后面,或者前面没有出现/*(bc_start == NULL)就遇到*

p++;

continue;

}

if (*(p + 1) != '/')//*之后不是/,例如:**/,第一个*之后并不是/,那么就继续寻找。

{

p++;

continue;

}

//否则,就是*/的情况,此时就找到了一对/*____________*/

p += 2;

memset(bc_start, ' ', p - bc_start);//清除一对/*____________*/之间的内容

bc_start = NULL;

break;

case 'n': /*换行符,主要处理遇到双斜杠时,需要清除双斜杠到n的前面的字符*/

if (lc_start == NULL)//如果还没有遇到双斜杠,那么忽略

{

p++;

continue;

}

c = *(p - 1);

memset(lc_start, ' ',((c == 'r') ? (p++ - 1) : (p++)) - lc_start);/*如果遇到过双斜杠,清空双斜杠本身和到n前面的那个字符,p指向下一个字符,/r是回车符(光标退回到最前面),这里要判断

c == 'r'是因为在UNIX系统下文件结尾的换行只有n,而windows系统下文件结尾的换行为rn */

lc_start = NULL;

break;

default:

p++;

break;

}

}

/****************************************************

如果遇到双斜杠,这个if语句存在的意义在于万一最后

一行代码是带有双斜杠但没有给换行符n的,也要清除掉。

*****************************************************/

if (lc_start)

{

memset(lc_start, ' ', p - lc_start);

}

}

int main(int argc, char *argv[])

{

int fd, n;

char buf[102400];

fd = open("C:/Documents and Settings/Administrator/桌面/test.c",_O_RDONLY, 0); /*只读打开*/

if (fd == -1)

{

return -1;

}

n = read(fd, buf, sizeof(buf));

if (n == -1 || n == 0)

{

close(fd);

return -1;

}

remove_comment(buf, n);

*(buf + n) = '';

printf(buf);

close(fd);

return 0;

}

标签: 实例 面试 语言
  • 文章版权属于文章作者所有,转载请注明 https://xuezhezhai.com/jsj/cyuyan/0ngpw.html