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 - K-YreX

#31
Cita de: MAFUS en  3 Septiembre 2021, 23:22 PM
Bueno, seguramente está empezando y coincidirás conmigo que esa es la forma de hacer de la mayoría de los tutoriales de internet.
Desde luego, pero la forma de publicar el código fue como "no sufráis más, ya he resuelto uno de los problemas del milenio y aquí lo tenéis".
Si hubiera publicado el mismo código pero con una frase como: "¿Cómo puedo mejorar este programa?", seguramente mi respuesta no habría sido tan tajante. Aunque no por tajante ha dejado de ser instructiva, ya que le enumeré algunas mejoras que podía implementar y alguna breve explicación del porqué.  :rolleyes: :rolleyes:
#32
Ese programa es mejorable por todas partes...
  • Utiliza una constante para la longitud máxima del array o utiliza un array dinámico.
  • El programa dice que cambia las vocales de un texto por la siguiente vocal. De ahí yo entiendo que cambia 'a' -> 'e' | 'e' -> 'i' | 'i' -> 'o' | 'o' -> 'u' | 'u' -> 'a'.
  • No se debe utilizar scanf() para almacenar cadenas de texto. Si introduzco "Hola Mundo", la salida es "Hele"... ¿Qué ha pasado con "Mundo"?
  • Demasiado código para el if-else-if. Eso se puede hacer mucho más compacto y limpio.
  • No es recomendable usar <system("pause")>. Utiliza en su lugar <getchar()>. Obtendrás el mismo resultado, más eficiente y sin necesitar la librería <stdlib.h>.
  • La librería <string.h> tampoco está siendo utilizada.
#33
Programación C/C++ / Re: Gestión clubes
2 Septiembre 2021, 12:22 PM
Ese código estuvo por aquí de visita hace unos días pero ya se fue.
Dijo algo de que nadie le requería y que se iba a otros foros a buscar interesados.

No se hacen tareas.
#34
Programación C/C++ / Re: Comparacion de vectores
1 Septiembre 2021, 03:12 AM
Antes de resolver tus dudas te diré algunos consejos para mejor el código:
  • main() es una función y como tal debe tener un tipo de retorno. La forma correcta de definir la función main() es:

    // Version simplificada (cuando se utilizan argumentos de ejecucion)
    int main() {
      //...
      return 0; // Si no se especifica, se incluye implicitamente
    }

    // Version completa (cuando se utilizan argumentos de ejecucion)
    int main(int argc, char *argv[]) {
      //...
      return 0; // Si no se especifica, se incluye implicitamente
    }


  • Utiliza constantes en vez de "números mágicos" (números literales que aparecen en el código sin explicación: 20). Así si de repente necesitas cambiar ese valor por otro, tan solo tendrás que cambiarlo en la definición y el resto del programa seguirá funcionando correctamente.

    const int NUM_EMPLEADOS = 20;

    int main() {
      int ventas[NUM_EMPLEADOS];
      for(int i = 0; i < NUM_EMPLEADOS; ++i) {
        //...
      }
    }


  • Utiliza funciones que hagan una tarea específica. Así tendrás el código más limpio, no repetirás código y podrás reutilizar una función tantas veces como necesites:

    int calcularSumaTotal(int array[], const int longitud) {
      int total = 0;
      for(int i = 0; i < longitud; ++i) total += array[i];
      return total;
    }

    int main() {
      int ventas2019[NUM_EMPLEADOS];
      int ventas2020[NUM_EMPLEADOS];
      //...

      int totalVentas2019 = calcularSumaTotal(ventas2019, NUM_EMPLEADOS);
      int totalVentas2020 = calcularSumaTotal(ventas2020, NUM_EMPLEADOS);
      //...

      int promedioVentas2019 = totalVentas2019 / NUM_EMPLEADOS;
      int promedioVentas2020 = totalVentas2020 / NUM_EMPLEADOS;




    Ahora sobre tus dudas específicamente:
  • La primera duda ya te la he resuelto en el apartado de crear tus propias funciones.
  • Para calcular la comisión de cada empleado en cada año basta con lo siguiente:

    const float PORCENTAJE_COMISION = 30;

    int main() {
      int ventas2019[NUM_EMPLEADOS];
      //...
      for(int i = 0; i < NUM_EMPLEADOS; ++i) {
        printf("La comision del empleado %d en el 2019 es de: $%.2f\n", (i+1), ventas2019[i] * PORCENTAJE_COMISION / 100.0f);
      }
    }


    Aparte de eso:
  • Las líneas 41 y 56 no tienen sentido. Repites un cálculo 20 veces para quedarte únicamente con el último resultado.
  • Además en la línea 56 estás utilizando el contador equivocado.

    PD: No utilices <system("pause")>. Utiliza mejor <getchar()>. Hace la misma función y requiere de menos recursos del sistema.
#35
Dudas Generales / Re: DAM experiencias
30 Agosto 2021, 23:53 PM
Yo he realizado el grado superior de DAM recientemente así que te daré una respuesta, espero que te sirva.
Es importante recalcar que antes de realizar este grado superior había estudiado 2 años de Ingeniería Informática y llevaba otros 2 años programando de forma autodidacta.

El grado se divide en 2 años:
  • Primer año: 9 meses de clase (septiembre - junio) con 30 horas semanales (6 horas/día de lunes a viernes)
  • Segundo año: 6 meses de clase (septiembre - febrero) con 30 horas semanales también + 3 meses de prácticas en una empresa (marzo - mayo)
    A mí parecer y viniendo de la universidad, el grado superior está mejor planteado. La universidad pierde demasiado tiempo con la teoría y con asignaturas de relleno mientras que en el grado superior vas a tener mucha más práctica. Te van a introducir un poco en todo y luego obviamente tendrás que profundizar tú en lo que más te interese.

    El primer año tienes (ordenados de mayor a menor importancia según mi experiencia):

    • Programación: El módulo principal de este año (8/30 horas semanales). Se suele hacer con Java (hasta donde yo sé). Si no tienes conocimientos previos en programación este es el módulo más difícil pero si ya sabes algo te resultará muy fácil, sobre todo los primeros meses, porque se empieza desde lo más básico. Aquí empiezas con los tipos de datos, operadores lógicos, estructuras de control y luego pasas a una parte un poco más avanzada con estructuras de datos, POO (herencia, polimorfismo,...) y acabas con algo de interfaces gráficas (swing).
    • Bases de datos: 6/30 horas semanales. Aquí empiezas con diagramas entidad-relación y después de unos meses empiezas a utilizar bases de datos SQL. Al igual que en Programación, si no conoces nada de esto tendrás que esforzarte para no perderte pero si ya lo conoces, te será sencillo pues empieza de 0.
    • Sistemas informáticos: 6/30 horas semanales. Esto es una mezcla con un poco de todo. Al principio tienes un poco de hardware: conocer los componentes de un ordenador (a grandes rasgos), después una parte de sistemas operativos (aquí verás funciones de configuración de Windows y Linux y algunos comandos de cmd/terminal). Yo diría que esta es la parte más complicada de este módulo pero también la más útil. Y finalmente algo de redes, direccionamiento IP y poco más.
    • Lenguaje de marcas: 4/30 horas semanales. Empiezas con HTML y después empiezas a usar también algo de CSS. Esta parte no tiene mayor relevancia si no tiras hacia la programación web. Después tienes XML, esquemas de documento, XPath, XQuery. Está bien aunque puede que no llegues a usarlo después, XML sí.
    • Entornos de desarrollo: 3/30 horas semanales. Aquí estudias un poco el IDE (en mi caso Eclipse) y las funciones que tiene para ayudarte a programar (refactorización, depuración,...). Después realización de tests (JUnit) y finalmente ves algo de diagramas (de clases, de comportamiento, casos de uso,...). Esta es un poco más teórica que las anteriores aunque digamos que complementa a la de programación entonces van un poco de la mano. Lo que aprendas aquí te servirá de ayuda para programación.
    • Formación y orientación laboral: 3/30 horas semanales. Es el más teórico pero si estás empezando en el mundo laboral no está mal. Aprendes un poco cómo se regula el trabajo, a entender una nómina, los tipos de contrato que hay... y la parte final va sobre prevención de riesgos laborales. Si ya tienes experiencia con esto, no aprenderás prácticamente nada. Al finalizar este módulo obtienes un certificado en prevención de riesgos laborales. Este módulo además es común a todos los grados de formación profesional por lo que si tienes hecho otro de antes lo puedes convalidar y librarte de estas horas.

    El segundo año tienes:

    • Acceso a datos: 6/30 horas semanales. Aprenderás persistencia de datos. Crearás programas que utilicen ficheros de texto, bases de datos y al final verás ORM. Seguramente sea con Java también e Hibernate. Muy importante pues la gran mayoría de programas trabajan con datos que están almacenados en el sistema o en otras ubicaciones. No es muy complicado si has llevado bien Programación y Bases de datos en 1º.
    • Programación de servicios y procesos:: 3/30 horas semanales. Que no te engañen esas 3 horas pues no serán fáciles. Aunque tengas experiencia programando es difícil acostumbrarse a la programación concurrente y a la sincronización correcta de hilos. Verás procesos e hilos, como conectarse unos con otros (pipes y sockets) y cómo mantener la consistencia utilizando la sincronización. Yo empecé las primeras prácticas en C (en Linux) y luego ya pasamos a Java. Seguramente será la asignatura que más tiempo tengas que dedicar pues son temas complejos y que no se ven hasta llegados a este punto.
    • Desarrollo de interfaces: 6/30 horas semanales. Aquí profundizarás en las interfaces gráficas. Lo mejor que te puede pasar desde mi punto de vista es dar esta asignatura en C#. Así aprenderás otro lenguaje aplicando lo que sabes de Java a C# y verás WinForm y WPF muy fáciles de utilizar y muy demandados actualmente para crear GUIs. Además a partir de aquí podrás profundizar en .NET que es muy completo, potente y demandado. También puede que veas cómo generar informes (pdf) desde el programa, cosa que también se utiliza mucho a nivel empresarial.
    • Programación multimedia y dispositivos móviles: 6/30 horas semanales. Aquí verás programación móvil (lo más seguro es que sea en Android mediante Java). Te servirá para conocer las bases pero si quieres dedicarte a ello tendrás que aprender mucho por tu cuenta pues nadie utiliza Java ahora para programación móvil. Aquí te servirá también el XML de 1º.
    • Sistemas de gestión empresarial: 6/30 horas semanales. Aquí verás ERPs y CRMs. Dependiendo del profesor harás las prácticas con SAP (el ERP más conocido pero para el que hay que estar certificado por SAP para poder impartirlo) o con otros (a mí me tocó uno gratuito llamado Odoo). Este módulo tiene bastante teoría y puede llegar a ser aburrido pero dependerá también de la forma en que te lo impartan. Si tienes suerte aprenderás algo de Python a nivel básico.
    • Empresa e Iniciativa emprendedora: 3/30 horas semanales. La continuación de Formación y Orientación Laboral. Aquí verás los tipos de sociedades que existen y características sobre todo. Puede que te toque hacer un proyecto de una startup durante todo el curso y no tendrás exámenes ni nada. En ese caso se agradece pues no tendrás que memorizar toda la teoría y si te interesa montar una startup puedes aprovechar ese proyecto para presentarlo a la hora de conseguir financiación. Al igual que FOL, es común y si tienes otro grado podrás convalidarlo y ganar tiempo para invertir en las primeras de la lista.

    Por lo demás, conociendo el temario, la experiencia te la marcarán los profesores que te toquen. Si son buenos y les gusta lo que hacen aprenderás mucho y te gustará. Si son malos o sin ganas de trabajar pues te tocará remar a contracorriente o dejar que te hundan con ellos.

    El primer año dedicaba muy poco tiempo en casa. Teniendo conocimientos previos apenas necesitarás 1 hora al día para hacer las prácticas que te vayan mandando (eso siempre que no te dé tiempo a hacerlo en clase, las primeras son muy sencillas) y muchos días saldrás de clase totalmente libre. En cambio si empiezas de 0, tendrás que echarle bastante tiempo porque como lo vayas dejando y te quedes atrás, te será muy complicado coger el ritmo de nuevo. Para entender una parte necesitas tener claras las anteriores por lo que el aprendizaje tiene que ser continuo y no vale olvidar lo aprendido una vez aprobado el examen.
    En marzo del primer año nos confinaron por el Covid-19. Fue un caos, sobre todo al principio, y cada profesor llevaba las clases a su manera. Lo mejor era que te diesen los apuntes y las prácticas y te organizabas tú a tu manera como quisieras con tal de tenerlos para la fecha de la entrega. Si tenías alguna duda te conectabas ese día a la clase o escribías un email.

    El segundo año se retomaron las clases presenciales pero en cuanto un profesor dijo que la asistencia era voluntaria, no volví a aparecer por clase más que para los exámenes. Los conocimientos de algunos profesores sobre sus respectivos módulos eran nefastos por lo que ganabas más tú leyendo los apuntes y resolviendo las dudas mediante otras fuentes de información (vídeos, pdfs, cursos online,...). Dedicaba cada día de la semana a 1 o 2 módulos. En unas 3-4 horas cada día tenía los apuntes leídos, las prácticas terminadas y me sobraba tiempo para hacer resúmenes o buscar más información sobre algunos temas por Internet.
    Algunos compañeros que sí iban a clase, al final dejaron de hacerlo y me dieron la razón en la cantidad de tiempo que ahorras. Pero como digo, si tienes unos buenos profesores, agradecerás el ir a clase. De eso ya te darás cuenta cuando llegue el momento.

    Mi mayor recomendación: ve siempre un paso por delante de lo que se ve en clase. Entonces te irá bien.
    Cualquier duda, puedes preguntarme e intentaré ayudarte. Un saludo y suerte.  :-X
#36
Realmente si no eres capaz de relacionarlo se podría decir que vas bien pues en caso de encontrar tal relación, estarías equivocado.

Todo esto viene a raíz de (no lo hice a propósito  :rolleyes:) del siguiente ejercicio típico o cualquiera de sus variantes:
CitarCrea un programa que, dado un número entero positivo n, determine si es o no primo.
Como tú y yo sabemos, un número primo es aquel que solo se puede dividir por uno mismo y la unidad (1), por ejemplo: 2, 3, 5, 7... (el 1 en la mayoría de casos no es considerado como un número primo pero eso da para otro tema por lo que lo dejaremos ahí)

La solución más básica y menos eficiente (llamémosla: el cerdito que hizo la casa de paja) sería calcular todos los divisores de n y ver si son 2 o más:

divisores := 0
PARA i := 1 HASTA n HACER
  SI n % i == 0 ENTONCES
    divisores := divisores + 1
  FIN SI
FIN PARA

SI divisores == 2 ENTONCES
  El numero n SI es primo
SINO
  El numero n NO es primo
FIN SI


Pero un día el hermano del anterior (el cerdito que hizo la casa de madera) dijo:
CitarSi ya tenemos más de 2 divisores, para qué vamos a seguir comprobando?
y creó algo mejor:

i := 1
divisores := 0
MIENTRAS i <= n && divisores <= 2 HACER
  SI n % i == 0 ENTONCES
    divisores := divisores + 1
  FIN SI
  i := i + 1
FIN MIENTRAS

SI divisores == 2 ENTONCES
  El numero n SI es primo
SINO
  El numero n NO es primo
FIN SI


Pero entonces el mayor de los 3 (el cerdito que hizo la casa de piedra), que era bueno en matemáticas porque era arquitecto por lo menos, dijo:
Citar
- Un número primo es aquel que únicamente puede expresarse como producto de 2 números naturales: n = a * b donde a = 1 y b = n o a la inversa (por la propiedad conmutativa del producto).
- Siempre 1 <= a, b <= n (a y b estarán en el rango [1,n]).
- Todo coeficiente a tendrá un coeficiente complementario b que se calcula como: b = n / a.
Entonces: Existe un punto medio x que cumple: (1 <= a <= x) y (x <= b <= n) teniendo como premisa a <= b (sin darles la vuelta a a y b). Lo que significa que solo hay que buscar algún valor que cumpla las condiciones de a para saber que existirá un b. Por lo que solo habrá que buscar en el rango [1, x] y no en el rango [1, n].
Entonces: Como a y b siempre están en el rango [1, n], el punto medio es x = n/2.
y diseñó lo que parecía la mejor solución de todas:

i := 1
divisores := 0
MIENTRAS i <= n/2 && divisores <= 2 HACER
  SI n % i == 0 ENTONCES
    divisores := divisores + 1
  FIN SI
  i := i + 1
FIN MIENTRAS

SI divisores == 1 ENTONCES // 1 porque no vamos a llegar hasta n que también es divisor
  El numero n SI es primo
SINO
  El numero n NO es primo
FIN SI


Los dos cerditos menores quedaron asombrados y fueron los 3 juntos a comercializar "el mejor algoritmo del mundo para encontrar números primos". Pero justo cuando iban a conseguir el reconocimiento mundial, apareció el lobo que era todavía mejor en matemáticas que el cerdito arquitecto y dijo:
Citar
Con todo lo anterior, el valor más grande de a es aquel que cumple que a = x. En tal caso, b tiene que valer su valor más pequeño que también es x.
Entonces: n = a * b se podría expresar como n = x * x. Un número x que multiplicado por si mismo da n, y esto hace referencia a la definición de raíz cuadrada de n.
Entonces: x no es n/2. x = sqrt(n). sqrt significa raíz cuadrada: square root.
Con esto el lobo mejoró el algoritmo del cerdito mayor y dejó a los 3 hermanos sin su ansiada recompensa.

i := 1
divisores := 0
MIENTRAS i <= sqrt(n) && divisores <= 1 HACER
  SI n % i == 0 ENTONCES
    divisores := divisores + 1
  FIN SI
  i := i + 1
FIN MIENTRAS

SI divisores == 2 ENTONCES
  El numero n SI es primo
SINO
  El numero n NO es primo
FIN SI


Todos estos códigos pueden ser implementados en muchos lenguajes de programación, entre ellos C++.
Así es como C++, los números primos, n/2, sqrt(n) y la fábula de los 3 cerditos están todos relacionados entre sí.
#37
Hola a tod@s.
Estoy con un proyecto desde hace un tiempo y aunque lo he planteado de varias formas diferentes, no logró decantarme por una. Os lo comento por si alguien quiere aportar su granito de arena:

Tengo x dispositivos que se comunican con el PC mediante un mismo puerto serie creado por un receptor. Cada dispositivo tiene un ID (2 dígitos) y para enviar un comando (aaaa) al dispositivo bb hay que escribir en el puerto serie: bbaaaa. El dispositivo responde con el mismo comando (bbaaaa) seguido de algún argumento si fuera necesario.

Como todos los dispositivos comparten el mismo puerto serie, creé algo así:
Código (csharp) [Seleccionar]

public class Dispositivo {
  private static SerialPort puertoSerie;

  public static void AbrirConexion(string nombreCOM) {...}

  public int Id { get; }
  public int NumeroSerie { get => ObtenerNumeroSerie(); }
  //...
}


En un principio la comunicación era comando-respuesta por lo que en los métodos utilizados implementé algo así:
Código (csharp) [Seleccionar]

lock(puertoSerie) {
  EnviarComando(comando);
  respuesta = RecibirRespuesta();
}
// gestion de la respuesta


De esta manera me aseguraba de que cuando una instancia de un dispositivo enviaba un comando al puerto serie, ninguno más pudiese enviar nada hasta obtener una respuesta de este (o superar el ReadTimeout del puerto serie y entonces devolver null). Esto funcionaba perfectamente mientras los comandos fuesen todos comando-respuesta.

El problema viene al intentar utilizar un comando que se envía una vez pero genera muchas respuestas seguidas durante x tiempo. Esta implementación para la comunicación ya no me servía así que opté por lo siguiente:
Código (csharp) [Seleccionar]

public class Dispositivo {
  //...
  private static readonly Dictionary<int, Dictionary<string, string>> gestorRespuestas = new Dictionary<int, Dictionary<string, string>>();
  //...
}


Lo que hago con esto es tener un almacén de respuestas. Cada dispositivo, tras enviar un comando se queda esperando una respuesta del puerto serie. Cuando ha obtenido una respuesta o null (si se supera el ReadTimeout) mira si esa respuesta coincide con la que estaba esperando. Si es así la gestiona y se acabó. Si no coincide, mira de qué dispositivo viene esa respuesta y a qué comando está respondiendo y lo almacena en gestorRespuestas[idEmisor][comandoRespondido], una vez hecho esto mira en gestorRespuestas[Id][comandoEnviado] si otro hilo ha almacenado una respuesta para él.

He realizado unas cuantas pruebas y funciona bastante bien excepto cuando escribo múltiples comandos en el puerto serie prácticamente al mismo tiempo que entonces alguno no llega a responderse nunca. Supongo que es porque hay que esperar un poco entre comando y comando (agregando una espera de 50 ms no he conseguido producir este problema).
La sincronización del puerto serie ahora la realizo justo para escribir en el puerto serie y para leer de él.


Me preguntaba si este enfoque es correcto o debería diseñar otra solución. Pensé también en hacer una cola de envíos y tener un único subproceso enviando comandos de esa cola cada x ms y otro subproceso únicamente para obtener las respuestas y guardarlas en el gestorRespuestas. Así cada hilo que trabaja con una instancia de dispositivo sólo tendría que acceder al gestorRespuestas y nunca al puerto serie directamente.
También he pensado en crear una clase ConcurrentSerialPort para no tener que gestionar los bloqueos desde la clase Dispositivo.

Estaré a la espera de vuestras aportaciones. :rolleyes:
#38
No entiendo la función de valor1 y valor2.
Deberías repasar bien las funciones y parámetros en C pues si no tienes eso claro, no sirve de nada intentar avanzar a duras penas.

Tampoco entiendo por qué has cambiado los parámetros de la segunda función.
#39
Tienes un problema con la definición de la estructura y es que estás sobreescribiendo datos. Si en la primera iteración dices que cursa 4 materias, en la segunda vuelta dices 5 y vas a sobreescribir el 4 anterior por el 5.

A simple vista tienes 2 opciones sin crear más estructuras. De más simple/rápida a más correcta/profesional serían:
  • Crear un array auxiliar y guardar después de cada iteración, la nota media (índice acumulado) de ese cuatrimestre. Al terminar haces la media de todos los valores del array y ya tienes la media de todos los cuatrimestres.
  • Modificar la estructura Estudiante para poder almacenar todos los datos sin tener que sustituirlos en cada iteración.

    Yo te recomiendo la segunda opción.
    El sentido de utilizar una estructura es poder almacenar todos los datos internamente y si utilizas la primera opción (con la estructura tal y como la tendrás ahora) estás sobreescribiendo datos en cada iteración, lo cual no tiene mucho sentido.

    (En este ejemplo voy a utilizar arrays estáticos porque son más fáciles que los dinámicos pero si sabes usar ya los arrays dinámicos, te recomiendo utilizarlos)

    #define MAX_CUATRIMESTRES 4
    #define MAX_MATERIAS_CUATRIMESTRE 10

    typedef struct {
       // los campos que consideres (nombre, edad, ...)
       int num_cuatrimestres;
       int materias[MAX_CUATRIMESTRES]; // El indice i indicara el numero de materias cursadas en el cuatrimestre i
       float notas[MAX_CUATRIMESTRES][MAX_MATERIAS_CUATRIMESTRE]; // El campo (i, j) indicara la nota de la materia j durante el cuatrimestre i
    } Estudiante;


    Ahora solo tienes que rellenar todos los datos:

    #define MAX_ESTUDIANTES 50

    int main() {
     Estudiante estudiantes[MAX_ESTUDIANTES];

     int num_estudiantes;
     // Para asegurarte de que se introduce un numero valido puedes hacer un filtro:
     // Utiliza los filtros para el resto de valores que tiene que introducir el usuario para asegurarte de que introducen valores validos
     do {
       printf("Introduce el numero de estudiantes: ");
       scanf("%d", &num_estudiantes);
     } while(num_estudiantes < 1 || num_estudiantes > MAX_ESTUDIANTES);

     for(int i = 0; i < num_estudiantes; ++i) {
       printf("Introduce el numero de cuatrimestres del estudiante %d: ", i+1);
       scanf("%d", &estudiantes[i].num_cuatrimestres);

       for(int j = 0; j < estudiantes[i].num_cuatrimestres; ++j) {
         printf("Introduce el numero de materias del estudiante %d durante el cuatrimestre %d: ", i+1, j+1);
         scanf("%d", &estudiantes[i].materias[j]);

         for(int k = 0; k < estudiante[i].materias[j]; ++k) {
           printf("Introduce la nota de la materia %d del cuatrimestre %d del estudiante %d: ", k+1, j+1, i+1);
           scanf("%f", &estudiantes[i].notas[j][k]);
         }
       }
     }
    }


    Ahora si haces una función como:

    float calcularMediaCuatrimestre(Estudiante estudiante, int cuatrimestre) {
     // tu codigo aqui
    }


    La función para calcular la media completa de un estudiante, sería algo así:

    float calcularMediaCompleta(Estudiante estudiante) {
     float sumaNotasCuatrimestres = 0;
     for(int i = 0; i < estudiante.num_cuatrimestres; ++i)
       sumaNotasCuatrimestres += calcularMediaCuatrimestre(estudiante, i);
     return sumaNotasCuatrimestres / estudiant.num_cuatrimestres;
    }
#40
Windows / Re: ayuda urgente busqueda de texto
10 Julio 2021, 15:49 PM
Desconozco si en Windows 8.1 existe el comando findstr pero puedes probar desde el cmd con:
findstr /N /S "<direccion_que_buscas>" <unidad_disco_duro>\*.txt
  • La opción /N es para que te indique el número de línea en la que se ha encontrado la coincidencia.
  • La opción /S es para buscar de forma recursiva en todos los subdirectorios del directorio dado.

    Por ejemplo:
    findstr /N /S "mi_direccion@loquesea.com" D:\*.txt