C - passing arrays through functions
I have the following...
void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys]) {}
int main ()
{
char keys[NumberOfKeys][LengthOfKeys] = {};
keySorter (&keys);
}
So, I have this, it compiles fine, but I'm getting back what I want. The keys[][] has been initialized with = {};
so it's empty, but it's supposed to get filled with stuff once inside the function.
The first element gets placed into the function the rest goes...? I watch the function STRCPY which puts the data into keys[][] and its has the right source va开发者_如何转开发lue the destination value seems to be garbage though (or at least it made up characters that look like garbage).
strcpy(*keys[i], "BLAH");
That's the other part of the function.
Inside keySorter
, keys
is a pointer to an array of arrays of char
. This means that to get an array of char
for use with strcpy
you need to derefence the pointer, then use array access to select an array.
E.g.
strcpy((*keys)[i], "test");
You can't use *keys[i]
because the precedence rules mean that []
is applied first and keys
is not a pointer to the first element of an array it is a pointer to the array itself.
Incidentally, for what you are doing it is much more conventional to declare keySorter
as taking a pointer to an array of chars and let the normal array to pointer decay happen on arguments to the function.
void keySorter(char keys[][LengthOfKeys]);
or
void keySorter(char (*keys)[LengthOfKeys]);
In this case you can simply do strcpy(keys[i], "blah")
because keys
is a pointer into an array of arrays of char
.
Called:
int main ()
{
char keys[NumberOfKeys][LengthOfKeys] = {};
keySorter(keys);
}
Here is (C99) code that works - the output is tidy if your window is more than 100 columns wide (adjust the 32 to a smaller number if you have narrow windows):
#include <stdio.h>
enum { NumberOfKeys = 20, LengthOfKeys = 32 };
static void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys])
{
size_t k = 0;
for (size_t i = 0; i < NumberOfKeys; i++)
for (size_t j = 0; j < LengthOfKeys; j++)
(*keys)[i][j] = ++k & 0xFF;
}
static void dumpKeys(char keys[NumberOfKeys][LengthOfKeys])
{
for (size_t i = 0; i < NumberOfKeys; i++)
{
for (size_t j = 0; j < LengthOfKeys; j++)
printf("%02X ", keys[i][j] & 0xFF);
putchar('\n');
}
}
int main(void)
{
char keys[NumberOfKeys][LengthOfKeys] = {};
printf("Before:\n");
dumpKeys(keys);
keySorter(&keys);
printf("After:\n");
dumpKeys(keys);
}
Notice the crucial difference between the notations used to access the array in keySorter()
compared to dumpKeys()
. In the first, because a pointer to a 2D array is passed, the code to access the array must first dereference the pointer with (*keys)[i][j]
, whereas in the second, the array is passed directly and the direct access notation keys[i][j]
is fine.
When I compiled with (GCC 4.2.1 on MacOS X 10.6.5) using:
gcc -O -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition xx.c -o xx
the code shown compiles cleanly. When I experimented with using keys[i][j]
in keySorter()
, it complained 'error: incompatible types in assignment`.
You can also revise the keySorter()
to use strcpy()
(you should #include <string.h>
too, of course):
static void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys])
{
for (size_t i = 0; i < NumberOfKeys; i++)
strcpy((*keys)[i], "BLAH");
}
You still have to dereference the pointer to the array before indexing into the array.
If/when you wrote:
strcpy(keys[i], "BLAH");
then you should be getting compiler warnings (if you aren't get a better compiler, or at the very least, work out how to make your compiler emit copious warnings), but the value of keys[0]
was the first array in the set of arrays pointed to by keys
, and then keys[1]
was the second array, and keys[2]
was the third array, and so on. The pointer might decay enough that you end up writing BLAH over the first row of each array, but you'll end up with a core dump or other such problems because you didn't allocate enough arrays in the main program.
You declare the auto variable keys
but don't put anything into it, so it will contain garbage values.
Yes, you are pasing the array correctly, in that the call and the declared function parameter type match. But you are passing a pointer to an array of an array of char instead of a simple pointer to the array's first char element. Perhaps you should do it this way:
void keySorter(char keys[NumberOfKeys][LengthOfKeys])
{...}
int main(void)
{
char keys[NumberOfKeys][LengthOfKeys];
keySorter(keys);
}
This allows you to access the array elements very simply:
for (int i = 0; i < NumberOfKeys; i++)
{
for (int j = 0; j < LengthOfKeys; j++)
{
... keys[i][j] ...
}
}
Addendum
Adding an explicit initializer value is sufficient to initialize the array to all zeros (i.e., all '\0'
char values):
char keys[NumberOfKeys][LengthOfKeys] = { 0 };
keys is already a pointer so you dont have to do this keySorter (&keys); put just keySorter (keys);
精彩评论