简体   繁体   中英

What is the C-language statement for function returning a pointer to an array?

What would be the C code for a function that accepts a pointer to a character as argument and returns a pointer to an array of integers?

I have a confusion here. My answer is as follows:

int * q (char *) [ ]

Im not sure if I'm correct. But if its incorrect then what is the correct answer more importantly what is the approach to answer it. In general i would appreciate any general method to learn to interpret such questions and convert them to C code?

When dealing with functions, you basically needs to consider arrays as pointers because it is very hard (if possible) to pass or return an array in a function and make operations such as the sizeof operator still work as intended.

For you purpose, int ** q (char *) is enough, although you would not be able to know the length of the returned array this way.

I think I see where your confusion is, and I'm not sure it has been cleared based on the answer you selected. int **q (char *) is a function that returns a pointer to pointer to int , which if that is what you need, that is fine, but understand, the only way a function can return a pointer to pointer to int is if (1) the address of an array of int (pointer to array) is passed as a parameter to q , or (2), pointers are allocated in q and the pointer to allocated pointers is returned.

You appear to want (1), but have selected an answer for (2). Take a look at cdecl.org (C-declarations tool) which can always help decipher declarations

The best way to help you sort it out is probably an example of each. The following examples just plays on the ASCII value of the character variable c (ASCII '5' by default -- decimal 53 ). In the first case, returning a pointer-to-int (which is a pointer to a block of memory holding zero or more integers). For example, here a block of memory is allocated to hold 53 integers filled with values from 53-105 :

#include <stdio.h>
#include <stdlib.h>

int *q (char *c)
{
    int *a = calloc (*c, sizeof *a);

    if (a)
        for (int i = 0; i < (int)*c; i++)
            a[i] = *c + i;

    return a;
}

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

    char c = argc > 1 ? *argv[1] : '5';
    int *array = NULL;

    if ((array = q (&c)))
        for (int i = 0; i < (int)c; i++)
            printf ("array[%3d] : %d\n", i, array[i]);

    free (array);   /* don't forget to free mem */

    return 0;
}

Now in the second case, you are returning a pointer-to-pointer-to-int (a pointer to a block of memory holding zero or more pointers to int -- which each in turn can be separately allocated to hold zero or more integers each). In this case each individual pointer is allocated with space to hold one int and the same values as above are assigned:

#include <stdio.h>
#include <stdlib.h>

int **q (char *c)
{
    int **a = calloc (*c, sizeof *a);   /* allocate *c pointers to int */

    if (a) {
        for (int i = 0; i < (int)*c; i++)
            if ((a[i] = calloc (1, sizeof **a))) /* alloc 1 int per-pointer */
                *(a[i]) = *c + i;
            else {
                fprintf (stderr, "error: memory exhausted.\n");
                break;
            }
    }

    return a;
}

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

    char c = argc > 1 ? *argv[1] : '5';
    int **array = NULL;

    if ((array = q (&c)))
        for (int i = 0; i < (int)c; i++) {
            printf ("array[%3d] : %d\n", i, *(array[i]));
            free (array[i]);  /* free individually allocated blocks */
        }
    free (array);   /* don't forget to free pointers */

    return 0;
}

Example Use/Output

In each case, if no argument is passed to the program, the default output would be:

$ ./bin/qfunction2
array[  0] : 53
array[  1] : 54
array[  2] : 55
...
array[ 50] : 103
array[ 51] : 104
array[ 52] : 105

Now it is entirely unclear which of the two cases you are after as you seem to explain you want a pointer to an array of integers returned. As I started my last answer with, you cannot return an array , all you can return is a pointer , but that pointer can point to a block of memory that can hold multiple integers, or it can point to a block of memory holding multiple pointers that can each in turn be allocated to hold multiple integers.

So the ambiguity comes in "Do you want the return to point to an array of integers or an array of pointers ?" int *q (char *) is for the first, int **q (char*) is for the second.

Now, going forward, you will realize that you have not provided a way to know how many integers (or pointers) are being returned. (that requires an extra parameter or global variable (discouraged) at the very least). That is left for another day. (it is also why the examples are a play on the ASCII value of 53 or whatever character is the first character of the first argument, it provides a fixed value to know what has been allocated)

I'm happy to provide further help, but I will need a bit of clarification on what you are trying to accomplish.

A pointer to an array of integers looks like:

int (*p)[];

where it is optional to have a dimension inside the square brackets.

So a function returning that would look like:

int (*func(char *))[];

Note that "pointer to array" is a different thing to "pointer to first element of array". Sometimes people say the former when they mean the latter. If you actually meant the latter then your function could be more simply:

int **func(char *);

The first form is rarely used because there is nothing you can do with the return value other than decay it to int ** anyway. It would sometimes be useful to specify a dimension if the function always is to return a pointer to a fixed-size buffer, but in that case I would recommend using a typedef for readability:

typedef int ARR_4_INT[4];

ARR_4_INT * func(char *);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM