Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Const arrays in C

Original question: If I define:

const int z[5] = {10, 11, 12, 13, 14}; 

does it mean:

  1. it's a constant array of integers i.e. the address which z points to is always constant and can never change, but the elements of z can change.

OR

  1. Each element of z is a constant i.e. their value can never change.

Edit:

More info:

There is another variable:

const int *y = z;
func((int *) y);

where func is defined as:

void func(int y[]) {
    int i;
    for(i = 0; i < 5; i++) {
        y[i] = i; //y[i] can be set to any integer; used i as example
    }
}

where in func, using y, the array is traversed and each element is changed. Is this is valid even though all elements of z are const?

like image 925
sandeeps Avatar asked Sep 21 '15 22:09

sandeeps


People also ask

What is constant array in C?

it's a constant array of integers i.e. the address which z points to is always constant and can never change, but the elements of z can change.

What are constant arrays?

In Excel, an array constant is a way to write an array of literal data in your Excel formulas. Think of it this way, a range of A1:A3 is actually an array of data.

Can array be declared as constant?

Arrays are Not Constants It does NOT define a constant array. It defines a constant reference to an array. Because of this, we can still change the elements of a constant array.

Should arrays be let or const?

There is no preferred one, its based on your choice of usage for that array or object. You have to understand mutation and reassigning clearly. If your usecase only needs mutation, you can go for const.. if you need reassigning then go for let.


2 Answers

It means that each element of z is read-only.

The object z is an array object, not a pointer object; it doesn't point to anything. Like any object, the address of z does not change during its lifetime.

Since the object z is an array, the expression z, in most but not all contexts, is implicitly converted to a pointer expression, pointing to z[0]. That address, like the address of the entire array object z, doesn't change during the object's lifetime. This "conversion" is a compile-time adjustment to the meaning of the expression, not a run-time type conversion.

To understand the (often confusing) relationship between arrays and pointers, read section 6 of the comp.lang.c FAQ.

It's important to understand that "constant" and const are two different things.

If something is constant, it's evaluated at compile time; for example, 42 and (2+2) are constant expressions.

If an object is defined with the const keyword, that means that it's read-only, not (necessarily) that it's constant. It means that you can't attempt to modify the object via its name, and attempting to modify it by other means (say, by taking its address and casting to a non-const pointer) has undefined behavior. Note, for example, that this:

const int r = rand();

is valid. r is read-only, but its value cannot be determined until run time.

like image 173
Keith Thompson Avatar answered Oct 13 '22 21:10

Keith Thompson


In your case the answer is:

  1. Each element of z is a constant i.e. their value can never change.

You can't create a const array because arrays are objects and can only be created at runtime and const entities are resolved at compile time.

So, the const is interpreted as in the first example below, i.e. applied for the elements of the array. Which means that the following are equivalent: The array in your example needs to be initialized.

 int const z[5] = { /*initial (and only) values*/};
 const int z[5] = { /*-//-*/ };

It is some type commutative property of the const specifier and the type-specifier, in your example int.

Here are few examples to clarify the usage of constant:

1.Constant integers definition: (can not be reassigned). In the below two expression the use of const is equivalent:

int const a = 3;  // after type identifier
const int b = 4;  // equivalent to before type qualifier

2.Constant pointer definition (no pointer arithmetics or reassignment allowed):

int * const p = &anInteger;  // non-constant data, constant pointer

and pointer definition to a constant int (the value of the pointed integer cannot be changed, but the pointer can):

const int *p = &anInteger;  // constant data, non-constant pointer
like image 3
Ziezi Avatar answered Oct 13 '22 21:10

Ziezi