10

I have a variable that needs to hold a pointer to an array. Normally this is done by first creating a variable with the array, then saving the pointer to that variable. However, I need to do this for maybe 10 variables, and I don't want to have to create an extra array for each of them. What I first tried was

int *numList = {1, 2, 3};

But that tries to create an array of pointers to integers. I think the following has the correct type for the list, but I don't know how to cast the array to a pointer.

int (*numList)[3] = {1, 2, 3};
Matthias
  • 648
  • 6
  • 18
  • Hard to imagine why is required 10 pointers to ... nothing important. Waht is main problem? – Jacek Cz Apr 21 '18 at 17:43
  • Yes, that is what I've been wondering -- what are you trying to achieve? – deLock Apr 21 '18 at 17:59
  • Basically, I'm writing a GUI in another (higher-level) language that's going to generate a bunch of instructions the form of C code including data in these arrays. The C code will then be complied and uploaded to a specific piece of hardware, which will execute the instructions. – Matthias Apr 21 '18 at 19:46

4 Answers4

12

In C99 and C11, you can use a compound literal to achieve what is requested in the question title, namely initialize a pointer so it points to an array literal without any extra variables:

int *numList = (int []){ 1, 2, 3 };

The array that numList points to has the same scope and lifetime as the pointer itself — it lasts for the block it is defined in if it is inside a function, or for the duration of the program if it is outside any function.

If you were so misguided as to create static int *numList = (int []){ 1, 2, 3}; inside a function, you'd be setting yourself up for a world of hurt — don't do it. (At file scope, outside any function, it doesn't present any problem.) The pointer would be initialized no later than when the function is first called, but there's no guarantee that what it points to has static duration and subsequent calls could be pointing at garbage.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

The standard says:

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.

You can assign the array into a type of int[], since "casting the array to a pointer" is not required by the very reason of arrays decaying into pointers by itself so to speak.

In short, int[] is treated like an int* from a practical point of view. Arrays are effectively pointers to their first element:

int array[] = { 1, 2, 3 };

Now you can pass this object to a function with the prototype void func(int *array); without casting it to int *. That is, you can call it as func(array).

Some relevant fact about this is array == &array. Consequently, you never need to explicitly cast an array into a pointer as that would be redundant.

Check What is array decaying? for more information.

neuro_sys
  • 805
  • 7
  • 13
  • Your quote appears to be from C99; [C11 §6.3.2.1 Lvalues, arrays, and function designators](http://port70.net/~nsz/c/c11/n1570.html#6.3.2.1p3) lists `_Alignof` and string literals used to initalize an array as other exceptions. The general topic of 6.3 is 'conversions'. I disagree with your contention that "`int []` _is_ an `int *`" — it is wrong. An array is readily converted to a pointer, but that is *not* the same as saying an array *is* the same as a pointer. You have also not addressed, much less answered, the main question — how do you initialize `pArray` without defining `array`. – Jonathan Leffler Apr 21 '18 at 21:07
  • Thanks for clarifications. Practically, you don't need to cast an `int []` to an `int *` explicitly as far as I know, since the conversion happens implicitly. It is similar to the reason that it shouldn't be needed to cast any pointer to `void *`. The answer to their question on my part was that they shouldn't cast an array of integers to a pointer to int, but instead, assign the object into an `int []`, which is what the object is. When they pass this object to elsewhere, casting won't be needed. – neuro_sys Apr 21 '18 at 22:00
-1

The array name itself is a pointer to the first element of the array.

ie, in your example,

int numList[3]={1,2,3};

numList points to 1.

if you want to pass this array's pointer to a function like

void sort(int *array)
{
//do something
}

you can call this function with your array's name as argument.

sort(numList);
thomachan
  • 378
  • 3
  • 14
  • It's not true that "There is no need for converting an array into poin[t]er". You cannot work with a name of an array variable as with a pointer. For example, you cannot do *array_name = 1; – deLock Apr 21 '18 at 18:54
  • 1
    You can do `*array_name = 1;`. Arrays are **not** pointers to their first elements, but they are automatically converted to pointers to their first elements in many contexts, including in `*array_name = 1;`. Nonetheless, this answer is incorrect to state that “The array name itself is a pointer to the first element of the array.” – Eric Postpischil Apr 21 '18 at 19:05
  • Automatic cast to pointer is not always allowed. And also you cannot do thing like array_name++. So no, array_name is not a pointer and you cannot work with it like with one. So my objection is valid -- it's not true that "There is no need for converting an array into a pointer." – deLock Apr 24 '18 at 16:08
-1
int (*numList)[3];

FYG, this is a pointer to an array of 3 integers (square brackets have higher precedence than *); you cannot initialize it this way.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278