Why does the indexing in an array start with zero in C and not with 1?
Array index always starts with zero.Let assume base address is 2000. Now arr[i] = *(arr+i)
. Now if i= 0
, this means *(2000+0
)is equal to base address or address of first element in array. this index is treated as offset, so bydeafault index starts from zero.
For the same reason that, when it's Wednesday and somebody asks you how many days til Wednesday, you say 0 rather than 1, and that when it's Wednesday and somebody asks you how many days until Thursday, you say 1 rather than 2.
It is because the address
has to point to the right element
in the array. Let us assume the below array:
let arr = [10, 20, 40, 60];
Let us now consider the start of the address being 12
and the size of the element
be 4 bytes
.
address of arr[0] = 12 + (0 * 4) => 12
address of arr[1] = 12 + (1 * 4) => 16
address of arr[2] = 12 + (2 * 4) => 20
address of arr[3] = 12 + (3 * 4) => 24
If it was not zero-based
, technically our first element address in the array
would be 16
which is wrong as it's location is 12
.
Because it made the compiler and linker simpler (easier to write).
Reference:
"...Referencing memory by an address and an offset is represented directly in hardware on virtually all computer architectures, so this design detail in C makes compilation easier"
and
"...this makes for a simpler implementation..."
first of all you need to know that arrays are internally considered as pointers because the "name of array itself contains the address of the first element of array "
ex. int arr[2] = {5,4};
consider that array starts at address 100 so element first element will be at address 100 and second will be at 104 now, consider that if array index starts from 1, so
arr[1]:-
this can be written in the pointers expression like this-
arr[1] = *(arr + 1 * (size of single element of array));
consider size of int is 4bytes, now,
arr[1] = *(arr + 1 * (4) );
arr[1] = *(arr + 4);
as we know array name contains the address of its first element so arr = 100 now,
arr[1] = *(100 + 4);
arr[1] = *(104);
which gives,
arr[1] = 4;
because of this expression we are unable to access the element at address 100 which is official first element,
now consider array index starts from 0, so
arr[0]:-
this will be resolved as
arr[0] = *(arr + 0 + (size of type of array));
arr[0] = *(arr + 0 * 4);
arr[0] = *(arr + 0);
arr[0] = *(arr);
now, we know that array name contains the address of its first element so,
arr[0] = *(100);
which gives correct result
arr[0] = 5;
therefore array index always starts from 0 in c.
reference: all details are written in book "The C programming language by brian kerninghan and dennis ritchie"
This question was posted over a year ago, but here goes...
While Dijkstra's article (previously referenced in a now-deleted answer) makes sense from a mathematical perspective, it isn't as relevant when it comes to programming.
The decision taken by the language specification & compiler-designers is based on the decision made by computer system-designers to start count at 0.
Quoting from a Plea for Peace by Danny Cohen.
For any base b, the first b^N non-negative integers are represented by exactly N digits (including leading zeros) only if numbering starts at 0.
This can be tested quite easily. In base-2, take 2^3 = 8
The 8th number is:
111
can be represented using 3
bits, while 1000
will require an extra bit (4 bits).
Computer memory addresses have 2^N
cells addressed by N
bits. Now if we start counting at 1, 2^N
cells would need N+1
address lines. The extra-bit is needed to access exactly 1 address. (1000
in the above case.). Another way to solve it would be to leave the last address inaccessible, and use N
address lines.
Both are sub-optimal solutions, compared to starting count at 0, which would keep all addresses accessible, using exactly N
address lines!
The decision to start count at 0
, has since permeated all digital systems, including the software running on them, because it makes it simpler for the code to translate to what the underlying system can interpret. If it weren't so, there would be one unnecessary translation operation between the machine and programmer, for every array access. It makes compilation easier.
Quoting from the paper: