C++字符数组似乎没有传递完整的数组



我想在前面加上我是一个初级但相对有经验的开发人员,但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 方法读取:

受测行为:

受测行为:

因此,即使使用截断的数据,我的第一个测试用例也通过了,但第二个测试用例失败了。知道为什么我没有正确查看数据吗?

此表达式

Test.findEmptySpace(*row, 4)

等效于表达式

Test.findEmptySpace(row[0], 4)

元素row[0]是一个指针,其值&o指向类型为char的标量对象o

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;
}

当你打电话时

unitUnderTest.findEmptySpace(*row, 4)

表达式row将衰减到指向row的第一个元素的指针,即指向&row[0]的指针。因此表达式*row等价于row[0],它是指向变量o的指针,即指向单个字符的指针。

在函数Widget::findEmptySpace中,在下面的循环中,您可以使用指向单个字符的指针,就好像它是指向 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从函子传递到函数TESTfindEmptySpace,那么您应该传递指向数组第一个元素及其长度的指针。你已经正确地做了后者,但你没有正确地做前者。因为数组的每个元素都是char *类型,指向数组第一个元素的指针将是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可以正确访问整个数组。

char *row[4] = {&o, &x, &x, &x};

这不是"字符数组"。这是一个由四个指向字符的指针组成的数组。

unitUnderTest.findEmptySpace(*row, 4)

这会将这些指针中的第一个传递到findEmptySpace()其第一个参数中。第一个指针是指向o的指针。

findEmptySpace()的第二个参数是 4。这就是上述声明在C++中所做的。

该函数findEmptySpace()执行以下操作:

for(int i = 0; i < size; i++) {
cout << row[i];
}

因此,它最终会打印传递给它的指针中的前四个字符。

问题是传入的指针是指向一个字符的指针:

&o

这是第一个指针。此函数最终尝试从仅指向一个字符的指针读取前四个字符。

这会导致未定义的行为。

相关内容

  • 没有找到相关文章

最新更新