Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - MAFUS

#1181
Si a una mitad del recuadro la tratas de una forma y a la otra mitad la tratas de otra nunca llegarás a una solución coherente.
En vez de usar un cuadro de 11x11 usa uno de 3x3 y sitúate en el centro. Obviamente el anillo exterior todo son 1s.

111
101
111

Reduciendo más el problema, si tomas en cuenta solo la distancia de los puntos en el eje X

101
101
101

y teniendo en cuenta solo la distancia de los puntos en el eje Y

111
000
111

Superponiendo estos dos últimos recuadros y tomando la conjunción lógica de ambos queda

101
000
101

¿Qué operación hace que los 0 del anillo tomen el valor de las esquinas?
#1182
Hace una cosa extraña.

Está pensado para modificar la misma lista que se le pasa, pero en vez de modificar directamente el parámetro list lo que hace es modificarlo y regresar un puntero con el dato modificado. Seguramente el autor pensó en esa solución para dar un valor en caso de que list fuera NULL. Pero hubiera hecho lo mismo con un puntero a puntero y el resultado habría sido más natural.

Supongamos el siguiente trozo de código:

SList mi_lista = NULL;

mi_lista = slist_append(mi_lista, 5);


Ahora mi_lista pasa a tener un elemento con un valor en data de 5. Continuamos con la variable mi_lista tal y como la hemos dejado en el siguiente código:

mi_lista = slist_append(mi_lista, 7);

Ahora mi_lista tiene dos elementos, uno que contiene el 5 y otro que contiene el 7. Se puede representar así [5 , 7].

Pero qué pasaría si hubiera:

SList lista_uno = NULL;
SList lista_dos = NULL;

lista_uno = slist_append(lista_uno, 5);
lista_dos = slist_append(lista_uno, 7);

¿Era esto lo que esperaba el autor que se hiciera?

Casi mejor hubiera sido definir la función con un puntero a puntero.

void slist_append(SList * list, int data) {
    /* Implementación de la función */
}

/* Código y más código */

SList mi_lista = NULL;
slist_append(&mi_lista, 5);
slist_append(&mi_lista, 7);


Ahora mi_lista estaría actualizada con [5 , 7] pero no habría posibilidad de darle a otra lista la posibilidad de acceder a los datos de ésta con lo que se previenen errores a la hora de escribir el programa.

Por otra parte esconder un puntero dentro de un typedef no es muy buena práctica, pero cada uno hace lo que quiere.

Por otra parte, sobre la primera pregunta: tal vez un array de punteros. Los elementos apuntados no se mueven de su sitio, lo que cambias son los punteros del array y tienes un array para acceder a ellos.
#1183
Sí, cada compilador genera su propio código y en verdad no se puede asegurar que uno u otro optimice más.
Por ejemplo GCC con O2 no genera ni el array en el ejemplo del array en pila de Eternal Idol:
Código (asm) [Seleccionar]

main:
.LFB24:
.cfi_startproc
sub rsp, 8
.cfi_def_cfa_offset 16
mov edx, 2
mov esi, OFFSET FLAT:.LC0
mov edi, 1
xor eax, eax
call __printf_chk
xor eax, eax
add rsp, 8
.cfi_def_cfa_offset 8
ret
.cfi_endproc





Todo depende de cada compilador y de la configuración que se le da. Continuar ahora sería entrar en una guerra de compiladores, jeje, y no es plan.
#1184
No se hacen tareas. Te podemos ayudar en temas puntuales, la parte donde te hayas estancado, pero no vamos a resolver todo el problema.
Muestra lo que tengas hecho o la parte donde no sabes seguir. Así sí que te podremos ayudar.




Lo digo, más que nada, porqué esto contraviene las reglas del foro y el moderador te puede cerrar el post y así no se te podrá ayudar en nada.
#1185
Moverse en la pila local es restar un literal a base pointer, un acceso al montón es cargar la dirección de memoria y despues hay que calcular el offset.




Dos programas que hacen casi lo mismo. El primero crea un array normal, en la pila; el segundo lo crea en el motón mediante malloc.
Código en C del array en pila:

#include <stdio.h>

int main( void ){
   int array[5];
   
   array[3] = 3;    
   printf("%i", array[3]);

    return 0;
}


Código en C del array en el montón:

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

int main( void ){
   int *array = malloc(sizeof(int) * 5);
   
   array[3] = 3;    
   printf("%i", array[3]);

    return 0;
}


Código ensamblador generado, sin optimización y en sintaxis INTEL, por GCC para el array en la pila:
Código (asm) [Seleccionar]

.file "c.c"
.intel_syntax noprefix
.section .rodata
.LC0:
.string "%i"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
push rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp
.cfi_def_cfa_register 6
sub rsp, 32
mov DWORD PTR [rbp-20], 3
mov eax, DWORD PTR [rbp-20]
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4"
.section .note.GNU-stack,"",@progbits


Código ensamblador generado, sin optimización y en sintaxis INTEL, por GCC para el array en el montón:
Código (asm) [Seleccionar]

.file "d.c"
.intel_syntax noprefix
.section .rodata
.LC0:
.string "%i"
.text
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
push rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp
.cfi_def_cfa_register 6
sub rsp, 16
mov edi, 20
call malloc
mov QWORD PTR [rbp-8], rax
mov rax, QWORD PTR [rbp-8]
add rax, 12
mov DWORD PTR [rax], 3
mov rax, QWORD PTR [rbp-8]
add rax, 12
mov eax, DWORD PTR [rax]
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4"
.section .note.GNU-stack,"",@progbits


Como se puede ver la escritura y la lectura en el montón, mediante puntero necesita de muchas más instrucciones que el acceso a un elemento el array.
#1186
Los arrays y las tablas són siempre más eficientes, pues son datos que se guardan en la pila y el código que se genera para acceder a ellos es más rápido que acceder el montón. Por otra parte la memoria de la pila es bastante más limitada, en tamaño que la del montón y para un gran número de elementos te podrías quedar sin pila de programa rápidamente.
También está el tema de pasar arrays a funciones como argumentos: como es un puntero se pierde totalmente la ventaja de un array propio ya que hay que tratarlo como si estuviera en el montón.
Por último la función realloc es una de las más lentas pues debe acceder al montón, comprobar si hay memoria suficiente para la nueva asignación,  copiar todos los datos que le son posible a la nueva asignación y liberar la memoria del puntero original.
#1188
Sí, la POO y los genéricos quitan mucha carga al programador y tal, pero la sintaxys de C++ me sigue preciendo muy engorrosa. Hace años microsoft tenía un proyecto de un C# que compilaba directamente a código nativo. Desconozco si ha tenido continuidad, pero es una lástima que no se haya hechi de dominio público. Me gustaba mucho C# y podría haberse convertido en el lenguaje de mi preferencia. No hubo suerte.
#1189
Yo soy de C. Allá por el 2005 - 2008 estuve tocando C# y me gustaba como lenguaje POO. Lo he intentado con otros lenguajes pero me siento incómodo por la falta de expresividad y control que obtengo con C. Y considero C++ un lenguaje muy sucio, hecho de parche, sobre parche, sobre parche.

En cuánto al estilo de código, siempre que éste sea coherente, claro y agradable a la vista, no tengo objeción.
#1190
En este caso, cuándo haces realloc, string1 deja de tener memoria asignada. Hay que verlo como si realloc hiciera internamente un free al puntero que se le pasa. El que veas string1 después del realloc es porqué los datos persisten en la memoria (no se pone a 0), aunque hay que recordar que el sistema ya no la tiene en cuenta por tanto en cualquier momento se puede reescribir.