LINUX.ORG.RU

Не нравится мне твоё "сделать массив", сдаётся мне что ты собрался ссылку на локальный массив возвращать. :) Очень не рекомендую. :)

Вообще обычно в таких случаях функции передают указатель на массив или структуру, в которую она пишет результаты. А возвращает она в таком случае просто код завершения (типа успешно/неуспешно). См., например, man 2 fstat.

Teak ★★★★★
()
Ответ на: комментарий от Teak

typedef struct {
  int one,
  int two
} retval2;

retval2 * f(...) {
  retval2 * retval = NULL;

  ...
  if (!error) {
    retval = malloc(sizeof(retval2));
    retval->one = one;
    retval->two = two;
  }

  return retval;
}

int main(...) {
  retval2 * retval;

  if (retval = f(...)) {
    printf("one = %i, two = %i\n", retval->one, retval->two);
    free(retval);
  }
}

---
что нить типа такого в голову не приходило??? )))

Ex ★★
()

> Нужно возвратить из функции значения 2х переменных. На ум приходит
> только идея сделать массив с этими значениями и через return выдать
> указатель на него. Но может есть другой способ?

Так можно делать только если массив статический:

int *foo()
{
    static int a[] = {1, 2};
    return a;
}

Второй способ вернуть структуру:

struct S foo(char c, double d)
{
    struct S s;
    s.ch = c;
    s.dl = d;
    return s;
}

Третий способ, который обычно применяется во всех библиотеках,
объявить массив или структуру во внешнем блоке и передавать в функцию
их адреса.

shumer
()

Можно возвращать структуру, но считается, что это не оч. хорошо,
т.к. вся структура укладывается в стек:

typedef struct {
  int one;
  int two;
} retval2;

retval2 f() {
        retval2 x;
        x.one=1;
        x.two=2;
        return x;
}

int main(int argc, char **argv) {
        retval2 y;
        y=f();
}

Выделять память внутри функции считается не оч. правильным путём,
насколько я понимаю. Так что наиболее правильным является передача
функции указателя на структуру (или массив):

typedef struct {
  int one;
  int two;
} retval2;

int f(reval2 *x) {
        x->one=1;
        x->two=2;
        return 1; //код возврата=всё ок
}

int main(int argc, char **argv) {
        retval2 y;
        if (!f(&y))
                //обработка ошибки

}

Davidov ★★★★
()
Ответ на: комментарий от Davidov

>> Выделять память внутри функции считается не оч. правильным путём, насколько я понимаю. Так что наиболее правильным является передача функции указателя на структуру (или массив):

не спорю, попросили привести пример, мну привел то что первое в голову пришло )

Ex ★★
()
Ответ на: комментарий от Ex

>не спорю, попросили привести пример, мну привел то что первое в голову пришло )

Да не, никаких претензий. Сам так иногда делаю. Более того, по-моему, в каких-то стандартных вызовах было нечто подобное.

Я так понимаю, что логика состоит в том, что выделением памяти и её освобождением должны быть в логически эквивалентных местах.

То есть, например, в случае наличия функций retval2 *alloc_s1() и int free_s2(retval2 *r), всё уже хорошо. Вот и пример, где это может быть оправдано.

Кстати, всё это уже начинает смахивать на ООП.

Davidov ★★★★
()
Ответ на: комментарий от Davidov

таки ООП это парадигма программирования и не зависит от конкретной реализации в ЯВУ

Ex ★★
()
Ответ на: комментарий от shumer

>Так можно делать только если массив статический:

>int *foo()
>{
>    static int a[] = {1, 2};
>    return a;
>}

Только надо быть очень аккуратным: при повторном вызове будет возвращён тот же указатель.

Davidov ★★★★
()
Ответ на: комментарий от Davidov

>>Так можно делать только если массив статический:

>>int *foo() >>{ >> static int a[] = {1, 2}; >> return a; >>}

>Только надо быть очень аккуратным: при повторном вызове будет возвращён >тот же указатель.

Еще это несколько не thread-safe

anonymous
()

void test_retval (int a,int b, int c, int *ret1,int *ret2){
 ...
 *ret1=...;
 *ret2=...;
}

....
int r1,r2
test_reatval(1,2,3,&r1,&r2);
....

xnix ★★
()
Ответ на: комментарий от shumer

> Так можно делать только если массив статический:

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

Teak ★★★★★
()
Ответ на: комментарий от Teak

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

Конечно так делать не следует, хотя и возможно. Вобщем я сказал "can", а ты имел ввиду "may" :)

Блин, простой вопрос растянули уже на чертову дюжину постов. Короче, vdm, передавай в функцию адрес структуры с двумя полями и не парься. Все остальное грязный хак.

shumer
()
Ответ на: комментарий от Ex

> ув. тов. Teak прочтите пост выше...

Не, Ex, извини, но ты там фигню написал. Заморачиваться со структурой в функции стоит только если ты ее всю будешь возращать (структурка небольшая). А создавать ее динамически, а потом возвращать указатель, имхо хреновая идея. Кто-то использующий твою функцию должен знать и помнить о том, что ему где-то free надо втыкать, лишний, тяжелый malloc, и ради чего все?

shumer
()
Ответ на: комментарий от Teak

> Согласен, все посты в этой теме, кроме первого, моего, - лишние. :)

нет:)

ты не указал решение с возвратом структуры. Оно непопулярно, потому что этого не было в ранних компиляторах и про это не написано в К&Р Но для 2-х полей оно оптимально

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

> Оно непопулярно, потому что этого не было в ранних компиляторах и про это не написано в К&Р

Вот хохма на эту тему, совершенно случайно наткнулся:

2.2: I heard that structures could be assigned to variables and passed to and from functions, but K&R I says not.

K&R I was wrong; they hadn't actually learned C very well before writing the book. Later, Ritchie got a job at Bell Labs, and worked closely with the authors of C, allowing the 2nd edition of the book to be much more accurate. (Kernighan already worked at Bell Labs, as a video game developer.)

shumer
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.