2016-10-31 2 views
1

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

Так вот код у меня есть:

#include <stdio.h> 
#include <stdlib.h> 

#define ARRAY_SIZE 5 

// gcc -std=c99 stackoverflow-example.c 

int main() { 

    // declare variable array1 
    int array1[ARRAY_SIZE]; 
    // declare and init variable array2 
    int array2[ARRAY_SIZE] = {}; // for integers, the default value is 0 

    // not initialized 
    for (int i = 0; i < ARRAY_SIZE; i++) { 
     // can be anything, not guaranteed to be 0 
     printf("array1[%d]: %d\n", i, array1[i]); 
    } 

    // initialized with initialization list 
    for (int i = 0; i < ARRAY_SIZE; i++) { 
     // element == 0 
     printf("array2[%d]: %d\n", i, array2[i]); 
    } 

    // This is the part that confuses me. 
    // array1 = {}; // error: expected expression before ‘{’ token 
    // array1[] = {}; // same error 

    return EXIT_SUCCESS; 
} 

Есть удобный способ для инициализации этого массива после его объявления? Или единственный способ установить каждый элемент в array1 это с цикл, например .:

for (int i = 0; i < ARRAY_SIZE; i++) 
    array1[i] = 0; 

// initialized with a for loop 
for (int i = 0; i < ARRAY_SIZE; i++) 
    // now it's guaranteed to be 0 
    printf("array1[%d]: %d\n", i, array1[i]); 

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

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

+0

Я думаю, вы должны попробовать функцию 'memset'. Он оптимизирован для инициализации блоков данных с постоянным значением. – Milack27

+0

Хорошо, спасибо. Хотя, он работает только для инициализации с помощью 0 (знаю, что я использовал 0 инициализированный массив в моем примере, так что это действительно сработало). и -1 [(и это действительно не гарантировано)] (http://stackoverflow.com/a/7202857/4541492). Благодарю вас, тем не менее. –

+0

О, мое плохое. Вы правы, 'memset' специфичен для массивов байтов. – Milack27

ответ

1

Технически говоря, initialization может быть выполнен один раз и только во время объявления, любое значение хранение после этого является присвоением или копированием.

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

Для отдельного элемента массива, (скалярное пункт), правило: (C11 со ссылкой, глава §6.7.9)

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

и пустой список {} не является допустимым инициализатора (выражения) для скаляра. следовательно, вы получили ошибку.

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

  • член-на-член, через петлю
  • с использованием memcpy() или memset если это так разрешений.
+0

Тогда позвольте мне перефразировать: есть ли способ (вроде как «синтаксический сахар», хотя я знаю, что это не то, о чем известно C), чтобы * назначать * различные элементы массива после объявления? –

+0

@ VinceVarga хорошо, memset() может быть вашим другом, но не для разных ценностей, я боюсь. –

+0

'memset()' будет устанавливать все байты на одно и то же значение, что, вероятно, не очень полезно, если вы хотите установить целочисленные элементы в одно и то же ненулевое значение.Вы обычно можете уйти с помощью 'memset()' для установки всех элементов в целое число '0', но, строго говоря, это не переносимо. Для установки элементов с тем же ненулевым значением цикл, вероятно, лучший выбор. Для установки элементов на разные значения это можно сделать с помощью отдельных назначений или с помощью 'memcpy()', чтобы скопировать все из другого (возможно, 'const') массива. –

Смежные вопросы