почему printf не принимает указатель в качестве аргумента - PullRequest
0 голосов
/ 10 марта 2020

почему происходит сбой кодоблока, когда я пытаюсь запустить этот код:

#include <stdio.h>
#include <stdlib.h>

void main(void)
{
    char *ch= "Sam smith";
    printf("%s\n",*ch);
}

, но он прекрасно работает, когда я удаляю * ch в printf и заменяю его просто на ch, как этот

void main(void)
{
    char *ch= "Sam smith";
    printf("%s\n",ch);
}

не должен ли * ch означать содержимое адреса, на который указывает ch , который является самой строкой, а ch означает адрес первого элемента в строке? поэтому я ожидал обратного!

Я использую блоки кода 17.12, g cc версия 5.1.0, windows 8.1.

Ответы [ 3 ]

3 голосов
/ 10 марта 2020

*ch разыменовывает указатель для получения данных, на которые он указывает. Здесь первый символ строки.

Предоставление неверного спецификатора для printf - неопределенное поведение (передача значения, в котором printf ожидает указатель)

printf("%c\n",*c);

напечатает первый характер, без сбоев. Если вы хотите напечатать всю строку, используя %c (или используйте putchar), l oop на символах. Но это то, что делает %s.

В качестве примечания, лучше использовать const для ссылки на литеральные строки, чтобы не рисковать пытаться изменить их:

const char *ch= "Sam smith";
2 голосов
/ 10 марта 2020

почему происходит сбой кодовых блоков при попытке запустить этот код:

char *ch= "Sam smith";
printf("%s\n",*ch);

ch имеет тип char *.

Преобразование %s Спецификатор ожидает char *.

Вы передаете *ch, который является разыменованным ch, то есть типа char.

Если спецификаторы преобразования делают не совпадают с типами аргументов, случаются плохие вещи (неопределенное поведение).

не должен *ch означать содержимое адреса, на которое указывает ch, что является самой строкой

В C нет типа данных "строка" и, следовательно, нет "указателя на строку".

"Строка", на языке C, представляет собой массив символы или указатель на массив символов с нулевым байтовым терминатором.

ch - это char *, указатель на первый символ этого массива - так сказать, строку.

*ch - это char, первый символ этого массива.

0 голосов
/ 10 марта 2020

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

Кроме того, неопределенное поведение , если спецификатор преобразования не соответствует типу относительного аргумента.


Таким образом,

printf("%s\n",*ch);

неправильно. *ch является первым символом в строке, в данном случае S, типа char, но спецификатор преобразования %s ожидает, что аргумент типа *char.

printf("%s\n",ch);

является правильным , ch имеет тип *char, как того требует спецификатор преобразования %s.

Итак, кодовые блоки " аварийно завершают работу ", очевидно, из-за несоответствующего типа аргумента.

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