2017-04-24 75 views
0

我正在刷新一些C++,因此我試圖解決的一個問題是計數字符指針中的字符,並根據我期望看到的內容進行檢查。然而在我的解決方案中,我注意到了一個特殊的結果。我將一個char引用傳遞給了我的函數,並且它返回了一個3的計數。爲什麼參考測試會返回一個計數爲3的字符引用?計數字符指針中的字符

我意識到字符沒有空終止符,所以代碼不斷地計數,但它最終返回結果,所以這意味着解決方案不足。任何想法,使其更強大?這是我的解決方案和結果。

CountCharacters.cpp

#include <cstdio> 
#include <iostream> 

#define ASSERT_EQUALS(paramx1, paramx2) \ 
{\ 
     int param1 = paramx1;\ 
     int param2 = paramx2;\ 
     if (param1==param2)\ 
       std::cout << "PASS! param1=" << param1 << " param2=" << param2 << std::endl;\ 
     else\ 
       std::cout << "FAIL! param1=" << param1 << " param2=" << param2 << std::endl;\ 
} 

int countCharacters(const char * characters); 


int main() 
{ 
     char character = '1'; 
     ASSERT_EQUALS(countCharacters("string8\0"), 7); 
     ASSERT_EQUALS(countCharacters("\0"), 0); 
     ASSERT_EQUALS(countCharacters(""), 0); 
     ASSERT_EQUALS(countCharacters(NULL), 0); 
     ASSERT_EQUALS(countCharacters(&character), 1); 
     ASSERT_EQUALS(countCharacters('\0'), 0); 
     return 0; 
} 


int countCharacters(const char * characters) 
{ 
     if (!characters) return 0; 
     int count = 0; 
     const char * mySpot = characters; 
     while (*(mySpot) != '\0') 
     { 
       std::cout << "Count=" << count << " mySpot=" << *(mySpot) << std::endl; 
       count++; 
       mySpot++; 

     } 
     return count; 
} 

結果:

PASS! param1=7 param2=7 
PASS! param1=0 param2=0 
PASS! param1=0 param2=0 
PASS! param1=0 param2=0 
FAIL! param1=2 param2=1 
PASS! param1=0 param2=0 
+0

你想重塑多少個車輪?有一個codereview的網站。 –

+1

[單個字符上的Strlen函數行爲]的可能重複(http://stackoverflow.com/questions/35477662/strlen-function-behavior-on-single-character) –

+0

您無法調整countCharacters功能到這種情況。沒有辦法確定它是否被賦予了以null結尾的字符串或單個字符。我認爲你最好的選擇是如果你這樣做是爲了超過char *的函數並返回1. – Squidy

回答

1

你不能傳遞一個字符的參考。你正在傳遞一個指針。具體而言,這是一個指針:

&character 

的&和*符號學習c時是有點混亂++。根據他們所在的位置,他們可以是一個指針或引用:

char character = '1';    // <- char variable 
char* characterPtr = &character; // <- pointer to the char variable 
char& characterRef = *characterPtr; // <- reference to the char variable 

所以,你傳遞一個指針的性格和你的函數處理它像一個字符串的頭部和計數字符,直到它命中nullptr。剛剛碰巧有一個字符,這就是爲什麼你得到的值2.

編輯:C/C++沒有本地字符串類型,只是字符類型。所以你需要像包含字符串這樣的字符的庫。約定是nullptr終止字符串。所以,你很好地運用了這個約定,但是也證明了指向一個字符的指針和指向字符串頭部字符的指針之間沒有區別的問題,所以很容易意外地將一個指針傳遞給一個字符一個期待字符串的函數。如果函數開始將字符複製到「字符串」中,事情會變得非常有趣,因爲它假定您分配了該內存,但可能是其他數據被壓縮。

除了危險之外,使用字符串的另一個主要缺點是操作它們非常繁瑣,因爲沒有本地函數。所以,像STL這樣的好庫已經被寫入來解決這些問題。它們不需要指針,因此使用起來更安全(您可以使用引用來代替邊界檢查),並且它們有很多內置方法,因此減少了需要執行的編碼量。

+0

啊...好吧,我明白了 - 所以我在這種情況下遇到了未定義的行爲。我會如何保護自己? – nndhawan

+0

這是一個尼特,但我不會稱這是一個未定義的行爲。挑戰在於C/C++沒有本地字符串類型。相反,它使用指向一系列字符的指針。指針既可怕又危險,所以應該謹慎使用。簡短的回答你的問題:使用std :: string。 – buttonsrtoys

+0

Ok @button。所以如果我在採訪中給出了這個解決方案,這個答案就足夠了,我可以忽略第五種情況,因爲給定函數簽名是不可解的。 – nndhawan