Что происходит при использовании «против» в C? - PullRequest
0 голосов
/ 10 апреля 2019

Кто-то поднял этот код для меня, что заставило меня задуматься о том, что там происходит код, как следует из VS 2019:

#include <stdio.h>
#include <string.h>

int main()
{
    char y = '5';
    char w = "5";
    printf("size of x %x\n",&w);
    printf("size of X %X\n", w);
    printf("size of X in number: %d \n", w);
    printf("size of Y %d\n\n", w);

    w = '5';
    printf("size of y %x\n", &w);
    printf("size of Y %X\n", w);
    printf("size of X in number: %d \n", w);
    printf("size of Y %d\n\n", 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 в основном дает результаты о том, как поместить символы в массив и т. П., Не смог найти никакой информации об этом поведении

Ответы [ 2 ]

4 голосов
/ 10 апреля 2019

Строка - это массив символов, заканчивающийся символом NUL. Данные здесь:

"5"

Это то же самое, что и

{'5','\0'}

Когда вы присваиваете значение массива чему-то в C, вы назначаете указатель на первый элемент в массиве. Поэтому, когда вы пишете:

char w = "5"

вы создаете символ и присваиваете его значение ячейке памяти первого элемента в массиве символов, символ недостаточно велик для хранения ячейки памяти.

Делаем это:

printf("size of x %x\n",&w);

Распечатывает расположение w в памяти

Делаем это:

printf("size of X %X\n", w);

печатает значение w, в вашем случае был назначен адрес массива строк и обрезан, потому что char не может соответствовать адресу.

Если вы хотите использовать строку, вы должны сделать это:

const char * w = "5"

Затем вы можете распечатать строку следующим образом:

printf("string: %s\r\n", w);

вы можете распечатать первый символ в массиве одним из следующих способов

printf("char: %c\r\n", *w);
printf("char: %c\r\n", w[0]);

Для второго бита, когда вы назначаете w следующим образом:

char w = '5';

печать &w печать местоположения в памяти.

печать w с %x печатает значение ASCII '5', которое составляет 0x35

0 голосов
/ 10 апреля 2019

Инициализация

char w = "5";

делает две вещи:

  • Определяет символьный литерал "5", представляющий собой некоторую область памяти, содержащую '5', за которой следует NUL ('\0').
  • Определите переменную w типа char и инициализируйте ее адресом строкового литерала, то есть адресом памяти, где находится '5'.Адрес (указатель) преобразуется в char, что приводит к потере части значения, поскольку char обычно меньше, чем указатель (char*).

С

printf("size of X %X\n", w);

вы печатаете значение char w в шестнадцатеричной форме, которое, вероятно, является наименее значимым байтом адреса строкового литерала.

Вам лучше использовать

printf("size of X %X\n", (unsigned int)w); /* %X = unsigned int */

или

printf("size of X %hhX\n", w); /* %hhX = unsigned char or signed char */

, чтобы формат соответствовал типу аргумента.

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

Когда я запускал ваш код, в одном случае значение w было 0xA8, которое печаталось как FFFFFFA8.В этом случае %hhX будет печатать только A8.

Я не уверен, что именно произойдет, когда вы передадите значение char в функцию printf, пока формат инструктирует функцию интерпретироватьданные как unsigned int.Это может зависеть от соглашений о вызовах вашей платформы и реализации компилятора.Возможно, на вашей платформе все аргументы более коротких типов данных преобразуются в int или unsigned int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...