#c
#c
Вопрос:
printf
принимает адрес строки и не принимает после разыменования, тогда как в случае указателя требуется разыменование.
#include <stdio.h>
#include<stdio.h>
int main()
{
char str[100];
int i;
int j=0;
int *p;
p=amp;j;
scanf("%s",str);
for(i=0;str[i];i )
{
if((str[i]>='A') amp;amp; (str[i]<='Z'))
{
str[i]=str[i] ('a'-'A');
}
else
{
str[i]=str[i]-('a'-'A');
}
}
printf("%s",str); //it should have been printf("%s",*str); here we are passing address
printf("%dn",j);
printf("%d",*p); //here we are passing evact value;
return 0;
}
при использовании с *
он выходит из строя, и если используется только str
, он работает нормально…
Комментарии:
1. char str[100] является указателем. Вы не хотите разыменовывать его. Вы можете (я не говорю, что вы должны) переключаться между синтаксисом массива / указателя в одной и той же переменной.
2. @petrch Массив и указатель — это не одно и то же. Один может распадаться на другой, но они различны.
Ответ №1:
%s
Спецификатор формата to printf
используется для печати строки и ожидает char *
аргумент, который указывает на первый элемент массива символов с нулевым завершением. %d
Спецификатор формата используется для печати целого числа в десятичном формате и ожидает int
.
Поскольку str
это массив, при использовании в выражении он распадается на указатель на его первый элемент. Таким образом, str
в выражении есть тип char *
, который соответствует тому, что %s
ожидается.
*str
недопустимо для %s
потому что имеет тип char
и имеет значение первого символа в массиве. Использование неправильного спецификатора формата для данного аргумента printf
вызывает неопределенное поведение.
*p
допустимо для, %d
потому что p
имеет тип int *
, что означает, что *p
имеет тип int
, который соответствует тому, что %d
ожидается.
Комментарии:
1. и в случае «* p» он принимает значение ..!! в случае string он ожидает char *, а в случае «p» он ожидает «int», почему бы не обратиться..
2. таким образом, в основном в «scanf» мы всегда принимаем входные данные как «addressof», а в случае «printf» это будет зависеть от «типа спецификатора» (%d или %s и так далее)
3. @dbush ну, вы написали в комментарии, что char str[100] не является указателем, но он «распадается» на него. Я предполагаю, что вы, возможно, имеете в виду какое-то абстрактное определение, но с практической точки зрения, если вы выполните printf(«%c:%c»,str[0],*(str 0)), вы получите точно такой же результат, включая интерпретацию в ассемблере. Также char * может указывать куда угодно, вы можете указать на массив целых чисел или любое место в памяти и интерпретировать местоположение как строку, если хотите.
4. @petrch Раздел 6.3.2.1 стандарта C : «За исключением случаев, когда это операнд оператора sizeof, оператора _Alignof или унарного оператора amp;, или строковый литерал, используемый для инициализации массива, выражение, имеющее тип ‘массив типа ’, преобразуется в выражение с типом ‘указатель на тип ’, которое указывает на начальный элемент объекта массива и не является строковым литералом, используемым для инициализации массива.» ценность»
5. @petrch Вы могли бы указать
char *
на какой-либо другой объект и обработать его как строку, но вы не можете ожидать, что результат будет согласованным.