Использование & и * взаимозаменяемо для разыменования? - PullRequest
0 голосов
/ 08 февраля 2019

Я смотрю на функцию getline() и ее параметры, и это вызывает у меня некоторое замешательство относительно использования амперсанда "&" и звездочки разыменования "*".

Я знаю, что "* "используется для объявления указателя и последующего разыменования его, а этот" & "используется для ссылки на адрес переменной.Но что происходит, когда вы используете «&» для «разыменования» указателя, похожего на строку:

characters = getline(&buffer,&bufsize,stdin);

из кода ниже?

он получаетадрес указателя?вроде как использовать двойную звездочку **?

этот фрагмент кода из: https://c -for-dummies.com / blog /? p = 1112

#include <stdio.h>
#include <stdlib.h>

int input(char *s,int length);

int main()
{
    char *buffer;
    size_t bufsize = 32;
    size_t characters;

    buffer = (char *)malloc(bufsize * sizeof(char));
    if( buffer == NULL)
    {
        perror("Unable to allocate buffer");
        exit(1);
    }

    printf("Type something: ");
    characters = getline(&buffer,&bufsize,stdin);
    printf("%zu characters were read.\n",characters);
    printf("You typed: '%s'\n",buffer);

    return(0);
}

1 Ответ

0 голосов
/ 08 февраля 2019

& в C - обратное значение *.

. Возьмем в качестве примера объявление char ch;.Он объявляет ch как однобайтовую целочисленную переменную.Допустим, эта переменная хранится в 0x80000000.

Когда вы говорите ch = 65, вы меняете значение в местоположении 0x80000000 на 65.

& дает вам адрес, где хранится переменная.Следовательно, &ch является указателем 0x80000000.Таким образом, char *pointerToCh; pointerToCh = &ch приведет к тому, что pointerToCh будет 0x80000000

* относится к значению по адресу указателя.Таким образом, *pointerToCh совпадает с ch.*pointerToCh = *pointerToCh + 7 изменит ch на 72, поскольку оно совпадает с ch = ch + 7.Из этого также следует, что *(&ch) - это то же самое, что и ch.

Есть небольшая проблема, потому что * также используется в объявлениях типов, чтобы сказать, что что-то является указателем - как вывидел выше в char *pointerToCh.* здесь не то же самое *, что и в *pointerToCh = *pointerToCh + 7: первый делает типы указателей;второй разыменовывает указатель.

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

void uselesslyChange(char copyOfCh) {
  // copyOfCh is 65
  copyOfCh = 80;
  // copyOfCh is 80
}

char ch = 65;
uselesslyChange(ch);
// ch is still 65

Однако, если мы знаем адрес, мы можем изменить его содержимое (даже если адрес просто копия).

void change(char* copyOfChPointer) {
  // copyOfChPointer is 0x80000000, and there's a 65 there
  *copyOfChPointer = 80;
  // copyOfChPointer is 0x80000000, and there's a 80 there
}

char ch = 65;
change(&ch);
// ch is now 80

Итак, ваш код.Важным битом является понимание того, что getline должен иметь возможность изменять как буфер (указатель на первый символ выделенной области памяти), так и размер буфера (целое число) для отражения размера читаемой строки (например,если буфер слишком мал, getline переместит его в другое место).Для того чтобы иметь возможность их изменять, необходимо знать их расположение в памяти, как и выше.Таким образом, getline принимает указатель на указатель на символ (char **buffer) и указатель на размер (size_t *bufsize).Помните, ** и * - это тип , не разыменование.

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