Строки и символ с printf
Меня смутило использование %c
и %s
в следующей программе C
#include<stdio.h>
void main()
{
char name[]="siva";
printf("%s\n",name);
printf("%c\n",*name);
}
Выход
siva
s
Почему нам нужно использовать указатель для отображения символа% c, а указатель не нужен для строки
Я получаю ошибку, когда я использую
printf("%c\n", name);
Ошибка, которую я получил,
str.c: In function ‘main’:
str.c:9:2: warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘char *’
Ответы
Ответ 1
Если вы попробуете это:
#include<stdio.h>
void main()
{
char name[]="siva";
printf("name = %p\n", name);
printf("&name[0] = %p\n", &name[0]);
printf("name printed as %%s is %s\n",name);
printf("*name = %c\n",*name);
printf("name[0] = %c\n", name[0]);
}
Выход:
name = 0xbff5391b
&name[0] = 0xbff5391b
name printed as %s is siva
*name = s
name[0] = s
Итак, 'name' на самом деле является указателем на массив символов в памяти. Если вы попробуете прочитать первые четыре байта в 0xbff5391b, вы увидите 's', 'i', 'v' и 'a'
Location Data
========= ======
0xbff5391b 0x73 's' ---> name[0]
0xbff5391c 0x69 'i' ---> name[1]
0xbff5391d 0x76 'v' ---> name[2]
0xbff5391e 0x61 'a' ---> name[3]
0xbff5391f 0x00 '\0' ---> This is the NULL termination of the string
Чтобы напечатать символ, вам необходимо передать значение символа printf. Значение можно указать как имя [0] или * имя (поскольку для имени массива = & name [0]).
Чтобы напечатать строку, вам нужно передать указатель на строку printf (в этом случае "имя" или "& name [0]" ).
Ответ 2
%c
предназначен для одного символа a char, поэтому он печатает только один элемент. Проводя массив char в качестве указателя, вы передаете адрес первого элемента массива (то есть одиночный char), а затем будет напечатан:
s
printf("%c\n",*name++);
напечатает
i
и т.д.
Указатель не нужен для% s, поскольку он может работать непосредственно с строкой символов.
Ответ 3
Вы путаете оператор разыменования * с аннотацией типа указателя *.
В принципе, в C * означают разные вещи в разных местах:
- В типе * означает указатель. int - целочисленный тип, int * - указатель на целочисленный тип
- В качестве префиксного оператора * означает "разыменование". name - это указатель, * name - результат разыменования его (т.е. получение значения, на которое указывает указатель)
- Конечно, в качестве инфиксного оператора * означает "умножить".
Ответ 4
Имя массива - это адрес его первого элемента, поэтому name
является указателем на память, содержащую строку "siva".
Также вам не нужен указатель для отображения символа; вы просто выбираете использовать его непосредственно из массива в этом случае. Вы могли бы сделать это вместо этого:
char c = *name;
printf("%c\n", c);