LINUX.ORG.RU

Как из функции вернуть 2 значения?

 , ,


2

0

Привет. Есть функция из которой возвращается указатель, в ней же происходит расчёт количества элементов для нового массива.

Так вот вопрос, как из неё вернуть количество элементов?

Или подскажите, как отдельно посчитать кол-во элемов в массиве чисел.

Пробовал добавить параметр в функции Int *count_new. И делать в функции вот так: count_new = &count, но не работает нифига.



Последнее исправление: CYB3R (всего исправлений: 1)

Ответ на: комментарий от DarkEld3r

Ну и сложнее проигнорировать остальные значения, если ты про всякие multiple-value-bind.

А почему это мне должно быть сложно их проигнорировать?

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

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

ChuCha
() автор топика
Ответ на: комментарий от Eddy_Em

Предлагаешь бросить си и начать с чего-то проще? Не вижу смысла, если разберусь в си, в другом будет не проблема, тем более хочется под линукс пописать.

ChuCha
() автор топика
Ответ на: комментарий от ChuCha

Предлагаешь бросить си и начать с чего-то проще?

Проще — только ассемблера. Начать с чего-нибудь сложней.

А вообще, выбирай: если хочется для себя любимого, то сишечка. А если "тяп-ляп — и в продакшн", то какая-нибудь жабка и т.п.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от ChuCha

1) Для того, чтобы избежать подобных проблем достаточно прочитать первую главу любой книжки по программированию.

2) Я говорил про изначальный вопрос, вообще говоря.

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

А почему это мне должно быть сложно их проигнорировать?

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

DarkEld3r ★★★★★
()
Ответ на: комментарий от no-such-file

Они удобны только потому, что в пистоне есть множественное присваивание на кортежах

Далеко не только в питоне.

даже лучше, т.к. поля именованы.

Во многих случаях, действительно лучше.

Там нисколько не сложнее

Ну я вообще-то наоборот говорю, что «там» (с нормальным возвратом нескольких значений) проще игнорировать.

компилятор заранее знает, что и сколько функция должна вернуть и соответственно её оптимизировать, а не просто тупо сконструировать кортеж/список/структуру в куче.

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

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

по алгоритмам достаточно:

Томас Х. Кормен Алгоритмы(Вводный курс)

по С: если ты действительно хочешь как оно работает/устроенно

то берёшь K&R(желательно первую редакцию eng1979ru1984?) и пишешь свою реализацию компилятора с (в помощь можешь использовать http://dl.acm.org/citation.cfm?id=358210 и http://bellard.org/otcc/ )

в качестве хост окружения выбери x64 и linux как целевую ось - так проще

а асм(в часть кодогенерации) в достаточном уровне освоишь что бы сравнить с выдачей того же gcc.

ps 3 - по поводу нерядовых алгоритмов: у Вирта в предисловии в его Построение Компиляторов(где он показывает реализацию недоОберона) - есть примечательное предложение: по мере переписывания компилятора тесты показали что нет необходимости использовать бинарных поиск в части поиска когда лексический анализ - достаточно линейного.

pps. у Кена Томпсона случилось на оборот старый метод поиска в каталоге был линейный (поэтому у некоторых до сих пор)- ибо ожидалось не более 64? входов :) - что потом вылезло боком когда каталоги пожирнели :)

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

Для себя первый год минимум, а так мне питон ещё нравится

ChuCha
() автор топика
Ответ на: комментарий от Quickern

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

ChuCha
() автор топика
Ответ на: комментарий от qulinxao

Интересно, опыта наберусь - попробую.

ChuCha
() автор топика
Ответ на: комментарий от ChuCha

Тут дело в том, что у меня ошибка была не с указателями, а в области видимости переменной

хочется надеяться, что дело именно в непонимании указателей

если проблемы с областью видимости переменной, то стоит сделать пару шагов назад и разобраться с этим

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

Множественные значения как раз стоит использовать когда есть одно основное значение и несколько побочных (drakma:http-request - отличный пример), а когда нужно вернуть несколько важных значений никто не мешает тебе объединить их в одну сущность, чтобы вызвавший код не упустил ничего просто так. Это может быть список, кортеж, структура, объект, функция, что душе угодно.

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

Множественные значения как раз стоит использовать когда есть одно основное значение и несколько побочных

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

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

Интересно, добавил в закладки, почитаю на досуге, спасибо.

ChuCha
() автор топика
Ответ на: комментарий от DarkEld3r

Самое смешное, что каждая из фич Common Lisp, кажется такой, что без нее «можно прожить». gc — переживем, будем руками, макросы — переживем, будем костыликами, на ограниченном языке, generalized boolean — будем, все как прилежные ученики приводить, скажем к #t,#f, ортогональность — да ну ее нафиг, введем сто «особых случаев».


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

seg-fault
()
Ответ на: комментарий от seg-fault

Самое смешное, что каждая из фич Common Lisp, кажется такой, что без нее «можно прожить».

Ну вообще-то не совсем так. Тот же ГЦ даётся не даром и в ряде случаев отказ от него будет вполне разумным и сознательным решением. Опять же, в «удобно мне» слишком много субъективного. Скажем, мне не слишком комфортно писать на языках с динамической типизацией.

Опять же, макросы есть и вполне нормальные не только в лиспо-подобных языках.

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

Тот же ГЦ даётся не даром

Я сам много писал писал на C/C++ и привык к «все для perf», в том числе и «максимально эффективному» контролю над распределением памяти. Для меня было интересно узнать, в отчетах лисповского time, что на GC тратится обычно <10% времени даже в очень пожирающих память программах.

Опять же, в «удобно мне» слишком много субъективного. Скажем, мне не слишком комфортно писать на языках с динамической типизацией.

Наверное. Не агитирую. Просто после того как groked CL все становится на свои места. По работе приходилось и приходится иметь дело с большими и сложными проектами на C++ (компиляторы,виртуальные машины и тп) и там весь идиотизм, в том числе и статической типизации, становится очевидным. Смотришь в чужой код на 100500 строк и понимаешь, что они на самом деле, пытаются сделать что-то, что на CL вообще «не надо решать», дано и так.

seg-fault
()
Ответ на: комментарий от seg-fault

и там весь идиотизм, в том числе и статической типизации, становится очевидным

Ну-ну. Я ничего не имею против CL (хотя мне больше по душе racket, впрочем, ни на том ни на другом я ничего сильно большого не писал), но вот таких аргументов не надо. А то послушаешь - прямо волшебный инструмент, который решает все задачи на порядок легче. Но почему-то этого не видно. Прекрасно понимаю «инертность» большинства людей, но хватило бы малого количества лисперов, которые бы «всех зарулили». Но что-то такого не наблюдается. Только, пожалуйста, не надо рассказывать про Viaweb.

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

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

Только, пожалуйста, не надо рассказывать про Viaweb.

А я не знаю ничего про Viaweb, меня там не было, да и все что про web мне неинтересно.

seg-fault
()
Ответ на: комментарий от seg-fault

Да они и так рулят

С чего ты взял? Почему об этом ничего неизвестно?

а тратить свое время на убеждение агрессивно настроенного большинства, кому это надо.

Ну о лиспе только из таких попыток убеждения и слышно...

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

Ну о лиспе только из таких попыток убеждения и слышно...

Лови плюсик.

anonymous
()
Ответ на: комментарий от DarkEld3r


Я о тех, кому надоело работать на дядю. А в каком смысле ты понимаешь 'рулить'? Быть передовым инженером в авангарде толпы?

seg-fault
()
Ответ на: комментарий от seg-fault

Я о тех, кому надоело работать на дядю

Т.е. о тех, кто делает свое дело? А при чем тут лисп? Тут уже программирование вообще ни при чем.

Быть передовым инженером в авангарде толпы?

Если бы CL был хорошим языком, на котором пишут хорошие проекты, то и та часть хороших проектов, что открыты и на слуху, с высокой долей вероятности так же были бы на лиспе. И тот факт, что их нет, говорит о многом.

anonymous
()
Ответ на: комментарий от seg-fault

А в каком смысле ты понимаешь 'рулить'?

В прямом. Пол Грэм как раз рассказывал как они с лёгкостью обошли всех конкурентов благодаря лиспу. Если бы лисп действительно давал такие явные преимущества, то лисповые стартапы куда чаще выстреливали и были бы на слуху. Да чего уж там - если инструмент хорош, то стали бы подтягиваться и большие конторы не смотря на «маргинальность синтаксиса».

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

Тут уже программирование вообще ни при чем.

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

то и та часть хороших проектов, что открыты и на слуху

Да в общем-то, и про закрытые часто известно на чём они написаны.

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

Агитировать за CL не буду, не интересно это мне. Равно как и утверждать, что CL это талисман который всем поможет. Если человек влез в программирование, потому что это модно или денежно, то ему точно не поможет.

Как сказал один умный человек из #lisp:

<nyef> «CL is like Democracy. It sucks, but it sucks less than the alternatives.»

Кто-то въезжает и разделяет это, кто-то нет. I'm fine with it.

Ориентироваться, да даже смотреть, на то как делают все, что модно, как делают большие конторы - рано или поздно набиваешь шишек, взрослеешь, умнеешь и все это становится не интересно. Мне абсолютно фиолетово где какие success stories, видно или не видно конторы использующие CL.

seg-fault
()
Ответ на: комментарий от seg-fault

Агитировать за CL не буду, не интересно это мне.

Тем не менее, именно этим ты тут и занимаешься.

Кто-то въезжает и разделяет это, кто-то нет.

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

Мне абсолютно фиолетово где какие success stories, видно или не видно конторы использующие CL.

Ну и зря, посмотреть по сторонам бывает полезно, расширение кругозора, опять же.

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

Тем не менее, именно этим ты тут и занимаешься.

OK больше не буду.

seg-fault
()
Ответ на: комментарий от DarkEld3r

Во первых, почему обязательно в куче?

А где? На стеке нельзя, в регистрах тем более.

компилятор в месте вызова не будет знать какие значения используются, а какие нет?

И какая разница? Компилятор будет фигачить отдельный вариант функции под каждый вызов? В случае с множественными значениями, если их например 2, то функция может возвращать их через регистры. Всегда. А если возвращается кортеж из 2 элементов, то при компиляции функции неизвестно будет ли он использоваться как кортеж, или как 2 значения по отдельности.

Во многих случаях, действительно лучше

Тогда к чему была ирония про высокоуровневые языки? Ну ладно, ляпнул и ляпнул.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

На стеке нельзя

Это ещё почему? Вот код на плюсах, где там выделение памяти в куче?

tuple<int, double, int> foo()
{
    return make_tuple(1, 2.0, 3);
}

const auto a = foo();

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

Это не так. Вот код на расте, по твоему, компилятор не сможет оптимизировать? Ну и с таким сахаром оно слабо отличается от возврата нескольких значений.

fn foo() -> (i32, f64) {
    (10, 11.0)
}

// У а тип i32, тупл целиком не нужен. 
let (a, _) = foo(); 
Кстати, структуры вполне могут возвращаться через регистры. Думаешь для туплов из двух элементов это невозможно?

Тогда к чему была ирония про высокоуровневые языки?

Ты сейчас вообще о чём? Я поинтересовался много ли ты знаешь языков с такой фичей и мне по прежнему интересно.

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

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

Вот код на плюсах, где там выделение памяти в куче?

А где там вообще выделение памяти? Кортеж попадает прямиком в a.

компилятор не сможет оптимизировать?

Нет, если только функция не инлайн. В момент компиляции функции компилятор не может знать, нужен ли тебе кортеж как самостоятельный объект, или ты его разбираешь на элементы. Когда ты пишешь let (a, _) = foo(); функция уже скомпилирована и там ничего поменять нельзя.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

А где там вообще выделение памяти? Кортеж попадает прямиком в a.

А вот так, например, может и не попасть:

tuple<int, double, int> foo()
{
    auto r = make_tuple(1, 2.0, 3);

    if( rand() % 2 )
        throw 0;

    return r;
}

const auto a = foo();

Если компилятор не окажется слишком умным. И тогда будет копирование внутри стека.

anonymous
()
Ответ на: комментарий от no-such-file

А где там вообще выделение памяти? Кортеж попадает прямиком в a.

Давай сначала - это ты почему-то сказал, что кортеж/структура будут создаваться в куче, в отличии от «честного возврата нескольких значений». В «а» кортеж попадёт, если будет оптимизация, что в общем-то не обязательно (но очень вероятно, да). Тем не менее, память на стеке вполне будет выделена.

Нет, если только функция не инлайн.

Есть ещё такие вещи как link time optimization. Впрочем, это как и иналйн детали реализации. Но потенциально такая оптимизация вполне возможна.

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

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

Да, вроде, NRVO давно не является чем-то экзотичным.

Я не зря вставил throw, он, например, препятствовал NRVO в MSVC. Как сейчас не знаю.

anonymous
()
Ответ на: комментарий от DarkEld3r

Тем не менее, память на стеке вполне будет выделена

Но ты об этом не узнаешь, т.к. она будет выделена «за сценой», и ты увидишь только что копия кортежа оказалась в a. Поэтому вообще-то так делать не принято, если нет гарантии (или большой вероятности), что ничего нигде дополнительно выделяться не будет.

Давай сначала

Давай

Да ладно, вполне удобный «костыль»

Костыль он и есть костыль, как ты его не крути. Функция должна вернуть кортеж, а для этого она должна его сделать именно как кортеж, как некую структуру данных.

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

На сколько я понял, здесь возражений нет - мне не понятно о чём мы спорим.

no-such-file ★★★★★
()
Ответ на: комментарий от DarkEld3r

Очень даже принято

Принято потому, что в любом вменяемом компиляторе ничего в стеке промежуточного не создается. Ты уже определись тогда, есть RVO или нет.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Ты уже определись тогда, есть RVO или нет.

Изначально спорил я с тем, что память будет выделена в куче. Но похоже мы опять по кругу пошли, в общем спор себя исчерпал.

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