Когда printf строка, мы не используем *. Зачем?

В программировании c, когда мы печатаем строку. Мы не используем * . Но когда вы печатаете число с помощью printf, мы используем * . Так как это понимание, я печатаю строку или Int. Понимание с использованием оператора%s?

Прикрепление примера кода

#include<stdio.h>

int main(int argc,char* argv){

char data[]="This is an example of pointer";
char *pointerstringdata =data;
printf("print the string data is >> %s\n",pointerstringdata);   /* Here we are not using * why?  case -1*/


int numberdata =100;
int *pointerintdata=&numberdata;
printf("print the int data is >> %d\n",*pointerintdata);   /* Here we are  using * why?  case -2*/
return 0;
}

6 ответов

Решение

Потому что указатели содержат ссылку на объект. * разыменовывать этот объект. Таким образом, если указатель содержит ссылку на объект char при разыменовании, мы получаем этот объект. Таким образом, указатель на разыменование char - это просто один символ, а не адрес первого символа в строке.

когда мы печатаем строку. Мы не используем * . Но когда вы печатаете число с помощью printf, мы используем *

Поскольку d спецификатор преобразования ожидает intтогда как s спецификатор преобразования ожидает указатель (на char и с этим к 1-му элементу 0-завершённый char массив, который фактически является тем, что C использует для имитации того, что обычно называют "строкой").

Язык C не предусматривает обработку строки как значения. Вы не можете передать строку в функцию. Указатель pointerstringdata это просто указатель на char, так *pointerstringdata это один char, а не строка. Переходя *pointerstringdata передаст только один символ, а не строку.

Для печати строк, когда %s используется, printf ожидает, что аргумент будет указателем. Он использует этот указатель для чтения из памяти, и он читает и печатает символы, пока не найдет нулевые символы.

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

%s Спецификатор формата ожидает указатель.

Если вы пройдете *pointerstringdata функция получит первый символ в массиве, который функция будет пытаться разыменовать, и, вероятно, вызовет сбой.

В

char data[]="This is an example of pointer";
char *pointerstringdata =data;
printf("print the string data is >> %s\n",pointerstringdata);   /* Here we are not using * why?  case -1*/

если вы хотите напечатать всю строку, вы должны дать ее адрес, нет *

если вы хотите напечатать его первый символ, вы делаете `printf("%c", *pointerstringdata);


в

int numberdata =100;
int *pointerintdata=&numberdata;
printf("print the int data is >> %d\n",*pointerintdata);   /* Here we are  using * why?  case -2*/

Вы не хотите печатать адрес, запомненный в pointerintdata но значение то же в этом адресе, поэтому вы должны разыменовать

нет никакой разницы со строкой... за исключением того, что вы хотите написать всю строку

указатель является указателем, независимо от того, что это указатель на символ или указатель на int

Отказ от ответственности: это объяснение того, как это выглядит для разработчика, а не после создания кода (особенно потому, что оптимизатор может все это изменить).


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

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

Содержимое переменной может быть:

  • Значение (например, как вы упомянули число)
  • Адрес в ОЗУ
  • Структура, которая использует больше последовательных RAM (и C позволяет использовать ее так, как если бы она была больше)
    • Stuct (фиксированная длина)
    • массив с фиксированной длиной

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

Поскольку строки имеют переменную длину, соглашение в C:

  • Есть адрес в переменной
  • Чтение реальных данных побайтно, начиная с этого адреса
  • Чтение данных, пока байт не станет равным 0 (NULL)

Это называется строкой с нулевым символом в конце.

Таким образом, вы можете передать данные переменной длины в printf, и printf определит длину, посмотрев первый байт, равный 0.

Преобразование переменных, содержащих адрес, в переменные, содержащие значение, работает следующим образом:
var_with_value = *var_with_address
var_with_address = &var_with_value

"var_with_address" называется указателем.

В заключение: вам нужно передавать строки как адрес, а не как значение, а числа как значение, а не как адрес, и в этом разница, почему вы должны использовать *

Другие вопросы по тегам