2016-02-24 3 views
0

Я изучал C и натолкнулся на следующий код. Я знаю, что он делает, но я не знаю, почему это так.using & with array возвратил неожиданный результат

char str[5] = "hele"; 
printf("string is %s: \n", &str[1]); 

output: 
ele 

Почему & ул [1] выход Ele? Из того, что я прочитал до сих пор, & возвращает адрес, поэтому & str [1] возвращает адрес «e». Поскольку выход «ele», я знаю, что это не тот случай, но я не могу понять, почему. Вся помощь оценивается.

+5

& str [1] действительно возвращает адрес. % S в функции printf использует его как начало строки и будет продолжаться до тех пор, пока не встретится с нулевым терминатором. Таким образом, ele. – Cobster

+0

this '& str [1]' - это адрес второго элемента в строковом массиве, индекс массивов начинается с 0, поэтому первым элементом является '& str [0]'. – milevyo

ответ

0

Это прототип printf:

int printf(const char *format, ...); 

и он идет с конверсионными спецификаторами, как% D, % a,% s,% c ...

Если используется %s, то аргумент const char * должен быть указателем на массив типа символа (указатель на строку).

Назад к вашему делу:

&str[1] действительно указывает на 'e' и это указатель на строку поэтому аргумент printf имеет, очевидно, правильный тип.

И что printf делает дальше, увидеть хорошее качество замечание Cobster

% s в функции PRINTF использует его как начало строки и будет продолжаться до тех пор, пока не встретится нулевой терминатор

0

Это потому, что строка C - это всего лишь несколько символов в памяти, за которыми следует нулевой символ. str имеет некоторый адрес в памяти, а &str[1] эквивалентен str + 1 (массив превращается в указатель в этом выражении). То, что вы получаете, является указателем на середину исходной строки, которая также будет допустимой строкой, просто не будет запускаться.

Как это выглядит в памяти, как это:

[h ] [e ] [l ] [e ] [\0] 
^ str points here 

Когда printf выводит строку, она принимает в указатель на первый символ так же, как и большинство функций, которые имеют дело со строками и печатает символы, пока не достигнет завершающий нуль (\0). Если вы вместо того, чтобы пройти в str + 1, он будет счастливо печатать часть строки, начиная с индекса 1.

+5

Нет строки C **, а не ** указателем. Цитируя стандарт C: «Строка A * - это непрерывная последовательность символов, заканчивающихся и включающая первый нулевой символ». ... «Указатель A * на строку * является указателем на его начальный (самый низкий адрес)». –

+0

@ KeithThompson: * Вздох * ... лучше? –

+0

Да. (* Sigh * ???) –

0

Прежде всего, строка в c представляет собой массив символов. Таким образом, ваша строка содержит

h (position 0) e (position 1) l (position 2) e (position 3) \0 (position 4) 

Все в скобках приводится только для пояснений.

Оператор & возвращает адрес переменной или адрес элемента массива.

Так что, когда вы делаете

printf("string is %s: \n", &str[1]); 

&str[1] возвращает адрес str [1]. Если вы поместите %c в printf, значение элемента str [1], которое равно e, будет напечатано. Но когда вы положили %s, printf берет его как начало строки, откуда он должен быть напечатан, и, таким образом, печатает строку до тех пор, пока не встретит нулевой ограничитель (\0).

Для лучшего объяснения:

Существует строка, которая имеет содержание hele. h - это 0-й элемент, e - 1-й элемент, l - 2-й элемент, e - это третий элемент, а \0 - четвертый элемент. Строка в основном представляет собой массив символов, в котором каждый элемент является char. У каждого из них есть адрес. Таким образом, &str [1] возвращает адрес 1-го элемента char array. Затем, %s принимает это как начало строки для печати и печатает строку до тех пор, пока не встретит нулевой ограничитель (\0). Таким образом, он принимает начало строки как 1 e, или 1-й элемент. Затем печатает l и e, после чего он встречает нуль-терминатор, где он останавливается.