引導語:面試程序員少不了考驗對語言操作的熟練性,以下是本站小編分享給大家的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) = '