You wait all day in line — you know, one of those bureaucratic government things — only to get to the front of the line and discover that you’re missing something. So back to the end of the line you go, ready to toil all over again. Sound familiar? But a computer wouldn’t care.
Computers don’t mind waiting, nor do they find problems with doing things repetitively. Just write the proper code and the computer does the rest. If only the DMV were as simple . . .
In this instance, I’m thinking of rotating or shuffling an array: Moving each element in the array up a notch and sending the first element (zero) to the end. For example:
{ 1, 2, 3, 4, 5, 6, 7, 8 }
Becomes:
{ 2, 3, 4, 5, 6, 7, 8, 1 }
You don’t need two arrays for this manipulation, just a routine that shuffles the elements. Here is my code that painlessly carries out the task:
2025_02_22-Lesson-a.c
#include <stdio.h> int main() { int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int size,x,save; /* obtain array size */ size = sizeof(a)/sizeof(a[0]); /* output the array */ for( x=0; x<size; x++ ) printf(" %d",a[x]); putchar('\n'); /* shuffle to the left */ /* retain the first element */ save = a[0]; /* move over all remaining elements */ for( x=0; x<size-1; x++ ) a[x] = a[x+1]; /* restore the first element to the last pos. */ a[size-1] = save; /* output the array */ for( x=0; x<size; x++ ) printf(" %d",a[x]); putchar('\n'); return 0; }
The program calculates the number of elements in int array a[]
by using this trick:
size = sizeof(a)/sizeof(a[0]);
The size of all storage occupied by a[]
is divided by the size of a single element, a[0]
. The result is the number of elements in the array. While I can easily see from the code that the number is 8, and I could just assign this value to variable size
, this expression allows me to change the array’s size without having to work hard finding and replacing each reference to the array’s size.
The first for loop outputs the original array. The next for loop performs the shuffle, but before then the first element is saved, save = a[0]
. The for loop counts from element zero to the next-to-last element:
for( x=0; x<size-1; x++ )
The x<size-1
limit is important as otherwise the statement that follows would access an array element beyond the end of the array. Its job is to “shuffle over” the element values:
a[x] = a[x+1];
Element x
becomes the next element, x+1
.
The final duty is to copy the saved first element to the last element:
a[size-1] = save
Before the program exits, a for loop outputs the newly-updated array, as shown in the output:
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 1
While this program is fun, and it demonstrates what I consider to be a proper shuffle, I want it to do more!
The following update performs the operation repeatedly until the array is re-shuffled back to its original order:
2025_02_22-Lesson-b.c
#include <stdio.h> int main() { int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int size,x,y,save; /* obtain array size */ size = sizeof(a)/sizeof(a[0]); /* output the array */ for( x=0; x<size; x++ ) printf(" %d",a[x]); putchar('\n'); /* shuffle to the left `size ` times */ for( y=0; y<size; y++ ) { /* retain the first element */ save = a[0]; /* move over all remaining elements */ for( x=0; x<size-1; x++ ) a[x] = a[x+1]; /* restore the first element to the last pos. */ a[size-1] = save; /* output the array */ for( x=0; x<size; x++ ) printf(" %d",a[x]); putchar('\n'); } return 0; }
The above modification requires another int variable, y
, to handle the outer loop. This loop spins size
number of times after the original array is output. Otherwise, the code contained in the y
loop is the same as presented earlier.
Here’s the updated output:
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 1
3 4 5 6 7 8 1 2
4 5 6 7 8 1 2 3
5 6 7 8 1 2 3 4
6 7 8 1 2 3 4 5
7 8 1 2 3 4 5 6
8 1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
There is a point to all this, which I’ll get to starting with next week’s Lesson.
Just a small note on the above sizeof() calculation:
In November last year, JeanHeyd Meneide—project editor for the ISO/IEC JTC1 SC22 WG14—conducted The Big Array Size Survey for C, where he asked the C community what a new operator that computes the size of an array-like thing in elements (not bytes) should be called.
In a follow-up post Results! he announced to results: the majority of people voted for the introduction of a
countof
keyword. (Probably not really a surprising result since MSVC has had a _countof macro since Visual C++ 2005.)Now, although this operator will only be included in the upcoming C standard (possibly C26), it should be possible to be forwards compatible by defining a macro. Better yet to put this macro in a header, so it can easily be included… maybe like so:
#ifndef BASIC_DEFS_H_
#define BASIC_DEFS_H_
#if (!defined(__STDC_VERSION__) || __STDC_VERSION__ <= 202311L) && !defined(countof)
#define countof(arr) (sizeof(arr)/sizeof((arr)[0]))
#endif
#endif
I have started to use the above definition in all my C projects!
I love it!