Как мы можем получить всю строку по указателю в C? - PullRequest
0 голосов
/ 21 декабря 2018

Я новичок в языке Си, и меня интересуют указатели.Итак, я не понимаю, как мы получаем строку WHOLE по указателю.Если указатель содержит адрес только первого символа в строке, как он возвращает всю строку?

Допустим, у нас есть что-то вроде char *s = "Test";

А поскольку это просто массив символов, он находится где-то в памяти, например так:

Строка: T est \ 0

Адреса: 100 101 102 103 104

Итак, *s будет содержать 100 (адрес первого символа T), если я правильно понимаю.

Тогда почему, когда мы делаем printf(s);, получаем ли мы всю строку Test в нашем выводе?

Сканирует ли он адреса, пока не встретит \0, или делает что-то еще?

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Как получить всю строку по указателю

Да, OP хорошо понимает в комментарии , что печатать содержимое строки выходной сигнал начинается с s[0] и продолжается до тех пор, пока s[i] не станет равным нулю.Последний элемент string , нулевой символ не печатается.


Примечание: printf(s) - это bad code asprintf() ожидает, что первый аргумент будет не только указателем на строку , но и будет интерпретироваться как формат .Если происходит '%', следующие символы будут интерпретироваться как спецификатор @ MM .Вместо этого:

printf("%s", s);
// or
fputs(s, stdout);

  • Impact

Такие функции, как strlen(), strcpy(), strcat(), также проводят довольно много времени, прогуливаясь по длине строки для определения его длины.Для длинных струн это может занять значительное время.

Этот утомительный бег по всей длине струны может иметь серьезные последствия.Рассмотрим s указателей на строку длиной n.

for (i=0; i<strlen(s); i++) {
  s[i] = 'x';
}

против

for (i=0; s[i] != '\0'; i++) {
  s[i] = 'x';
}

При компиляции первого фрагмента кода может не отображаться, что длина строки не изменяется(поскольку строка изменяется) за одну итерацию, а затем вызывайте strlen(n) n раз, каждый вызов занимает n операций или общее O(n*n) время.2-й код будет принимать только порядка n операций за время (n).

Эффективный код C распознает это и избегает повторных вычислений длины.

0 голосов
/ 21 декабря 2018

Обратите внимание, что строка представляет собой массив символов, а имя массива соответствует указателю, ссылающемуся на адрес первого элемента.

, поэтому при выполнении printf ("% s", s) это означаетчто вы передаете указатель самого первого элемента массива char в функцию printf.

Функция printf будет проходить через массив, начиная с переданного адреса, пока не найдет '\ 0'

#include<stdio.h>
int main(){
  char *s= "abcdef ghij";
  char *s2;
  s2 = &s[3];
  printf("%s",s2);
  return 0;
}

Обратите внимание, как я передал указатель, ссылающийся на элемент 4 массива, в функцию printf.А вот и вывод.

Вывод:

def ghij

0 голосов
/ 21 декабря 2018

Нет другого способа просто пройти всю строку, пока не будет достигнут ноль:

size_t strlen(const char *str)
{
    size_t len = 0;
    while(*str++)
    {
        len++;
    }
    return len;
}

или

size_t strlen(const char *str)
{
    const char *start = str;
    while(*str++);
    return str - start;
}

char *strcpy(char *dest, const char *src)
{
    char *saveddest = dest;

    while(*src)
    {
        *dest++ = *src++;
    }
    *dest = 0;
    return saveddest;
}

void puts(const char *s)
{
    char c;
    while((c = *s++))
        putc(c);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...