elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Como proteger una cartera - billetera de Bitcoin


  Mostrar Mensajes
Páginas: 1 ... 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 [55] 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 ... 102
541  Programación / Programación C/C++ / Re: Problema mazo de cartas en: 4 Septiembre 2019, 06:13 am
Voy a intentar ayudarte aunque sin revisar tu código ya que al centrarlo creo que me está dando dolor de cabeza leerlo... :xD
Depende de los recursos que quieras/puedas usar:
  • Usar contenedores de la STL como <set>, <multiset> u otros.
  • Usar un array unidimensional de TAM = numCartas y cada vez que escoges una carta, la pones en array[numCartasDisponibles - 1] y decrementas <numCartasDisponibles>.
Habrá más formas de hacerlo pero creo que esas son las más intuitivas y sencillas haciendo uso o no de la STL. :-X
PD: Cambia la alineación del código para verlo bien tabulado  :silbar: y si aprovechas y pones las etiquetas específicas de C++ mejor ya que así resalta la sintaxis. (Para ello en la etiqueta de apertura que pone "code" entre corchetes, añade "=cpp" para que quede <corchete><code=cpp><corchete> :-X
542  Programación / Programación C/C++ / Re: podria ser mas eficiente este codigo ?? consejoss :) en: 4 Septiembre 2019, 04:32 am
El primer consejo (que espero que sea tenido en cuenta) es: poner el código entre etiquetas de código GeSHi de lenguaje C. Yo creo que este es el más importante de todos así que no lo tomes a la ligera si piensas seguir participando en el foro... :silbar:

Aparte del consejo estrella pues se me ocurre alguno más:
  • Nombre de variables mejorables. No hay nada como leer un código y no tener que volver al principio para recordar qué hacía una variable llamada <a> por ejemplo.
  • Asignas dos veces 0 a <sum> de forma innecesaria.
  • Asignas dos veces 0 a <cont> de forma innecesaria.
  • Las asignaciones que hay dentro de los <printf()> no son nada claras de ver.
  • No usar "magic numbers".
  • Primero trabaja con los datos (lee valores, guarda valores, realiza cálculos, etc) y al final muestra los resultados. Así queda más claro el código.

Luego a mí personalmente me gusta dejar los prototipos sin nombres de parámetros (sólo con el tipo) y poner los nombres únicamente a las implementaciones. Así no tengo que andar recordando que nombres puse para poner los mismos y si hago algún cambio no tengo que acordarme de realizarlo en ambos sitios.
Y las variables de un <struct> prefiero ponerlas una por línea así se ve más fácil cuántas hay y de qué tipo es cada una.

Y si quieres alguna mejora de eficiencia ahí va una aunque te parecerá ridícula: usar en los bucles <for> un contador (i/j) de 64 bits ahorra a la hora de generar el código ensamblador una instrucción que se encarga de transformar los índices de 32 bits en índices de 64 bits.

Yo de momento me fijaría más en los primeros consejos que en este último ya que siempre existirá una lucha entre eficiencia y legibilidad. Un código relativamente pequeño no va a conseguir mucha optimización por este tipo de cambios pero sí puede conseguir que un programador tenga más o menos ganas de leerlo según lo legible que sea. :-X
543  Programación / Programación C/C++ / Re: Funcion buscar en archivos en: 3 Septiembre 2019, 07:56 am
Por lo que se ve en tu código primero guardas el código del proveedor y después su nombre y la búsqueda la quieres realizar por código. En cambio tal y como lo tienes implementado estás comparando el código a buscar con el nombre de los proveedores por lo que dudo que vayas a obtener alguna coincidencia.
Además las líneas 65 y 66 hacen que te saltes uno de cada dos proveedores.
544  Programación / Programación C/C++ / Re: Problema con las pilas C++ en: 31 Agosto 2019, 00:56 am
No estoy seguro de haberte entendido así que te explico más o menos:
Citar
Por que hay que usar -> y no se puede usar "."
El operador -> no es necesario. Quiero decir que no es un operador que haga algo que no puedas hacer con otro. El operador flecha se creó para evitar el punto y asterisco juntos.
Código
  1. struct Persona{
  2.    string nombre;
  3.    int edad;
  4. };
  5.  
  6. int main(){
  7.    Persona persona1;
  8.    Persona *punteroPersona = &persona1;
  9.  
  10.    cout << "Nombre persona: ";
  11.    getline(cin, punteroPersona->nombre); // equivale a: getline(cin, (*punteroPersona).nombre)
  12.    //...
  13. }
Es decir cuando estamos usando un puntero <punteroPersona> y tenemos que:
  • Acceder al dato del puntero: <*punteroPersona>
  • Acceder al dato miembro de ese datos: <(*punteroPersona).nombre>
Podemos directamente usar el operador flecha para que quede mejor a la vista: <punteroPersona->nombre>

Respecto al otro tema: las variables globales no es necesario pasarlas como parámetros ya que ya son conocidas en todo el programa y por tanto se pueden usar en cualquier parte de este. Supongo que si las pasa como parámetros será para poder ver en el <main> qué variable es la que está pasando a la función o por si te da por cambiar el nombre de la variable global, no tener que cambiarlo x veces en las funciones, sólo lo cambias en el parámetro y listo.
De todas formas es mejor no usar variables globales ya que puedes tener una global y una local que se llamen igual y en una función prepararla por estar trabajando con la que no querías trabajar. Por eso es más seguro limitar su uso a lo imprescindible.
545  Programación / Programación C/C++ / Re: Problema con las pilas C++ en: 29 Agosto 2019, 16:26 pm
No le ves la utilidad porque ves muy complejo el hecho de crear una pila para hacer algo que podrías hacer con un array sin tanta complicación. La realidad es que para usar una pila siempre podemos usar la que alguien se preocupó en crear para la STL. Esta tienes sus funciones optimizadas.
Un buen programador no sólo debe limitarse a resolver un problema sino a hacerlo de la forma más eficaz y eficiente que pueda. Existen ocasiones en las que sólo necesitamos conocer el último elemento que hemos introducido, recuerdo un ejercicio: paréntesis correctos. Este ejercicio podría decir algo tal:
Código:
Ejercicio: Paréntesis correctos
Dada una frase u operación matemática, comprobar si la secuencia de paréntesis es correcta.
Una secuencia de paréntesis es correcta si todas las llaves de apertura tienen su correspondiente llave de cierre y nunca aparece una llave de cierre antes que su correspondiente llave de apertura.
Si te apetece puedes intentarlo. Además ya tienes una pista: se hace con pilas. :xD

Lo que estás haciendo ahora es recrear el contenedor <stack> de una forma un poco más cutre pero que sirve para entender cómo funciona. Es un ejercicio típico en programación el crear manualmente contenedores que ya existen (pilas, colas, listas enlazadas, listas doblemente enlazadas, etc).
546  Programación / Programación C/C++ / Re: Importante-Curioso en: 29 Agosto 2019, 16:03 pm
  • La función <menu()> sigue haciendo demasiadas cosas y algunas mal... Y sigue recibiendo un parámetro inútil... Además de que le sobran variables...
  • La función <crearPilaVacia()> sigue retornando un <bool> y en tu caso no retorna nada...
  • Las funciones <pilaLlena()> y <pilaVacia()> las puedes acortar a una sola línea como te comenté...
  • A la función <apilar()> le falta el <return> y aunque la función está mejor, cuando la llamas en el <case> vuelves a hacerla inútil...
  • Las funciones <cima()> está bien.
  • La función <visualizarElementos()> debe retornar un <float> y no lo hace...
  • La función <sumaPila()> tiene dos variables para hacer lo que se puede hacer con una...
Lo único bueno con lo que me quedo es que teniendo el trabajo aprobado sigues intentando comprenderlo y la verdad, un profesor que ve este programa debería saber al instante que no se tienen los conceptos claros y debería aclararlos. Si te ha aprobado sin más... Diría que se la suda lo que sus alumnos aprendan...

La única forma que se me ocurre para poder ayudarte sin tener que volver a escribir un mensaje como el anterior es que me expliques tu razonamiento para:
  • Mandar <eleccion> como parámetro en <menu()> (línea 24)
  • Crear la variable <acum> en <menu()> (línea 28)
  • Llamar a la función <crearPilaVacia()> en el <printf()> (línea 47)
  • LLamar a las funciones <pilaVacia()> y <pilaLlena()> (líneas 51 y 56)
  • El bloque del <case 4> (líneas 62 - 64)
  • La llamada a la función <sumaPila()> (línea 77)
  • Los valores de retorno <return> que le has asignado a cada función
Igual entendiendo por qué haces lo que haces pueda ayudarte ya que de momento no hemos avanzado demasiado.
547  Programación / Programación C/C++ / Re: Importante-Curioso en: 28 Agosto 2019, 15:44 pm
Una pila o stack es un contenedor LIFO (last in first out), es decir, que el último que entra es el primero que sale. Imagina para esto una "pila" de platos, tú los vas amontonando uno encima de otro y cuando vas a coger uno, coges el de arriba del todo. Puedes fijarte en el contenedor <stack> de la STL para C++ para crear una pila en C lo más parecida posible a lo que existe. Entonces necesitas un contenedor de datos ordenado (en tu caso un array) y las siguiente funciones por lo menos (más o menos ya las tienes):
Código:
T top(); // devuelve el ultimo elemento de la pila del tipo que sea (int/float/char/...)
void push(T elemento); // introduce un nuevo elemento
void pop(); // saca el ultimo elemento de la pila
bool empty(); // devuelve true/false dependiendo de si la pila esta vacia o no
int size(); // devuelve el numero de elementos que contiene la pila

Una cola o queue es lo contrario a la pila, un contenedor FIFO (first in first out) donde el primero que entra es el primero que sale. Imagina una cola de personas que se ponen en un cajero, el primero que llega es el primero que usa el cajero y se va. En C++ también existe una cola de la STL <queue> y tiene los siguiente elementos además de un contenedor ordenado (que en tu caso usarías un array):
Código:
T front(); // devuelve el elemento que antes se inserto en la cola
void pop(); // elimina el elemento que antes se inserto
T back(); // devuelve el elemento que se inserto el ultimo
// No existe un pop() para eliminar el ultimo ya que entonces no seria una cola ya que dejaria de ser FIFO
void push(T elemento); // introduce un nuevo elemento a la cola
bool empty(); // devuelve true/false dependiendo de si la cola esta vacia o no
int size(); // devuelve el numero de elementos que contiene la cola

Una lista o list es como una mezcla, es un contenedor que permite insertar y eliminar elementos tanto por delante como por detrás. Al igual que para las otras, en C++ tenemos el contenedor <list> de la STL que tiene además del propio contenedor de valores las siguientes funciones:
Código:
void push_back(T elemento); // inserta un elemento al final de la lista
void push_front(T elemento); // inserta un elemento al comienzo de la lista
void pop_back(); // elimina el ultimo elemento de la lista
void pop_front(); // elimina el primer elemento de la lista
T front(); // devuelve el primer elemento de la lista
T back(); // devuelve el ultimo elemento de la lista
bool empty(); // devuelve true/false dependiendo de si la lista esta vacia o no
int size(); // devuelve el numero de elementos de la lista

Ahora respecto a las mejoras de tu programa. Algunas buenas prácticas son:
  • Evitar el uso de variables globales siempre que se pueda
  • Evitar mostrar mensajes dentro de las funciones a no ser que la función se encargue justo de eso, de mostrar un mensaje (ej; un menú).
  • Las constantes en mayúsculas. Por ejemplo <max> -> <MAX>
Supongo que si estás aprendiendo ahora, todavía no te habrán enseñado el uso de <struct> para agrupar variables o el paso de arrays como parámetros por eso lo usas de forma global y por separado <pila> y <tope>. Para el caso de esas dos variables lo dejaré pasar por lo dicho, aún no te habrán dicho cómo se hace de otra forma.
Sin embargo, la variable <i> de la línea 10 es global y luego en las líneas 140 y 150 vuelves a declarar una variable <i> para cada función de forma local. En este caso te recomiendo borrar la de la línea 10 para evitar una variable global.
También tienes en la línea 10 una variable <acum> que sólo usas dentro de la función <sumaPila()> y que contiene lo mismo que la variable <suma> que declaras dentro de la función. Entonces la variable <acum> sobra también.
Otra cosa importante es el uso de funciones. Una función sirve para agrupar un grupo de código y poder reutilizarlo por lo que hay que crear funciones fáciles de reutilizar. Tú pregúntate que programa se entiende mejor, el primero o el segundo:
Código
  1. int main(){
  2.    int eleccion;
  3.    menu(eleccion);
  4. }
  5.  
  6. int main(){
  7.    int eleccion = mostrarMenu();
  8.    while(eleccion != -1){
  9.        switch(eleccion){
  10.            case 1:
  11.                pilaNueva();
  12.                break;
  13.            case 2:
  14.                if(pilaVacia()) printf("La pila esta vacia");
  15.                else printf("La pila no esta vacia");
  16.                break;
  17.            // y asi con todos que me canso de seguir...
  18.        }
  19.        eleccion = mostrarMenu(); // al acabar lo que sea volvemos a dar a elegir
  20.    }
  21. }
Como ves en el primer caso delegas TODO el trabajo a otra función <menu()> por lo que te ves en las mismas. El <main> no te dice nada y todo el código está en <menu()>. La cosa está en que leyendo el <main> entiendas lo que el programa hace pero no hace falta que entiendas cómo lo hace. En el segundo ejemplo, se ve que muestras un menú y ese menú devuelve una opción, luego según la opción ves lo que el programa hace (por ejemplo, crear una pila nueva) pero si quieres saber CÓMO es cuando tienes que ir a la función <pilaNueva()>. Así el código queda limpio pero a la vez comprensible.

Paso de parámetros:
Tú tienes que pasar una variable como parámetro a una función cuando necesites esa variable fuera de la función y el valor de esa variable condicione algo de la función.
En tu función <menu()> recibes un parámetro <eleccion> que:
  • 1. No tiene ningún valor definido,
  • 2. No sirve para nada fuera de la función.
Necesitas ese parámetro? NO.
En la función <apilar()> sin embargo es al revés.
  • Objetivo de la función: insertar un elemento en la pila.
  • Parámetro: el elemento a insertar.
Hasta aquí todo perfecto pero resulta que lo que luego haces en la función es insertar el elemento, pedir uno nuevo y sobreescribir el primero por el nuevo... Para qué mandas un elemento como parámetro si no lo usas para nada "productivo"??

Respecto al resto de funciones:
La función <menu()> hace demasiadas cosas y recibe parámetros innecesarios.
Recomendación: hacer una función <int mostrarMenu()> que sólo muestre las opciones, de al usuario una a elegir y devuelva ese valor.

La función <crearPilaVacia()> tiene que retornar un <bool> y no retorna nada. Por tanto lo que retorna es -1 que es el valor de la asignación de la función. Y -1 traducido a <bool> es siempre <true>. No dejes la tarea de adivinar el valor de retorno. Deja bien claro qué devuelve una función (si tiene que devolver algo, claro, yo en este caso lo veo innecesario...).
Recomendacion: una función <void pilaNueva()> que lo único que haga sea poner el <tope> a -1.

Las funciones <pilaVacia()> y <pilaLlena()> podrías ahorrártelas ya que conoces el tamaño de la pila <MAX> y el número de elementos <tope>. Pero tampoco es un problema grave, si prefieres usar esas funciones eres libre de hacerlo pero se pueden acortar:
Código
  1. bool pilaVacia(){
  2.    if(tope == -1){ // comprueba si lo de dentro del parentesis es true o false...
  3.        return true; // ... si el parentesis vale true, devuelve true
  4.    }
  5.    else{ //... si el parentesis vale false...
  6.        return false; // ... devuelve false
  7.    }
  8. }
  9. // Al final lo que haces es devolver lo mismo que el resultado del parentesis
  10. // No sera mejor entonces devolver directamente el resultado del parentesis?
  11. bool pilaVacia(){
  12.    return (tope == -1);
  13. }
Recomendación: acortar ambas funciones como se ve en el ejemplo.

La función <apilar()>, como antes te he explicado, no tiene fundamento lo que haces. Además como antes decía es mejor evitar mostrar mensajes dentro de las funciones.
Recomendación: una función <bool apilar(int elemento)> que compruebe si se puede insertar el elemento. Si es posible, lo inserta y devuelve true y si no es posible no lo inserta y devuelve false. Así sin mostrar mensajes tú puedes saber si el elemento se insertó o no.

Para la función <desapilar()> más de lo mismo. Se pueden evitar los mensajes haciendo lo mismo que en <apilar()>
Recomendación: una función <bool desapilar()> que compruebe si la pila está vacía. Si está vacía devuelve false y si no está vacía, elimina el elemento (restar 1 a <tope>) y devuelve true. (No es necesario poner el elemento a 0 antes de eliminarlo).

En la función <visualizarElementos()> se podría eliminar el mensaje que sirve de "titulillo" y dejar únicamente los elementos. En caso de querer que se vea el titulillo ese siempre puedes ponerlo antes de llamar a la función.
Código
  1. printf("Los elementos de la pila son: ");
  2. visualizarElementos();
Recomendación: dejar la función igual <void visualizarElementos()> pero quitando el primer mensaje.

Y para la última función, <sumaPila()>, que también muestra los mensajes en pantalla tenemos que evitar esto.
Recomendación: una función <int sumaPila()> que calcule la suma y en vez de mostrarla por pantalla, la devuelva. Entonces para mostrar la suma haríamos:
Código
  1. printf("La suma de los elementos de la pila es: %d", sumaPila());

Unos consejos extra:
Código
  1. // Cuando se repite la misma variable justo antes y justo despues del = se puede acortar:
  2. suma += otro; // equivale a: suma = suma + otro
  3. resta -= otro; // equivale a: resta = resta - otro
  4. producto *= 2; // equivale a: producto = producto * 2
  5. // etc...
  6. // Para incrementar variables en una unidad se puede hacer:
  7. ++numero; // equivale a: numero = numero + 1
  8. numero++; // equivale a: numero = numero + 1
  9. // Para decrementar variables en una unidad se puede hacer:
  10. --numero; // equivale a: numero = numero - 1
  11. numero--; // equivale a: numero = numero - 1
Y para los condicionales:
Código
  1. // Poner:
  2. if(condicion == true){...}
  3. // ...es lo mismo que poner:
  4. if(condicion){...}
  5. // Al igual que para:
  6. if(condicion == false){...}
  7. // ...es lo mismo que poner:
  8. if(!condicion){...}
548  Programación / Programación C/C++ / Re: Problema con los punteros C++ en: 28 Agosto 2019, 03:45 am
Te pongo un caso más útil para que veas cómo se podrían usar los punteros a funciones. Imagina que vas a hacer un programa que ordene un array y quieres dar la posibilidad de ordenarlo ascendente y descendentemente. La primera opción que le vendría a cualquiera a la cabeza es esta:
Código
  1. void ordenarAscendente(int *numeros, int size){
  2.    for(size_t i = 1; i < size; ++i)
  3.        for(size_t j = 0; j < size-i; ++j)
  4.            if(numeros[j] > numeros[j+1]){
  5.                numeros[j] += numeros[j+1];
  6.                numeros[j+1] = numeros[j] - numeros[j+1];
  7.                numeros[j] -= numeros[j+1];
  8.            }
  9. }
  10.  
  11. void ordenarDescendente(int *numeros, int size){
  12.    for(size_t i = 1; i < size; ++i)
  13.        for(size_t j = 0; j < size-i; ++j)
  14.            if(numeros[j] < numeros[j+1]){
  15.                numeros[j] += numeros[j+1];
  16.                numeros[j+1] = numeros[j] - numeros[j+1];
  17.                numeros[j] -= numeros[j+1];
  18.            }
  19. }
Tenemos dos funciones que si ves siguen el mismo tipo de ordenamiento (un bubblesort muy simple :xD) pero una de forma ascendente y otra de forma descendente. Tampoco es demasiado trabajo pero imagina que queremos ordenar un array de 50 formas distintas, tendríamos que hacer 50 funciones iguales cambiando únicamente la condición de ordenamiento. Entonces podríamos hacer algo así:
Código
  1. bool mayor(int a, int b){
  2.    return a > b;
  3. }
  4.  
  5. bool menor(int a, int b){
  6.    return a < b;
  7. }
  8.  
  9. void ordenar(int *numeros, int size, bool (*orden)(int,int)){
  10.    for(size_t i = 1; i < size; ++i)
  11.        for(size_t j = 0; j < size-i; ++j)
  12.            if(!orden(numeros[j], numeros[j+1])){
  13.                numeros[j] += numeros[j+1];
  14.                numeros[j+1] = numeros[j] - numeros[j+1];
  15.                numeros[j] -= numeros[j+1];
  16.            }
  17. }
Y esto mismo lo podríamos hacer con otros tipos de ordenamiento. Es decir, hacemos una simple función que determine el tipo de orden a seguir y reutilizamos la función que tiene el algoritmo de ordenamiento.
Luego ya si nos venimos arriba le ponemos unos <template> a ese programa y ya podemos ordenar cualquier tipo de dato (primitivos/objetos) que tengan claro está los operadores que usemos sobrecargados (en este caso < y >). Tampoco quiero adelantarte contenidos, ya lo verás más adelante pero para que veas que conocer los recursos disponibles ayuda a ahorrar muchas líneas de código al programador.

PD: Ahí te he dejado también como curiosidad cómo intercambiar el valor de dos variables sin usar ninguna variable auxiliar.
549  Programación / Programación C/C++ / Re: Problema con los punteros C++ en: 27 Agosto 2019, 23:14 pm
Citar
Creo que ya he visto todo de los punteros creo
Claro que no :xD :xD. Para trabajar a un nivel básico o incluso un poco avanzado ya tienes pero los punteros no son sólo lo que has visto. Como bien dices aunque un poco mezclado tienes por una parte los punteros de tipo <void> y por otra parte los punteros a funciones.

Los punteros de tipo <void> se usan para apuntar a un dato sin especificar el tipo de dato y así mediante estos punteros podemos pasar diferentes tipos de datos a una misma función. Esto da mucha libertad a la hora de trabajar con ello (pero también hay que saber cuándo de verdad compensa usarlos, de momento es mejor que no los uses). A la vez que da libertad también la quita ya que no podemos desreferenciar el puntero (mediante *) para trabajar con su valor sin antes hacer un <cast>.
Código
  1. void incrementar(void *puntero, int size){
  2.    if(size == sizeof(char)){
  3.        char *p_char = (char*)puntero;
  4.        ++(*p_char);
  5.    }
  6.    if(size == sizeof(int)){
  7.        char *p_int = (int*)puntero;
  8.        ++(*p_int);
  9.    }
  10. }
  11.  
  12. int main(){
  13.    char letra = 'a';
  14.    int numero = 1;
  15.    incrementar(&letra, sizeof(letra));
  16.    incrementar(&numero, sizeof(numero));
  17.    cout << letra << " - " << numero << endl;
  18. }
Código:
Salida: b - 2 

Por otro lado están los punteros a funciones. Esto sirve para pasarle a una función, otra función.
Código
  1. int sumar(int a, int b){
  2.    return a + b;
  3. }
  4.  
  5. int restar(int a, int b){
  6.    return a - b;
  7. }
  8.  
  9. int realizarOperacion(int (*operacion)(int,int), int a, int b){
  10.    int resultado = (*operacion)(a,b);
  11.    return resultado;
  12. }
  13.  
  14. int main(){
  15.    int a = 4, b = 1;
  16.    int (*realizarResta)(int,int) = restar;
  17.    int resultadoSuma = realizarOperacion(sumar, a, b);
  18.    int resultadoResta = realizarOperacion(realizarResta, resultadoSuma, b);
  19. }
Este es un ejemplo típico de punteros a funciones. Está claro que no parece necesario usarlos pero pueden darse casos en los que sí y entonces pues ahí está la opción de hacerlo así.

Podía haber hecho un último mensaje corto pero eso no es lo mío. Dejo un ejemplo de cada uno de estos y así podríamos decir que este tema del foro queda bastante completo en cuanto a punteros se refiere.
PD: Te recomiendo para tenerlo más a mano hacerte un programa (por ejemplo punteros.cpp o punterosExplicaciones.cpp) y ponerte ahí todo lo que has ido viendo que se puede o no se puede hacer y con algunos comentarios. Y en caso de que necesites recordar algo más en profundidad entonces ya puedes volver aquí y buscar este tema. Suerte :-X
550  Programación / Programación C/C++ / Re: Problema con los punteros C++ en: 27 Agosto 2019, 21:23 pm
Citar
PD: Si lo he entendido bien esto:
Código
  1. void funcion(int**& p_m) // usando new
  2. //seria equivalente a:
  3. void funcion(int m[][100]
La diferencia radicaría en que en la primera se usa para crear una matriz dinámica y así ahorrar espacio en la memoria y en la segunda ya tienes el espacio reservado, no?
Respecto a esto, más que para qué se usa, es qué estoy haciendo con cada cosa. La primera cosa a tener en cuenta es, dicho de una forma poco exacta es que unos corchetes se pueden sustituir por un asterisco y un asterisco por unos corchetes (hablando de arrays como parámetros). Entonces tenemos estas opciones principalmente:
Código
  1. void funcion1(int **matriz); // pasamos la direccion de memoria del elemento [0][0]
  2. void funcion2(int **&matriz); // pasamos la direccion de memoria que apunta a la direccion de memoria del elemento [0][0]
  3. void funcion3(int matriz[][TAM]); // igual que funcion1() pero necesitamos indicar todas las dimensiones excepto la primera
  4. void funcion4(int &matriz[][TAM]); // igual que funcion2() pero indicando las dimensiones como en la funcion3()
Luego claro está que podemos mezclar asteriscos y corchetes y decir "pues quito un par de corchetes y pongo un asterisco" o al revés. Recalco: lo de intercambiar asteriscos y corchetes es para arrays. Si queremos pasar un puntero que no es un array no podemos usar corchetes.
No puedo explicarte mucho más de esto ya que el tema de los arrays estáticos ha ido evolucionando mucho y no estoy muy puesto en ello pero ahora por ejemplo se permite crear un array estático indicando su tamaño en una variable cosa que en versiones anteriores no se podía y de ahí lo de declarar los tamaños usando <#define> (sobre todo en C) o usando una constante global al comienzo del programa <const int> (en C++).

Citar
PD2: las variables dinámicas no tienes nombre? o solo se les puede llamar a través del puntero del que se crean?
Claro que tienen nombre. El puntero. Lo puedes entender como si al hacer:
Código
  1. int miArray[5];
El compilador por dentro hiciese:
Código
  1. int *miArray = new int[5];
En el primer caso el nombre del array está claro. Y en el segundo? Pues es lo mismo, el nombre es el del puntero que lo está apuntando. Ya que con memoria dinámica se pueden hacer cosas como:
Código
  1. int *miArray = new int[10];
  2. int *otroArray = new int[5];
  3. // Queremos intercambiarlos pero en cuanto asignemos algo a uno de esos punteros, perderemos el array entonces:
  4. int *auxiliar = miArray; // Ahora el primer array tiene dos nombres: <auxiliar> y <miArray>
  5. miArray = otroArray; // Ahora hacemos que el puntero <miArray> apunte al mismo sitio que <otroArray>
  6. otroArray = auxiliar; // Y ahora <otroArray> apunta al mismo sitio que <auxiliar> que era el array original al que apuntaba <miArray>
Otra duda típica en estos casos es: ¿y hago algún <delete> por ejemplo a <auxiliar>? Pues no. El delete no borra el puntero, borra la memoria dinámica a la que apunta ese puntero. Entonces si hacemos por ejemplo:
Código
  1. delete [] auxiliar;
<auxiliar> a dónde estaba apuntando? Al mismo array que <otroArray>. Pues entonces <otroArray> ya sólo es un puntero ya que el array que habíamos reservado, nos lo hemos cargado con ese <delete>.
Páginas: 1 ... 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 [55] 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 ... 102
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines