Как сбросить запись структуры в C - PullRequest
0 голосов
/ 17 декабря 2009

У меня есть массив структур. Это объявлено так:

tableEntry [MAXSCOPE][MAXSIZE];

Когда создаются структуры, C автоматически инициализирует все элементы равными 0 или нулю.

Допустим, я дал некоторые значения членам структуры tableEntry [1] [0], tableEntry [1] [1] и tableEntry [1] [2].

Теперь я хочу повторно инициализировать все элементы структуры в tableEntry [1] [x], где x может быть любым числом от 0 до MAXSIZE. Как бы я это сделал?

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

Ответы [ 6 ]

4 голосов
/ 17 декабря 2009

Нет, C автоматически инициализирует все члены равными 0, когда ваша переменная имеет статическое хранилище, в противном случае вы должны написать:

struct TableEntry tableEntry [MAXSCOPE][MAXSIZE] = {0};

Если ваш tableEntry является глобальной переменной или объявлен static внутри функции, то вам не нужна часть = {0}.

Затем вы можете использовать memset для повторной инициализации некоторых записей впоследствии:

memset(tableEntry[1], 0, sizeof(struct TableEntry) * MAXSIZE);

выполнит повторную инициализацию tableEntry[1][0] ... tableEntry[1][MAXSIZE - 1] до 0.

1 голос
/ 17 декабря 2009

В дополнение к memset предложениям я предлагаю следующее:

/* Global variables are initialized to zero by compiler. */
struct foo TableEntry[MAXSCOPE][MAXSIZE];
struct foo zero;

/* Initialize yourself. */
for (int i = 0; i < MAXSIZE; ++i)
    TableEntry[1][i] = zero;

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

1 голос
/ 17 декабря 2009

Если вы хотите сбросить целую строку, игнорируйте этих людей с for петлями. Вы можете сделать строку за один вызов memset(), потому что строки в памяти являются последовательными:

memset(&tableEntry[1][0], 0, sizeof(tableEntry[0]));

sizeof(tableEntry[0]) будет MAXSIZE * sizeof(type), поэтому будут сброшены все элементы, которые, будучи нижним уровнем массива, должны быть смежными в памяти. (Любой, кто говорит иначе, спорит с учеными, потому что ОП опубликовал предыдущие вопросы по этому поводу, и я считаю, что tableEntry - это просто двумерный массив, выделенный в стеке.)

1 голос
/ 17 декабря 2009

Вы можете использовать memset , чтобы установить все биты на ноль.

#include <string.h>

    memset(&tableEntry[1][0], 0, sizeof tableEntry[1][0]);
    memset(&tableEntry[1][1], 0, sizeof tableEntry[1][1]);
    memset(&tableEntry[1][2], 0, sizeof tableEntry[1][2]);

    /* if the elements are contiguous in memory,
     * you can set more than 1 in a single statement */
    memset(&tableEntry[1][0], 0, 3 * sizeof tableEntry[1][0]); /* zeroes ...[1][0], [1][1], and [1][2] */

    /* to set all of a sub array */
    memset(tableEntry[1], 0, sizeof tableEntry[1]);

Возможно, установка всех битов в 0 может быть не тем, что вы хотите. Если это так, вам нужно «удалить» элементы один за другим.

1 голос
/ 17 декабря 2009

Почему бы не просто

memset( &tableEntry1[1][x], 0, sizeof(tableEntry1[0][0]) );

Кстати, максимальное значение x - MAXSIZE-1, а не MAXSIZE.

0 голосов
/ 17 декабря 2009

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

static struct T zeroed; /* static, therefore every member
                           is initialized to an appropriate
                           'zero' value */
size_t i;
for (i=0; i < MAXSIZE; ++i)
    tableEntry[1][i] = zeroed;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...