El nombre de la matriz no es igual a la función pointer---sizeof() para encontrar el tamaño incorrecto de la matriz

Prefacio: Hoy, en el proyecto, necesitamos encontrar el número de puntos de muestreo y atravesarlos. Los puntos de muestreo se almacenan en una matriz. Personalicé una función para usar sizeof para encontrar su longitud y luego atravesarla. El resultado falla Después de consultar, encontré los siguientes problemas:

En la función principal, sizeof funciona bien

#include <stdio.h>

int Number[10];   

int main()
{
    
    
	int size = sizeof(Number);
	printf("数组大小为:%d\n",size);
	int len = sizeof(Number)/sizeof(int);
	printf("数组共有%d个数据\n",len);

	return 0;
}

Salida:
inserte la descripción de la imagen aquí
pero no en una función personalizada, de la siguiente manera:

#include <stdio.h>

int Number[10]; 

void print_1(int n[])
{
    
    
	int size = sizeof(n);
	printf("数组大小为:%d\n",size);
	int len = sizeof(n)/sizeof(int);
	printf("数组共有%d个数据\n",len);
}
  

int main()
{
    
    
	
	print_1(Number); 
	
	return 0;
}

inserte la descripción de la imagen aquí
Entonces primero necesitamos saber la función de la función sizeof:

sizeof es el espacio de almacenamiento que ocupan los datos obtenidos en memoria, contados en bytes.

Entonces, algunos estudiantes tendrán problemas en este momento. La primera dirección de la matriz se pasa dos veces. ¿Por qué es posible en la función principal, pero no en la función personalizada?

Gracias a la popularidad y las ventas de los libros en lenguaje C del Sr. Tan, mucha gente piensa que el nombre del arreglo es un puntero a la primera dirección del arreglo, pero en realidad esta afirmación es incorrecta.

Usemos un ejemplo más simple, asumiendo que el nombre de la matriz es un puntero, entonces:

#include <stdio.h>

int Number[10]; 

int *Number2;
  
int main()
{
    
      
	int a=sizeof(Number);
	int b=sizeof(Number2);
	
	printf("a的大小为:%d \n b的大小为 %d\n",a,b); 
	
	return 0;
}

Number es un puntero y Number2 también es un puntero. Normalmente, el tamaño debería ser 8,
pero la salida real es de hecho a=40 b=8

Es decir, el nombre de la matriz no es igual al puntero en algunos casos, pero degenerará en un puntero en algunos casos.

En primer lugar, necesitamos saber que un nombre de matriz simple, no un puntero

El nombre de la matriz es un identificador que identifica una serie de espacios de memoria que hemos solicitado anteriormente, y los tipos de elementos en este espacio son los mismos, es decir, el nombre de la matriz representa un bloque de memoria y el tipo de elemento en este bloque de memoria.

Es solo que en la mayoría de los casos, el nombre de la matriz "degenera" (el estándar C usa las palabras decaer y convertirse) para ser un puntero al primer elemento. El puntero no es una estructura de datos agregados, contiene la dirección de cierto tipo de objeto (excepto void*) y también apunta a este objeto. Podemos acceder a este objeto a través de esta dirección. Explique con un diagrama, donde a representa todo el bloque de memoria que declaramos, y p solo apunta a un objeto de tipo char

char a[] = {
    
    'h' 'e' 'l' 'l' 'o'};
char b[] = {
    
    'w' 'o' 'r' 'l' 'd'};

char *p=b;

inserte la descripción de la imagen aquí
¿entonces qué pasó?

Echemos un vistazo al estándar C99:

El tercer párrafo de C99 6.3.2.1 Lvalues, arrays, and function designators dice esto:

Excepto cuando es el operando del operador sizeof o el operador unario &, o es un
literal de cadena usado para inicializar una matriz, una expresión que tiene tipo ''matriz de tipo'' se
convierte en una expresión con tipo ''puntero a type'' que apunta al elemento inicial del
objeto de matriz y no es un valor l. Si el objeto de la matriz tiene una clase de almacenamiento de registros, el
comportamiento no está definido.

El significado de este pasaje es: El nombre de la matriz está solo en el

  1. tamaño del operador
  2. dirección y operador
  3. Cadena matriz inicializada constante Str[]="abcdef"

No se produce degeneración (desintegración de la matriz) en estos tres casos.

En otros casos, llamar al nombre de la matriz degenerará en un puntero a la primera dirección de la matriz.


Para profundizar, es necesario comprender el tamaño de los punteros.

El puntero se utiliza para registrar la dirección de otro objeto, por lo que el tamaño de la memoria del puntero es igual al ancho del bus de direcciones interno de la computadora.

El tamaño de una dirección es 4 si es un sistema de 32 bits, y 8 si es un sistema de 64 bits, por lo que en la función sizeof obtiene la longitud del puntero en lugar de la longitud del array

El valor sizeof de una variable de puntero no tiene nada que ver con el objeto al que apunta el puntero.


Conclusión:
Es decir, en el lenguaje C, el nombre del arreglo degenera en un puntero cuando se llama a la función, use Sizeof para los parámetros de la función, el resultado obtenido por sizeof es el tamaño del puntero, no el tamaño de la matriz en sí.


Eche otro vistazo al tiempo de procesamiento de Sizeof

sizeof es un operador unario en lenguaje C (pero algunas personas piensan que es una macro especial), como otros operadores en lenguaje C ++, y así sucesivamente. No es una función .
El operador sizeof proporciona el tamaño de almacenamiento de su operando en bytes. El operando puede ser una expresión o un nombre de tipo entre paréntesis. El tamaño de almacenamiento del operando está determinado por el tipo del operando.En pocas palabras, su función es devolver la cantidad de bytes de memoria ocupados por un objeto o tipo.

Es decir, Sizeof es un operador de lenguaje C, entonces su etapa de procesamiento está en la etapa de compilación, es decir, antes de que su programa no se esté ejecutando, sizeof(arr) se reemplaza por una constante fija, luego para generar dinámicamente The el tamaño de una matriz no se puede calcular usando sizeof.

Solución:

Agregue un parámetro más a la función, indicando la longitud de la matriz,

#include <stdio.h>

int Number[10]; 

void print_1(int n[], int len)
{
    
    

	printf("数组大小为:%d\n",len);
	
	printf("数组共有%d个数据\n",len/sizeof(int));

}
  
int main()
{
    
    
	
	print_1(Number,sizeof(Number)); 
	
	return 0;
}

Lo anterior es el resumen del problema.

Por favor agregue la descripción de la imagen
Por favor agregue la descripción de la imagen

Supongo que te gusta

Origin blog.csdn.net/as480133937/article/details/123512497
Recomendado
Clasificación