printf ведет себя по-разному … и принимает адрес, а также значение ….адрес строки и только для указателя после разыменования

#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 * на какой-либо другой объект и обработать его как строку, но вы не можете ожидать, что результат будет согласованным.