#arrays #c #char
#массивы #c #символ
Вопрос:
Я просто привыкаю к указателям в C. Я думал об использовании %s для печати первого символа массива символов.
Почему в следующем коде %s не работает, но %c работает? Если *my_string разыменовывает первое значение массива символов, не будет ли %s пытаться напечатать все символы в памяти, начиная с этого адреса, и продолжать до тех пор, пока не будет достигнут нулевой символ?
Кроме того, как это printf("%s", my_string)
работает, а printf("%s" *my_string)
нет?
char* my_string = "The original value.";
printf("Value of my_string: %sn", my_string);
my_string = "The new value.";
printf("Value of my_string: %sn", *my_string); // Error
printf("Value of my_string: %cn", *my_string); // Prints only the first letter 'T', but does not have any errors
Комментарии:
1.
%s
ожидает строку, заканчивающуюся нулем, которая*my_string
не является указателем, этоchar
значение, и%s
пытается использовать это значение в качестве указателя, что, очевидно, неверно.2. » Если *my_string разыменовывает первое значение», так и есть. Это означает, что он переходит по адресу и извлекает оттуда содержимое. «разве %s не попытался бы напечатать все символы в памяти, начинающиеся с этого адреса», но
my_string
это адрес,*my_string
это содержимое этого адреса.%s
ожидается первое, а не второе.
Ответ №1:
Звездочка *
отменяет ссылку указателя на тип, на который она указывает, поэтому, когда my_string
это указатель на символ, *my_string
это символ. Ваш компилятор C видит строку вашего формата, содержащую a %s
и параметр *my_string
, который является символом, и выдает вам ошибку.
Чтобы вывести всю строку, выведите ее, как при вашем первом вызове printf
, чтобы напечатать только один символ, сделайте, как вы делали при вашем последнем вызове printf
.
Ответ №2:
почему %s не работает, но %c работает?
Это правило, по которому работает функция printf. Для «%s» ожидается указатель на строку, заканчивающуюся нулем, а для «%c» — один символ.
Если *my_string разыменовывает первое значение массива символов, не будет ли %s пытаться напечатать все символы в памяти, начиная с этого адреса, и продолжать до тех пор, пока не будет достигнут нулевой символ?
ДА. Поэтому вы должны быть осторожны, если это слишком длинная строка, и эти символы могут быть напечатаны перед нулевым окончанием.
Кроме того, почему работает printf(«%s», my_string), а printf(«%s» *my_string) — нет?
Для «%s» ожидается указатель. «*my_string» — это символ.
Комментарии:
1. Хороший первый ответ.
Ответ №3:
Чтобы понять это, нам нужно разобраться в том, как строка "The original value."
хранится в памяти и на что char* my_string
указывает.
Мы можем ожидать структуру памяти, подобную этой
0xDEADBEEF ASCII T
0xDEADBEEF 1 ASCII h
0xDEADBEEF 2 ASCII e
0xDEADBEEF 3 ASCII <space>
...
0xDEADBEEF 16 ASCII u
0xDEADBEEF 17 ASCII e
0xDEADBEEF 18 ASCII .
0xDEADBEEF 19 0
Итак, когда у вас есть a, char* my_string
это указывает на первый символ или, в данном случае, на адрес 0xDEADBEEF
. Поэтому, когда вы используете %s
в printf
, он будет перебирать все символы, начиная с первого, на который вы указали, пока не достигнет
. Но *my_string
считывается только первый символ по этому адресу. По этой причине нам нужно присвоить ей указатель.