0

I've forgotten how count a double dimension C array because I don't understand why this code return me a count of 12 instead of 6.

// My tab
static NSString *kStringTag[][2] = {
    {@"string1", @"1"},
    {@"string2", @"1"},
    {@"string3", @"0"},
    {@"string4", @"0"},
    {@"string5", @"1"},
    {@"string6", @"1"},
    {nil, nil}
};

// My C func
unsigned int tablen(void **tab)
{
    unsigned int i = 0;

    while (tab[i] != nil)
        i++;

    return i;
}

 - (void)viewDidLoad
{
    NSLog(@"%d", tablen((void **)kStringTab));
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
klefevre
  • 8,595
  • 7
  • 42
  • 71

2 Answers2

4

Your code is not C.

If it were C, tab would be an array of array of pointers to NSStrings (whatever that is).

In C an array of arrays of pointers to NSStrings is not necessarily compatible with a pointer to pointer to void ... so remove the casts and get the types correct.

In C, this works ...

#include <stdio.h>

static char *kStringTab[][2] = {
    {"string1", "1"},
    {"string2", "1"},
    {"string3", "0"},
    {"string4", "0"},
    {"string5", "1"},
    {"string6", "1"},
    {NULL, NULL},
};

unsigned int tablen(char *tab[][2]) {
  unsigned int i = 0;
  while (tab[i][0] != NULL) i++;
  return i;
}

int main(void) {
  printf("%d\n", tablen(kStringTab));
  return 0;
}

Suggestion: increase the warning level of your compiler and mind the warnings.


Edit: new generic version

#include <math.h>
#include <stdio.h>

static double anothertest[][3] = {
    {42, 54, -122},
    {33, -0.001, 0.001},
    {6, 0, 7},             /* 0 in middle: stop condition in nullp2 :) */
    {2, 2, 2},
};

static char *kStringTab[][2] = {
    {"string1", "1"},
    {"string2", "1"},
    {"string3", "0"},
    {"string4", "0"},
    {"string5", "1"},
    {"string6", "1"},
    {NULL, NULL},
};

int nullp2(const void *elem) {
  const double *tmp = elem;
  return (fabs(tmp[1]) < 0.000000001);
}

int nullp(const void *elem) {
  char (*const *tmp)[2] = elem; /* tmp is a pointer to each element of kStringTab */
  return ((*tmp)[0] == NULL);
}

unsigned int tablen(void *x, size_t size,
                    int (*check)(const void *)) {
  char *y = x;
  unsigned int i = 0;

  while (!check(y)) {

    i++;
    y += size;
  }
  return i;
}

int main(void) {
  printf("tablen returns %d\n",
        tablen(kStringTab, sizeof *kStringTab, nullp));
  printf("tablen returns %d\n",
        tablen(anothertest, sizeof *anothertest, nullp2));
  return 0;
}

You can see it running at ideone.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • It works but Im looking for a generic function, but you right I think NSString isnt compatible with that – klefevre May 28 '11 at 13:51
0
  tab[i]

is just an offset from a memory address, and you have 12 items stored at that address.

Rayfleck
  • 12,116
  • 8
  • 48
  • 74
  • return i/2; This is unsatisfying, but your tablen function doesn't know the underlying structure of what it's reading, it's only chewing through raw memory. If you made a typedef for one of the array dimensions, then your tablen could measure with sizeof. – Rayfleck May 28 '11 at 12:25
  • Some good reading: [here](http://stackoverflow.com/questions/423554/passing-multi-dimensional-arrays-in-c) and [here](http://stackoverflow.com/questions/1527806/multi-dimensional-char-array) – Rayfleck May 28 '11 at 12:28