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 - dereference address obtained
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.
Ideone link.
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.
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
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
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;
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.
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.
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.