1. 程式人生 > >【 C 】關於相鄰字串常量自動合併的標準(新舊標準)(新舊風格)(陷阱)

【 C 】關於相鄰字串常量自動合併的標準(新舊標準)(新舊風格)(陷阱)

如果一個字串太長了,我們需要把它分行來寫,舊式風格是這樣來做的:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 int main()
  4 {
  5     printf( "I love you not because of \
  6             who you are, but because of \
  7            who I am when I am with you.\n"
  8             );
  9     return 0;
 10 }
 11 

編譯並執行得到如下結果:

這是什麼鬼呀,雖然也得到了結果,可是這顯示的也太出乎意料了吧。哪位大佬知道,可以告訴我哪裡出問題了。

ANSI C引入的另一種新特性是相鄰的字串常量將被自動合併成一個字串的約定。這就省掉了過去在書寫多行資訊時必須在行末加"\"的做法。

現在用一連串的字串常量來代替它,它們會在編譯時自動合併。除了最後一個字串外,其餘每個字串末尾的NUL位元組('\0')會被自動刪除。如下:

新式風格:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 int main()
  4 {
  5     printf( "I love you not because of "
  6             "who you are, but because of "
  7            "who I am when I am with you.\n"
  8             );
  9     return 0;
 10 }
 11 

Linux下編譯執行結果如下:

顯示的還不錯。

然而,這種自動合併意味著字串陣列在初始化時,如果不小心漏掉一個逗號,編譯器將不會發出錯誤資訊,而是悄無聲息地把兩個字串合併在一起。這在下面的例子中引起可怕的後果:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 
  5 int main()
  6 {
  7     char *available_resource[] = {
  8         "reborn lee",
  9         "Soul Da",
 10         "vickey"//這裡少了一個逗號!
 11         "dog",
 12         "mouse",
 13         "keyboard",
 14         "family",  //這個逗號會引起什麼問題嗎?   
 15     };
 16 
 17     char *src = malloc( 20 * sizeof( char ) );
 18     if(src != NULL)
 19         strcpy( src, available_resource[3] );
 20     else
 21         printf( "memory allocation false!\n" );
 22 
 23     printf( "I love %s\n", available_resource[2] );
 24    // strcpy( src, available_resource[3] );
 25     printf( "puppy is a name of %s\n", src );
 26     free( src );
 27     return 0;
 28 }
 29 

結果如下:

[email protected]:~# vim test.c [email protected]:~# gcc test.c [email protected]:~# ./a.out I love vickeydog puppy is a name of mouse [email protected]:~#

上面的這段程式中,我們很容易發現,第三個字串後少了一個逗號,這樣的話,按照ANSI C標準,就會自動的把它和下一個字串合成一個字串,所以呢?如果我們想要得到第三個字串的內容,本來使用available_resource[2]打印出來就可以了,正如上例中的語句:

 23     printf( "I love %s\n", available_resource[2] );

本來我想說的是:I love vickey,但是結果卻列印成了:I love vickeydog,這樣,如果vickey是我的女朋友,她看到豈不是誤會我罵她,所以不能疏忽!

同樣,這條語句:

 19         strcpy( src, available_resource[3] );

 25     printf( "puppy is a name of %s\n", src );

我想表達的是puppy is a name of dog,但是由於那個逗號的遺忘,意思也變了,打印出來的字串變成了:puppy is a name of mouse

我的天呀,意思千差萬別,puppy怎麼會是一個老鼠的名字。我家的寵物狗叫puppy好吧。

哈哈,通過上面貌似扯淡的討論,其實道出了一個問題,就是如果忘掉了一個逗號,編譯器也不會報錯,但是得到的答案卻千差萬別,所以要謹防這種問題的出現。

最後需要說的是,程式中的最後一個字串後面的逗號:

 14         "family",  //這個逗號會引起什麼問題嗎?

這個地方有沒有問題呢?

其實是沒有問題的,你也不要懷疑作者是不是多打了一個逗號,事實上,它並不是一個錯誤,而是從最早的C語法中繼承下來的東西,不管存在與否都沒有意思!所以見怪不怪吧!