О значениях структуры C по умолчанию, как насчет этого кода? - PullRequest
9 голосов
/ 29 марта 2011

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

struct stuff {
  int stuff_a = 1;
  int stuff_b = 2...
  ...and so on...
};

) код:

struct a{   a() : i(0), j(0) {};  INT i;   INT j;}

Я никогда не видел ничего подобного для C. Пожалуйста, помогите мне понять это;Я думаю, что это очень приятно!

ОБНОВЛЕНИЕ: Подожди, я спрашиваю о C !!!!Почему изменился мой вопрос?Если это невозможно в C, просто скажите ... Я не знаю C ++, я не знал, что это было о C ++ ...

Ответы [ 8 ]

15 голосов
/ 29 марта 2011

Если вы хотите установить объект структуры за один раз и у вас есть компилятор C99, попробуйте это:

struct stuff {
    int stuff_a;
    int stuff_b;
    // and so on...
};

struct stuff foo;
/* ... code ... */
foo = (struct stuff){.stuff_b = 42, .stuff_a = -1000};

В противном случае, с помощью компилятора C89, вы должны установитькаждый член один за другим:

foo.stuff_b = 42;
foo.stuff_a = -1000;

Пример выполнения @ ideone: http://ideone.com/1QqCB


Исходная строка

struct a{   a() : i(0), j(0) {}   INT i;   INT j;}

является синтаксисомошибка в C.

10 голосов
/ 01 июня 2011

Как вы, вероятно, узнали из других ответов, в C вы не можете объявить структуру и инициализировать ее члены одновременно . Это разные задачи и должны выполняться отдельно.

Есть несколько вариантов инициализации переменных-членов структуры. Я покажу пару способов ниже. Сейчас предположим, что следующая структура определена в начале файла:

struct stuff {
  int stuff_a;
  int stuff_b;
};

Затем в вашем main() коде представьте, что вы хотите объявить новую переменную этого типа:

struct stuff custom_var;

Это момент, когда вы должны инициализировать структуру. Серьезно, я имею в виду, что вы действительно действительно должны! Даже если вы не хотите присваивать им конкретные значения, вы должны хотя бы инициализировать их нулем. Это обязательно, потому что ОС не гарантирует, что она даст вам чистое пространство памяти для запуска вашего приложения. Поэтому всегда инициализируйте ваши переменные некоторым значением (обычно 0), включая другие типы по умолчанию, такие как char, int, float, double и т.д ...

Один из способов инициализации нашей структуры в ноль - через memset():

memset(&custom_var, 0, sizeof(struct stuff));

Другой имеет доступ к каждому члену индивидуально:

custom_var.stuff_a = 0;
custom_var.stuff_b = 0;

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

struct stuff custom_var = { 1, 2 };

Код выше эквивалентен:

struct stuff custom_var;
custom_var.stuff_a = 1;
custom_var.stuff_b = 2;
7 голосов
/ 26 мая 2011

... создать структуры со значениями по умолчанию ...

Это невозможно в C. Тип не может иметь значения по умолчанию. Объекты любого типа не могут иметь значение по умолчанию , отличное от 0, хотя они могут быть инициализированы тем, что нужно.
Определениеstruct - это определение типа, а не объекта.


То, что вы спрашиваете, примерно так же, как способ установить по умолчанию int s, скажем,42.

/* WRONG CODE -- THIS DOES NOT WORK */
typedef int int42 = 42;
int42 a;
printf("%d\n", a); /* print 42 */

Или, адаптируясь к вашему примеру

/* WRONG CODE -- THIS DOES NOT WORK */
struct stuff {
    int42 stuff_a;
    int65536 stuff_b;
}
struct stuff a;
printf("%d\n", a.stuff_b); /* print 65536 */
6 голосов
/ 29 марта 2011

Обновление: этот ответ предполагает, что мы говорим о C ++, потому что код, размещенный в ответе, не является допустимым C.

 struct a {
     a() : i(0), j(0) {}   // constructor with initialization list
     int i;
     int j;
 }

Строка, помеченная комментарием, является просто конструктором для экземпляров struct a (напоминание: структуры похожи на классы, за исключением того, что видимость элемента по умолчанию public вместо private).

Часть после : называется списком инициализации : она позволяет инициализировать элементы struct значениями (либо константами, либо передаваемыми в качестве параметров конструктора). Инициализация элементов в этом списке происходит до ввода тела конструктора. предпочтительно инициализировать членов классов и структурировать их, если это вообще возможно.

См. Также C ++: список конструктор и инициализатор в struct / class .

3 голосов
/ 01 июня 2011

Невозможно инициализировать значения в определении структуры.

Я бы предложил:

typedef struct {
   int stuff_a;
   int stuff_b;
} stuff ;

int stuffInit(int a, int b, stuff *this){
   this->stuff_a = a;
   this->stuff_b = b;
   return 0; /*or an error code, or sometimes '*this', per taste.*/
}


int main(void){
   stuff myStuff;
   stuffInit(1, 2, &myStuff);

   /* dynamic is more commonly seen */
   stuff *dynamicStuff;
   dynamicStuff = malloc(sizeof(stuff));  /* 'new' stuff */
   stuffInit(0, 0, dynamicStuff);
   free(dynamicStuff);                    /* 'delete' stuff */

   return 0;
}

До дней объектно-ориентированного программирования (C ++) нас учили «Абстрактные данные».Типы ".

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

В конце концов, определение (я) структуры и соответствующие функции заканчиваются в своих собственных файлах и заголовках, связанных позже, что дополнительно инкапсулирует дизайн.

Но эти дни прошли и заменены на «Класс» и «Терминология ООП конструктора.

«Все одинаково, изменились только имена» - Бон Джови.

3 голосов
/ 28 мая 2011

Инициализация типа невозможна в C.

  • Значение должно храниться в памяти.
  • Тип не занимает память, то, что занимает памятьпеременная этого типа.

    struct stuff; - это тип;она не занимает память

    struct stuff aStuff; - переменная этого типа;aStuff занимает память

  • Поскольку тип не занимает память, it is not possible to save values into a type.

  • Если есть синтаксический сахар для поддержки хранения / инициализации значенийв тип тогда должно быть additional code, которое вставляется для присвоения значений каждой мгновенной переменной этого типа (например, в constructor in C++).Это приведет к снижению эффективности C, если эта функция доступна.

  • Как часто вам нужно сохранять значения по умолчанию?Я думаю, что это вряд ли.Вы можете создать функцию для инициализации переменной значениями по умолчанию или просто инициализировать каждое поле желаемыми значениями.Так что инициализатор типа не является фундаментальной вещью.C is about simplicity.

3 голосов
/ 28 мая 2011

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

struct a_struct my_struct = {1, 2};

Или более свежий и безопасный:

struct a_struct my_struct = {.i1 = 1, .i2 = 2};

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

typedef struct a_struct {
   int i1;
   int i2;
} sa;

static const sa default_sa = {.i1 = 1, .i2 = 2};

static sa sa1 = default_sa;
static sa sa2 = default_sa;

// obviously you can do it dynamically as well
void use_temp_sa(void)
{
     sa temp_sa = default_sa;
     temp_sa.i2 = 3;
     do_something_with(&temp_sa);
}

// And re-initialise
void reset_sa(sa *my_sa)
{
    *my_sa = default_sa;
}
3 голосов
/ 29 марта 2011

в C (до C99) также работает:

#include <stdio.h>
typedef struct
{
    int a;  
    int b;
    int c;
 } HELLO;

int main()
{
HELLO a = {1,2,3};

printf("here: %d %d %d\n",a.a,a.b,a.c);
exit(1);
}

См. кодовая панель

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...