LINUX.ORG.RU

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

 , ,


2

0

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

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

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

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



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

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

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

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

А где именно код, который выше с вашей идеей. Код i-rinat-a вижу, твоего с его подсказкой (какая тут идея) — не вижу.

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

Ну и чванство.

http://skipy.ru/philosophy/learning.html

Представьте себе ситуацию: вам надо что-то сделать, но вы не знаете, как. Как вы поступите – спросите у кого-то или начнете разбираться сами? Как часто вы поступаете первым способом? Как часто вторым?

Большая, если не большая часть тем в форумах по программированию, как правило, сводится к вопросу «как... ?». Как сделать это? Как реализовать это? Как? Как? Как?.. Причем зачастую для ответа на этот вопрос достаточно всего лишь прочитать пару страниц документации. Не нужно ничего сверхъестественного. И тем не менее – вопросы появляются с завидной регулярностью.
greenman ★★★★★
()
Ответ на: комментарий от ChuCha

запаковывай в 128битное( long long long?) число.

ведь всё лишь последовательности бит.

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

нырни в реализации в Golang либо в старые libc От фрей али ещё более древних юниксов.

там код вполне читаем ( в отличии от gnu-сверхзаточеных под констекст простынь)

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

менеджить память - это удовольствие.

ну ведь num_of_elem_without_zeros можеш возвращать по ((T*)normalize_rec)[-1] :) где T is typeof(num_of_elem_without_zeros)

so: change u(:() code to :

char *normalize_number(int count, char *res) {
	int num_of_zeros = 0;
	int i = 0;
	while (res[i] == 0) {
		num_of_zeros++;
		i++;
	}

	int num_of_elem_without_zeros = count - num_of_zeros;

	char *normalize_res = malloc(sizeof(char) * (num_of_elem_without_zeros)+sizeof(int));
        ((int*)normalize_res)[0]=num_of_elem_without_zeros;
         normalize_res+=sizeof(int);

	for (int i = num_of_elem_without_zeros, j = 0; i < count; i++, j++)
		normalize_res[j] = res[i];


	return normalize_res;
}

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

python потом golang

если куришь С тогда mmix

а программировать учиться стоит сразу на алгол языках(паскаль в доисторические времена, ща питон)

C слишком требовательный к уровню(способностям) новичка.

обрати внимание создатель C - чель с оконченным математическим образованием.

и вообще суть С видеть битики за полуабстракциями.

поэтому стоит научиться пользоваться хэшами и прочими авторасширяющимися массивами(в жабе Аrray , в С++ vector<>, в Python [] (list))

по саморасширающимся массивам - реализации и там и там с высоты птичьего полёта везде одна.

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

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

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

Напиши себе либу в с++/ооп стайле и пиши норм.

typedef struct {
  void * ptr;
  uint64_t len;
} buf_t;

buf_t buf_alloc(uint64_t len) {
  return (buf_t){malloc(len), len};
}

void * buf_get_end(buf_t buf) {
  return buf.ptr + buf.len;
}

void * buf_get_begin(buf_t buf) {
  return buf.ptr;
}

uint64_t buf_get_len(buf_t buf) {
  return buf.len;
}
buf_t buf_create(void * ptr, uint64_t len) {
  return (buf_t){ptr, len};
}

buf_t buf_memcpy(buf_t from, buf_t to) {
  return (buf_t){memcpy(buf_get_begin(to), buf_get_begin(from), buf_get_len(to)), buf_get_len(to)};
}

buf_t buf_cpy(buf_t x) {
  return buf_memcpy(x, buf_alloc(buf_get_len(x)));
}

buf_t buf_pseek(buf_t buf, void * new_ptr) {
  return (buf_t){new_ptr, buf_get_len(buf) - (new_ptr - buf_get_begin(buf))};
}

buf_t normalize(buf_t res) {
  return buf_cpy(buf_pseek(res, ({
    char * it = buf_get_begin(res);
    while(!(*it)) ++it;
    it;
  })));  
}

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

Пиши красиво - скилл будет расти просто по тонне в секунду.

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

1. Не используй глобальных переменных никогда, будь оно хоть хеллоуворлдом. Иногда без них не обойтись, но это не тот случай.

2. Сейчас меня закидают и будут правы, но вот то, что ты хочешь:

char *normalize_number(int count, char *res, int *noewz) {
    ...

    *noewz = num_of_elem_without_zeros;
    return normalize_res;
}

void f()
{
    ...
    int noewz;
    arr = normalize_number(cnt, rs, &noewz);
    ...
}
После чего в noewz будет значение num_of_elem_without_zeros.

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

Мистер Царь, доброго вам дня. За компом буду, разберу ваш код. А так да, моя софтина именно это и делает.

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

Сам по себе p - это указатель, в котором содержится адрес. Чтобы обратиться к переменной по этому адресу, нужно разыменовывать указатель: *p. &num — это адрес переменной num. В коде:

p = &num;

Ты присваиваешь адрес переменной num указателю p. Переменная-указатель p теряется, как только заканчивается выполнение функции (а значение переменной, на которую указывает p, не изменилось). Тебе же нужно присвоить переменной, на которую указывает p, значение num. То есть правильно будет так:

*p = num;
anonymous
()
Ответ на: комментарий от anonymous

Я это понимаю, дело в другом, почему не работает вот так.

Int *p; Char * F(char *buf,int *p) { Int a; p = &a; } По идеи в p указывает на a, верно?получить этого значения я не могу. Компилятор пишет варнинг, что p не инициализирована, хотя там должен быть адрес. Но я так понимаю, что переменная а перестаёт жить и теряется адрес.

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

buf_get_end(buf) - new_ptr

Молодец. Возможно именно по этой причине я и написал эту функцию, но почему-то не заюзал. А щас даже не знаю почему, странно.

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

Не, не из-за этого. Ты объявляешь глобальную переменную p. А затем её переопределяешь в функции F(...), точнее в её сигнатуре. По правилам областей видимости, внешняя переменная p перекрывается внутренней (в пределах этой функции). Ты присваиваешь значение внутренней переменной. Затем функция заканчивается, и внутренняя переменная p исчезает. Как видишь, к внешней переменной ты не обращаешься и ничего её не присваиваешь, поэтому она и остаётся неинициализированной. Решением будет либо не объявлять переменную p в сигнатуре и использовать одну глобальную p, либо не объявлять глобальную p и передать адрес переменной (на которую будет указывать p) параметром при вызове F(...) из другой функции.

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

Хотя, впрочем, это тоже верно.

anonymous
()
char *normalize(char *buf, int length, int *new_length)  {
  while (!(*buf))  {
    ++buf;
    --length;
  }
  *new_length = length;
  return memcopy(malloc(length), buf, length);
}
anonymous
()
Ответ на: комментарий от ChuCha

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

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

Си чаще всего приводит к синдрому утенка.

Изучал бы тогда какой-нибудь из языков ассемблера, если хочешь работы на низком уровне. У си таки есть своя абстрактная машина и он все равно не задаёт последовательность действий ВС напрямую.

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

Зачем ты рассуждаешь о том, в чем абсолютно нихрена не понимаешь?

Дефолтный пример того, как домохозяйка оправдывает своё скудоумие и ограниченность в выборе профессии тем, что типа «работа». А самое смешное, что ни одна из этих пистон-мастериц не осилила ни сишки, ни чего-либо, о чем кукарекает.

И правильно, ведь не осилила не потому, что не может, а потому, что типа не нужно.

TrueTsar1C
()
Ответ на: комментарий от i-rinat

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

Это либо анальная рабыня Pinkbyte, либо сам он. Скудоумие друг обоих, поэтому точно отличить нереально.

И тут мы видим - я спорил и обоссывал эту балаболку сотню раз(и одну и вторую), под данной учёткой уже раза 3обоссал анонимуса точно. И почему-то меня не банили. А тут вдруг забанили, почему?

Потому, что жопу разорвало так, как никогда. Это банальный пример моей правоты. Мне очень пичально, что я живу в мире таких убогих мразей - не будь таким. Вот в чём смысл? Зачем меня банить? Просто напакастил.

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

Только проблема одна, балабол никогда этого не поймёт без канавы, жалко.

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

как это внутри

просто по пиши на асме(т.е. на аля debug.exe - где мнемоники(опкоды) команд вместо машкода а в остальном абсолютная адрессация во всей красе в сегментах).

т.е на на асме как промышленном а на асме учебном.

ну и во всех(?) современных ide можно пошаговый отладчик включить не только на уровне команд языка , но и на уровне целевой машины - т.е. на асме - вполне просвещает.

разница между с и паскалем в обучении слишком преувеличена.

тот же turbo pascal имел такой глобальный массив как mem - так что выстрелить в ногу можно было и в нём.

а вот непонимае массивов(а не умение в указатели это и есть частный случай не понимания как работают массивы) - это без осознания поциентом ни как иначе не лечиться

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

у царя приступ конспирологии, и веры в существовании Его(Он) как части Их(Они)

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

Почему бред? Что конкретно бред - скажи, я тебе объясню.

Только постарайся отвечать конкретно.

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

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

ChuCha
() автор топика

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

Правильно не работает. Так ты присваиваешь внешней переменной адрес внутренней переменной функции. Адрес, а не значение копируешь. Эта внутренняя переменная у тебя создана на стеке и уничтожится по выходу из функции. Соответственно, count_new будет указывать на мусор. Нет, он тебя послушается, адрес будет верным, именно тот, который ты туда записал, но вот значение по этому адресу уже уничтожится к тому времени. Это как прийти на свидание с букетом роз и опоздать, девушка уже ушла.

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

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

В высокоуровневых языках используют множественные возвращаемые значения.

И много таких языков?

Кортежи это костыль

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

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

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

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

Я не считаю си плохим выбором, мне интересно.

Хорошо, если интересно. Но я так понял, вы про обучение тут говорите. И вот тут вопрос спорный, является ли си хорошим языком для обучения... У него непростой синтаксис, слабые средства абстракции, слабые выразительные средства. И я не очень понимаю, зачем для обучения брать именно его. За то время, когда вы разбираетесь с особенностями си(именно си, т.е. эти особенности при работе с другими языками вам не потребуются), можно разобраться с другими темами, которые к языку не привязаны. Скажем, с конкурентностью, параллельностью. С сетевыми технологиями. С распределенными системами. С алгоритмами. С методиками анализа больших данных. С компьютерной графикой. Да еще черт знает с чем.

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

если я научусь программировать на си, я смогу видеть надостатки в чем угодно и каждый день ныть о том, что писать на си было бы в 100 раз продуктивней и приятней (в реале же никто сейчас на си не пишет, кроме ембедщегов, но туда тебя без 10 лет опыта не возьмут все равно)

fixed for glory

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

Тем более, если я научусь программировать на си, я смогу программировать на чем угодно.

С чего ты взял? Это, мягко скажем, не так.

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

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

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

Я согласен с вами в отношении тем не привязанных к языку. Алгоритмы для меня в приоритете.

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

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

Quickern ★★
()

Попробуй поделать упражнения из K&R.

И да, трижды подумай, прежде чем углубиться в С! Недаром выше аноним не советовал тебе этот ЯП. Как пример негативного воздействия сишечки на человеческий мозг приведу тебе себя. У меня вообще все на сях: от "скриптиков" и прошивок мелкоконтроллеров до считалок и веб-сервисов. Правда, я — не программист, в моем случае важен результат, а на инструмент пофиг. Вот и деградирую я, не имея совершенно никакого желания изучать другие ЯП.

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

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

Если знания самого языка «не очень», то читайте Ворожцов и Винокуров, там первая часть очень здорово погружает в язык, вторая в алгоритмы плюс задачи есть интересные и вообще гнига написана преподами МФТИ, а там хорошие преподы.

IvanR ★★★
()
Последнее исправление: IvanR (всего исправлений: 1)
Ответ на: комментарий от ChuCha

если я научусь программировать на си, я смогу программировать на чем угодно

Нет.

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

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

Они удобны только потому, что в пистоне есть множественное присваивание на кортежах. А вот в перле всё тоже самое, но на списках. Что теперь, списки удобный костыль? Ну тогда в Си есть присваивание структур - ничуть не хуже кортежей или списков для возврата значений, даже лучше, т.к. поля именованы.

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

Там нисколько не сложнее, учитывая, что можно запилить свой макрос или просто использовать destructuring-bind. Больше того, с настоящими множественными значениями компилятор заранее знает, что и сколько функция должна вернуть и соответственно её оптимизировать, а не просто тупо сконструировать кортеж/список/структуру в куче.

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