我想以我是一名初級但相對經驗豐富的開發人員作為序言,但C 經驗很少。
我有這個測驗方法,它應該傳遞一個字符陣列來找到“O”。
TEST(MyTest, ReturnIndexOfO)
{
Widget unitUnderTest;
char x = 'X';
char o = 'O';
char *row[4] = {&o, &x, &x, &x};
char *row2[4] = {&x, &o, &x, &x};
EXPECT_EQ(unitUnderTest.findEmptySpace(*row, 4), 0);
EXPECT_EQ(unitUnderTest.findEmptySpace(*row2,4 ), 1);
}
這已經正確呼叫了我的 findEmptySpace 方法,即:
#define WHITE_SPACE 'O'
int Widget::findEmptySpace(char row[], int size)
{
cout << "The row under test is:\n";
for(int i = 0; i < size; i ) {
cout << row[i];
}
cout << "\n";
for(int i = 0; i < size; i ) {
if(row[i] == WHITE_SPACE) {
return i;
}
}
return -1;
}
但不幸的是,我的輸出似乎表明并非所有字符都被我的 findEmptySpace 方法讀取:
被測驗的行是:
牛
被測驗的行是:
X
所以即使有截斷的資料,我的第一個測驗用例通過了,但第二個測驗用例失敗了。知道為什么我沒有正確看到資料嗎?
uj5u.com熱心網友回復:
這個表達
Test.findEmptySpace(*row, 4)
等價于運算式
Test.findEmptySpace(row[0], 4)
并且元素row[0]是一個指標,其值指向該型別&o的標量物件ochar
char o = 'O';.
所以帶有此類引數的函式呼叫(函式內的內部回圈)沒有意義
看來你的意思是以下
EXPECT_EQ(unitUnderTest.findEmptySpace(row, 4), 0);
和
#define WHITE_SPACE 'O'
int Widget::findEmptySpace(char * row[], int size)
{
cout << "The row under test is:\n";
for(int i = 0; i < size; i ) {
cout << *row[i];
}
cout << "\n";
for(int i = 0; i < size; i ) {
if( *row[i] == WHITE_SPACE) {
return i;
}
}
return -1;
}
uj5u.com熱心網友回復:
你打電話的時候
unitUnderTest.findEmptySpace(*row, 4)
該運算式row將衰減為指向 的第一個元素的指標row,即&row[0]。因此,運算式*row等價于row[0],它是指向變數o的指標,即指向單個字符的指標。
在函式Widget::findEmptySpace中,在以下回圈中,您使用指向單個字符的 this 指標,就好像它是指向 4 個字符的指標一樣:
for(int i = 0; i < size; i ) {
cout << row[i];
}
由于函式引數row(與具有該名稱的原始陣列相反)是指向單個字符的指標,因此唯一有效的索引row是row[0]. 但是,您正在使用索引row[0],row[3]因此您正在越界訪問物件,從而導致未定義的行為。
函式簽名
int Widget::findEmptySpace(char row[], int size)
可能不是你想要的。如果要將指向整個陣列的指標row從 functonTEST傳遞給 function findEmptySpace,則應將指標傳遞給陣列的第一個元素及其長度。您已經正確地執行了后者,但是您沒有正確地執行前者。由于陣列的每個元素都是 type char *,指向陣列第一個元素的指標將是 type char **,即指向指標的指標。因此,您應該將函式簽名更改為以下內容:
int Widget::findEmptySpace( char **row, int size )
或者,如果您愿意,您可以使用這個等價物,以明確更高級別的指標指向一個陣列:
int Widget::findEmptySpace( char *row[], int size )
當然,您將不得不重寫您的函式findEmptySpace以適應不同的引數型別,以便它取消參考指標:
int Widget::findEmptySpace( char *row[], int size )
{
cout << "The row under test is:\n";
for( int i = 0; i < size; i ) {
cout << *row[i];
}
cout << "\n";
for( int i = 0; i < size; i ) {
if( *row[i] == WHITE_SPACE ) {
return i;
}
}
return -1;
}
現在,在函式中,由于更改了函式引數TEST,您必須更改呼叫函式的方式。findEmptySpace你應該改變線條
EXPECT_EQ(unitUnderTest.findEmptySpace(*row, 4), 0);
EXPECT_EQ(unitUnderTest.findEmptySpace(*row2,4 ), 1);
到:
EXPECT_EQ(unitUnderTest.findEmptySpace( row, 4), 0);
EXPECT_EQ(unitUnderTest.findEmptySpace( row2, 4 ), 1);
現在您不再傳遞第一個陣列元素的值,而是傳遞一個指向第一個陣列元素的指標,以便函式findEmptySpace可以正確訪問整個陣列。
uj5u.com熱心網友回復:
char *row[4] = {&o, &x, &x, &x};
這不是“字符陣列”。這是一個由四個指向字符的指標組成的陣列。
unitUnderTest.findEmptySpace(*row, 4)
這會將這些指標中的第一個傳遞給findEmptySpace()它的第一個引數。第一個指標是指向 的指標o。
to的第二個引數findEmptySpace()是4。這就是上面的陳述句在C 中的作用。
該函式findEmptySpace()執行以下操作:
for(int i = 0; i < size; i ) {
cout << row[i];
}
所以它最終列印了傳遞給它的指標的前四個字符。
問題是傳入的指標是一個指向一個字符的指標:
&o
這是第一個指標。這個函式最終試圖從一個只指向一個字符的指標中讀取前四個字符。
這會導致未定義的行為。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/448323.html
上一篇:如何解決這個嘗試迭代字串的問題?
