#c
#c
Вопрос:
Кто-то поднял этот код для меня, что заставило меня задуматься, что там происходит, код выглядит следующим образом из VS 2019:
#include <stdio.h>
#include <string.h>
int main()
{
char y = '5';
char w = "5";
printf("size of x %xn",amp;w);
printf("size of X %Xn", w);
printf("size of X in number: %d n", w);
printf("size of Y %dnn", w);
w = '5';
printf("size of y %xn", amp;w);
printf("size of Y %Xn", w);
printf("size of X in number: %d n", w);
printf("size of Y %dnn", w);
return 0;
}
Результат выглядит следующим образом:
size of x 8ff8bb
size of X 30
size of X in number: 48
size of Y 48
size of y 8ff8bb
size of Y 35
size of X in number: 53
size of Y 53
Мне интересно, что там происходит на самом деле? кто-то указал, что ‘ — это символ, а » — строка, но если это так, почему здесь можно поместить строку в символ, и почему это результат?
Спасибо за ответы, я понимаю, что это может быть не слишком актуально для использования, но мне интересно, что там происходит, я только недавно вернулся к повторному изучению C
Код скомпилирован и не выдает никаких предупреждений в VS2019
Поиск в Google в основном дает мне результаты о том, как помещать символы в массив и тому подобное, не удалось найти никакой информации об этом поведении
Комментарии:
1.
"size of x %xn",amp;w
— За исключением того, что он не печатает размер, посколькуamp;w
это не размер чего-либо.2. Это ничего не может вывести, поскольку оно не компилируется .
3.
char w = "5";
сгенерирует предупреждение и, скорее всего, не будет делать то, что вы думаете.4. Выходной текст, похоже, не имеет никакого отношения к выводимым значениям. Например, последние два
printf
s в каждой группе, очевидно, печатают один и тот же номер, но имеют разный текст.5. Почему вы сделали свой вывод таким запутанным? Вы печатаете «размер X», чтобы показать значение
w
. Почему вы делаете это так сложно? Кого вы пытаетесь запутать?
Ответ №1:
Строка — это массив символов, заканчивающийся нулевым символом. Данные здесь:
"5"
Это то же самое, что:
{'5',''}
Когда вы присваиваете значение массива чему-либо в C, вы присваиваете указатель на первый элемент в массиве. Итак, когда вы пишете:
char w = "5"
вы создаете символ и присваиваете его значение ячейке памяти первого элемента в массиве символов, символ недостаточно велик для хранения ячейки памяти.
Выполнение этого:
printf("size of x %xn",amp;w);
Выводится ли местоположение w в памяти
Выполнение этого:
printf("size of X %Xn", w);
выводится значение w, в вашем случае присвоенное адресу массива строк и усеченное, потому что символ char не может соответствовать адресу.
Если вы хотите использовать строку, вы должны сделать это:
const char * w = "5"
Затем вы можете распечатать строку следующим образом:
printf("string: %srn", w);
вы можете распечатать первый символ в массиве одним из следующих способов
printf("char: %crn", *w);
printf("char: %crn", w[0]);
Для второго бита, когда вы назначаете w следующим образом:
char w = '5';
печать amp;w
печатает местоположение в памяти.
печать w
с %x
помощью печатает значение ASCII '5'
, равное 0x35
Комментарии:
1. Спасибо за ответ, думаю, тогда он действительно просто усечен
Ответ №2:
Инициализация
char w = "5";
делает две вещи:
- Определите символьный литерал
"5"
, который представляет собой некоторую область памяти, содержащую a'5'
, за которым следует aNUL
(''
) . - Определите переменную
w
типаchar
и инициализируйте ее адресом строкового литерала, то есть адресом памяти, где'5'
находится. Преобразуется адрес (указатель), вchar
который будут потеряны части значения, посколькуchar
обычно он меньше указателя (char*
).
С
printf("size of X %Xn", w);
вы печатаете значение char w
в шестнадцатеричной форме, которое, вероятно, является младшим значащим байтом адреса строкового литерала.
Вам следует лучше использовать
printf("size of X %Xn", (unsigned int)w); /* %X = unsigned int */
или
printf("size of X %hhXn", w); /* %hhX = unsigned char or signed char */
чтобы формат соответствовал типу аргумента.
Даже если это не изменит результат в вашем случае, это гарантирует, что код printf
не обращается к памяти, которая может быть неинициализирована или может содержать несвязанные данные.
Когда я запускал ваш код, в одном случае значение w
было 0xA8
напечатано как FFFFFFA8
. В этом случае %hhX
будет только печать A8
.
Я не уверен, что именно произойдет, когда вы передадите char
значение в функцию printf
, в то время как формат указывает функции интерпретировать данные как unsigned int
. Это может зависеть от соглашений о вызовах вашей платформы и реализации компилятора. Возможно, на вашей платформе все аргументы более коротких типов данных преобразуются в int
или unsigned int
.
Комментарии:
1. Выполняем
printf("size of X %hhXn", w);
иprintf("size of X %Xn", (unsigned int)w);
даем тот же результат, что и раньше Спасибо за ответ