String C String Вывод - PullRequest
       0

String C String Вывод

2 голосов
/ 14 июля 2011

Я пытался выучить строки в Си, когда натолкнулся на этот код.

#include <stdio.h>
int main(){
        char s[] = "Hello world";
        printf("%s" , s);
        printf("%s" , &s);
        return 0;
}

Оба дали Hello World в качестве вывода. Насколько я понимаю, этот вывод в порядке для первого случая. Как это работает для второго? Пожалуйста, уточните.

Ответы [ 6 ]

6 голосов
/ 14 июля 2011

Получение адреса массива аналогично получению адреса его первого элемента. Когда используется имя массива, оно также распадается на адрес своего первого элемента, поэтому выражения s и &s дают одинаковый результат.

4 голосов
/ 14 июля 2011

s возвращает адрес первого элемента в массиве, а &s возвращает адрес самого массива - они совпадают.

Как правило, если вы хотите быть более явным, выражение &s[0] также можно использовать для возврата адреса первого элемента.

2 голосов
/ 14 июля 2011

s и &s возвращают один и тот же адрес и, следовательно,.Этот адрес является местом хранения «H» из «Hello world».

Потому что,
Имя массива распадается на адрес первого элемента в массиве &
Адрес первого элемента совпадает с адресом массива.

1 голос
/ 14 июля 2011

Как раз для того, чтобы получить техническую поддержку, ваша вторая версия:

printf("%s" , &s);

имеет неопределенное поведение и работает только случайно. Явно беря адрес, вы получаете адрес массива (что нормально), но результат имеет тип «указатель на массив из 12 символов», а не тип «указатель на символ», как требуется для printf% s конверсия. Поскольку типы не совпадают, результатом является неопределенное поведение.

В действительности, однако, это чисто техническая составляющая - код будет отлично работать на каждой реализации C, о которой я знаю.

Если вы хотите продемонстрировать, что разница существует, вы можете сделать это довольно легко. Например:

char string[] = "hello world";

printf("without &: %p, %p\n", (void *)string, (void *)(string+1));
printf("with &:    %p, %p\n", (void *)&string, (void *)(&string+1));

В первом случае string распадается на указатель на символ, поэтому в первой строке второй указатель будет ровно на единицу больше первого. Во второй строке мы добавляем единицу к указателю на массив символов, поэтому, когда мы добавим единицу, он фактически добавит размер массива. Запустив это на моей машине, я получаю следующие результаты:

without &: 0038F96C, 0038F96D
with &:    0038F96C, 0038F978
0 голосов
/ 16 июля 2011

char s [] похож на char * s, который является указателем charecter, который указывает на первый элемент массива (он содержит адрес первого сохраненного элемента). мы также можем хранить строки, сохраняя адрес первого символа. во время выполнения компьютер начинает брать символы с этого адреса по одному и формирует строку, пока не достигнет нулевого символа ('\ 0'). в приведенном выше примере «s» и «% s» представляют собой одно и то же значение (адрес начального символа), надеюсь, вы его получите. если вы используете char s [10] (массив фиксированной длины), вы все поймете.

0 голосов
/ 14 июля 2011

s эквивалентно & s [0], поэтому мы передаем адрес s [0], а не адрес указателя, указывающего на s [0], поэтому он выведет Hellow world во втором случае.

s имя массива, а не указатель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...