C++ 用于多级指针取消引用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/758673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:08:13  来源:igfitidea点击:

Uses for multiple levels of pointer dereferences?

c++pointers

提问by Jake

When does using pointers in any language require someone to use more than one, let's say a triple pointer. When does it make sense to use a triple pointer instead of just using a regular pointer?

什么时候在任何语言中使用指针都需要有人使用多个指针,比如说三重指针。什么时候使用三重指针而不是只使用常规指针有意义?

For example:

例如:

char  * * *ptr;

instead of

代替

char *ptr;

回答by SingleNegationElimination

each star should be read as "which pointed to by a pointer" so

每颗星都应该读作“由指针指向的”,所以

char *foo;

is "char which pointed to by a pointer foo". However

是“由指针 foo 指向的字符”。然而

char *** foo;

is "char which pointed to by a pointer which is pointed to a pointer which is pointed to a pointer foo". Thus foo is a pointer. At that address is a second pointer. At the address pointed to by that is a third pointer. Dereferencing the third pointer results in a char. If that's all there is to it, its hard to make much of a case for that.

是“由指向指针的指针指向的字符,而指针指向的指针指向指针 foo”。因此 foo 是一个指针。在那个地址是第二个指针。在它指向的地址处是第三个指针。取消引用第三个指针会产生一个字符。如果仅此而已,则很难对此进行充分论证。

Its still possible to get some useful work done, though. Imagine we're writing a substitute for bash, or some other process control program. We want to manage our processes' invocations in an object oriented way...

不过,它仍然有可能完成一些有用的工作。想象一下,我们正在编写 bash 或其他一些过程控制程序的替代品。我们希望以面向对象的方式管理我们的流程调用......

struct invocation {
    char* command; // command to invoke the subprocess
    char* path; // path to executable
    char** env; // environment variables passed to the subprocess
    ...
}

But we want to do something fancy. We want to have a way to browse all of the different sets of environment variables as seen by each subprocess. to do that, we gather each set of envmembers from the invocation instances into an array env_listand pass it to the function that deals with that:

但是我们想做一些奇特的事情。我们希望有一种方法可以浏览每个子进程所看到的所有不同的环境变量集。为此,我们env将调用实例中的每组成员收集到一个数组中env_list,并将其传递给处理它的函数:

void browse_env(size_t envc, char*** env_list);

回答by Constantino Tsarouhas

If you work with "objects" in C, you probably have this:

如果您在 C 中使用“对象”,您可能会遇到以下情况:

struct customer {
    char *name;
    char *address;
    int id;
} typedef Customer;

If you want to create an object, you would do something like this:

如果你想创建一个对象,你会做这样的事情:

Customer *customer = malloc(sizeof Customer);
// Initialise state.

We're using a pointer to a structhere because structarguments are passed by value and we need to work with oneobject. (Also: Objective-C, an object-oriented wrapper language for C, uses internally but visibly pointers to structs.)

我们在struct这里使用指向 a 的指针,因为struct参数是按值传递的,我们需要处理一个对象。(另外:Objective-C,一种用于 C 的面向对象的包装语言,在内部使用但明显指向structs 的指针。)

If I need to store multiple objects, I use an array:

如果我需要存储多个对象,我使用一个数组:

Customer **customers = malloc(sizeof(Customer *) * 10);
int customerCount = 0;

Since an array variable in C pointsto the first item, I use a pointer… again. Now I have double pointers.

由于 C 中的数组变量指向第一项,因此我再次使用指针……。现在我有双指针。

But now imagine I have a function which filters the array and returns a new one. But imagine it can't via the return mechanism because it must return an error code—my function accesses a database. I need to do it through a by-reference argument. This is my function's signature:

但是现在想象我有一个函数来过滤数组并返回一个新的数组。但是想象一下它不能通过返回机制,因为它必须返回一个错误代码——我的函数访问一个数据库。我需要通过引用参数来做到这一点。这是我的函数签名:

int filterRegisteredCustomers(Customer **unfilteredCustomers, Customer ***filteredCustomers, int unfilteredCount, int *filteredCount);

The function takes an array of customers and returns a reference to an array of customers (which are pointers to a struct). It also takes the number of customers and returns the number of filtered customers (again, by-reference argument).

该函数采用客户数组并返回对客户数组的引用(它们是指向 a 的指针struct)。它还采用客户数量并返回过滤客户的数量(同样,通过引用参数)。

I can call it this way:

我可以这样称呼它:

Customer **result, int n = 0;
int errorCode = filterRegisteredCustomers(customers, &result, customerCount, &n);

I could go on imagining more situations… This one is without the typedef:

我可以继续想象更多的情况……这个没有typedef

int fetchCustomerMatrix(struct customer ****outMatrix, int *rows, int *columns);

Obviously, I would be a horrible and/or sadistic developer to leave it that way. So, using:

显然,我会成为一个可怕的和/或虐待狂的开发人员,如果不这样做。所以,使用:

typedef Customer *CustomerArray;
typedef CustomerArray *CustomerMatrix;

I can just do this:

我只能这样做:

int fetchCustomerMatrix(CustomerMatrix *outMatrix, int *rows, int *columns);

If your app is used in a hotel where you use a matrix per level, you'll probably need an array to a matrix:

如果您的应用在每层使用矩阵的酒店中使用,您可能需要一个矩阵数组:

int fetchHotel(struct customer *****hotel, int *rows, int *columns, int *levels);

Or just this:

或者只是这个:

typedef CustomerMatrix *Hotel;
int fetchHotel(Hotel *hotel, int *rows, int *columns, int *levels);

Don't get me even started on an array of hotels:

不要让我开始介绍一系列酒店:

int fetchHotels(struct customer ******hotels, int *rows, int *columns, int *levels, int *hotels);

…arranged in a matrix (some kind of large hotel corporation?):

...排列在矩阵中(某种大型酒店公司?):

int fetchHotelMatrix(struct customer *******hotelMatrix, int *rows, int *columns, int *levels, int *hotelRows, int *hotelColumns);

What I'm trying to say is that you can imagine crazy applications for multiple indirections. Just make sure you use typedefif multi-pointers are a good idea and you decide to use them.

我想说的是,您可以想象多个间接访问的疯狂应用程序。typedef如果多指针是一个好主意并且您决定使用它们,请确保您使用它们。

(Does this post count as an application for a SevenStarDeveloper?)

(这篇文章算作SevenStarDeveloper的应用程序吗?)

回答by René Nyffenegger

ImageMagicks's Wand has a function that is declared as

ImageMagicks 的 Wand 有一个函数声明为

WandExport char* * * * * * DrawGetVectorGraphics    (  const DrawingWand  *) 

I am not making this up.

这不是我编造的

回答by Brian R. Bondy

A pointer is simply a variable that holds a memory address.

指针只是一个保存内存地址的变量。

So you use a pointer to a pointer, when you want to hold the address of a pointer variable.

因此,当您想要保存指针变量的地址时,您可以使用指向指针的指针。

If you want to return a pointer, and you are already using the return variable for something, you will pass in the address of a pointer. The function then dereferences this pointer so it can set the pointer value. I.e. the parameter of that function would be a pointer to a pointer.

如果你想返回一个指针,并且你已经在使用返回变量做某事,你将传入一个指针的地址。该函数然后取消引用该指针,以便它可以设置指针值。即该函数的参数将是一个指向指针的指针。

Multiple levels of indirection are also used for multi dimensional arrays. If you want to return a 2 dimensional array, you would use a triple pointer. When using them for multi dimensional arrays though be careful to cast properly as you go through each level of indirection.

多维数组也使用多级间接。如果你想返回一个二维数组,你可以使用三重指针。当将它们用于多维数组时,尽管在遍历每个间接级别时要小心正确地转换。

Here is an example of returning a pointer value via a parameter:

以下是通过参数返回指针值的示例:

//Not a very useful example, but shows what I mean...
bool getOffsetBy3Pointer(const char *pInput, char **pOutput)
{
  *pOutput = pInput + 3;
  return true;
}

And you call this function like so:

你像这样调用这个函数:

const char *p = "hi you";
char *pYou;
bool bSuccess = getOffsetBy3Pointer(p, &pYou);
assert(!stricmp(pYou, "you"));

回答by Matt J

N-dimensional dynamically-allocated arrays, where N > 3, require three or more levels of indirection in C.

N 维动态分配的数组,其中 N > 3,在 C 中需要三个或更多的间接级别。

回答by Not Sure

A standard use of double pointers, eg: myStruct** ptrptr, is as a pointer to a pointer. Eg as a function parameter, this allows you to change the actual structure the caller is pointing to, instead of only being able to change the values within that structure.

双指针的标准用法,例如:myStruct** ptrptr,是作为指向指针的指针。例如,作为函数参数,这允许您更改调用者指向的实际结构,而不是只能更改该结构中的值。

回答by Pat

Char *** foo can be interpreted as a pointer to a two-dimensional array of strings.

Char *** foo 可以解释为一个指向二维字符串数组的指针。

回答by Jonathan Leffler

You use an extra level of indirection - or pointing - when necessary, not because it would be fun. You seldom see triple pointers; I don't think I've ever seen a quadruple pointer (and my mind would boggle if I did).

您在必要时使用额外的间接级别 - 或指向 - 不是因为它会很有趣。你很少看到三重指针;我认为我从未见过四重指针(如果我看到了,我的想法会令人难以置信)。

State tables can be represented by a 2D array of an appropriate data type (pointers to a structure, for example). When I wrote some almost generic code to do state tables, I remember having one function that took a triple pointer - which represented a 2D array of pointers to structures. Ouch!

状态表可以由适当数据类型的二维数组表示(例如,指向结构的指针)。当我编写一些几乎通用的代码来处理状态表时,我记得有一个函数接受一个三重指针——它表示一个指向结构的指针的二维数组。哎哟!

回答by tpdi

 int main( int argc, char** argv );

回答by jalf

Functions that encapsulate creation of resources often use double pointers. That is, you pass in the address of a pointer to a resource. The function can then create the resource in question, and set the pointer to point to it. This is only possible if it has the address of the pointer in question, so it must be a double pointer.

封装资源创建的函数通常使用双指针。也就是说,您传入一个指向资源的指针的地址。然后该函数可以创建有问题的资源,并将指针设置为指向它。这只有在它具有相关指针的地址时才有可能,因此它必须是双指针。