#c #arrays #data-structures #malloc
#c #массивы #структуры данных #malloc
Вопрос:
Я создал структуру, подобную такой:
struct ponto {
int x;
int y;
int z;
};
1) Могу ли я инициализировать значения int значением по умолчанию? int var = value; похоже, не работает, компилятор сообщает «синтаксическая ошибка перед ‘=’ token» или что-то в этом роде.
2) Мне нужно работать с несколькими из них, как с массивом структур, но я знаю, сколько мне нужно, только после запуска приложения, после чтения файла. Как я могу это исправить?
Заранее спасибо
РЕДАКТИРОВАТЬ: Так много ответов, я благодарен. К сожалению, я могу отметить только один
Комментарии:
1. Ответов так много, что вы выбираете ответ, за который отдано 2 голоса
2. @fahad: Извините, если я не проверяю свои вопросы каждый раз в течение дня. Если я выбрал это в то время, это означает, что это, вероятно, было приемлемо для большинства, включая меня.
3. вам следует уделить некоторое время сообществу, чтобы оно проанализировало ответы, которые были бы лучше для вас, и SO.
Ответ №1:
a) Вы можете инициализировать с
struct pronto p = {1,2,3};
В последних компиляторах (не уверен, насколько это переносимо, думаю, это C99?)
б) Вы можете выделить массив с помощью malloc:
struct pronto *array = malloc(sizeof(struct pronto) * NUMBER);
Комментарии:
1. Если вы не приведете к
struct ponto *
, в C, вы, вероятно, получите предупреждение от компилятора. В C это вообще не будет компилироваться.2. Из Википедии: «В соответствии со стандартом ANSI C приведение является избыточным». en.wikipedia.org/wiki/Malloc
3. Ваш ответ (a) не имеет ничего общего с C99. Вы путаете инициализацию со составными литералами.
4. Я не думал, что это допустимый синтаксис для k amp; r c, и я не мог вспомнить, когда он был введен.
Ответ №2:
Чтобы инициализировать элементы вашей структуры равными 0, выполните:
struct ponto foo = { 0 };
Чтобы malloc()
получить массив нужного размера, выполните:
struct ponto *arr = (struct ponto *) malloc(COUNT * sizeof(struct ponto));
Не забудьте free()
удалить массив, когда закончите с ним.
Комментарии:
1. 1 за запрос к
free
массиву после использования. Нельзя говорить это достаточно часто!
Ответ №3:
struct ponto* create_and_init_ponto(int n)
{
struct ponto* array;
int i;
array = (struct ponto*)malloc( n * sizeof(struct ponto) );
for ( i = 0; i < n; i )
{
array[ i ].x = 0;
array[ i ].y = 0;
array[ i ].z = 0;
}
return array;
}
Ответ №4:
Вы создали определение структуры, теперь вам нужно создать переменную этой структуры, прежде чем вы сможете задать поля:
struct ponto xyz;
xyz.x = 7;
Чтобы выделить достаточно места:
int need_to_have = 24;
struct ponto *pontos = malloc (need_to_have * sizeof(struct ponto));
Ответ №5:
-
У вас не может быть значений «по умолчанию» для элементов структуры. Для определения структуры не выделено места. Вы просто создаете новый тип (например, встроенный
int
). Когда вы на самом деле определяете переменную типаponto
, для нее будет выделено место. -
Вы можете сделать обоснованное предположение о том, сколько вам понадобится, выделить место для этого количества (используя malloc) и продолжить. Если вы обнаружите, что достигли предела, вы можете использовать функцию realloc для изменения размера вашего массива.
Ответ №6:
1) Вы не можете присвоить определенной структуре значения по умолчанию для ее элементов на уровне языка, потому что все переменные в C неинициализированы, если вы явно не инициализируете их (или не делаете их статическими / внешними, в этом случае они инициализируются нулем). Однако, если вы разрабатываете свои структуры таким образом, что все нули являются хорошим набором начальных значений, вы всегда можете инициализировать их следующим образом:
struct foo myfoo = {0};
{0}
служит универсальным нулевым инициализатором, который работает для любого типа.
Если вам нужны другие значения по умолчанию, лучший способ — использовать макрос и задокументировать, что код, использующий вашу структуру, должен использовать макрос:
#define FOO_INITIALIZER { 1, 2, 3 }
struct foo myfoo = FOO_INITIALIZER;
2) Если вы знаете, прежде чем начать использовать какую-либо структуру, сколько их вам понадобится, просто malloc
используйте их все, как только узнаете число:
if (count > SIZE_MAX / sizeof *bar) abort();
struct foo *bar = malloc(count * sizeof *bar);
Обратите внимание на правильную идиому для вызова malloc
и предотвращения уязвимостей переполнения.
Если вы не знаете, какое число вам понадобится, пока не начнете с ними работать, начните с выделения приличного числа, а если оно закончится, увеличьте это число на фиксированное кратное, например, удвоение размера является обычным и простым делом. Здесь вы захотите проверить, нет ли переполнений. Затем используйте realloc
.
Ответ №7:
Вопрос № 1: Если вам нужно инициализировать int значением:
struct ponto p1;
p1.x = p1.y = p1.z = 3; // initializing with three
В качестве альтернативы, если вы хотите инициализировать все значения равными 0, вы можете использовать memset
вот так:
memset(amp;p1, 0, sizeof(struct ponto));
Вопрос № 2: использовать malloc:
struct ponto *ps;
ps = (struct ponto *)malloc(N*sizeof(struct ponto));
// where N is your element count.
Это приведет к выделению памяти для хранения N
элементов типа struct ponto
. После этого вы можете инициализировать его значения с помощью:
int initvalue = 3; // assuming you want to initialize points with value 3
for (i=0; i<N; i ) {
ps[i].x = ps[i].y = ps[i].z = initvalue;
}
Комментарии:
1. Я думал, что приведение из void * подобным образом считалось дурным тоном в C?
2. @awoodland: Почему? Каков ХОРОШИЙ СПОСОБ приведения из
void *
в C?3. Вам не нужно приведение, чтобы перейти от void * к struct pronto * в C, хотя вы бы сделали это в C . Возможно, здесь я ошибаюсь, но я думал, что причина отказа от написания (избыточного) приведения заключалась в том, что, поскольку оно не делает ничего полезного в правильном коде, единственное, что оно могло бы сделать, — это скрыть проблемы в неправильном коде. (Например, случайное удаление const в каком-то другом примере)
4. @Pablo: это не считается хорошей практикой в C. Это почти повсеместно считается вредным.
5. Кроме того, ваш ответ не инициализирует структуру. Он назначает своих членов. Инициализация была бы
struct ponto p1 = { 3, 3, 3 };