Чар и объявление двойных указателей - PullRequest
0 голосов
/ 26 сентября 2018

Я начинаю с языка программирования C и у меня есть сомнения по поводу инициализации указателей.Я знаю, что когда мы объявляем указатель, мы резервируем память для конкретного указателя, но этот указатель может указывать на x-адрес, о котором мы ничего не знаем, дело в том, что я могу сделать это: char * s = "Hi";, но я не могусделайте это double * f = 3;, чтобы я «инициализировал» этот двойной указатель следующим фрагментом кода:

double * d;
double x = 3;
d = &x;

Так что у меня есть указатель, указывающий на определенную ячейку памяти с начальным значением, которое я хочуиметь.

Подводя итог, я сомневаюсь:

1.- Есть ли способ инициализировать указатели типа double / int как с символами char?

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Да, но обычно не следует:

double *x = (double []) {3};

Так же, как char *x = "Hi"; создает массив char и инициализирует x, чтобы указать на первый член массива, код вышесоздает массив double и инициализирует x для указания его первого члена.(Я показал только один элемент, но вы могли бы написать больше.) Это называется составным литералом.

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

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

0 голосов
/ 26 сентября 2018

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

double d[] = {3};

будет выделять пространство (глобально или в стеке, в зависимости отвыполняется ли это в глобальном или функциональном масштабе) и инициализируется сразу.Практически во всех случаях обращение к d приведет к его снижению до double*.

Основное отличие состоит в том, что для массивов, выделенных стеком (область действия функции, без квалификатора static), массивживет только до конца вызова функции.Объявление его как static double d[] = {3}; сделает его действующим на всю жизнь программы, но оно будет иметь единственную инициализацию, и любые изменения будут сохраняться бесконечно.

Другое важное отличие состоит в том, что вы не можете изменитьадрес, так как это не действительно указатель;++d не будет допустимым, поскольку d является массивом, а не указателем.

Для точного эквивалента char *s = "Hi"; вы в основном застряли с двумя строками.Этот код примерно эквивалентен:

static char unnamed[] = {'H', 'i', '\0'};
char *s = unnamed;

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

static double dstorage[] = {3};
double *d = dstorage;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...