Когда printf строка, мы не используем *. Зачем? - PullRequest
0 голосов
/ 12 января 2019

В программировании 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 ]

0 голосов
/ 12 января 2019

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


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

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

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

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

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

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

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

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

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

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

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

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

0 голосов
/ 12 января 2019

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

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

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

0 голосов
/ 12 января 2019

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

0 голосов
/ 12 января 2019

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

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

0 голосов
/ 12 января 2019

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

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

0 голосов
/ 12 января 2019

в

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

...