Можно ли подробно объяснить следующую программу указателей в c? - PullRequest
0 голосов
/ 30 октября 2018
void main(){
   char a[2][30]={"Don't walk in front of me..", "I am not follow"};
   printf("%c%c", *(a[0]+9), *(*(a+0)+5));
}

И выход программы

k

Ответы [ 4 ]

0 голосов
/ 30 октября 2018

Некоторые примеры, основанные на объяснениях ...

c-массивы могут быть доступны двумя способами:

как массив:

char a[10] = "0123456789";
printf("%c", a[5]); // prints "5"

В качестве указателя:

char a[10] = "0123456789";
printf("%c", *(a + 5)); // prints "5"

Во втором примере мы просто разыменовываем a как указатель на начало строки плюс 5.

Это также можно использовать для массивов 2d, 3d и т. Д. ...

char a[2][10] = {"012", "abc"};
printf("%c", *(*(a + 0)+1)); // prints "1"
printf("%c", *(*(a + 1)+1)); // prints "b"

Вы можете смешать два метода:

printf("%c", *(a[0] + 1); // prints "1"
printf("%c", *(a + 1)[1]; // prints "b"

И просто для полноты (это можно считать «нормальным» способом доступа к значениям массива):

printf("%c", a[0][1]; // prints "1"
printf("%c", a[1][1]; // prints "b"
0 голосов
/ 30 октября 2018
char a[2][30]

Это говорит программе, что в стеке должен быть двухмерный массив размером 2х30 символов. Это просто непрерывный блок 60 chars, но он позволяет программе узнать правильную позицию, к которой вы пытаетесь получить доступ, используя нотацию, например [2] [3].

{"Don't walk in front of me..", "I am not follow"};

Это так называемый «строковый литеральный инициализатор для символьных и широких символьных массивов». Массив заполняется содержимым этих строковых литералов (включая '\0' в конце). Обратите внимание, что это не заполняет все 60 символов, остальные после нулевых терминаторов также заполняются '\0'.

printf("%c%c",

Это печатает два символа, которые указаны в следующих аргументах вызова.

*(a[0]+9)

Он берет адрес первой строки, добавляет к ней 9 и, таким образом, получает адрес k в walk. Затем он разыменовывается, в результате чего получается символ k.

*(*(a+0)+5));

Это делает нечто очень похожее, просто вместо a[0] оно записывается как *(a+0). Вместо 9 вы только добавляете 5, поэтому вместо 'k' вы получите ' ' (пробел между словами Don't и walk).

Вот так печатается "k " (это k и пробел, а не просто k.).

0 голосов
/ 30 октября 2018

Вы можете написать свой char массив a так:

char a[2][30]={{"Don't walk in front of me.."}, //a[0][30]
              // 0123456789 - *(a[0]+9) is a[0][9] is `k`
              // 012345 - *(*(a+0)+5) is is a[0][5] is ' '
               {"I am not follow"}}; //a[1][30]     

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

0 голосов
/ 30 октября 2018

Вывод не k, а k[WHITESPACE].
В C все переменные являются числами. Указатели тоже.


Первый %c

*(a[0] + 9)

a[0] - указатель, поэтому число соответствует a[0] -ому байту памяти. Если вы добавите 9 к нему, вы получите еще 9 байтов.

a[0] указывает на первый символ "Don't walk in front of me": D
Затем, если вы добавите 9 к a[0], вы получите адрес десятого символа в строке: k

*() означает, что вам не нужно значение a[0] + 9 (0x hexNumber ), а значение с адресом a[0] + 9: k (107)


Второй %c

*(*(a+0)+5))

  • *(a + 0) - это значение, указанное a + 0: a[0]
  • *(a[0] + 5): Должен ли я действительно объяснить это ?? 1048 *

Надеюсь, это ответит на ваш вопрос!

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