Объем переменных C в структуре - PullRequest
0 голосов
/ 30 апреля 2009

В последнее время в C я сталкивался с тремя отдельными ситуациями, в которых я бы помог:

  1. Мой C код имеет глобальную переменную:

    int ref_buf; //declared in a header file
    

    В определении функции я использую то же имя, что и параметр:

    void fun(int ref_buf, param2, param3)
    {
    }
    

    Будет ли он перезаписывать первоначально определенную глобальную переменную и вызывать ошибки?

  2. Могу ли я объявить статическую переменную в C структуре данных следующим образом?:

    struct my
    {
        int a;
        static int b;
    };
    

    Это работает? Есть ли какая-то конкретная ситуация, когда это понадобится?

  3. Можно ли инициализировать отдельную структурную переменную следующим образом:

    struct my
    {
        int a;
        int b = 4;
    };
    

Ответы [ 7 ]

7 голосов
/ 30 апреля 2009

Вопрос 1

Все ссылки на ref_buf в этой функции будут привязаны к параметру, а не к глобальной переменной.

Вопрос 2

Это недопустимо в C, но допустимо в C ++. Ключевое слово static в C может использоваться только в переменных области файла или в локальных файлах.

Вопрос 3

Нет, это недопустимо в C (или C ++). Вам нужно будет создать фабричный метод для обработки этого.

my create_my() {
  my m;
  m.b = 4;
  return m;
}
4 голосов
/ 30 апреля 2009

В Q3: GCC позволяет инициализировать структуру, подобную этой (как того требует стандарт C99):

struct
{
    int a;
    int b;
} my = { .b = 4 };

GCC doc для назначенных инициализаторов

2 голосов
/ 30 апреля 2009

1a) Локальные и глобальные переменные являются отдельными объектами, поэтому локальная переменная не будет перезаписывать глобальные. Однако глобальный не будет доступен внутри функции (см. Также примечания ниже).

1b) На самом деле это не правильно, но гарантированно может вызвать путаницу, а путаница приведет к ошибкам, поэтому лучше использовать разные имена для каждого.

2) Нет, это не разрешено C. Однако вы можете сделать всю структуру статичной.

3) Нет. Вы делаете это так:

struct my
{
    int a;
    int b;
} = {0, 4};

Примечание 1. Переменные должны объявляться в файлах .c, а не в файлах .h. Если вам нужно сделать переменную доступной в нескольких файлах, поместите объявление extern в заголовочный файл.

Примечание 2: по возможности избегать глобальных переменных.

0 голосов
/ 30 апреля 2009

В Q1:

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

Если вам действительно нужны глобальные переменные, а это происходит гораздо реже, чем думают обычные новички, поместите что-то вроде extern int ref_buf; в заголовочный файл и int ref_buf; в исходный файл. Это означает, что есть один ref_buf, и все остальные исходные файлы смогут его найти.

Параметр функции - это, по сути, новая переменная с тем же именем, и все ссылки в функции будут на нее. Вы не сможете получить доступ к глобальной переменной из этой функции. Функция создает внутреннюю область видимости, а переменные, объявленные во внутренней области видимости, отличаются от переменных во внешней области видимости. Это может сбивать с толку и создавать ошибки, поэтому не рекомендуется использовать переменные с одинаковыми именами и разными областями действия. (Переменные с одним и тем же именем в разных определениях структуры обычно не сбивают с толку, так как вы должны указать, какая структура содержит переменную.)

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

0 голосов
/ 30 апреля 2009
  1. Да, технически он будет перезаписан, но хороший компилятор предупредит вас об этой ситуации, и у вас будет "warnings = errors" при компиляции, так что это на самом деле не будет компилироваться. 1004 *

  2. Не требуется, поскольку структура "my" уже объявлена ​​как статическая, и поэтому она объявлена ​​для всей структуры. Это распределяет память для всей структуры, поэтому нет необходимости говорить «принять часть структуры, которая уже является статической, и сделать ее статической».

  3. Нет, не в определении, но вы можете при создании «экземпляра» что-то вроде:

    struct my MY =
    {
        {0, 4}
    };
    
0 голосов
/ 30 апреля 2009

1) Локальные переменные всегда имеют приоритет, например,

int ref = 10;

void fun(int ref)
{
  printf("\n%d\n", ref);
}

int main()
{
 fun(252);
 return 0;
}

показывает: 252

Вопросы 2 и 3 не будут работать в C.

0 голосов
/ 30 апреля 2009

Вопрос 1: Я думаю, что переменная, объявленная в локальной области видимости, имеет преимущество, она не должна перезаписывать ее, но в области, в которой объявлена ​​переменная, она будет использоваться вместо этого.

Это предполагает, что он компилируется.

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