Как получить инициализированные, непоследовательные индексы массива в C - PullRequest
0 голосов
/ 29 марта 2019

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

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

Итак, предположим, у нас есть массив целых чисел размера 20. Только несколько элементов в этом массиве были инициализированы со значением'1'

Как узнать, какие индексы были инициализированы?

#include <stdio.h>

int main() {
    int data[20];

    data[1] = 1;
    data[5] = 1;
    data[8] = 1;
    data[16] = 1;

    return 0;
}

, поэтому в приведенном выше примере как получить 1,5,8,16 в качестве результата?Это даже правильный способ работы с массивами в C?

Ответы [ 3 ]

3 голосов
/ 29 марта 2019

Он не помнит, какие инициализированы, а какие нет.В вашем примере вы можете, например, инициализировать их все в 0, а затем проверить все значения, которые не 0.

int main() {
    int data[20] = {0};

    data[1] = 1;
    data[5] = 1;
    data[8] = 1;
    data[16] = 1;

    for (int i = 0; i < 20; i++) {
        if (data[i]) {
            printf("data[%d] is initialized to %d\n", i, data[i]);
        }
    }
    return 0;
}

. Это печатает:

data[1] is initialized to 1
data[5] is initialized to 1
data[8] is initialized to 1
data[16] is initialized to 1

Объяснение: int data[20] = {0}; говорит ему явно инициализировать первый элемент 0, а остальные инициализируются по умолчанию (что является 0 для int).Таким образом, int data[20] = {5}; установит для первого элемента значение 5, а для остальных будет установлено значение 0.

1 голос
/ 29 марта 2019

Остальные элементы массива будут содержать совершенно случайные значения, возможно, 1, поэтому вы можете найти более 4 элементов, которые содержат 1 в качестве значения.

Чтобы инициализировать массив, вы должны выполнить его итерацию или использовать memset(data, 0, sizeof(data)).

То, как вы устанавливаете 1 в некоторых элементах, более присваивает, а не инициализирует.

0 голосов
/ 29 марта 2019

В C массив содержит сами значения, а не ссылки на значения. Для вашего int data [20] в стеке будет выделено 20 слотов, каждый из которых содержит одно значение типа int. Выделенные слоты не очищаются, поэтому начальные значения элементов массива будут данными, хранящимися в этих слотах стека, кем бы они ни использовались ранее. Назначения, которые вы сделали для элементов массива, такие как data[8] = 1;, не инициализируют элементы массива, они просто заменяют текущие значения элементов новыми значениями.

Другими словами, все элементы вашего массива инициализируются сразу после объявления массива. В вашем конкретном случае они инициализируются некоторыми значениями мусора из стека. Если вы хотите инициализировать их с какими-то определенными значениями, вы должны использовать инициализатор массива так:

int data[20] = {
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
};

Это относится и к переменным, не относящимся к массиву. В контракте с некоторыми другими языками, такими как Java, вы не можете инициализировать переменную после объявления, но только внутри объявлений. Итак:

int a = 13; // Initialize to 13
int b; // Initialize to garbage from stack

a = 11; // Just assignment, not initialization
b = 17; // Yet another assignment, not initialization
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...