Нужно объяснить, как работают указатели при передаче в качестве аргументов функции - PullRequest
5 голосов
/ 19 августа 2009

Мне показалось, что я понял основы указателей, но после ознакомления с некоторыми документами по некоторым методам sqlite3 меня бросили, поэтому теперь я не уверен, правильно ли мое понимание.

Вот вызов метода sqlite3:

char* dataFilePath = "foobar.sqlite";
if (sqlite3_open(dataFilePath, &database) != SQLITE_OK) {...}   

А вот объявление заголовка функции:

int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);

Почему база данных & вдруг становится указателем на указатель?

Другой вызов метода для закрытия соединения с базой данных: sqlite3_close (база данных);

Со следующим в заголовке функции:

int sqlite3_close(sqlite3 *);

Почему это просто указатель, когда я передаю указатель? Разве это не указатель на указатель?

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

// function
void foo(someDataType *bar) { ... }

// function call
foo(&bar);

Спасибо за помощь.

Ответы [ 5 ]

15 голосов
/ 19 августа 2009

Скорее всего, sqlite3_open выделяет память для дескриптора базы данных. По этой причине функции необходим указатель на указатель на дескриптор базы данных (sqlite3), чтобы она могла изменять указатель к дескриптору базы данных. Например:

typedef struct { /*...*/ } sqlite3;

int sqlite3_open(const char *filename, sqlite3 **ppDb) {
    /* ... */

    // Allocate memory for the database handle.
    *ppDb = (sqlite3 *)malloc(sizeof(sqlite3));

    /* ... */
    return 0;
}

Однако, sqlite3_close нужен только один указатель на free память:

int sqlite3_close(sqlite3 *pDb) {
    /* ... Cleanup stuff ... */

    free(pDb);

    return 0;
}
5 голосов
/ 19 августа 2009

Я думаю, что краткое объяснение того, что вы спрашиваете, заключается в том, что использование «&» по сути означает «указатель на это»

int value = 0;
int *pointer = &value;
int **doublePointer = &pointer;
4 голосов
/ 19 августа 2009

Указатель - это адрес переменной.

Предполагается, что database объявлено как sqlite3* database;, &database - это адрес (или указатель на) указателя database.

sqlite3_open принимает указатель на указатель, чтобы он мог установить значение, на которое указывает указатель.Он создает значение sqlite и изменяет указатель на него.sqlite3_close не меняет то, на что указывает указатель, поэтому все, что ему нужно, это сам указатель.

0 голосов
/ 21 августа 2009

Я не знаю, что вы хотите сделать с функцией sqlite. Но использование указателей заставляет вас сохранять изменения в функциях.

Когда вы передаете переменную в функцию, она будет продублирована.

например

int var1=0;
in *ptr1=&var1;
func(var1, ptr1);

значение var1 = 5

адрес var1 = 0xff2200 (что-то в этом роде)

значение ptr1 = 0xff2200 (адрес var1)

адрес ptr1 = 0xff0022 (что-то другое)

Давайте напишем функцию, которая использует эти две переменные как arg

void func1(int x, int *p){
    x+=5;
    (*p)-=5;
}

после использования этой функции;

func(var1, ptr1);

var1 не будет равно 0 !!! Это будет -5

Потому что; в функции func1

значение x = 0 (значение var1)

адрес x = 0xaabbcc (что-то отличное от var1 !!!, поэтому x + = 5 не действует на var1. Это происходит в другой части памяти! Когда вы вернетесь, эта память снова будет свободна. И вы потеряю твои изменения ...)

адрес p = 0xcccccc (тоже что-то другое)

значение p = 0xff2200 (значение ptr1 и адрес var1! Эта операция будет выполнена по адресу var1, поэтому вы не потеряете свои изменения)

Если мы должны сохранить наши изменения переменных в функциях, мы должны использовать указатели для этих переменных. Если у нашей переменной есть адрес, значит; это указатель. И если мы хотим сохранить изменения указателя в функциях, то мы должны использовать указатель на указатель.

Это мое первое сообщение, и я надеюсь, что это будет полезно ...

И «передача по ссылке» означает «передача по указателю», другие языки не используют указатели. так что иногда приходится передавать по ссылке. Но в C указатели будут делать свое дело ...

0 голосов
/ 20 августа 2009

Как обычно, список часто задаваемых вопросов C содержит соответствующую информацию. См. У меня есть функция, которая принимает и, как предполагается, инициализирует указатель: и Есть ли в C даже "передача по ссылке"? .

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