Size of unknown array element

My C is very rusty...

Assuming:

#define SEG_A 0
#define SEG_B 13
#define SEG_C 14
#define SEG_D 15
#define SEG_E 16
#define SEG_F 17
#define SEG_G 18
#define SEG_H 19
byte dig_0[] = {SEG_A, SEG_G, SEG_B, SEG_C, SEG_F, SEG_E}; // 0
byte dig_1[] = {SEG_B, SEG_C}; // 1
byte dig_2[] = {SEG_A, SEG_B, SEG_H, SEG_F, SEG_E}; // 2
byte dig_3[] = {SEG_A, SEG_B, SEG_C, SEG_H, SEG_E}; // 3
byte dig_4[] = {SEG_G, SEG_H, SEG_B, SEG_C}; // 4
byte dig_5[] = {SEG_A, SEG_G, SEG_H, SEG_C, SEG_E}; // 5
byte dig_6[] = {SEG_A, SEG_G, SEG_H, SEG_C, SEG_E, SEG_F}; // 6
byte dig_7[] = {SEG_A, SEG_B, SEG_C}; // 7
byte dig_8[] = {SEG_A, SEG_B, SEG_C, SEG_E, SEG_F, SEG_G, SEG_H}; // 8
byte dig_9[] = {SEG_A, SEG_B, SEG_C, SEG_E, SEG_G, SEG_H}; // 9

byte *digits[10] = {dig_0, dig_1, dig_2, dig_3, dig_4, dig_5, dig_6, dig_7, dig_8, dig_9};

Why does this print 2, not 4 as expected?

void turnOnDigit(byte digit, byte value) {
  
  byte numSegments = sizeof(digits[4]); // value is 2, not 4
}

?

Digits is an array of pointers.

Digits[4] is a pointer.

The size of a pointer is 2.

I'm guessing that you, somehow, would like to calculate the number of elements in one of your int arrays.

For example: dig_4 is an array of ints. There are four ints and each int takes two bytes, so the size of dig_4 is eight.

The number of elements in dig_4 is equal to the size of the array divided by the size of an element in the array

In general, the way to have the compiler calculate the number of elements in an array could go something like this:

int num_elements_in_arr = sizeof(arr)/sizeof(arr[0]);

[edit]Note that num_elements_in_arr is a constant, known at compile time. A more appropriate statement might be

const int num_elements_in_arr = sizeof(arr)/sizeof(arr[0]);

[/edit] This works regardless of what the data type of the array is (could be floats or ints or chars or whatever...)

Bottom line: There is no way (no way) that a program can use a pointer to calculate the size of an array that the pointer is pointing to.

Period.

Regards,

Dave

Ok, good point… How would I go about accessing the size of the digit I am looking for? I had a 2-D array but I cannot have a variable length in the second array level. I thought that my current approach would get around it. I am just trying to avoid another array of digit lengths…

As you know the length at compile time, you could just have an array hold the size of each digit array :) [edit]I was writing this as you wrote that you did not want an additional array, so here is another thought: You could designate a terminator. So each digit end with a END_OF_DIGIT, and then you could make a function for counting all elements in an array until the END_OF_DIGIT is read. That way you can determine at runtime how many elements there are in a digit array.[/edit]

Give an example of the 2-D array that you want. Are both dimensions known at compile time, or does one or the other depend on user input (or program calculations) at run time?

(Note that the result of the sizeof() operator is evaluated at compile time, and the result is a constant, not a variable.)

This is what I'm after, however it fails to compile if I don't set the second dimension.

byte digits[10][8] = {
  {SEG_A, SEG_G, SEG_B, SEG_C, SEG_F, SEG_E}, // 0
  {SEG_B, SEG_C}, // 1
  {SEG_A, SEG_B, SEG_H, SEG_F, SEG_E}, // 2
  {SEG_A, SEG_B, SEG_C, SEG_H, SEG_E}, // 3
  {SEG_G, SEG_H, SEG_B, SEG_C}, // 4
  {SEG_A, SEG_G, SEG_H, SEG_C, SEG_E}, // 5
  {SEG_A, SEG_G, SEG_H, SEG_C, SEG_E, SEG_F}, // 6
  {SEG_A, SEG_B, SEG_C}, // 7
  {SEG_A, SEG_B, SEG_C, SEG_E, SEG_F, SEG_G, SEG_H}, // 8
  {SEG_A, SEG_B, SEG_C, SEG_E, SEG_G, SEG_H} // 9
};

What I thought that they meant was to add this to your code:

uint8_t sizeof_digits[] = {
6,  //sizeof(digits[0])
2,  //sizeof(digits[1])
5,  //sizeof(digits[2])
5,  //sizeof(digits[3])
...
}

And just access the size of, say, digits[4] by using sizeof_digits[4].

however it fails to compile if I don’t set the second dimension.

The statement as you wrote it declares a 2-D array. We call it a 2-D array, but actually it declares an array of ten arrays. Each of the ten is an array of eight uint_8 data members.

That’s the way it works in C and C++ arrays: All elements of the inner array of a 2-D array have the same size.

Since the sizes of the initializer lists for the ten arrays are smaller than 8, other elements of those inner arrays are initialized to zero. That’s also part of the C and C++ standard language specification.

So…

Your statement is treated exactly the same as if you had written

byte digits[10][8] = {
  {SEG_A, SEG_G, SEG_B, SEG_C, SEG_F, SEG_E,     0, 0}, // 0
  {SEG_B, SEG_C,     0,     0,     0,     0,     0, 0}, // 1
  {SEG_A, SEG_B, SEG_H, SEG_F, SEG_E,     0,     0, 0}, // 2
  {SEG_A, SEG_B, SEG_C, SEG_H, SEG_E,     0,     0, 0}, // 3
  {SEG_G, SEG_H, SEG_B, SEG_C,     0,     0,     0, 0}, // 4
  {SEG_A, SEG_G, SEG_H, SEG_C, SEG_E,     0,     0, 0}, // 5
  {SEG_A, SEG_G, SEG_H, SEG_C, SEG_E, SEG_F,     0, 0}, // 6
  {SEG_A, SEG_B, SEG_C,     0,     0,     0,     0, 0}, // 7
  {SEG_A, SEG_B, SEG_C, SEG_E, SEG_F, SEG_G, SEG_H, 0}, // 8
  {SEG_A, SEG_B, SEG_C, SEG_E, SEG_G, SEG_H,     0, 0}  // 9
};

The big question is: Why are you doing this? How are you going to use this array? If none of the SEG_x values is equal to zero, there may be a way to do what you need without changing the array declaration or introducing another array (or making a struct, as I previously suggested).

So…maybe you can show a little more code???

Regards,

Dave

@InvalidApple

And just access the size of, say, digits[4] by using sizeof_digits[4].

1. In the original post, digits[] was an array of pointers, so sizeof digits[n] is equal to 2 for n = 0, 1, ..., 9

2. In the most recent code, digits[] is an array of arrays, and sizeof digits[n] is equal to 8 for n = 0, 1, ..., 9

Bottom line for C and C++: All elements of an array have the same data type (and, therefore, they have same size), regardless of what is stored in the array.

Regards,

Dave

Thanks for all the help guys, I think I understand now. The purpose was supposed to be a quick and dirty test sketch for a LED module I found in a recent score of a bunch of electronics gear. Tiny digits that almost seemed like vfd, but the 2.5v out of my multimeter (on continuity) would light up the leds... 11 digits including periods.

I got it working using an array of lengths, only to find that a good chunk of the leds were burnt out (hence the giveaway).

So... While I will not be using the code at the moment, I now understand C's odd (from the standpoint of a php programmer) implementation of certain programming concepts I am used to :)

@nickvd

C's odd...implementation

You have it backwards. C has seniority, so PHP is the oddball. See footnote.

Regards,

Dave

Footnote: "Orthodoxy is my doxy; Heterodoxy is another man's doxy." ---Attributed to Bishop Walburton

Very true, my apologies.

@ davekw7x

  1. In the original post, digits[] was an array of pointers, so sizeof digits[n] is equal to 2 for n = 0, 1, ..., 9

  2. In the most recent code, digits[] is an array of arrays, and sizeof digits[n] is equal to 8 for n = 0, 1, ..., 9

I think you misunderstood me.

What I meant was to [u]create[/u] a different single dimension array with all the lengths stored in it.

uint8_t sizeof_digits[] = {
6,  //sizeof(digits[0])
2,  //sizeof(digits[1])
5,  //sizeof(digits[2])
5,  //sizeof(digits[3])
...
}

And just get the info out of that instead of calculating it at run time.

When I said, "What I thought that they meant was to add this to your code..." I was just saying where the idea came from.

:)

InvalidApple@

I think you misunderstood me.

Yes I did. You wrote it right; I didn't read it right.

Sorry.

Regards,

Dave

It strikes me that perhaps this whole discussion is pointless. The segment pin numbers could be in one eight byte array, then the digit patterns are held in a second ten (or sixteen if you want hex) byte array, with the bit positions indexing the segment pin number array.

No worries dave!

Grove, can you please explain what you mean? I don't understand how this can solve the sizeof() problem?

:)

It solvesit by reappraising the problem, and not introducing a sizeof in the first place.