# One-based array index

Using one-based array index proved for me to be very convenient. I hope you consider that in Zig.

Would you elaborate on that?
Why 1-based, specifically?

IIRC, there was a language (Pascal?) that allowed to specify any index base for specific arrays. Anyway, itās just syntactic sugar, IMO.

Moreover, in C usual notation `a[i]` is also syntactic sugar.
Non-sugar form for accessing elements of an array is

``````float *a;
int i;
... *(a + i)...
``````

Which means

• take the address of the beginning of the array (a)
• add `i * sizeof(float)` to it ā this is the address of i-th element of the array

And since `a + 4 * i = 4 * i + a`, you can write wierdly looking things like `i[a]` instead of `a[i]`, if I am not mistaken.

Anyway, to get an address of an i-th element of an array you do `a + i * sizeof(ArrayElement)`,
this is why indexing usually starts with zero, but not one (yes, Pascal is one of the exceptions).

yes, no problem:

``````#include <stdio.h>

float a[] = {
[0] = 1.1,
[1] = 2.2,
[2] = 3.3,
};

int main(void) {
printf("a[2] = %.1f\n", a[2]);
printf("2[a] = %.1f\n", 2[a]);
}
``````
``````\$ ./a.out
a[2] = 3.3
2[a] = 3.3
``````

However, for multidimensional arrays `[]` notation is not merely syntactic sugar. It does simplify the presentation of array element significantly.
Otherwise you could argue that everything is syntactic sugar - `for` loops, `switch`āes, etc.

I was referring to this specifically - you can start indexing with whatever you want:

``````program exArrays;
var
n: array [-10..10] of integer;   (* n is an array of 21 integers *)
i, j: integer;

begin
(* initialize elements of array n *)
for i := -10 to 10 do
n[ i ] := i * 2;

(* output each array element's value *)
for j:= -10 to 10 do
writeln('Element[', j, '] = ', n[j] );
end.
``````

You can try it out here.

However, you can achieve the same result like this:

``````program exArrays;
var
n: array [0..20] of integer;   (* n is an array of 21 integers *)
i, j: integer;

begin
(* initialize elements of array n *)
for i := 0 to 20 do
n[ i ] := (i - 10) * 2;

(* output each array element's value *)
for j:= 0 to 20 do
writeln('Element[', j - 10, '] = ', n[j] );
end.
``````

Moreover, Iām pretty sure this is how the first program works āunder the hoodā as well, hence my question - why is this important to OP.

I do not understand this either.

@dude_the_builder, got it!
Is zig supported?

Yes, itās the default language for highlighting if you donāt specify one or if you add `zig` after the backticks. I donāt think Discourse can handle Pascal, but Iāll check to make sure.

I have tried `Pascal`, `pascal` and `pas`, but it didnāt work.
Anyway, I doubt weāll see much Pascal in this forum.

Confirmed, thereās no Pascal syntax highlighting. Bad news for you old timers. lol

1 Like

It is a purpose of syntactic sugar to simplify how a code looks like, isnāt it?..
Still, in C `a[j][k]` is sugar for `*(*(a + j) + k)`:

``````#include <stdio.h>

float a[3][3] = {
[0] = {[0] = 1.1, [1] = 2.2, [2] = 3.3},
[1] = {[0] = 4.4, [1] = 5.5, [2] = 6.6},
[2] = {[0] = 7.7, [1] = 8.8, [2] = 9.9},
};

int main(void) {

int j = 1;
int k = 1;
printf("a[%d][%d] = %.1f\n", j, k, a[j][k]);
printf("a[%d][%d] = %.1f\n", j, k, *(*(a + j) + k));
}
``````

and output:

``````\$ ./a.out
a[1][1] = 5.5
a[1][1] = 5.5
``````
1 Like

I have a good experience with one-based array index in Julia. It was so straightforward. You canāt make unnecessary mistakes when manipulating strings and arrays using such indexes.

I have also used Julia in the past and honestly I found it pretty annoying that indices started at 1. Especially for implementing math concepts it was pretty weird because mathematicians often use 0-indexing as well (for example polynomials: aāxā° + aāxĀ¹ + ā¦).

In general I would suggest you to just get used to 0-indexing. Itās used by most programming languages and it is more efficient because the compiler doesnāt need to subtract 1 from all your indices.

By the way, thanks to multi-object for-loops you may not even need indices in zig. Here for example a string compare without any indices:

``````for(stringA, stringB) |a, b| if(a != b) return false;
return true;
``````
3 Likes

Got it. Thank you for the clarifying.

I understand that, just like Pascal (mentioned above), Lua has 1-based indexing, and remember many BASICs did too. I hope Zig (and all other languages) do NOT follow this convention ever, and stick to 0-based indexing.

I really cringe when I need to program in one-based index programming languages. It would be horrible if zig would do that.

1 Like

I think all these 0-based vs 1-based indexing battles are happening because of some substitution of two concepts (offset and index). Iāll try to explain what I mean somehow.
āNormalā people are usually count things starting from 1. Programmers when they are not coding also do this. We have, say, 3 apples on a table and we are counting them like āone, two, threeā, so that the number (index) of the last is equal to the total amount of things. But when these apples are arranged in a rowā¦ (as an array elements in computer memory), then offset come into the game.

• 1-st (index = 1) element has offset (measured in things) 0 from the startoffset
• 2-nd (index = 2) element has offset 1
• and so on

So when we write `a[i]` (in C, Zigā¦) , `i` actually means offset from the beginning of an array, but we ātradionallyā name it index. This is a bit of double-talk.

0-based is more natural for offsets
1-based is kinda more natural for indices.

1 Like

0-based indexing is contra human brain. in slicing/substring(1, 5) the slice spans from element 2 through element 4. Neither 2 or 4 mentioned as parameters! it get more confusing when works it backward.

Exactly!

0-based indexing is contra human brain. in slicing/substring(1, 5) the slice spans from element 2 through element 4. Neither 2 or 4 mentioned as parameters! it get more confusing when works it backward.

When I heard of 1-based indexing for the first time my reaction was, WHAT! When I tried it I realized it was way more convenient than 0-based one.