当我想要单指针时我很困惑,什么时候我应该采用双指针? 在以下结构中究竟做了什么?
struct objc_class {
Class isa;
Class super_class;
const char *name;
long version;
long info;
long instance_size;
struct objc_ivar_list *ivars;
struct objc_method_list **methodLists;
struct objc_cache *cache;
struct objc_protocol_list *protocols;
};
为什么我们使用“** methodLists”双指针。
被修改
int sqlite3_get_table(
sqlite3 * db,
const char * zSql,
char *** pazResult,
int * pnRow,
int * pnColumn,
char ** pzErrmsg
);
在上面的场景中,三指针char *** pazResult的含义是什么?
答案 0 :(得分:6)
嗯,至少在C中,双指针通常用于2D数组。最常见的2D数组可能是C字符串数组(char*
)。有时也会使用双指针通过引用将指针传递给函数,但这不太可能在您发布的代码示例中使用。
根据名称methodLists
,我猜这是一个列表数组。 C中的(链接)列表通常由指向节点的指针表示,objc_method_list
可以是。然后使用双指针实现这样的列表数组。
答案 1 :(得分:4)
在您引用的代码中可能不是这种情况,但是每当您想要将指针传递给函数并且对该指针的更改反映在该函数的范围之外时,您还需要一个双指针。
例如,如果您尝试重写strcpy函数以便用户不必为源字符串分配内存,则可以尝试类似以下内容:
void MyStrcpy(char* dst, char* src){
dst = (char*)malloc(sizeof(char)*(strlen(src)+1));
for(int i=0;i<=strlen(src);i++)
dst[i] = src[i];
printf("src: %s ", src);
printf("dst: %s\n\n", dst);
}
如果您当时要调用该功能,
int main() {
char *foo = "foo";
char *newPtr;
MyStrcpy(newPtr, foo);
printf("foo: %s ", foo);
printf("new: %s\n", newPtr);
}
您的输出如下:
src:foo dst:foo
foo:foo 新:
根据您的系统,在尝试打印newPtr时,您可能还会遇到段错误。这种行为的原因与您不希望更改为通过值传递给函数的int的原因完全相同的原因是在该函数之外反映:您传递给MyStrcpy的只是内存地址newPtr引用。当你在函数内部为dst的空间malloc时,你正在改变地址dst指向。此更改不会反映在MyStrcpy的范围之外!
相反,如果你想让newPtr指向新分配的内存块,你需要让dst成为指针的指针,一个char **。
void MyStrcpy(char** dst, char* src){
*dst = (char*)malloc(sizeof(char)*(strlen(src)+1));
for(int i=0;i<=strlen(src);i++)
(*dst)[i] = src[i];
printf("src: %s ", src);
printf("dst: %s\n\n", *dst);
}
现在,如果您要调用该功能:
int main() {
char *foo = "foo";
char *newPtr;
MyStrcpy(&newPtr, foo);
printf("foo: %s ", foo);
printf("new: %s\n", newPtr);
}
你会得到预期的输出:
src:foo dst:foo
foo:foo 新:foo
希望有所帮助!
答案 2 :(得分:3)
答案 3 :(得分:2)
在最常见的情况下,双指针是指向指针列表的指针。
答案 4 :(得分:1)
通常,指针用于保存另一个变量的地址。如果我们需要保留指针的地址,在这种情况下,我们将使用双指针。当我们要保留双指针的地址时,我们使用三指针。