0

I´m starting with C programing language and I have a doubt with the initialization of pointers. I know that when we declare a pointer we are reserving memory for the specific pointer, but this pointer may point to x address we don´t know anything about, the point is that I can do this: char * s = "Hi"; but I can´t do this double * f = 3; so what I do to "initialize" this double pointer is the next piece of code:

double * d;
double x = 3;
d = &x;

So that I have the pointer pointing to an specific memory location with the initial value I want to have.

Summing up, my doubt is:

1.- Is there any way to initialize double/int pointers as with char ones?

Angelixus
  • 160
  • 1
  • 5
  • 13
  • I think the best you can do is declare the pointer after the declaration of `x`. Then you can initialize the pointer to `&x` when you declare it, e.g. `double *d = &x;` – Tom Karzes Sep 26 '18 at 00:48
  • @TomKarzes and do you know why the char pointer initialization I wrote works, `char * s = "Hi";` but `double * f = 3;` does not? – Angelixus Sep 26 '18 at 00:50
  • String constants (in that context) are actually arrays whose elements have type `char`. So for instance, `"abc"` has type `char [4]` (the fourth character is the terminating null character). Compare with the character constant `'a'`, which has type `int`. – Tom Karzes Sep 26 '18 at 00:52
  • @TomKarzes so if I understand right, the syntax I wrote for initializing the String with the char pointer is an "special" syntax of C in order not to initialize an array of chars and initialize the indexes of that array that will contain the chars of the String – Angelixus Sep 26 '18 at 00:56
  • The string declaration is basically doing pointer assignment. The string constant degrades to a `char *` in that context. You can think of these as assignments. You can assign one pointer to another, or an array to a pointer (in which case the array degrades to a pointer), but you can't assign an integer to a pointer. If you could write `{3.0}` and have it implicitly create a `double [1]` array that's initialized to `{3.0}`, then that would work, but C only supports that when used to initialize an array. String constants are special in that regard. – Tom Karzes Sep 26 '18 at 01:01
  • @TomKarzes: C does not support that only when used to initialize an array. One can write “(double []) { 3.0, 4.0, 5.0 }” to create an array of `double` in the middle of an expression, including when initializing a pointer, as my answer shows. – Eric Postpischil Sep 26 '18 at 01:38
  • @EricPostpischil Oh, I guess that was added with C99 (and prior to that as a gnu extension to C90). I saw it described [here](https://stackoverflow.com/questions/1269568/how-to-pass-a-constant-array-literal-to-a-function-that-takes-a-pointer-without). – Tom Karzes Sep 26 '18 at 02:11

2 Answers2

4

Yes, but you usually should not:

double *x = (double []) {3};

Just as char *x = "Hi"; creates an array of char and initializes x to point to the first member of the array, the code above creates an array of double and initializes x to point its first member. (I have shown only a single element, but you could write more.) This is called a compound literal.

An important difference is that the lifetime of a string literal is the entire execution of the program, so you can safely return its address from a function. In contrast, a compound literal inside a function exists only as long as the function is executing, so its address cannot be returned from the function. If this definition appeared outside a function, the compound literal would exist for the entire execution of the program.

Compound literals are useful at times, but the situations where it is good to initialize a pointer to the address of a compound literal as I show above are very limited. Code like that should be used with restraint and discretion.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
2

The best you could do would be to use an array instead of a raw pointer. Since the array degrades to a pointer in almost every use case, it will behave roughly the way you want.

double d[] = {3};

will allocate the space (globally or on the stack, depending on whether it's performed at global or function scope) and initialize it at once. For almost all purposes, referring to d will cause it to degrade to a double*.

The main difference is that, for stack allocated arrays (function scope, without static qualifier), the array only lives until the end of the function call. Declaring it as static double d[] = {3}; will make it live for the life of the program, but it will have a single initialization, and any changes will persist indefinitely.

The other important distinction is that you can't modify the address, since it's not really a pointer; ++d won't be legal, since d is an array, not a pointer.

For an exact equivalent of char *s = "Hi";, you're basically stuck with a two-liner. That code is roughly equivalent to:

static char unnamed[] = {'H', 'i', '\0'};
char *s = unnamed;

It's a special behavior of C string literals, which no other type has direct language support for. Mimicking it precisely with double would always be a two liner:

static double dstorage[] = {3};
double *d = dstorage;
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271