2010-11-02 29 views
13

En C: ¿Cómo se encuentra el número de elementos en una matriz de estructuras, después de enviarlo a una función?C: encontrar el número de elementos en una matriz []

int main(void) { 
    myStruct array[] = { struct1, struct2, struct3, struct4, struct5, struct6 }; 
    printf("%d\n", sizeof(array)); 
    printf("%d\n", sizeof(array[0])); 
    f(array); 
} 
void f(myStruct* array) { 
    printf("%d\n", sizeof(array)); 
    printf("%d\n", sizeof(array[0])); 
} 

Por alguna razón, el printf en el principal muestra resultados diferentes que el printf en f. Mi necesidad es saber cuántos elementos hay en la matriz.

+0

Porque 'sizeof()' es un operador en tiempo de compilación y no una función miembro (como en C++). – ruslik

Respuesta

18

No se puede.

usted tiene que pasar el tamaño de la función, por ejemplo:

void f(myStruct* array, size_t siz); 

Observe también que en f array es un puntero, mientras que en main es una matriz. Las matrices y punteros son cosas diferentes.

+1

¿Por qué usar 'size_t'? ¿No podría simplemente usar un número entero para la longitud de la matriz, o de alguna manera no es seguro? –

+2

@Christian Mann: Varias razones, entre ellas: el tipo del valor devuelto por 'sizeof' es' size_t'; los tamaños de matriz nunca pueden ser negativos, por lo que tiene sentido utilizar un tipo sin signo para el tamaño de la matriz; 'size_t' tiene la garantía de ser lo suficientemente amplio para contener el número máximo de bytes que se pueden asignar en cualquier momento, mientras que' int' no es (IOW, si una matriz de T puede contener 2^64 bytes, luego 'size_t' se garantiza que tiene 64 bits de ancho, pero 'int' solo garantiza que tenga al menos 16 bits de ancho); –

+0

Una alternativa para pasar el tamaño es terminar NULL la matriz, una solución probada, pero esto solo funciona si tiene una matriz de punteros (que es más común que una matriz de matrices en C). –

10

En f array es un puntero, en la principal array es una matriz.

+5

Y una vez que tienes un puntero no puedes determinar la cantidad de elementos. –

0

No se puede saber la cantidad de elementos en una matriz en C consistentemente. Especialmente si pasa el conjunto a través de punteros.

Normalmente, si debe usar utilice el tamaño de matriz en una función, páselo como parámetro.

+1

La cantidad de elementos en una matriz siempre viene dada por 'sizeof array/sizeof array [0]'. Siempre que la matriz sea honesta, es muy fácil :) – pmg

1

Debe pasar esos datos como un parámetro separado a la función. En C y C++ tan pronto como se pasa una matriz a una función, la matriz degenera en un puntero. Los punteros no tienen noción de cuántos elementos hay en la matriz que señalan.

Una forma común de obtener el tamaño es declarar el conjunto e inmediatamente obtener el elemento del conjunto de cuentas dividiendo el tamaño total por el tamaño de un elemento. De esta manera:

struct my_struct my_struct_array[] = { 
{"data", 1, "this is data"}, 
{"more data", 2, "this is more data"}, 
{"yet more", 0, "and again more data"} 
}; 
const size_t my_struct_array_count = sizeof(my_struct_array)/sizeof(my_struct_array[0]); 
0

Cuando usa sizeof en main, está evaluando la matriz y le da el tamaño de la matriz real.

Cuando se utiliza en sizeoff, que haya pasado el nombre de la matriz como un argumento a una función, por lo que ha decaído a un puntero, por lo que te dice sizeof aproximadamente del tamaño de un puntero.

En general, si pasa una matriz a una función, necesita escribir la función para trabajar solo con un tamaño específico de matriz, o pasar explícitamente el tamaño de la matriz para que funcione en una invocación particular.

1

En el código anterior, la función f() no tiene forma de saber cuántos elementos había en su matriz original. Es una característica del lenguaje y no hay forma de evitarlo. Tendrás que pasar el largo.

1

Como dice C reference, no puede hacer esto a menos que el último elemento sea único o pase un conteo de elementos de la matriz a la función.

1

tienes que terminar la matriz con un valor especial y en la función llamada tienes que contar hasta ese valor que es cómo strlen() funciona cuenta hasta el valor NULL '\ 0'.

+0

Esa es ciertamente una solución, pero no es la única. –

+0

está enviando a la función un puntero (una dirección en la memoria) cómo va a contar, si no sabe dónde está terminando. No hay ningún tipo de matriz en C, como sabemos en los idiomas superiores. Puedes crear una clase de matriz en C++ que también almacena su tamaño (o usar las ya definidas) – bkilinc

0

Puede usar un formato para su matriz. Estoy usando elementos de cuerda, debería funcionar para struct.

#define NULL "" 
#define SAME 0 

static char *check[] = { 
     "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256", 
     "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", 
     "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", 
     "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", 
     "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320", 
     "lzo", "cts", "zlib", NULL 
}; // 38 items, excluding NULL 

en main()

char **algo = check; 
int numberOfAlgo = 0; 


while (SAME != strcmp(algo[numberOfAlgo], NULL)) { 
    printf("Algo: %s \n", algo[numberOfAlgo++]); 
} 

printf("There are %d algos in the check list. \n", numberOfAlgo); 

Debe obtener la salida:

Algo: des 
    : 
    : 
Algo: zlib 

There are 38 algos in the check list. 

Como alternativa, si no desea utilizar el NULL, debe hacerse lo siguiente:

numberOfAlgo = 0; 

while (*algo) { 
    printf("Algo: %s \n", *algo); 
    algo++;   // go to the next item 
    numberOfAlgo++; // count the item 
} 

printf("There are %d algos in the check list. \n", numberOfAlgo); 
0

como un ejemplo para su solución:

Dada

struct contain { 
char* a;  // 
int allowed; // 

struct suit { 
    struct t { 
      char* option; 
      int count; 
    } t; 

    struct inner { 
      char* option; 
      int count; 
    } inner; 
} suit; 
}; 

// por ejemplo. inicializado

 struct contain structArrayToBeCheck[] = { 
    { 
     .a = "John", 
     .allowed = 1, 

     .suit = { 
      .t = { 
       .option = "ON", 
       .count = 7 
      }, 

      .inner = { 
       .option = "OFF", 
       .count = 7 
      } 
     } 
    }, 
    { 
     .a = "John", 
     .allowed = 1, 

     .suit = { 
      .t = { 
       .option = "ON", 
       .count = 7 
      }, 

      .inner = { 
       .option = "OFF", 
       .count = 7 
      } 
     } 
    }, 
    { 
     .a = "John", 
     .allowed = 1, 

     .suit = { 
      .t = { 
       .option = "ON", 
       .count = 7 
      }, 

      .inner = { 
       .option = "OFF", 
       .count = 7 
      } 
     } 
    }, 
    { 
     .a = "John", 
     .allowed = 1, 

     .suit = { 
      .t = { 
       .option = "ON", 
       .count = 7 
      }, 

      .inner = { 
       .option = "OFF", 
       .count = 7 
      } 
     } 
    } 

}; 

en main()

printf("Number of Struct within struct array: %d \n", sizeof(structArrayToBeCheck)/sizeof(struct contain)); 

le da la respuesta correcta.

1

Tenga en cuenta que en main(), array se refiere a la matriz real y sizeof() da la respuesta requerida.

Pero cuando lo pasa como parámetro de función, en realidad está pasando la dirección del primer elemento de la matriz que se almacena en la variable de puntero 'array'.
Así que ahora sizeof() da el tamaño de la variable del puntero y por eso difiere de la respuesta real.

Posible solución puede ser la de

1.Declare la matriz a nivel mundial

2. Pase el tamaño del array como parámetro de la función espero que ayude!

Cuestiones relacionadas