¿La conversión a diferentes tipos cambia mucho?

programación


Hola !

Tengo una pregunta rápida: me preguntaba qué cambia el tipo de reparto. Por ejemplo :

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

int main()
{
int *x;
char *y;
float *z;

x = (int*)y;
y = (char*)z;

return 0;
}

Me preguntaba si algo cambia para ser honesto.
Que quiero decir ? La aritmética de punteros se basa en los propios punteros y no en el valor que tienen.

Por ejemplo, si el puntero “x” es un int y apunta a un carácter, la aritmética x+1 o x+i, el tamaño de se basa en el tipo de “x” y no en el tipo de “y”.

Entonces, ¿por qué necesitamos cambiar la distribución de las otras variables?

Básicamente :

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

int main()
{
int *x;
char *y;

x = (int*)y;
x = (char*)y;

return 0;
}

No debería cambiar nada.

Soy consciente de que mezclar tipos no es una buena idea, pero, para ser honesto, estaba un poco mezclado con el casting de tipos.

PD.

He encontrado algunos ejemplos de cómo se ve cambiando el tipo de conversión:

Cita:

*(int *)((char *)ptr + 2*tamañode(int))

Realmente no sabía mucho qué sucede aquí y por qué el tipo ptr se cambia dos veces. Esto es algo sobre aritmética de punteros, pero me lo imaginé: si tengo ptr + 1, entonces es (ptr+1*sizeof(int)), y aquí tengo (char*) y otro (int*), así que tengo (ptr +1*sizeof(int)) multiplicado por sizeof(char) y luego multiplicado por sizeof(int) ???? Extraño.

Lo que he probado:

Traté de pensar principalmente por qué es así cuando el puntero solo toma la dirección y por qué cambiar el tipo.

Solución 3

Una conversión no realiza ningún cambio en los datos. Puede considerarse como una señal para el compilador de que “sí, sé que xey son tipos diferentes, ¡pero haz la tarea de todos modos!”. Luego, el compilador organiza una copia bit a bit de xay. Si obtiene un cambio en el valor, será debido a la diferencia en el tamaño del origen y el destino, por ejemplo.

C
int i = 256;  /* 0x100 */
char c = i;  /*  c will be assigned 0x00 ie. last byte of i */

Debe tener cuidado al realizar conversiones entre punteros de diferentes tipos. En general, un puntero char (un puntero a un solo byte) no tiene requisitos de alineación, pero otros tipos, digamos un int, pueden requerir que esté alineado en un límite de 4 bytes (o 2, 8 o 16, etc., dependiendo de el tipo). En ese caso, es posible que obtenga un error de segmentación al intentar eliminar la referencia a un puntero. p.ej

C
char str[5] = { 0x00, 0x00, 0x00, 0x00, 0x0 };  /* a 5 byte string, all zeros */
int *i = (int *)&(str[0]);
printf("*i = %d\n", *i);  
i = (int*)(&str[1]);
printf("*i = %d\n", *i);

Dadas las restricciones anteriores, una de las dos declaraciones printf producirá una falla de segmento, ya que uno u otro de los punteros int están desalineados según los requisitos de la CPU. Por lo tanto, debes tener cuidado con lo que haces cuando lanzas punteros de un tipo a otro. Tenga en cuenta que malloc() y se garantiza que las llamadas relacionadas devolverán un puntero correctamente alineado para cualquier tipo, por lo que no tendrá problemas para hacerlo. type *ptr = (type*)malloc(sizeof(*ptr) * 42)

Solución 1

Si hace +1 en un puntero, mueve el puntero a la siguiente dirección después del tipo.
Si hace +1 en un puntero a 4 bytes flotantes, entonces la dirección aumentará 4 bytes.
Si hace +1 en un puntero a un doble de 8 bytes, aumentará 8 bytes.

Para entender por qué hay 2 moldes, hay que fijarse en los paréntesis.
La conversión a char generalmente se realiza porque hace que cualquier aritmética de puntero use ‘1’ como tamaño para contar.

Entonces, trate a ptr como un char* y luego agregue 2 veces el tamaño de un int (que sería 4 en un sistema de 32 o 64 bits de forma predeterminada). esto significa que intentas leer un int, 8 bytes eliminados de ptr.
Una forma mucho más sencilla de escribir sería

*((int *)ptr + 2)

O si ptr ya es de tipo int*, simplemente haga

*(ptr + 2)

Solución 2

Los tipos puntiagudos tienen diferentes tamaños, por lo que las cosas se vuelven interesantes al realizar aritmética de punteros.
Además, la interpretación del patrón de bits de los tipos puntiagudos es diferente, por lo que las cosas se vuelven aún más interesantes cuando se intenta deferenciar los punteros.
Si sabes lo que estás haciendo, podría ser útil. Por ejemplo, el siguiente código

C
#include <stdio.h>
int main()
{
  float f = -0.25;
  printf("%04X", *(unsigned int *) &f);
}

salidas

BE800000

Ese es el patrón de bits del floatde acuerdo con el IEEE 754 estándar.

コメント

タイトルとURLをコピーしました