изменение указателей на функции, c - PullRequest
3 голосов
/ 25 сентября 2011

Я заранее скажу, что я спрашиваю об указателях на указатели, поэтому мои слова могут быть немного расплывчаты, но постарайтесь остаться со мнойуказатель, переданный в качестве аргумента, вступает в силу вне области действия функции.Пока это то, что я понимаю: если указатель передается в качестве аргумента функции, я могу изменить только то, на что указывает указатель, а не сам указатель (я говорю об изменении, которое вступит в силу вне области действияфункции, как я уже сказал).И если я хочу изменить то, на что указывает указатель, я должен передать указатель на указатель.

Прав ли я до сих пор?Кроме того, я заметил, что когда у меня есть структура, содержащая некоторые указатели, если я хочу инициализировать эти указатели, я должен передать struct в функцию инициализации в качестве указателя на указатель.Это по той же причине?

Ответы [ 4 ]

4 голосов
/ 25 сентября 2011

Вы правы в первом бите, но если вы выделили структуру, вы можете передать указатель на нее.Однако если функция распределила структуру, то либо вы используете функцию return для сбора значения вновь распределенной структуры, либо вы передаете указатель на указатель в списке параметров.

(я неполучил компилятор переменного тока, но я попытался написать несколько примеров).

  • Вы выделили указатель

    int main() {
       struct x *px = malloc(...);
       initx(px); 
    }

    void intix(struct x* px){
        px-> ....
    }
 
  • Функция присвоилауказатель

     int main() {
       struct x *px = initx(); 
     }

     struct x* intix(){
        struct x *px = malloc(...);
        px-> ....
        return px;
     }
 
  • Функция выделенного указателя

     int main() {
       struct x *px;
       initx(&px); 
     }

     void intix(struct x** ppx){
        struct x *px = malloc(...);
        px-> ....
        *ppx = px;
     }
 
3 голосов
/ 25 сентября 2011

Что вам следует понять, так это то, что указатель является адресом. Это означает, что он говорит, что «данные для объекта на самом деле там». Поэтому вы должны разделить, меняете ли вы переменную или память.

Когда вы разыменовываете указатель и присваиваете ему изменяемую память, а не переменную.

int **x;
int **p;
int *q;

время диаграммы блока:

+-----------+    +------+    +-----+
| x (**int) | -> | *int | -> | int |
+-----------+    +------+    +-----+

Скажите, что я пишу в первое поле: x = p

+-----------+    +------+    +-----+
| x (**int) | XX | *int | -> | int |
+-----------+    +------+    +-----+
             \
              \   +------+    +-----+
               -> | *int | -> | int |
                  +------+    +-----+

Скажите, что я пишу во второе поле: *x = q

+-----------+    +-----------+    +-----+
| x (**int) | -> | (*x) *int | XX | int |
+-----------+    +-----------+    +-----+
                              \
                               \   +-----+
                                -> | int |
                                   +-----+
0 голосов
/ 25 сентября 2011

Вы правы с первого счета - в стандарте C есть только параметры-значения, и вы должны передать указатель на любую внешнюю переменную, которую вы хотите изменить изнутри процедуры.

Причина чего-то вроде функций инициализации структуры, желающих получить указатель на указатель, различна, но в основном это просто для согласованности с аналогичными функциями, которые выделяют структуру, или из-за этой конкретной группы функций (я думаю о некотором M $ интерфейсы) приняли этот стиль, по-видимому, просто для того, чтобы быть более загадочным (или, что более вероятно, чтобы те же интерфейсы могли использоваться языком передачи по ссылке).

Но учтите, что если запрашивается указатель на указатель, функция может делать что-то отличное от того, что вы обычно предполагали.

0 голосов
/ 25 сентября 2011

В Си указатели не очень сильно отличаются от чисел. Вы можете видеть это как числовой адрес памяти чего-либо. Далее в C все передается как значение. Это означает, что если вы получили указатель, переданный вашей функции, и изменили его, вы измените только свою локальную копию указателя. Изменения, внесенные в аргумент указателя, не будут видны снаружи.

Теперь, что если я хочу, чтобы функция действительно что-то изменила? Затем я даю адрес этого функции! Таким образом, функция знает фактическое местоположение информации, которую я хочу, чтобы она изменила, чтобы она могла изменить ее. Вот как это работает в C.

Надеюсь, это объяснение прояснит ситуацию.

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