为什么sqlite3_open我们使用双指针**而对于sqlite3_prepare我们使用指针*

请纠正我在哪里理解错误。

我读了这个答案https://stackoverflow.com/a/833124/5175709 ,我理解的是,由于对象可能会扩展并耗尽空间,因此内存位置也会改变。但是这里有两个sqlite3语法引用了对象不同。 为什么?

sqlite3_open我们有: sqlite3 **ppDb

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

对于sqlite3_prepare,我们有: sqlite3 *db

 SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ 

sqlite3_open需要以某种方式为您提供数据库连接对象; 即一个sqlite3对象。

为了防止人们访问内部, sqlite3.h sqlite3声明为不透明的结构。 这意味着你不能为sqlite3分配空间,因为你不知道它拥有什么; SQLite库必须为你分配它并给你一个指向它的指针( sqlite3* )。

所以现在我们有一个假设函数sqlite3* sqlite3_open(...); ,它打开一个DB并返回一个指向连接对象的指针。 但坚持下去; 如果发生错误怎么办? 我们可以返回NULL ,但是开发人员如何区分“数据库不存在”错误与“数据库是只读”,“数据库是否已损坏”或其他错误?

因此, sqlite3_open返回一个整数返回码,并将连接指针写入ppDB参数指向的内存(如果打开成功)。

sqlite3_open通常像这样使用:

 sqlite3* myDB; int status = sqlite3_open("/path/to/db", &myDB); if(status != SQLITE_OK) { // error occured return; } // sqlite3_open wrote a database pointer to myDB, use it here status = sqlite3_prepare_v2(myDB, "SELECT * FROM whatever", -1, NULL, NULL); // ...