From: Pat on
Ulrich Eckhardt wrote:
> Pat wrote:
>> What does it mean when a function argument contains multiple "*" - for
>> example:
>>
>> /***************************************/
>> int GetNameData(char*** faceName)
>> {
>> *faceNames = registeredFaceNames;
>> return numOffaceNames;
>> }
>
> There's nothing special when it's a function argument.
>
>> I know a single "*" after a type designation makes it a
>> "pointer-to-type", but what about multiple "*" (such as char*** or
>> char ** shown above)? What do those do?
>
> int i; // integer
> int* pi; // pointer to integer
> int** ppi; // pointer to pointer to integer
> int*** pppi; // pointer to pointer to pointer to integer
>
> If you want, you can introduce further levels of indirection, though it
> tends to not make code more easy to read and understand.
>
>> Also, so far I've only seen this used with "char" types. Is this
>> something specific to that type only?
>
> No. The reason that you have only seen this is probably that only char is
> almost always used as 'char*' or 'char const*' in order to express a
> string. Now, if you want a pointer to a string, you suddenly have two
> levels of indirection, i.e. 'char**'. In above function, you additionally
> have a pointer to an array of strings, which adds another level of
> indirection.
>
> BTW: when I see above code, I think it could be rewritten for better
> readability. I guess that the code doesn't only store names, but also
> further data associated with the name. In the form above, it stores an
> array with the names and further arrays to store the associated data.
> Instead of that, I would rather define a structure that holds all relevant
> data including the name and then store an array of that structure.
>
> Further, for any type that holds an array size or an object size, I would
> always use size_t. That's the type that 'sizeof' yields and also the type
> that e.g. 'strlen()' returns. This gives your program more consistency and
> avoids justified warnings by the compiler.
>
> Uli
>

Thanks Uli for the feedback. This is code someone else wrote, but I
don't doubt that it could be improved. At this point I'm just trying to
understand what it does, and since I'm new to C++ (and am learning that
at the same time) its proven quite a challenge! But this newsgroup (and
a couple of good C++ books) have been a tremendous help.

Thanks again for your help. I appreciate it. -Pat
From: Jim Langston on
Pat wrote:
> What does it mean when a function argument contains multiple "*" - for
> example:
>
> /***************************************/
> int GetNameData(char*** faceName)
> {
> *faceNames = registeredFaceNames;
> return numOffaceNames;
> }
> /***************************************/
>
> or
>
> /***************************************/
> int AreValuesValid(char ** error, double * paramValues)
> {
> <statements>
> }
> /**************************************?
>
> ?
>
> I know a single "*" after a type designation makes it a
> "pointer-to-type", but what about multiple "*" (such as char*** or
> char ** shown above)? What do those do?
>
> Also, so far I've only seen this used with "char" types. Is this
> something specific to that type only?
>
> Thanks for any help.

A pointer to a pointer is usually used in C when when you want change the
original pointer itself. (In C++ you would probalby want to use a reference
to a pointer).

Parameters in C and C++ are passed by value, they are copied. If you wish
to change the actual variable passed in you will need a pointer to it (or a
reference).

This is what your first function GetNameData is doing, although it is
changing faceName to point to an array of pointers.

I.E.

char** Names;
( Names wants to point to an array of pointers).
int Count;
Count = GetNameData( &Names );

The variable Names is actually changed since a pointer (the address) of
Names was passed in.

This is not always the case for a ** though, an array of pointers is
sometimes set up this way, as we see for names. Since we want to change
names in the function an additional level of indirection is required, a
pointer to a char** or char***.

In C++ we would make the call

int GetNameData(char**& faceName)

Or a reference to a char**.

Now it's possible that we would want to pass our pointer to our array of
pointers to another function where it would be

DisplayNames( char** Names, int Count )

where we are not going to modify Names. But we still need a pointer to a
pointer because we still have an array of pointers.
--
Jim Langston
tazmaster(a)rocketmail.com