C++ — возвратите x, y; Какой смысл?

Я программировал в C и C++ в течение нескольких лет, и теперь я сейчас беру курс колледжа в нем, и наша книга имела функцию как это для примера:

int foo(){
  int x=0;
  int y=20;
  return x,y; //y is always returned
}

Я никогда не видел такой синтаксис. На самом деле я никогда не видел , оператор используется за пределами списков параметров. Если y всегда возвращается хотя, затем какой смысл? Существует ли случай, где оператор возврата должен был бы быть создан как это?

(Кроме того, я отметил C также, потому что он относится к обоим, хотя моей книгой конкретно является C++),

46
задан Justin Ethier 5 August 2011 в 19:42
поделиться

12 ответов

Оператор запятой в основном используется в для операторов , например:

for( int i=0, j=10; i<10; i++, j++ )
{
    a[i] = b[j];
}

Первая запятая не является оператором запятой, это часть синтаксиса объявления. Второй - это оператор запятой.

20
ответ дан 26 November 2019 в 20:08
поделиться

Это оператор запятой (,) .

Вычисляются оба выражения x и y. Результатом общего выражения является y, то есть последнее значение.

Трудно сказать, почему он здесь используется. Думаю, в демонстрационных целях. Очевидно, что функция может быть изменена на:

int foo()
{
  return 20;
}
4
ответ дан 26 November 2019 в 20:08
поделиться
 struct Point {
   int x, y;
   Point(int x_) : x(x_), y(0) {}
   Point(const Point& p) : x(p.x), y(p.y) {}
   Point operator, (int y_) const { Point p=*this; p.y = y_; return p; }
 };

 Point get_the_point () {
    int x = 0;
    int y = 20;
    return (Point)x, y;
 }

: p

8
ответ дан 26 November 2019 в 20:08
поделиться

Запятая в списках параметров предназначена только для разделения параметров и отличается от оператора запятой. Оператор запятой, как в вашем примере, оценивает как x, так и y, а затем отбрасывает x.

В этом случае я бы предположил, что это ошибка человека, который пытается вернуть два значения и не знает, как это сделать.

23
ответ дан 26 November 2019 в 20:08
поделиться

Так же, как все комментирующие здесь считают это бессмысленным, и я с этим не согласен, просто глядя на пример, я сделаю предположение, что это не намного лучше:

Автор получал предупреждение компилятора о том, что x не используется внутри функции, и это был простой способ убрать предупреждение.

5
ответ дан 26 November 2019 в 20:08
поделиться

Это вообще не отвечает на исходный вопрос, но может быть интересным для некоторых людей, но если вы хотите, чтобы он возвращал оба в C ++, вы нужно было бы написать это так (и потребуется компилятор c ++ 0x)

tuple<int, int> foo()
{
    int x = 0;
    int y = 20;
    return make_tuple(x, y);
}

Доступ к нему вот так -

tuple<int, int> data = foo();
int a = get<0>(data);
int b = get<1>(data);
9
ответ дан 26 November 2019 в 20:08
поделиться

Это оператор запятой. Такой синтаксис можно использовать для отключения предупреждения компилятора о неиспользуемой переменной x .

1
ответ дан 26 November 2019 в 20:08
поделиться

Вне циклов другой основной пользователь этого командного оператора (в отличие от версии вызова функции) находится в макросах, которые возвращают значение после выполнения некоторых действий. . Есть и другие способы сделать это сейчас, но я думаю, что раньше было самым чистым способом использовать командный оператор.

#define next(A, x, y, M) ((x) = (++(y))%(M) , A[(x)])

Обратите внимание, что этот макрос является плохим примером макроса в целом, потому что он повторяет x и, вероятно, по другим причинам. Использование оператора запятой таким образом должно быть редкостью. Пример из вашей книги, вероятно, был попыткой уместить экзамен кода в пределах количества строк, доступных для этого примера.

1
ответ дан 26 November 2019 в 20:08
поделиться

В этом операторе возврата нет смысла.

Если x был объявлен volatile , это вызвало бы доступ (поскольку, по крайней мере, в C ++ ссылки на volatile переменные считаются наблюдаемым извне поведением) , но это не так.

Если бы вместо x было какое-то вычисление с побочными эффектами, он бы выполнил это вычисление и затем вернул бы y . Однако не летучий x не имеет побочных эффектов. Реализация не требуется для выполнения какого-либо кода, который не имеет побочных эффектов или поведения, наблюдаемого извне. Оператор запятой выполняет все, что находится слева от запятой, игнорирует результат и выполняет и сохраняет значение правой стороны (за исключением того, что в этом случае можно игнорировать левую часть оператора).

Следовательно, оператор return x, y; - это то же самое, что return y; . Если бы x не было просто совершенно бессмысленным исполнением, было бы стилистически лучше записать его как x; return y; , что в точности то же самое.Это было бы не так запутанно.

2
ответ дан 26 November 2019 в 20:08
поделиться

Согласно FAQ по C :

Точно указано, что значение оператора запятой в общем выражении

e1, e2

таково: «вычислить подвыражение e1, затем вычислить e2. ; значением выражения является значение e2. " Следовательно, e1 лучше использовать присваивание, или приращение ++, или декремент, или вызов функции, или какой-либо другой побочный эффект, потому что в противном случае он будет вычислять значение, которое будет отброшено.

Итак, я согласен с вами, нет никакого смысла , кроме как продемонстрировать, что это действительный синтаксис, если это так.

Если вы хотите вернуть оба значения в C или C ++, вы можете создать структуру struct , содержащую члены x и y , и вместо этого вернуть структуру:

struct point {int x; int y;};

Затем вы можете определить тип и вспомогательную функцию, чтобы вы могли легко возвращать оба значения в структуре struct :

typedef struct point Point;

Point point(int xx, int yy){
  Point p;
  p.x = xx;
  p.y = yy;
  return p;
}

А затем изменить исходный код для использования вспомогательной функции:

Point foo(){
  int x=0;
  int y=20;
  return point(x,y); // x and y are both returned
}

И, наконец, вы можете попробовать:

Point p = foo();
printf("%d, %d\n", p.x, p.y);

Этот пример компилируется как на C, так и на C ++. Хотя, как предлагает Марк ниже, в C ++ вы можете определить конструктор для структуры point , что дает более элегантное решение.


Кстати, возможность напрямую возвращать несколько значений прекрасна для таких языков, как Python, которые ее поддерживают:

def foo():
  x = 0
  y = 20
  return x,y # Returns a tuple containing both x and y

>>> foo()
(0, 20)
51
ответ дан 26 November 2019 в 20:08
поделиться

Похоже на ужасный пример кода. Это может быть допустимый синтаксис в C / C ++, но я не могу придумать причину, по которой вы когда-либо захотели бы это сделать.

Если вы хотите вернуть и x, и y, лучший способ сделать это в C ++ - определить класс или структуру «Point» со свойствами x и y и вернуть их. Другой вариант - передать x и y по ссылке, а затем соответствующим образом установить значения в методе.

Если метод собирается просто вернуть y, я бы просто «вернул y;». Если x необходимо «вычислить» перед оператором return, это следует сделать в отдельной строке.

3
ответ дан 26 November 2019 в 20:08
поделиться

С одной стороны, это могло быть честной ошибкой со стороны автора.

С другой стороны, автор может объяснять синтаксически правильный код, а не предупреждения компилятора.

В любом случае, единственный способ вернуть несколько результатов - это определить класс и использовать его экземпляр или, возможно, массив или коллекцию.

1
ответ дан 26 November 2019 в 20:08
поделиться