修改通过引用传递的变量

4

我正在编写一个函数,用于查找数组中最小的元素。我尝试使用引用传递来修改变量s。我是C++的新手,不确定我是否正确地使用了引用传递。有人可以确认这是否是正确的方法,或者建议更好的方法来处理使用引用传递的最小值函数吗?

#include <cstdlib>
#include <stdlib.h>
#include <iostream>

using namespace std;

int smallestElm(int numArray[], int length, int &smallest);

int main() {

    int n[3] = {2,5,3};
    int s = 0;
    int length = 0;

    cout << smallestElm(n, length, s) << endl;
}

int smallestElm(int numArray[], int length, int &smallest) {
    smallest = numArray[0];
    length = sizeof (numArray) / sizeof (int);
    for (int i = 1; i < length; i++) {
        if (numArray[i] < smallest) {
            smallest = numArray[i];
        }
        cout << smallest << endl;
        return 0;

    }
}

1
你听说过std::min [http://en.cppreference.com/w/cpp/algorithm/min]吗? - ZivS
2
为什么在循环体中使用return语句?这会在查看第二个元素后结束函数... - kmdreko
1
如果你在for循环内返回,可能会在找到最小元素之前就返回了!而且为什么要有一个长度参数,当你不使用它而是在函数内重新计算长度呢? - PeterO
1
@ZivS 也有 std::min_element,我想到了,不知道为什么错过了你的方法... - gsamaras
只有编译器能够计算大小,sizeof 才能正常工作。 - stark
显示剩余2条评论
3个回答

3

是的,这是正确的。你应该能够自行判断,通过将你的主要函数修改为以下内容:

int main() {
    int s = 0;    
    // call your function
    cout << s << endl; // Here you print 's', thus you confirm whether you are right or not
}

如果 s 的值不会改变,那么你的引用传递就不正确了(因为 s 在函数体内部会改变其值)。
至于函数本身,它是错误的,因为它在检查所有元素之前就返回了!所以,将其更改为以下内容,以在确定最小元素之前检查数组的所有元素:
#include <stdlib.h>
#include <iostream>

using namespace std;

void smallestElm(int numArray[], size_t length, int &smallest);

int main() {

    int n[] = {2,5,3}; // size is not needed, it's automatically computed by the compiler
    int s = 0;
    size_t length = 3;

    smallestElm(n, length, s);
    cout << "smallest element = " << s << endl;
    return 0;
}

void smallestElm(int numArray[], size_t length, int &smallest) {
    smallest = numArray[0];
    for (int i = 1; i < length; i++) {
        if (numArray[i] < smallest) {
            smallest = numArray[i];
        }
        cout << smallest << endl;
    }
}

输出:

Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall main.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
2
2
smallest element = 2

别忘了STL提供了min_element,你可以像这样使用:

#include <algorithm>
#include <iostream>

using namespace std;

int main() {

    int n[] = {2,5,3};
    int *s = std::min_element(n, n + 3); // 3 size of the array
    cout << "smallest element = " << *s << endl;
    return 0;
}

输出:

Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall main.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
smallest element = 2

1
太棒了!感谢您提供如此详细的回复。我从中学到了很多。 - the_martian

2

有人可以确认这是正确的做法吗?

是的,这是声明引用参数的正确方式。而且,是的,你可以通过引用修改对象。

或者建议更好的方法来处理最小值函数...

一个更好的方法可能是返回最小值,而不是修改实参。现在这个函数总是返回0,看起来没什么用。

...采用按引用传递的方式

那是个愚蠢的想法,但你的方法是通过引用传递的正确方式。这个函数本身存在多个错误:

  • 它似乎总是在第一次迭代后就返回,所以它将始终找到前两个元素中的一个作为“最小值”。
  • 未使用 int length 参数的值。在使用之前被覆盖了。
  • sizeof(numArray) 返回指针 numArray 的大小,与指向的数组的大小没有任何关系。
  • 函数总是使用 numArray[0],因此如果 length==0,它将具有未定义的行为。

0

你的代码是正确的,但还有另一种方法:使用指向int的指针,将其作为函数参数并使用变量s的内存地址调用该函数,如下面的示例所示:

#include <stdlib.h>
#include <iostream>

using namespace std;

void smallestElm(int numArray[], size_t length, int *smallest);

int main() {

int n[] = {2,5,3}; // size is not needed, it's automatically computed by the compiler
int s = 0;
size_t length = 3;

smallestElm(n, length, &s);
cout << "smallest element = " << s << endl;
return 0;
}

void smallestElm(int numArray[], size_t length, int *smallest) {
*smallest = numArray[0];
for (int i = 1; i < length; i++) {
    if (numArray[i] < *smallest) {
        *smallest = numArray[i];
    }
    cout << *smallest << endl;
}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接