vectores - suma de matrices en c



¿Cómo puedo determinar el tamaño de mi matriz en C? (14)

@Skizz: Estoy bastante seguro de que tengo razón, aunque la mejor "fuente" que puedo ofrecerle en este momento es Wikipedia, del artículo sobre sizeof:

Wikipedia está mal, Skizz tiene razón. sizeof (char) es 1, por definición.

Quiero decir, simplemente lea la entrada de Wikipedia muy de cerca para ver que está mal. "múltiplos de char". sizeof(char) nunca puede ser otra cosa que "1". Si fuera, digamos, 2, significaría que sizeof(char) era dos veces el tamaño de char!

https://code.i-harness.com

¿Cómo puedo determinar el tamaño de mi matriz en C?

Es decir, ¿el número de elementos que la matriz puede contener?


"Has introducido una forma sutil de dispararte en el pie"

C matrices 'nativas' no almacenan su tamaño. Por lo tanto, se recomienda guardar la longitud de la matriz en una variable / const separada, y pasarla cada vez que pase la matriz, es decir:

#define MY_ARRAY_LENGTH   15
int myArray[MY_ARRAY_LENGTH];

DEBE siempre evitar los arreglos nativos (a menos que no pueda, en cuyo caso, cuide su pie). Si está escribiendo C ++, use el contenedor 'vector' de STL . "En comparación con las matrices, ofrecen casi el mismo rendimiento", ¡y son mucho más útiles!

// vector is a template, the <int> means it is a vector of ints
vector<int> numbers;  

// push_back() puts a new value at the end (or back) of the vector
for (int i = 0; i < 10; i++)
    numbers.push_back(i);

// Determine the size of the array
cout << numbers.size();

Consulte: http://www.cplusplus.com/reference/stl/vector/


El sizeof es la forma correcta iff está tratando con matrices no recibidas como parámetros. Una matriz enviada como un parámetro a una función se trata como un puntero, por lo que sizeof devolverá el tamaño del puntero, en lugar de la matriz.

Por lo tanto, dentro de las funciones de este método no funciona. En su lugar, siempre pase un size_t size parámetro adicional size_t size indique el número de elementos en la matriz.

Prueba:

#include <stdio.h>
#include <stdlib.h>

void printSizeOf(int intArray[]);
void printLength(int intArray[]);

int main(int argc, char* argv[])
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };

    printf("sizeof of array: %d\n", (int) sizeof(array));
    printSizeOf(array);

    printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
    printLength(array);
}

void printSizeOf(int intArray[])
{
    printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}

void printLength(int intArray[])
{
    printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}

Salida (en un sistema operativo Linux de 64 bits):

sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2

Salida (en un sistema operativo Windows de 32 bits):

sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1

El tamaño del "truco" es la mejor manera que conozco, con un pequeño pero importante (para mí, que es un motivo importante para las mascotas) un cambio importante en el uso del paréntesis.

Como deja claro la entrada de Wikipedia, el sizeof de C no es una función; es un operador Por lo tanto, no requiere paréntesis alrededor de su argumento, a menos que el argumento sea un nombre de tipo. Esto es fácil de recordar, ya que hace que el argumento se vea como una expresión de conversión, que también usa paréntesis.

Entonces: Si tienes lo siguiente:

int myArray[10];

Puedes encontrar el número de elementos con código como este:

size_t n = sizeof myArray / sizeof *myArray;

Eso, para mí, es mucho más fácil que la alternativa con paréntesis. También estoy a favor del uso del asterisco en la parte derecha de la división, ya que es más conciso que la indexación.

Por supuesto, todo esto también es tiempo de compilación, por lo que no hay que preocuparse por la división que afecta el rendimiento del programa. Así que usa este formulario siempre que puedas.

Siempre es mejor usar sizeof en un objeto real cuando tiene uno, en lugar de en un tipo, ya que entonces no necesita preocuparse por cometer un error e indicar el tipo incorrecto.

Por ejemplo, supongamos que tiene una función que genera algunos datos como un flujo de bytes, por ejemplo, a través de una red. Llamemos a la función send() y hagamos que tomen como argumentos un puntero al objeto a enviar y el número de bytes en el objeto. Así, el prototipo se convierte en:

void send(const void *object, size_t size);

Y luego necesitas enviar un número entero, así que lo codificas así:

int foo = 4711;
send(&foo, sizeof (int));

Ahora, has introducido una forma sutil de dispararte en el pie, especificando el tipo de foo en dos lugares. Si uno cambia pero el otro no, el código se rompe. Así, siempre hazlo así:

send(&foo, sizeof foo);

Ahora estás protegido. Claro, duplica el nombre de la variable, pero eso tiene una alta probabilidad de interrumpir de una manera que el compilador pueda detectar, si la cambia.


La macro ARRAYELEMENTCOUNT(x) que todos están haciendo uso de evalúa incorrectamente . Esto, de manera realista, es solo un asunto delicado, porque no puede haber expresiones que resulten en un tipo de "matriz".

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0]))

ARRAYELEMENTCOUNT(p + 1);

En realidad evalúa como:

(sizeof (p + 1) / sizeof (p + 1[0]));

Mientras

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])

ARRAYELEMENTCOUNT(p + 1);

Se evalúa correctamente a:

(sizeof (p + 1) / sizeof (p + 1)[0]);

Esto realmente no tiene mucho que ver con el tamaño de los arreglos explícitamente. Acabo de notar muchos errores al no observar realmente cómo funciona el preprocesador de C. Siempre envuelve el parámetro de macro, no se puede involucrar una expresión en.

Esto es correcto; Mi ejemplo fue malo. Pero eso es exactamente lo que debería suceder. Como mencioné anteriormente, p + 1 terminará como un tipo de puntero e invalidará toda la macro (como si intentara usar la macro en una función con un parámetro de puntero).

Al final del día, en este caso en particular , la falla no importa realmente (así que solo estoy perdiendo el tiempo de todos, ¡huzzah!), Porque no tiene expresiones con un tipo de 'matriz'. Pero en realidad, el punto sobre los subartículos de evaluación del preprocesador creo que es importante.


La mejor manera es guardar esta información, por ejemplo, en una estructura:

typedef struct {
     int *array;
     int elements;
} list_s;

Implemente todas las funciones necesarias, como crear, destruir, verificar la igualdad y todo lo que necesite. Es más fácil pasar como parámetro.


Puede usar el operador sizeof pero no funcionará para las funciones porque tomará la referencia del puntero; puede hacer lo siguiente para encontrar la longitud de una matriz:

len = sizeof(arr)/sizeof(arr[0])

Código encontrado originalmente aquí: programa C para encontrar el número de elementos en una matriz


Puede utilizar el operador & . Aquí está el código fuente:

#include<stdio.h>
#include<stdlib.h>
int main(){

    int a[10];

    int *p; 

    printf("%p\n", (void *)a); 
    printf("%p\n", (void *)(&a+1));
    printf("---- diff----\n");
    printf("%zu\n", sizeof(a[0]));
    printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0])));


    return 0;
};

Aquí está la salida de muestra

1549216672
1549216712
---- diff----
4
The size of array a is 10

Si conoce el tipo de datos de la matriz, puede usar algo como:

int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};

int noofele = sizeof(arr)/sizeof(int);

O si no conoce el tipo de datos de la matriz, puede usar algo como:

noofele = sizeof(arr)/sizeof(arr[0]);

Nota: Esto solo funciona si la matriz no está definida en tiempo de ejecución (como malloc) y la matriz no se pasa en una función. En ambos casos, arr (nombre de la matriz) es un puntero.


Si realmente desea hacer esto para pasar su matriz, sugiero implementar una estructura para almacenar un puntero al tipo del que desea una matriz y un entero que represente el tamaño de la matriz. Entonces puedes pasar eso a tus funciones. Simplemente asigne el valor de la variable de la matriz (puntero al primer elemento) a ese puntero. Luego puede ir a Array.arr[i] para obtener el elemento i-th y usar Array.size para obtener el número de elementos de la matriz.

Incluí un código para ti. No es muy útil, pero podría ampliarlo con más funciones. Sin embargo, para ser honesto, si estas son las cosas que deseas, debes dejar de usar C y usar otro idioma con estas características incorporadas.

/* Absolutely no one should use this...
   By the time you're done implementing it you'll wish you just passed around
   an array and size to your functions */
/* This is a static implementation. You can get a dynamic implementation and 
   cut out the array in main by using the stdlib memory allocation methods,
   but it will work much slower since it will store your array on the heap */

#include <stdio.h>
#include <string.h>
/*
#include "MyTypeArray.h"
*/
/* MyTypeArray.h 
#ifndef MYTYPE_ARRAY
#define MYTYPE_ARRAY
*/
typedef struct MyType
{
   int age;
   char name[20];
} MyType;
typedef struct MyTypeArray
{
   int size;
   MyType *arr;
} MyTypeArray;

MyType new_MyType(int age, char *name);
MyTypeArray newMyTypeArray(int size, MyType *first);
/*
#endif
End MyTypeArray.h */

/* MyTypeArray.c */
MyType new_MyType(int age, char *name)
{
   MyType d;
   d.age = age;
   strcpy(d.name, name);
   return d;
}

MyTypeArray new_MyTypeArray(int size, MyType *first)
{
   MyTypeArray d;
   d.size = size;
   d.arr = first;
   return d;
}
/* End MyTypeArray.c */


void print_MyType_names(MyTypeArray d)
{
   int i;
   for (i = 0; i < d.size; i++)
   {
      printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age);
   }
}

int main()
{
   /* First create an array on the stack to store our elements in.
      Note we could create an empty array with a size instead and
      set the elements later. */
   MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")};
   /* Now create a "MyTypeArray" which will use the array we just
      created internally. Really it will just store the value of the pointer
      "arr". Here we are manually setting the size. You can use the sizeof
      trick here instead if you're sure it will work with your compiler. */
   MyTypeArray array = new_MyTypeArray(2, arr);
   /* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */
   print_MyType_names(array);
   return 0;
}

Vale la pena señalar que sizeof no ayuda cuando se trata de un valor de matriz que se ha reducido a un puntero: aunque apunta al inicio de una matriz, al compilador es lo mismo que un puntero a un solo elemento de esa matriz formación. Un puntero no "recuerda" nada más sobre la matriz que se utilizó para inicializarla.

int a[10];
int* p = a;

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));

 int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
 int len = (int) sizeof(arr) / sizeof(*arr);
 printf("%d\n", len);


int size = (&arr)[1] - arr;

Echa un vistazo a este enlace para la explicación





memory