Форум программистов, компьютерный форум, киберфорум
Наши страницы

C для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.63
Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
#1

Есть ли в Си аналог std::fill() в C++? - C (СИ)

20.09.2012, 20:01. Просмотров 4462. Ответов 32
Метки нет (Все метки)

Иногда хочется по-быстрому обнулить массив(типов double, int), написать функцию, конечно, не сложно, но, может, есть в стандартной библиотеке универсальный обнулятор?
Читал про memset, но, как я понял, он предназначен для char
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.09.2012, 20:01
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Есть ли в Си аналог std::fill() в C++? (C (СИ)):

Есть ли аналог Оператору foreach из C# - C (СИ)
Есть ли в Си аналог Оператору foreach который повторяет группу вложенных операторов для каждого элемента массива?

Есть ли в Си аналог GraphABC из Паскаля? - C (Си)
Собственно, сабж. Надо по данным из файла нарисовать график. В паскале надо было просто подрубить GraphABC, что подрубить надо тут?...

Есть ли в С аналог оператора locate (установка курсора на нужную позицию)? - C (СИ)
В языке бейсик оператор locate устанавливает курсор в нужное место. С этого места можно например выводить данные. А в Си?? Что есть?...

Есть ли аналог realloc(), но расширяющийся в обратную сторону и возвращающий указатель на начало - C (СИ)
встречный вопрос форумчанам. Есть ли аналог realloc(), но расширяющийся в обратную сторону и возвращающий указатель на начало. т.е. так ...

Есть ли в Qt аналог std::string copy ? - C++ Qt
Это снова я :) В std::string есть замечательная функция для копирования своего содержимого в какой - нибуть выходной буффер - copy, а в...

А есть какой нибудь широкий аналог std::ofstream? - C++
Ну чтоб wchar_t и указатель на wchar_t принимал. Хоть в какой нибудь уникодовой кодировке.

32
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
22.09.2012, 03:20 #16
Evg, так в данном случае явное приведение типа ведь не является требованием языка (мы ведь говорим о Си?).
0
Evg
Эксперт CАвтор FAQ
18246 / 6371 / 438
Регистрация: 30.03.2009
Сообщений: 17,625
Записей в блоге: 28
22.09.2012, 09:25 #17
Цитата Сообщение от Nameless One Посмотреть сообщение
Evg, так в данном случае явное приведение типа ведь не является требованием языка (мы ведь говорим о Си?).
Если говорить строго по стандарту, то точно не могу сказать. Указатель void* можно преобразовывать в любой другой, но вот обязательно ли писать преобразование - я не знаю. Я всегда писал и никогда этим вопросом глубоко не заморачивался. Но даже если не написать, то ничего не случится и построится ровно такой же код. А так же если операцию преобразования построить с указателем другого типа (именно об этом случае говорил ТС - поменял тип указателя-переменной, но забыл поменять тип после вызова malloc'а), то ничего не случится (кроме того, что код станет некрасивым). Компилятор в крайнем случае выдаст предупреждение
0
easybudda
Модератор
Эксперт CЭксперт С++
9693 / 5643 / 962
Регистрация: 25.07.2009
Сообщений: 10,848
22.09.2012, 12:02 #18
Evg, некто Роберт Лав (автор книги "linux системное программирование") пишет, что ручное приведение типа указателя, возвращаемого malloc, не только лишнее, но даже может создавать проблемы. У него и два примера приведено. Один из них мне кажется надуманным, но тем не менее... А вот у КиР в главе 7.8.5 наоборот сказано, что прям таки надо приводить указатель, возвращённый malloc/calloc к нужному типу. Авторы небезызвестной книги "UNIX разработка сетевых приложений" снова не считают нужным приведение типа значения, возвращаемого этими функциями. Дело ясное, что дело тёмное... Я просто из лени никогда не пишу руками приведение типа - если не пытаться компилировать код, как С++, проблем не замечал.
0
silent_1991
Эксперт С++
4986 / 3043 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
22.09.2012, 20:48 #19
Цитата Сообщение от Buckstabue Посмотреть сообщение
Плюс malloc не очень удобен, если вдруг где-то пришлось изменить тип массива с int на double, то приходится искать выделение под него памяти и менять типы и там, а если забудешь поменять, то компилятор вряд ли предупредит
Кто-то из крутых дядек советовал делать так:
C
1
2
int *d = NULL;
d = malloc(SIZE * sizeof(*d));
При смене типа в объявлении, при выделении его менять не придётся, и всё будет работать корректно. Судя по всему, именно об этом и говорил Nameless One здесь.
2
Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
22.09.2012, 20:54  [ТС] #20
silent_1991, только разыменование нулевого указателя довольно опасное дело вроде. Хотя это на этапе компиляции вычисляется...
0
silent_1991
Эксперт С++
4986 / 3043 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
22.09.2012, 22:04 #21
Buckstabue, нет там разыменование. Выражение внутри sizeof не вычисляется, sizeof - операция стадии компиляции. Компилятор вычисляет только тип выражения, стоящего внутри sizeof, а разыменования как такового не происходит.
1
Evg
Эксперт CАвтор FAQ
18246 / 6371 / 438
Регистрация: 30.03.2009
Сообщений: 17,625
Записей в блоге: 28
22.09.2012, 22:21 #22
Цитата Сообщение от easybudda Посмотреть сообщение
Evg, некто Роберт Лав (автор книги "linux системное программирование") пишет, что ручное приведение типа указателя, возвращаемого malloc, не только лишнее, но даже может создавать проблемы. У него и два примера приведено. Один из них мне кажется надуманным, но тем не менее... А вот у КиР в главе 7.8.5 наоборот сказано, что прям таки надо приводить указатель, возвращённый malloc/calloc к нужному типу. Авторы небезызвестной книги "UNIX разработка сетевых приложений" снова не считают нужным приведение типа значения, возвращаемого этими функциями. Дело ясное, что дело тёмное... Я просто из лени никогда не пишу руками приведение типа - если не пытаться компилировать код, как С++, проблем не замечал.
Реально приведение типов с иходнике не обязательно. Во-первых, компилятор сам его построит, во-вторых в коде приведение типов для указателя не выражается вообще никак (экзотические процессоры не рассматриваем). Навскидку сейчас не вспомню, но вроде бы старые версии компиляторов ругались на отсутствие приведения типа, а потому у меня вошло в привычку его писать с тех самых пор

Цитата Сообщение от silent_1991 Посмотреть сообщение
Кто-то из крутых дядек советовал делать так:
C
1
2
int *d = NULL;
d = malloc(SIZE * sizeof(*d));
При смене типа в объявлении, при выделении его менять не придётся, и всё будет работать корректно. Судя по всему, именно об этом и говорил Nameless One здесь.
Тут да, при замене типов можно хорошо накосячить. Как-то и не подумал я об этом
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
23.09.2012, 04:56 #23
Цитата Сообщение от Buckstabue Посмотреть сообщение
Хотя это на этапе компиляции вычисляется...
В верном направлении мыслишь. sizeof принимает своим аргументом тип или выражение. В случае с выражением он вычисляет размер типа, значение которого является результатом выражения. Естественно, при этом само выражение не вычисляется. Вычисляется лишь его тип и размер этого типа.

Это можно проследить на следующем примере (аргумент sizeof представляет собой выражение с побочными эффектами):

C
1
2
3
4
5
6
7
#include <stdio.h>
 
int main(void)
{
    printf("%zu\n", sizeof puts("SIZEOF"));
    return 0;
}
Вызова функции puts не произойдет, что явно видно из вывода программы.

BTW, если аргумент sizeof представляет собой не тип, а выражение, то скобки вокруг аргумента можно опустить (как в предыдущем примере). Но это уже дело вкуса.
1
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
23.09.2012, 05:13 #24
Цитата Сообщение от silent_1991 Посмотреть сообщение
Судя по всему, именно об этом и говорил Nameless One здесь.
именно. Я как-то раз об этом уже писал подробный пост.

Цитата Сообщение от Evg Посмотреть сообщение
Навскидку сейчас не вспомню, но вроде бы старые версии компиляторов ругались на отсутствие приведения типа
если я не ошибаюсь, это было из-за того, что раньше функции выделения памяти возвращали char*
1
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
23.09.2012, 05:23 #25
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от easybudda Посмотреть сообщение
А вот у КиР в главе 7.8.5 наоборот сказано, что прям таки надо приводить указатель, возвращённый malloc/calloc к нужному типу
о преимуществах и недостатках можно почитать тут. Согласно этой статье, для современного Си преимуществ нет
3
Evg
Эксперт CАвтор FAQ
18246 / 6371 / 438
Регистрация: 30.03.2009
Сообщений: 17,625
Записей в блоге: 28
23.09.2012, 11:02 #26
Цитата Сообщение от Nameless One Посмотреть сообщение
если я не ошибаюсь, это было из-за того, что раньше функции выделения памяти возвращали char*
Вполне возможно. Мне уже просто негде взять эти старые компиляторы, чтобы проверить, но очень может быть, что именно так оно и было. Во всяком случае такой вариант мне видится намного более логичным в плане ругательства компилятора

Добавлено через 2 минуты
Цитата Сообщение от Nameless One Посмотреть сообщение
о преимуществах и недостатках можно почитать тут. Согласно этой статье, для современного Си преимуществ нет
В 64-битных режимах мы действительно много раз нарывались на описанную проблему. Так что привычку пора менять и преобразование типа не писать вообще, ибо так получается надёжнее

Добавлено через 2 минуты
Что бы там ни думали модераторы, но иногда всё-таки полезно разводить флуд после того, как ТС получил ответ на свой вопрос. Век живи, век учись. В полезные ссылки добавил пост #25
0
easybudda
Модератор
Эксперт CЭксперт С++
9693 / 5643 / 962
Регистрация: 25.07.2009
Сообщений: 10,848
23.09.2012, 11:30 #27
Nameless One, здесь на форуме есть одно очевидное преймущество приведения типов - не нужно в сотый раз объяснять, что С программу как С и компилируют.
Кстати есть ещё один "стандартный обнулятор" - http://www.freebsd.org/cgi/man.cgi?q...lt&format=html
1
remarkes
303 / 226 / 13
Регистрация: 01.07.2011
Сообщений: 809
Записей в блоге: 1
26.09.2012, 21:23 #28
Цитата Сообщение от easybudda Посмотреть сообщение
есть ещё один "стандартный обнулятор"
man 3 bzero
4.3BSD. This function is deprecated (marked as LEGACY in
POSIX.1-2001): use memset(3) in new programs. POSIX.1-2008 removes the
specification of bzero().
0
easybudda
Модератор
Эксперт CЭксперт С++
9693 / 5643 / 962
Регистрация: 25.07.2009
Сообщений: 10,848
27.09.2012, 00:07 #29
remarkes, но тем не менее к gcc эта функция и под *NIX и под Win прилагается, а мелкомягким чужие стандарты вообще не указ, им бы со своими разобраться. К тому же в BSD-шном мануале про то, что этой функцией лучше не пользоваться, ничего не сказано. Опять же, авторы упомянутой уже книги "UNIX разработка сетевых приложений" пользуются именно ей, но с оговоркой, что bzero не является функцией ANSI C.

Цитата Сообщение от Evg Посмотреть сообщение
Тут да, при замене типов можно хорошо накосячить.
Цитата Сообщение от easybudda Посмотреть сообщение
а на случаи внезапной смены типа typedef существует.
Ну про это и говорил, только немного в другом ключе:
C
1
2
3
typedef int my_great_type;
/*...*/
my_great_type * ptr = malloc(sizeof(my_great_type) * ELEMENTS_COUNT);
При замене первой строки на
C
1
typedef double my_great_type;
возня с динамической памятью должна бы работать так же. Но при замене типа с вводом/выводом заморочки в любом случае появятся, может и ещё с чем-нибудь...
0
remarkes
303 / 226 / 13
Регистрация: 01.07.2011
Сообщений: 809
Записей в блоге: 1
27.09.2012, 07:41 #30
Цитата Сообщение от easybudda Посмотреть сообщение
а мелкомягким чужие стандарты вообще не указ, им бы со своими разобраться
95% разрабов MS поди и не знают, что Windows (sic!) поддерживает POSIX.

Цитата Сообщение от easybudda Посмотреть сообщение
с оговоркой, что bzero не является функцией ANSI C
много чего не является ANSI C , как правило на это кладется "std прибор"
Имхо, легче перенести программу со своей средой, чем пытаться подстраиваться под стандарт.
0
27.09.2012, 07:41
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.09.2012, 07:41
Привет! Вот еще темы с ответами:

Алгоритм std::find_end - аналог std::search_n - C++
Есть два семейства стандартных алгоритмов: std::search и std::find_end. Первое семейство предназначено для поиска первого совпадения...

Аналог std::replace. - C++
вечер добрый. template &lt; class ForwardIterator, class T &gt; void replace ( ForwardIterator first, ForwardIterator last, ...

Аналог std::system() из C++ - C#
подскажите аналог std::system(&quot;explorer&quot;); в c#?

Аналог std::string - C++
Имеется некоторый класс, обеспечивающий работу с символами UTF-8. Назовём его uchar. Можно ли простым способом организовать класс ustring,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru