В чем разница между const char * и const int *? [Дубликат]

Просто оберните весь код css внутри селектора для родительского элемента, скажем, что это div с id из foo, вы сделали бы следующее:

div#foo{
//All your css
}

И преобразуйте его как less к css с помощью инструмента, подобного http://less2css.org/ , он будет добавлять правые селекторы. Обратите внимание, что вам нужно будет позаботиться о таких вещах, как @media и т. Д.

11
задан Nakilon 17 March 2016 в 12:54
поделиться

5 ответов

"Something"

по существу является коротким для:

static const char some_hidden_array[] = {'S', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', '\0'};
some_hidden_array

То есть, когда вы пишете "Something", компилятор генерирует массив за кулисами и дает вам указатель на начало этого массив. Поскольку это уже указатель на символ, вам не составит никакого труда назначить его переменной «указатель на символ» (написанной как char*).

10

- not для чего-либо подобного. Это всего лишь номер 10 - это не указатель на массив, содержащий число 10, или что-то в этом роде.

Обратите внимание, что char является единственным символом , а не string, поэтому синтаксис строки необычен по сравнению с большинством других типов - строка несколько символов, а не только одна. Если вы попытаетесь использовать простой старый char, вы увидите то же самое:

char *myChar = 'a'; // error

или для любого другого типа:

float *myFloat = 42.1f; // error

Другими словами, это не странно, что 10 дает ошибку - во всяком случае, странно, что "Something" не . (По крайней мере, это странно, пока вы не знаете, как работают строковые литералы)

19
ответ дан immibis 20 August 2018 в 08:34
поделиться

Когда вы выполняете char *myChar = "Something";, вы создаете литеральный литерал только для чтения где-то в памяти, который заканчивается нулевым символом. Теперь это что-то особенное с компилятором, что он интерпретирует кусок переменных «char», которые хранятся непрерывно и заканчиваются нулевым символом в виде строки. Таким образом, в основном вы создали массив символов, а когда вы делаете *myChar*, он возвращает строку.

В случае целых чисел или любых других типов данных он различает int *ptr как указатель на целое число и int ptr как целое число. Вероятно, вы получаете ошибку, потому что введенный вами адрес может быть недействительным / доступным для вас.

Также, делая

char myChar = "Something";  //this is an error, since char can hold one character
char *charAddr = &myChar;

Обратите внимание, что myChar и &myChar то же, поскольку myChar является указателем!

Редактирование: см. здесь о строковых литералах: Возможно ли изменить строку символа в C?

2
ответ дан Community 20 August 2018 в 08:34
поделиться
  • 1
    Спасибо за объяснение, так что наберите * var = something, всегда создайте переменную только для чтения в памяти? И по второму вопросу, я больше имел в виду, если эти 2 равны (короче) :) Спасибо! – J. Doe 14 March 2016 в 01:03
  • 2
    @ J.Doe Да. Посмотрите на это: stackoverflow.com/questions/1011455/… – Sahil Arora 14 March 2016 в 01:06
  • 3
    Спасибо, это очень помогает. – J. Doe 14 March 2016 в 01:20
  • 4
    @ J.Doe нет, type *var = something не создает переменную только для чтения. Только строковый литерал "Something", доступный только для чтения (и это не переменная) – M.M 14 March 2016 в 01:55

Почему назначение char работает, но целое нет (возможно, причина char рассматривается как массив)?

Вы правы, "Something" является строковым литералом и может рассматриваться как массив символов. После char *myChar = "Something"; происходит следующее: выделяется длина + 1 байт памяти, где "Something" будет сохранена, myChar указывается на начальный адрес этой памяти. Строковые литералы несколько особенны.

Вот общий способ инициализации массива с постоянными значениями:

// valid initializations;
char s2[] = { 'a', 'b', 'c' };
int a[] = { 1, 2, 3 };
char s1[] = "123";

Также меня смущает, когда напрямую назначается указательная переменная, автоматически получает адрес?

Да.

Взгляните на 8.5.2. Массивы символов c ++ docs

2
ответ дан Ivan Gritsenko 20 August 2018 в 08:34
поделиться

Это то же самое (магия от компилятора не происходит). По умолчанию литералы типа 10 являются значениями int, а не int *.

Вам нужно бросить:

int *myNum = (int*)10; // Need to cast
char *myChar = "Something"; // No need to cast "..." is already a char*

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

Что касается вашего второго вопроса, «...» рассматривается как непрерывная последовательность символов в памяти, подобная массиву, и эквивалентна char *.

Для продуманного понимания C, указателей и различия между массивами и указателями, вы должны прочитать следующее: Expert C Programming: Deep C Secrets by Peter van der Linden.

10
ответ дан Laurent 20 August 2018 в 08:34
поделиться
  • 1
    Спасибо! Что касается второго вопроса, я имел в виду больше, если бы эти 2 равны? Является первым примером более короткого способа получения адреса? Благодаря! – J. Doe 14 March 2016 в 01:00
  • 2
    Не забудьте выбрать это как ваш принятый ответ, если он ответит на ваш вопрос. – Kent Kostelac 14 March 2016 в 01:52
  • 3
    Сделано, спасибо :) – J. Doe 14 March 2016 в 03:09
  • 4
    "..." не является char*. И я бы не рекомендовал C-книгу для изучения C ++; идиомы совершенно разные. – Lightness Races in Orbit 14 March 2016 в 11:56
  • 5
    @ J.Doe Нет, второй пример просто не работает. Строковый литерал not a char, это char[]. Изменив это, получив адрес char[], вы получите указатель на указатель - в этом случае указатель на переменную стека, поэтому он будет определен только до тех пор, пока область действия не выйдет. Это очень важно, поскольку строковые литералы немного волшебны - они появляются и «локальные», но на самом деле не имеют области; исходный указатель действителен всюду, указатель на указатель - нет. – Luaan 14 March 2016 в 12:31

Теоретически первый int *myNum = 10 имеет смысл, особенно если вы знаете, что есть полезный int по адресу ten & mdash; в общем, он редко полезен и потенциально весьма опасен.

Однако есть определенные назначения указателей, которые широко используются и совершенно безопасны:

int *myNum = 0;

На 99,9 +% современных архитектур процессора это то же самое, что и

int *myNum = NULL;

См. определение NULL в <stddef.h> здесь .

Как правило, назначение переменных указателя лучше всего сделать, установив адрес другого.

int k, *p = &k;
1
ответ дан wallyk 20 August 2018 в 08:34
поделиться
  • 1
    Благодаря! Hmm так в основном, int * myNum = 10 // Указатель на адрес "10" а не на самом деле адрес, который содержит переменную int со значением 10? – J. Doe 14 March 2016 в 01:06
  • 2
    int *myNum = 0; совпадает с int *myNum = NULL; во всех системах. Он делает нулевой указатель. Вы смешиваетесь с тем фактом, что нулевой указатель может не быть представлен всеми битами-ноль (что не имеет никакого значения для этого кода) – M.M 14 March 2016 в 01:57
  • 3
    @ J.Doe Да, и ваше замешательство в значительной степени объясняет, почему вам нужно добавить явное приведение, чтобы сделать эту компиляцию - это почти всегда ошибка , а не предполагаемое поведение. На современной настольной / серверной системе вы действительно не хотите использовать указатели для выбранных вручную адресов. Это было полезно в прошлом, хотя, например, для прямого доступа к графической памяти (или любого другого устройства). С аппаратной абстракцией очень мало легитимных применений (за пределами довольно очевидного случая 0 / NULL, который на C стандартном всегда работает :)). – Luaan 14 March 2016 в 12:26
Другие вопросы по тегам:

Похожие вопросы: