Я пытаюсь понять, как использовать структуру - PullRequest
1 голос
/ 04 апреля 2020

Вот фрагмент кода, который я разыгрываю с пониманием символа внутри структуры.

typedef struct{
    int mpg;
    int wheels;
    char owner[20];
}desc_t;

typedef struct{
    int price;
    char purchase_location[20];
    desc_t desc;
}car_t;

int main(void)
{
    car_t car;

    printf("enter car purchase location: ");
    scanf("%s", car.purchase_location);

    printf("enter car owner: ");
    scanf("%s", car.desc.owner);
}

в обеих структурах, owner и purchase_location хранятся в массиве символов, поэтому Логично, что при печати я не использую знак «&».

Однако ..

typedef struct{
    int mpg;
    int wheels;
    char owner;
}desc_t;

typedef struct{
    int price;
    char purchase_location;
    desc_t desc;
}car_t;

int main(void)
{
    car_t car;

    printf("enter car purchase location: ");
    scanf("%s", &car.purchase_location);

    printf("enter car owner: ");
    scanf("%s", &car.desc.owner);
}

В этой версии Owner и purchase_location не имеют квадратных скобок, выделяющих память для массива символов, и я должен поставить знак '&' в запустить его без предупреждения. Я заметил, что этот код выводит то же самое, что и фрагмент кода выше.

Я думал объявить строку, вам нужно также объявить размер массива.

Что я не понимаю здесь?

1 Ответ

0 голосов
/ 04 апреля 2020

Во-первых, вашего работающего кода недостаточно для того, чтобы сказать, что он правильный.

Во втором фрагменте кода purchase_location - это не строка или массив символов, это просто один символ. Причина, по которой вы не получаете никакого предупреждения, заключается в том, что scanf просто нужен адрес. Когда вы ставите & перед именем переменной, он просто дает адрес переменной (который scanf может использовать для хранения значения пользовательского ввода в). Теперь, когда дело доходит до массивов, имя массива без квадратных скобок или индекса просто дает адрес первого элемента массива, чтобы было понятно, как это выглядит ниже:

Предположим, у нас есть char a[10], a даст адрес первого элемента массива, a[0] даст значение первого элемента массива, и если вы будете следовать, вы будете знать, что &a[0] снова даст адрес Первый элемент массива. Если у нас есть char b, &b - это адрес переменной char. Теперь для scanf оба &b и a являются просто адресами двух переменных типа char, но на самом деле они совершенно разные,

Если вы скажете scanf, что ожидаете строку, упомянув %s, он будет принимать введенные вами символы и помещать их по указанному адресу, вот и все. Я полагаю, что в вашем случае вам повезло, что у вас есть этот пробел.

Если вы скажете printf, что переменная является строковой переменной, и дадите ей адрес, она просто примет все символы, доступные в этой части память.

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

...