как инициализировать глобальный константный указатель? - PullRequest
2 голосов
/ 24 июня 2010

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

Как мне обойти эту проблему?

typedef struct PT {
 int x;
 int y;
 struct PT *next;
} POINT;

//globals
POINT * const mypoint_head;

int main(int argc, char *argv[])
{
    int size = 100;
    mypoint_head= InitPoint(size);   // error C2166: l-value specifies const object
    //rest of code

}


POINT* InitPoint(int size)
{
   POINT *tmp;
   POINT *orig;
   int a = 10;
   int b = 1000;
   orig = (POINT*) malloc (sizeof(POINT) * size);
   if(orig == NULL)
      return NULL;

   tmp = orig;
   for (i = 0; i < size; i++)
   {
      tmp->x = a++;
      tmp->y = b++;
      if (i == size -1) {
            tmp->next = NULL:
      }
      else {
            tmp->next = tmp+1; 
      }
      tmp++;
   }
   return orig;
} 

Ответы [ 8 ]

4 голосов
/ 24 июня 2010

Вы не можете - вот и весь смысл const.

2 голосов
/ 24 июня 2010

Никто еще не предложил это:

int main(int argc, char *argv[])
{
    int size = 100;

    // cast address of mypoint_head to a non-const pointer:
    POINT ** nc_pmh = (POINT **)&mypoint_head;
    // use the address to set mypoint_head:
    (*nc_pmh) = InitPoint(size);
    //rest of code
}

Это может не работать в C ++, где на самом деле не может быть места для константных объектов.

Кстати: это не очень хорошая практика. В этом случае, однако, это работает хорошо.

Кстати: вам нужно проверить возврат от InitPoint() и действовать соответственно (вызовите exit (), вероятно).

2 голосов
/ 24 июня 2010

Вы правы в том, что объявленная переменная const никогда не может быть изменена. К сожалению, ваша строка mypoint_head= InitPoint(size); считается попыткой изменить переменную. Вы должны инициализировать переменную const значением, когда оно объявлено.

Попробуйте что-то вроде этого:

//globals
static POINT head_of_list;
POINT* const mypoint_head = &head_of_list;

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

mypoint_head->next= InitPoint(size-1);

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

1 голос
/ 25 июня 2010

не имеет глобального константного указателя в качестве интерфейса ко всему остальному.

используйте функцию: -

static POINT * mypoint_head;

POINT* point_head()
{
    return mypoint_head;
}
1 голос
/ 24 июня 2010

Удалите квалификатор const из глобального объявления и объявите rest_of_code как функцию, которая принимает версию указателя с указанием const.

//globals
POINT * mypoint_head;

void rest_of_code(POINT* const mypoint_head)
{
    mypoint_head = NULL;    // this errors out now
}
int main(int argc, char *argv[])
{
    int size = 100;
    mypoint_head= InitPoint(size);   // no longer errors out
    //rest of code
    rest_of_code(mypoint_head);
}

0 голосов
/ 01 октября 2016

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

const_cast<POINTER *>(mypoint_head) = InitPoint(size);

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

0 голосов
/ 24 июня 2010

(предполагается, c) const должны быть инициализированы, когда они объявлены, и они не могут быть оценены.Может быть, вы могли бы использовать указатель const, чтобы он указывал на вашу голову и выставлял его для остальной части кода.Если я должен достичь, может быть, я выставлю переменную с помощью функции getListHead () и назову ей какое-то непонятное имя:)

Интересно, что такое вариант использования.Я бы заставил мой список работать, даже если указатель его головы изменится.(если у меня есть const head, если мне нужно удалить головной узел, мне придется сдвигать элементы, как в массиве)

0 голосов
/ 24 июня 2010

Вы должны использовать инициализатор в объявлении:

static POINT mypoint_data[100];
POINT * const mypoint_head = &mypoint_head;

Затем измените вашу функцию InitPoint, чтобы взять указатель на пространство данных вместо вызова malloc и передать его mypoint_data

Вы также можете вставить extern POINT * const mypoint_head; в заголовочный файл, чтобы он был доступен для других модулей компиляции.

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