интерпретация указателя на символ в C - PullRequest
0 голосов
/ 07 октября 2018

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

char *str="string1";
*str = "string2";   --> Gives a segmentation fault
puts(ptr);

, тогда как это работает

char *ptr="string1";
puts(ptr);
ptr="string2";
puts(ptr);

Ответы [ 3 ]

0 голосов
/ 07 октября 2018

* str = "string2";-> Выдает ошибку сегментации, потому что вы пытаетесь присвоить значение из нескольких символов указателю char * str, который должен возвращать только одно значение char, поскольку его указатель char не является указателем строки.

char *ptr = "string2";

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

0 голосов
/ 07 октября 2018
char *str="string1";
*str = "string2";   --> Gives a segmentation fault
puts(ptr);

Ваше назначение *str = "string2"; является нарушением ограничения .

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

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

*str имеет тип char."string2" является строковым литералом, имеет тип char[8] и массив char.Но в большинстве случаев (это еще одна странная вещь в C), выражение типа массива обрабатывается как выражение типа указателя.Так что "string2" обрабатывается как выражение, дающее результат типа char*, указатель на 's' в "string2".

C не поддерживает присваивание для массивов.

Не имеет смысла присваивать значение указателя объекту char (маленькое целое число) - но в старых версиях C десятилетия назад не было четкого различия между целыми числами и указателями.В идеале современный компилятор C должен просто отклонить присваивание из-за конфликта типов, но ваш генерирует код, который принимает адрес типа char*, обрабатывает его как целое число, усекает это целое значение для хранения в одном байте и пытается сохранить его в 0-м элементе массива.(Вы все еще можете сделать это в современном C с приведением, явным преобразованием, но вы все равно не хотите этого делать.)

Так почему же ошибка сегментации?Строковые литералы доступны только для чтения.(Ну, вроде как, длинная история; они не гарантированы только для чтения, но часто так и есть.) Таким образом, кусок памяти, содержащий массив "string1", защищен операционной системой от изменения.Ошибка сегментации, убивающая вашу программу, заключается в том, как ОС реагирует, когда вы пытаетесь обойти эту защиту.

Кстати, последняя строка должна быть puts(str);, а не puts(ptr);.При публикации вопроса здесь всегда лучше скопировать и вставить скомпилированный код точный .Если есть ошибки, нам нужно знать, являются ли они ошибками в вашем реальном коде или просто опечатками.

0 голосов
/ 07 октября 2018

Этот

*str = "string2";   --> Gives a segmentation fault

должен быть записан так:

str = "string2";

Идентификатор str имеет тип char *,то есть указатель на char .Чтобы избежать ошибки, вы можете написать так:

char* str;

Кроме того, вы присваиваете переменную constant .Итак, если вы хотите назначить изменяемую строку для str , используйте strcpy (копирование строки):

char str[40];
strcpy(str, "My string");
str[2] = '_'; //replacing space with underscore
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...