[C] Copiar arreglo de caracteres con Operador Igual

Iniciado por AlbertoBSD, 21 Junio 2016, 22:13 PM

0 Miembros y 2 Visitantes están viendo este tema.

AlbertoBSD

Muy buen dia.

Algo que aprende el dia de ayer fue a copiar un arreglo de caracteres con el operador igual sin ayuda de memcpy o strcpy y derivados.

Segun el libro no es algo que se recomiende muy a menudo pero que por lo general indican produce un codigo de ensamblador muy optimizado.

Dadas 2 Cadenas de Igual longitud es posible copiar el contenido de una en otra con  el operador igual.

char cadena1[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char cadena2[27] = {0};


Normalmente la operacion siguientearca error de compilacion.

cadena2 = cadena1;

Pero con ayuda de una estructura de datos de igual longitud:
struct X{
char A[27];
};


podemos por ejemplo.

*(struct X*)cadena2=*(struct X*)cadena1;

Repito en el libro no lo recomiendan pero indican que si lo que buscas es optimizar un poco mas el codigo generado sería una opcion valida.

En el Libro muestran una funcion generica que hace una copia de bloques como el ejemplo mostrado para cualquier cantidad arbitraria de bytes.

En lo que llegue a la casa pongo el código mencionado.

Saludos.
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

fary

Que buena Alberto  ;-) 

#include <stdio.h>
#define MAX 5

struct Cadena
{
    char CantidadBytes[MAX];
};

int main()
{
    char BufferOriginal[MAX] = "fary";
    char BufferDestino[MAX] = {0};

    *(struct Cadena*)BufferDestino = *(struct Cadena*)BufferOriginal;

    printf("%s",BufferDestino);
    return 0;
}
Un byte a la izquierda.

AlbertoBSD

El libro menciona una funcion al estilo de memcpy llamada blockmove

#include <stdio.h>
#include <string.h>

#define BLOCKSIZE 256
void blockmove(dest,src,count)
register unsigned char *dest,*src;
register unsigned count;
{
struct mblock{
char a[BLOCKSIZE];
};
while(count >= BLOCKSIZE){
*(struct mblock*)dest = *(struct mblock*)src;
dest+=BLOCKSIZE;
src+=BLOCKSIZE;
count -= BLOCKSIZE;
}
while(count--)
*dest++ = *src++;
}

int main() {
char A[1048],B[1048];
memset(B,'C',1048-1);
blockmove(A,B,1048);
printf("%s\n",A);
    return 0;
}


Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

class_OpenGL

#3
Vale, igual se me ha ido un poco de las manos XDD

#include <stdio.h>

int main() {
char cadena1[16] = "Hola";
char cadena2[16];

*(char **)cadena2 = *(char **)cadena1;

fprintf(stdout, "%s\n", cadena1);
fprintf(stdout, "%s\n", cadena2);
fputc('\n', stdout);
fprintf(stdout, "%p\n", cadena1);
fprintf(stdout, "%p\n", cadena2);

return 0;
}


Salida:
Hola
Hola

000000000023FE40
000000000023FE30



Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

AlbertoBSD

#4
*(char **)&cadena2 = *(char **)&cadena1;

;-) ;-) ;-) ;-)

Esa si que no me la sabia, hay que ver que codigo de ASM produce para ver si hay diferencia.

Aun asi ese ejemplo solo copia 4 u 8 bytes no? Digo por el tamaño de un apuntador

Deja hago pruebas y lo veo.

Saludos!




Efectivamente solo copia bytes igual al tamaño de un apuntador:

#include <stdio.h>
#include <string.h>

int main() {
char cadena1[16];
char cadena2[16];

memset(cadena1,'A',15);
*(char **)&cadena2 = *(char **)&cadena1;

fprintf(stdout, "%s\n", cadena1);
fprintf(stdout, "%s\n", cadena2);
fputc('\n', stdout);
fprintf(stdout, "%p\n", cadena1);
fprintf(stdout, "%p\n", cadena2);

return 0;
}


Salida

AAAAAAAAAAAAAAA
AAAAAAAA


000000000060FE40
000000000060FE30

Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

class_OpenGL

Sinceramente, no sé cómo el código funciona XD

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

AlbertoBSD

#6
El codigo orignal viene de que es posible usar el operador igual para copiar una estructura completa de una variable A a una variable B ejemplo:

#include <stdio.h>
#include <string.h>


struct X {
int A;
int B;
int C;
};

int main() {
struct X variable1, variable2;
variable1.A = 1;
variable1.B = 10;
variable1.C = 100;
variable2 = variable1;
printf("%d,%d,%d\n",variable2.A,variable2.B,variable2.C);
return 0;
}


salida:

1,10,100

La linea responsable por la copia completa del bloque de memoria de la variable1 a la variable2 es:

variable2 = variable1;

Y de ahi el codigo mostrado en los post anteriores.

lo que tu realizaste fue lo mismo pero  solo con el tamaño de un apuntador.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

class_OpenGL

Justo lo acabo de entender y lo iba a publicar... Estoy ciego xD

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

fary

Es lo mismo solo qie tratas la estructura como si fuera plana. :xD

Saludos y muy buena también!!
Un byte a la izquierda.