Autor
|
Tema: dudas a la hora de programar (Leído 5,939 veces)
|
Drewermerc
|
hola a todos. bueno las dudas que tengo son la siguientes. 1.-porque se dice que las intrucciones como break (exepto de switch), continue, y goto hacen que un programa en c que debe ser programacion estructurada deje de serlo al usar estas instrucciones. 2-En que casos o usos de funciones como las anteriores o librerias al usarlas nuestro programa dejaria de ser estructurado. 3- En este ejemplo que se hace cuando se programa sockets: server.sin_addr = *((struct in_addr *)he->h_addr);
se utiliza para pasar los valores de he a h_addr pero es estado viendo alguno codigo donde usan puntero o vectores y usan igual esto " -> ", lo que quisiera saber es si es el unico uso que se le da para trasferir datos y en que casos se puede usar y como se usa en realidad no se si me puedan ayudar con un ejemplo. 4-Tambien queria ver si me podrian decir si en c existe alguna alternativa a try-catch ya que esta solo encuentro informacion para c++ y al compilar me dice que esta indefido try. Tambien si el manejo de exepcion es importante a la hora de programar y si son muy usadas. bueno espeor que me puedan ayudar. saludos. drewermerc.
|
|
« Última modificación: 9 Mayo 2014, 06:21 am por Drewermerc »
|
En línea
|
|
|
|
eferion
Desconectado
Mensajes: 1.248
|
1.-porque se dice que las intrucciones como break (exepto de switch), continue, y goto hacen que un programa en c que debe ser programacion estructurada deje de serlo al usar estas instrucciones. Cuando tu escribes un programa en C, sin usar las instrucciones que comentas, se cumplen que las instrucciones se ejecutan siempre en el mismo orden que se encuentran escritas. La única excepción son los condicionales, pero dado que éstos son imprescindibles en el código, se asumen como algo normal. Las instrucciones "break", "continue" y "goto" introducen saltos en el código, al igual que hacen las llamadas a funciones. Sin embargo hay una sutil diferencia. Cuando tu haces una llamada a una función y el código "sale" de la función, vuelve automáticamente a la instrucción siguiente a la que causaba la llamada: void main( ) { int i=0; func( ); // llamada a funcion // al salir de "func", el codigo ejecutara esta instruccion // independientemente del contenido de "func" i++; }
Sin embargo, las instrucciones que comentan rompen este diseño, ya que permiten que la ejecución sea, digamos, aleatoria. El más radical, como veremos, es goto, los otros dos son más "seguros". goto"goto" es la opción más radical de las disponibles. Permite saltar entre instrucciones sin restricciones. int main( ) { int main( ) { goto a; }
El programa anterior imprime "hola mundo", pero claro, como puedes ver, el código desde luego no se ejecuta, ni de lejos, en el mismo orden en el que se ha escrito. break"break" es menos agresivo que goto, ya que, si lo usamos, lo que vamos a conseguir es salir del bucle que se esté ejecutando. Si hay varios bucles anidados, se saldrá únicamente del bucle más cercano. Es una especie de "goto", solo que la elección del salto no es libre, después del "break" se ejecutará siempre la primera instrucción que esté fuera del bucle. int main( ) { int i=0; while ( 1 ) // Este bucle no deberia terminar nunca { if ( i == 5 ) break; // mas codigo i++; } }
En el ejemplo, el bucle "while" debería ejecutarse hasta el fin de los tiempos... sin embargo, al introducir el "break" conseguimos escapar del bucle. Como puedes ver, la instrucción "break" puede encontrarse en cualquier parte del bucle ( incluso dentro de condicionales, que suele ser lo habitual ). Este mismo comportamiento se puede reproducir con "goto": int main( ) { int i=0; while ( 1 ) // Este bucle no deberia terminar nunca { if ( i == 5 ) goto fin; // mas codigo i++; } }
Lo ideal bastantes casos es poner la condición en el while y olvidarnos del break: int main( ) { int i=0; while ( i != 5 ) { // mas codigo i++; } }
Como comentaste antes, "break" tiene un trato de favor cuando se usa con "switch", la razón es que "switch" es un condicional, y aquí el uso de break sería equivalente a sustituir "switch" por "if". int main( ) { int valor = func( ); // switch ( es equivalente a la secuencia de ifs siguiente switch ( valor ) { case 0: break; case 1: break; case 2: break; } if ( valor == 0 ) else if ( valor == 1 ) else if ( valor == 2 ) }
continue"continue", a diferencia de "break", no sale del bucle. "continue" realiza un salto al inicio del bucle. En este caso, podemos evitar el uso de "continue" introduciendo condicionales... aunque a veces por claridad es mejor poner un "continue". 2- En que casos o usos de funciones como las anteriores o librerias al usarlas nuestro programa dejaria de ser estructurado. Es indiferente, si las usas, el programa pierde su condición de estructurado. Aún así no te asustes, son sentencias totalmente válidas y conforme al estándar. Mi consejo es usarlas si con ello se mejora la legibilidad del programa... en caso contrario es mejor evitarlas. 3- En este ejemplo que se hace cuando se programa sockets: Código server.sin_addr = *((struct in_addr *)he->h_addr); se utiliza para pasar los valores de he a h_addr pero es estado viendo alguno codigo donde usan puntero o vectores y usan igual esto " -> ", lo que quisiera saber es si es el unico uso que se le da para trasferir datos y en que casos se puede usar y como se usa en realidad no se si me puedan ayudar con un ejemplo.
Esto son dos preguntas en una. 1. El uso del operador "->" está vinculado, en lenguaje "C", al uso de estructuras. Cuando quieres acceder a algún valor almacenado en una estructura tienes que usar el operador "." ( si la estructura la estás usando por valor ), o el operador "->" (si accedes a la estructura a través de un puntero). Y esto es así independientemente de la forma y tamaño de la estructura. Lo único que define la forma de acceder es la existencia o no de punteros. 2. A estas alturas sabrás que si intentas copiar, "a pelo" una cadena de caracteres en otra, el resultado no suele ser el esperado: int main( ) { char* cad1 = "Mensaje"; char* cad2 = "Otro mensaje"; cad2 = cad1; printf ("%d %d", cad1 , cad2 ); }
El programa hace una "copia" entre cadenas de caracteres e imprime la posición de memoria a la que apunta cada puntero después de la asignación. ¿Resultado? No se ha copiado la cadena... los dos punteros apuntan a la misma cadena (las posiciones de memoria que se imprimen son iguales). Sin embargo, si se puede copiar una estructura en otra con una simple asignación: typedef struct { int numero1; int numero2; } objeto; int main( ) { objeto obj1, obj2; obj1.numero1 = 20; obj1.numero2 = 45; obj2 = obj1; printf ( "%d %d", obj2. numero1, obj2. numero2 ); }
Esto mismo es lo que está haciendo en la línea que has puesto de ejemplo. La explicación es la siguiente: "h_addr" es un puntero a una estructura, el asterisco que está justo después del '=' hace que para la asignación se use la estructura por valor, en vez de por puntero. El resultado es que se copia el contenido de "h_addr" en "server.sin_addr". 4-Tambien queria ver si me podrian decir si en c existe alguna alternativa a try-catch ya que esta solo encuentro informacion para c++ y al compilar me dice que esta indefido try. Las excepciones son un mecanismo existente en C++, no en C. Su utilidad es aportar más flexibilidad al tratamiento de errores. Fijate que digo "aportar más flexibilidad" y no "permitir el", es decir, se puedes escribir un programa en C++ sin necesidad de usar excepciones. La ventaja que tienen las excepciones es que puedes almacenar una gran cantidad de información valiosa sobre el error que se ha producido y tratarla en una parte del código de más alto nivel, incluso centralizada. Si bien un buen uso de las excepciones aporta muchísimas ventajas, su uso no es obligatorio. E incluso un mal uso es perjudicial. Un ejemplo de un mal uso: void sumar( int a, int b ) { throw a + b; } int main( ) { try { sumar( 4, 6 ); } catch ( const int& resultado ) { std::cout << resultado; } }
El tema de las excepciones es polémico, hay gente que está a favor, otros están en contra... cada uno que elija su propio criterio. En C, al no existir excepciones, tienes que hacer las comprobaciones a mano para evitar errores: int dividir( int dividendo, int divisor ) { if ( divisor == 0 ) { // Tratamiento del error } else return dividendo / divisor; }
|
|
|
En línea
|
|
|
|
Drewermerc
|
hola eferion. gracias por contestar. bueno entonces el operador solo se puede usar con estructuras. entonces es o mismo poner cad2 = cad1; que esto cad2 -> cad1;
o como eso si no lo entendi muy bien. bueno ya aprobechndo este hilo quisera hacerte una consulata mas. por que en este codigo no escribe la segunta linea ya intente varias formas pero no logro escribir una lineas mas. #include <stdio.h> #include <stdlib.h> #include <string.h> int main () { FILE *archivo; int final; char *cuno, *cdos; cuno = (char *)calloc(sizeof(char), sizeof(char)); cdos = (char *)calloc(sizeof(char), sizeof(char)); archivo = fopen("hola", "a");// archivo = fopen("hola", "a"); if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite(cuno , sizeof(char), 15, archivo ); //archivo = fopen("hola", "rt"); archivo = fopen("hola", "a"); final = fseek(archivo , 0L, SEEK_END ); //final = fseek(archivo, 0, SEEK_END); fwrite(cdos , sizeof(char), 15, archivo ); return 0; }
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
entonces el operador solo se puede usar con estructuras. entonces es o mismo poner cad2 = cad1; que esto cad2 -> cad1;
No, no es lo mismo. El operador de asignación lo puedes utilizar con estructuras pero no con arrays. Una soluciona a medias a la copia de arrays es colocar estas dentro de estructuras, de esa forma al copiar la estructura se copia el array (que se utilice el operador "->" es tema aparte). Por ejemplo: #include <stdio.h> #include <stdlib.h> struct aux { char nombre[100]; }; int main(void) { struct aux a = {"Hugo"}; struct aux b = {"Paco"}; printf("%s, %s\n", a. nombre, b. nombre); /* Hugo, Paco */ a = b; printf("%s, %s\n", a. nombre, b. nombre); /* Paco, Paco */ return EXIT_SUCCESS; }
---- por que en este codigo no escribe la segunta linea ya intente varias formas pero no logro escribir una lineas mas. Algo habrás hecho con el programa ya que si bien tiene deficiencias el contenido de los dos bloques de memoria se envía al archivo. Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
Drewermerc
|
hola rir3760. bueno es que es precisamente el tema del operador "->" el que quiero entender. ya estuve investigandoun poco sobre este operador pero no encuentro mcuha informacion lo unico que encuentr son ejemplos como este. #include <stdio.h> #include <stdlib.h> struct datos { char *nombre; int edad; }; int main() { struct datos uno, *dos; uno.nombre = "hola amigo"; uno.edad = 12; dos = &uno; dos->nombre = "sfa"; return 0; }
y bueno entendi que solo se puede usar el operador cuando se usan estructura con puntero y que es el aquivalente a poner (*dos).nombre pero intente hacer esto. #include <stdio.h> #include <stdlib.h> struct datos { char *nombre; int edad; }; struct da { char *nom; int ed; }; int main() { struct datos uno, *dos; struct da *d; uno.nombre = "hola amigo"; uno.edad = 12; d->nom = "sfa"; return 0; }
pero al ejecutarlo me dice violacion de segmento segun yo es lo mismo que en el ejemplo anterio pero no se por que me da error aun no termino de entender bien este operador. ******************************************************************************************************************** buen con respecto al siguiente codigo ya lo intente de varias formas manejado memoria dinamica arays, y nadamas con puro texto enviado por la funciones como fprintf, fputs, y fwrite y ninguna imprime el segunda linea. #include <stdio.h> #include <stdlib.h> #include <string.h> void uno(); void dos(); void tres(); void cuatro(); int main () { //uno(); dos(); //tres(); //cuatro(); } void uno () { FILE *archivo; int final; char *cuno, *cdos; cuno = (char *)calloc(sizeof(char), sizeof(char)); cdos = (char *)calloc(sizeof(char), sizeof(char)); archivo = fopen("hola", "a"); if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite(cuno , sizeof(char), 15, archivo ); cuno = NULL; archivo = fopen("hola", "a"); fseek(archivo , 0L, SEEK_END ); fwrite(cdos , sizeof(char), 15, archivo ); cdos = NULL; } void dos () { FILE *archivo; int final; char *cuno, *cdos; cuno= "hola amigo"; cdos= "\nhola\n"; //printf("error"); archivo = fopen("hola", "a"); if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite(cuno , sizeof(char), 15, archivo ); archivo = fopen("hola", "a"); fseek(archivo , 0L, SEEK_END ); fwrite(cdos , sizeof(char), 15, archivo ); } void tres() { FILE *archivo; int final; char cuno[15], cdos[15]; archivo = fopen("hola", "a"); if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite(cuno , sizeof(char), 15, archivo ); archivo = fopen("hola", "a"); fseek(archivo , 0L, SEEK_END ); fwrite(cdos , sizeof(char), 15, archivo ); } void cuatro() { FILE *archivo; int final; archivo = fopen("hola", "a"); if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite("hola amigo", sizeof(char), 15, archivo ); archivo = fopen("hola", "a"); fseek(archivo , 0L, SEEK_END ); fwrite("como estas", sizeof(char), 15, archivo ); }
bueno espero que me puedan ayudar.
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
pero intente hacer esto. struct da *d; /* 1 */ /* ... */ d->nom = "sfa"; /* 2 */
pero al ejecutarlo me dice violacion de segmento segun yo es lo mismo que en el ejemplo anterio pero no se por que me da error El programa revienta porque el valor inicial de la variable "d" es no definido o basura (1), despues cuando aplicas indireccion con el operador "->" (2) resulta en "(*BASURA).nom" y eso genera UB (en tu caso el programa revienta). buen con respecto al siguiente codigo ya lo intente de varias formas manejado memoria dinamica arays, y nadamas con puro texto enviado por la funciones como fprintf, fputs, y fwrite y ninguna imprime el segunda linea. Acabo de ejecutar ese programa y aun con los detalles menores (por supuesto se deben corregir) se crea el archivo "hola" en el directorio actual y este contiene los 30 bytes, que no se vean como texto es normal. Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
Drewermerc
|
bueno ya pude corregirlo. y bueno aun que intente de varias formas al ultimo se soluciono con asignarle la misma direccion de memoria que la de la primera estructura. lo que no entiendo bien es si lo que hace es tener la misma direccion de memoria que la primera estructura, no se supone que tiene acceso a esas datos por lo tanto al momento de decirle que agrege a la variable nom el nombre se debera de modificar lo valores de hay. o acaso lo unico que sucede es que al aiganarle la misma direccion de memoria pero lo que hace es usarla para almacenare la estructura pero con sus respectivas variables nose si me puedas explicar bien esto. #include <stdio.h> #include <stdlib.h> struct datos { char *nombre; int edad; }; struct da { char *nom; int ed; }; int main() { struct datos uno, dos; struct da *d; d = &dos; uno.nombre = "hola amigo"; uno.edad = 12; d->nom = "sfa"; return 0; }
y bueno entonces como hago para que el texto si se pueda ver en el archivo, bueno yo revise el codigo y no encuentro esos errores menores que dices y por lo tanto no los e podido corregir nose si me pdrias decir mis errores para intentar corregirlos. saludos. drewermerc.
|
|
|
En línea
|
|
|
|
Blaster
Desconectado
Mensajes: 190
|
bueno ya pude corregirlo. y bueno aun que intente de varias formas al ultimo se soluciono con asignarle la misma direccion de memoria que la de la primera estructura. lo que no entiendo bien es si lo que hace es tener la misma direccion de memoria que la primera estructura, no se supone que tiene acceso a esas datos por lo tanto al momento de decirle que agrege a la variable nom el nombre se debera de modificar lo valores de hay.
La estructura datos y da son dos estructuras diferentes por lo tanto el puntero d de tipo da debe apuntar a una instancia de la estructura da en tu caso la asignas a una instancia de datos eso es una asignación incompatible, debe tirarte una warning Saludos
|
|
« Última modificación: 11 Mayo 2014, 04:07 am por Blaster »
|
En línea
|
|
|
|
Drewermerc
|
hola blaste. bueno pues si tenias razon al parecer no me fije bien y no me di cuenta de que me mandaba un warning bueno creo que ya lo arregle ahora si bueno auqi les pongo mi codigo para que em digan si esta bien o me falta algo. #include <stdio.h> #include <stdlib.h> struct datos { char *nombre; int edad; }; struct da { char *nom; int ed; }dd, *d; int main() { struct datos uno; uno.nombre = "hola amigo"; uno.edad = 12; d = ⅆ d->nom = "skfhkl"; return 0; }
bueno lo que entendi del operado es que sirve para accder a los datos de las structuras y que tambien es muy util cuando se pasan valores de estructuras en funciones. bueno esto es lo que entendi nose si me quieran corregir algo o agregar algo que me haga falta. bueno ya solo una cosa mas nose si me puedan ayudar para que las lineas que escribo en un fichero se vean por que no logo hacer que funcione bien el codigo ya lo intente de varias formas pero no logro hacer que las lineas que imprimo se vean, ya lo habia puesto pero lo vuelvo a ponerlo. #include <stdio.h> #include <stdlib.h> #include <string.h> void uno(); void dos(); void tres(); void cuatro(); int main () { //uno(); dos(); //tres(); //cuatro(); } void uno () { FILE *archivo; int final; char *cuno, *cdos; cuno = (char *)calloc(sizeof(char), sizeof(char));cdos = (char *)calloc(sizeof(char), sizeof(char));archivo = fopen("hola", "a");if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite(cuno , sizeof(char), 15, archivo ); cuno = NULL; archivo = fopen("hola", "a");fseek(archivo , 0L, SEEK_END ); fwrite(cdos , sizeof(char), 15, archivo ); cdos = NULL; } void dos () { FILE *archivo; int final; char *cuno, *cdos; cuno= "hola amigo"; cdos= "\nhola\n"; //printf("error"); archivo = fopen("hola", "a");if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite(cuno , sizeof(char), 15, archivo ); archivo = fopen("hola", "a");fseek(archivo , 0L, SEEK_END ); fwrite(cdos , sizeof(char), 15, archivo ); } void tres() { FILE *archivo; int final; char cuno[15], cdos[15]; archivo = fopen("hola", "a");if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite(cuno , sizeof(char), 15, archivo ); archivo = fopen("hola", "a");fseek(archivo , 0L, SEEK_END ); fwrite(cdos , sizeof(char), 15, archivo ); } void cuatro() { FILE *archivo; int final; archivo = fopen("hola", "a");if (archivo == NULL) { printf("error al crear el archivo\n"); } fwrite("hola amigo", sizeof(char), 15, archivo ); archivo = fopen("hola", "a");fseek(archivo , 0L, SEEK_END ); fwrite("como estas", sizeof(char), 15, archivo ); }
saludos. drewermerc.
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
aun que intente de varias formas al ultimo se soluciono con asignarle la misma direccion de memoria que la de la primera estructura. lo que no entiendo bien es si lo que hace es tener la misma direccion de memoria que la primera estructura, no se supone que tiene acceso a esas datos por lo tanto al momento de decirle que agrege a la variable nom el nombre se debera de modificar lo valores de hay. o acaso lo unico que sucede es que al aiganarle la misma direccion de memoria pero lo que hace es usarla para almacenare la estructura pero con sus respectivas variables nose si me puedas explicar bien esto. Lo primero que debes hacer es explicarte de una forma mas clara ya que apenas se entiende ese texto y por favor (y lo digo en buen plan) consigue un libro de calidad, no hay mejor forma de aprender que esa. struct datos uno, dos; struct da *d; d = &dos;
Ahí declaras un puntero, una variable que debe almacenar una dirección en memoria, eso lo consigues con la asignación "d = &dos". Después de eso al aplicar indirección con "*d." o "d->" ya no estas trabajando con la dirección en memoria de "dos" sino con el objeto "dos". En resumen puntero + indirección == objeto apuntado. como hago para que el texto si se pueda ver en el archivo, bueno yo revise el codigo y no encuentro esos errores menores que dices y por lo tanto no los e podido corregir nose si me pdrias decir mis errores para intentar corregirlos. Las partes a cambiar en tu ultimo programa sobre archivos son: * Reservas memoria en dos ocasiones consecutivas cuando una sola basta. * En C las conversiones explicitas al utilizar malloc, calloc y realloc no son necesarias y no se recomiendan. * Si ocurre un error al tratar de abrir un archivo no tienes porque generar el mensaje manualmente, deja que perror lo haga. * No hay necesidad de vaciar el bufer correspondiente con fflush. * Abres al archivo en modo "a", ello implica que todas las operaciones de escritura se realizaran al final del archivo sin importar si utilizas fseek directa o indirectamente (via rewind). Para almacenar las dos lineas en modo texto lo usual es fprint, por ejemplo: #include <stdio.h> #include <stdlib.h> #define NOM_ARCHIVO "hola" int main(void) { FILE *archivo; char a[]= "Primera linea"; char b[]= "Segunda linea"; char c[sizeof a]; if ((archivo = fopen(NOM_ARCHIVO , "a")) == NULL ){ return EXIT_FAILURE; } if ((archivo = fopen("hola", "r")) == NULL ){ return EXIT_FAILURE; } puts("Las lineas en el archivo son:"); while (fgets(c , (int) sizeof c , archivo ) != NULL ) return EXIT_SUCCESS; }
Si al ejecutarlo ocurre un error al abrir el archivo la función perror te dará (al menos en teoría) una idea de cual es. Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
¿Peculiaridades del DevC++ a la hora de programar en C++?
Programación C/C++
|
invisible_hack
|
5
|
3,790
|
28 Abril 2010, 20:11 pm
por invisible_hack
|
|
|
Me tira error a la hora de programar
Programación General
|
Zedmix
|
1
|
3,043
|
30 Agosto 2011, 02:55 am
por Feedeex
|
|
|
dudas con uml a la hora de programar en java
Java
|
rivet
|
2
|
2,896
|
26 Abril 2012, 14:23 pm
por raul_samp
|
|
|
dudas a la hora de reparar una pc
Hardware
|
Mario Olivera
|
3
|
2,182
|
9 Mayo 2014, 19:04 pm
por el-brujo
|
|
|
Cómo programar el cierre de tus aplicaciones a una hora determinada
Noticias
|
wolfbcn
|
0
|
1,147
|
19 Octubre 2018, 23:10 pm
por wolfbcn
|
|