我正在通過 K&R 書學習并做一個練習,我應該使用 switch 函式將一個陣列復制到另一個陣列中,并進行細微的更改(將轉義字串轉換為實際的符號和字母)escape(from,to)。
看起來我做得很好,但令我困惑的是陣列(來自)也被更改為幾個字母。我想知道為什么會發生這種情況,如果我對 switch 或其他東西了解得不夠多?
#include <stdio.h>
#include <stdlib.h>
#define MAX 250
int main()
{
char ar1[MAX];
char ar2[MAX];
int c;
int i = 0;
while((c = getchar()) != EOF)
{
if ( i < MAX - 1 ){
ar1[i] = c;
i ;}
else
ar1[i ] = '\0';
}
escape(ar1,ar2);
printf("%s",ar2);
printf("%s",ar1);
return 0;
}
escape(char s[],char t[])
{
int i = 0;
int j = 0;
while (i < MAX )
{
switch(s[i])
{
case '\n':
t[j] = '\\';
j ;
t[j ] = 'n';
i ;
break;
default:
t[j] = s[i];
i ;
j ;
break;
}
}
t[j] = '\0';
}
uj5u.com熱心網友回復:
K&R 已經過時,其中的 C 版本也已過時,稱為 C90。這個舊版本允許各種語言缺陷,例如“隱式 int”和“無原型函式”。當您escape(ar1,ar2);在沒有可見的先前函式宣告的情況下鍵入時,在這個舊版本中會發生什么,編譯器會“抓住機會”使用所使用的型別 - 特別是它假定所有內容都有 type int。
在您的情況下,C90 編譯器會找到呼叫escape(ar1,ar2);然后:“哦,天哪escape,以前從未聽說過它。它可能是一個int escape (int, int)函式,對吧?讓我們這樣做,看看是否會有煙花”。
雖然實際上它應該讓void escape (char s[],char t[])您的程式按預期運行。
同樣,當您鍵入escape(char s[],char t[])then 時,會隱含地假定此函式回傳int,這不是您想要的。
您可以通過更新到當前標準 C 來擺脫所有這些問題,還可以找到一本不太過時的書。在標準 C 中,您的代碼不允許編譯,不會有奇怪的意外。
無論 C 版本如何,您都可以通過提供原型格式(存在型別)函式宣告來解決問題:
void escape (char s[], char t[]); // function declaration, prototype format
int main()
{
...
}
void escape (char s[], char t[]) // function definition
{
...
}
uj5u.com熱心網友回復:
escape函式中的回圈將始終超出輸出陣列的范圍。即使沒有要轉義的換行符,finalt[j] = '\0';也會這樣做,因為您無條件地運行MAX回圈的迭代,因此j至少增加MAX次數。未定義的行為結果,其中對其他變數的意外修改是一種相當常見的表現。
您將輸入陣列構造為字串,因此escape當資料到達字串終止符時可能應該停止轉換資料。但是,為了完全安全,它還必須確保在填充輸出陣列時終止,如果它在處理所有輸入之前這樣做(并且不要忘記為輸出的字串終止符留出空間)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/407547.html
標籤:
上一篇:為什么函式指標不能被隱式轉換?
