Я программировал в C и C++ в течение нескольких лет, и теперь я сейчас беру курс колледжа в нем, и наша книга имела функцию как это для примера:
int foo(){
int x=0;
int y=20;
return x,y; //y is always returned
}
Я никогда не видел такой синтаксис. На самом деле я никогда не видел ,
оператор используется за пределами списков параметров. Если y
всегда возвращается хотя, затем какой смысл? Существует ли случай, где оператор возврата должен был бы быть создан как это?
(Кроме того, я отметил C также, потому что он относится к обоим, хотя моей книгой конкретно является C++),
Оператор запятой в основном используется в для операторов
, например:
for( int i=0, j=10; i<10; i++, j++ )
{
a[i] = b[j];
}
Первая запятая не является оператором запятой, это часть синтаксиса объявления. Второй - это оператор запятой.
Это оператор запятой (,) .
Вычисляются оба выражения x и y. Результатом общего выражения является y, то есть последнее значение.
Трудно сказать, почему он здесь используется. Думаю, в демонстрационных целях. Очевидно, что функция может быть изменена на:
int foo()
{
return 20;
}
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
Запятая в списках параметров предназначена только для разделения параметров и отличается от оператора запятой. Оператор запятой, как в вашем примере, оценивает как x, так и y, а затем отбрасывает x.
В этом случае я бы предположил, что это ошибка человека, который пытается вернуть два значения и не знает, как это сделать.
Так же, как все комментирующие здесь считают это бессмысленным, и я с этим не согласен, просто глядя на пример, я сделаю предположение, что это не намного лучше:
Автор получал предупреждение компилятора о том, что x не используется внутри функции, и это был простой способ убрать предупреждение.
Это вообще не отвечает на исходный вопрос, но может быть интересным для некоторых людей, но если вы хотите, чтобы он возвращал оба в 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);
Это оператор запятой. Такой синтаксис можно использовать для отключения предупреждения компилятора о неиспользуемой переменной x
.
Вне циклов другой основной пользователь этого командного оператора (в отличие от версии вызова функции) находится в макросах, которые возвращают значение после выполнения некоторых действий. . Есть и другие способы сделать это сейчас, но я думаю, что раньше было самым чистым способом использовать командный оператор.
#define next(A, x, y, M) ((x) = (++(y))%(M) , A[(x)])
Обратите внимание, что этот макрос является плохим примером макроса в целом, потому что он повторяет x и, вероятно, по другим причинам. Использование оператора запятой таким образом должно быть редкостью. Пример из вашей книги, вероятно, был попыткой уместить экзамен кода в пределах количества строк, доступных для этого примера.
В этом операторе возврата нет смысла.
Если x
был объявлен volatile
, это вызвало бы доступ (поскольку, по крайней мере, в C ++ ссылки на volatile
переменные считаются наблюдаемым извне поведением) , но это не так.
Если бы вместо x
было какое-то вычисление с побочными эффектами, он бы выполнил это вычисление и затем вернул бы y
. Однако не летучий
x
не имеет побочных эффектов. Реализация не требуется для выполнения какого-либо кода, который не имеет побочных эффектов или поведения, наблюдаемого извне. Оператор запятой выполняет все, что находится слева от запятой, игнорирует результат и выполняет и сохраняет значение правой стороны (за исключением того, что в этом случае можно игнорировать левую часть оператора).
Следовательно, оператор return x, y;
- это то же самое, что return y;
. Если бы x
не было просто совершенно бессмысленным исполнением, было бы стилистически лучше записать его как x; return y;
, что в точности то же самое.Это было бы не так запутанно.
Согласно 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)
Похоже на ужасный пример кода. Это может быть допустимый синтаксис в C / C ++, но я не могу придумать причину, по которой вы когда-либо захотели бы это сделать.
Если вы хотите вернуть и x, и y, лучший способ сделать это в C ++ - определить класс или структуру «Point» со свойствами x и y и вернуть их. Другой вариант - передать x и y по ссылке, а затем соответствующим образом установить значения в методе.
Если метод собирается просто вернуть y, я бы просто «вернул y;». Если x необходимо «вычислить» перед оператором return, это следует сделать в отдельной строке.
С одной стороны, это могло быть честной ошибкой со стороны автора.
С другой стороны, автор может объяснять синтаксически правильный код, а не предупреждения компилятора.
В любом случае, единственный способ вернуть несколько результатов - это определить класс и использовать его экземпляр или, возможно, массив или коллекцию.