Помощь Structura и Вектор в C, Простая программа Учеников и Отметок

Как делать вектор? Какой формы делать, чтобы не помещать nota1;nota2;nota3;etc? Я сделал 2 кодекса, но Вы я не функционируете. Как делать с темой средней величины?

1) Класть данные консистентных учеников учреждения в NOMBRE (string 30 характеров), SEXO (char), и NOTAS 10 кодифицированные предметы 0 в 9 (int). Прибыль закончится, когда будет положено имя FIN.

2) Показывать количество учеников, которое есть в учреждении, средняя величина которого была больше или равно как 4 и несовершеннолетний, который 7.

Транскрипция фотокопии, которую Вы просили делать:

  1. Класть данные учеников учреждения состоящих в ИМЕНИ (string 30 характеров), ПОЛ (char) и ТЫ ЗАМЕЧАЕШЬ 10 кодифицированными предметами от 0 до 9 (int). Прибыль закончится, когда будет положено имя "ЦЕЛЬ". Известно, что у учреждения нет более чем 10000 учеников.
  2. Печатать список 10 лучших учениц.
  3. Показывать, сколько учеников есть в учреждении, средняя величина которого была больше или равно как 4 и несовершеннолетний, что семь.
  4. Позволять прибыль имени и показывать совокупность Ваших данных, или, если Вы не принадлежите учреждению.

Кодекс 1:

#include stdio.h
#include stdlib.h
#include ncurses.h
#include string.h

struct promedio{
    int nota1;
    int nota2;
    int nota3;
    int nota4;
    int nota5;
    int nota6;
    int nota7;
    int nota8;
    int nota9;
    int nota10;
};

struct alumno{
    char nombre[20];
    char sexo[20];
    int edad;
    struct promedio prom;
}alumnos[100];

int main(){
    int n,i,pmay;
    int promedio[100], mayor = 0;
    printf("Digite el total de alumnos: ");
    scanf("%i",&n);

    for(i=0;i<n;i++){

        printf("%i. Digite su nombre: ",i+1);
        scanf("%s",alumnos[i].nombre);
        printf("%i. Digite su sexo: ",i+1);
        scanf("%s",alumnos[i].sexo);
        printf("%i. Digite sus notas: ",i+1);
        scanf("%i %i %i %i %i %i %i %i %i %i",&alumnos[i].prom.nota1,
        &alumnos[i].prom.nota2,&alumnos[i].prom.nota3,&alumnos[i].prom.nota4,
      &alumnos[i].prom.nota5,&alumnos[i].prom.nota6,&alumnos[i].prom.nota7,&alumnos[i].prom.nota8,
      &alumnos[i].prom.nota9,&alumnos[i].prom.nota10);
        printf("\n");

        promedio[i] = (alumnos[i].prom.nota1+alumnos[i].prom.nota2+alumnos[i].prom.nota3+alumnos[i].prom.nota4+alumnos[i].prom.nota5+
        alumnos[i].prom.nota6+alumnos[i].prom.nota7+alumnos[i].prom.nota8+alumnos[i].prom.nota9+alumnos[i].prom.nota10)/3;

        if(promedio[i] > mayor){
            mayor = promedio[i];
            pmay = i;
        }
    }

    printf("\n- El Alumno con Mayor Promedio-\n");
    printf("\nNombre: %s",alumnos[pmay].nombre);
    printf("\nSexo: %s",alumnos[pmay].sexo);
    printf("\nPromedio: %i\n",promedio[pmay]);


    getch();
    return 0;
}

Кодекс 2:

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

#define MAX 100

struct {
    char nombre[20];
    char sexo;
    int notas[10];
} alumno[MAX];

int main() {
    int j,i=0,suma,a,b,c;
    float promedio=0.0;

    while (1) {
        printf("Nombre del alumno (para terminar teclee FIN): ");
        scanf("%s",alumno[i].nombre);
        getchar();

        if (strcmp(alumno[i].nombre,"FIN") == 0)
            break;
        else {
            printf("Sexo: M o F: ");
            scanf("%c",&alumno[i].sexo);
            for (j=0; j<10; j++) {
                printf("Ingrese nota # %d: ",j+1);
                scanf("%d",&alumno[i].notas[j]);
            }
        }
        printf("\n");
        i += 1;
    }

    for (a=0; a<i; a++) {
        suma = 0;
        for (b=0; b<10; b++)
            suma = suma+alumno[a].notas[b];

        promedio = suma/3;
        if (promedio >= 4 && promedio < 7)
            c += 1;
    }
    printf("Total de alumnos con promedio >= 4 y promedio < 7 = ");
    printf("%d",c);

    return 0;
}
1
задан 26.10.2016, 05:35
3 ответа

Проблема, у которой есть первое предложение, состоит в том, что он осложнен, делать вычисление средних величин, потому что ты не можешь помещать цикл. Лучший выбор состоял бы в том, чтобы использовать вторую, у которой кроме того есть меньше код:

#define MAX_NOTAS 10

struct alumno
{
    char nombre[20];
    char sexo;
    int notas[MAX_NOTAS];
};

С другой стороны, в изложении они говорят тебе следующее:

Вводить в компьютер данные учеников учреждения состоящих в ИМЕНИ (string 30 символов), ПОЛ (char) и ТЫ ЗАМЕЧАЕШЬ 10 кодифицированными материями от 0 до 9 (int). Ввод информации закончится, когда будет введено в компьютер имя "КОНЕЦ". Известно, что у учреждения нет более чем 10000 учеников.

В части, приданной особое значение уже они дают тебе предел учеников. Первое, что ты должен делать, состоит в том, чтобы размещать достаточное место, чтобы хранить это число элементов. Я лично избежал бы использовать глобальные переменные, так как они со временем будут давать тебе больше проблем, чем радостей. Также он избежал бы входить буквальные между кодом:

#define MAX_ALUMNOS 10000

int main()
{
  struct alumno alumnos[MAX_ALUMNOS];
}

Цикл, чтобы входить ученики, должен заканчиваться, когда вмешается слово "FIN", хотя, так как у нас есть верх учеников, он не был бы больше проверения, что мы не превосходим вышеупомянутый предел, хотя он будет из-за ошибки:

int num_alumnos;
for( num_alumnos=0; num_alumnos<MAX_ALUMNOS; num_alumnos++ )
{
  printf("Nombre del alumno (para terminar teclee FIN): ");
  scanf("%s",alumnos[num_alumnos].nombre);
  if( strcmp(alumnos[num_alumnos].nombre,"FIN") == 0 )
    break;
  // else ....
  // nota que como el if tiene un break no es necesario el else
}

Когда ты учишься программировать, ты догадываешься, что ты должен относиться к пользователю как будто это был полный бесполезный и мог запутываться всегда..., представь, что тот, кто будет использовать программу, - обезьяна, которая избивает клавиатуру..., ты должен подтверждать все то, что вмешивается, чтобы знать, действительный ли он:

do
{
  char sexo;
  printf("Sexo: M o F: ");
  scanf("%c",&sexo);
  alumnos[num_alumnos].sexo = toupper(sexo);
} while( alumnos[num_alumnos].sexo != 'M' && alumnos[num_alumnos].sexo !='F');

И в конце концов, чтобы вводить замечания, мы можем использовать постоянную величину, которую мы объявили сначала (изящество использования постоянных величин состоит в том, что, если мы хотим сделать быстрые доказательства, только нужно меняться, оцени в сайте);

for (int j=0; j<MAX_NOTAS; j++)
{
  printf("Ingrese nota # %d: ",j+1);
  scanf("%d",&alumnos[num_alumnos].notas[j]);
}

Сейчас мы проверяем среднюю величину:

for (int i=0; i<; a++) {
  suma = 0;
  for (b=0; b<10; b++)
    suma = suma+alumnos[a].notas[b];

  int promedio = suma/3; // <<--- AQUI!!!
  if (promedio >= 4 && promedio < 7)
    c += 1;
}

Почему ты разделяешь сумму между 3? Мы не остались, в котором это 10 замечаний? Это одна из проблем, ассоциируемых с использованием буквальных в коде:

int resultado = 0;
for (int i=0; i<num_alumnos; i++) {
  int suma = 0;
  for (int j=0; j<MAX_NOTAS; j++)
    suma += alumnos[i].notas[j];

  promedio = suma/MAX_NOTAS;

  // Esto ...
  if (promedio >= 4 && promedio < 7)
    resultado++;
  // ... es equivalente a ...
  resultado += (promedio >= 4 && promedio < 7);
}

И с этими изменениями программа ты была бы должна функционировать.

Приветствие.

2
ответ дан 24.11.2019, 12:54
  • 1
    Спасибо за ответ он подал меня многого, но средняя величина продолжает давать мне плохо. – Gabriel Forzza 26.10.2016, 23:19
  • 2
    Если ты хочешь среднюю величину с десятичными tendr и # 225; s, что вычислять результат в float – eferion 26.10.2016, 23:25
  • 3
    Или это или ты ошибся, принеся изменения в твою программу – eferion 26.10.2016, 23:26
  • 4
    @GabrielForzza Попытайся объявлять среднюю величину внутри цикла... Не идите быть что est и # 233; s, складывая средние величины, не замечая – eferion 26.10.2016, 23:28

Идея об этом форуме состоит в том, чтобы выдвигать пунктуальные сомнения относительно специфических проблем программирования. Вопросы, прося ответы на, как решать целое упражнение они обычно не хорошо получены, также я бросаю тебе какую-то помощь для того, чтобы ты смог решать это.

Структура, которую ты был бы должен использовать, - следующая:

Struct alumno {
    char nombre[30];
    char sexo;
    int notas[10];
    float promedio;
};

Для пола не необходимо использовать вектор, так как он достиг ее, тебя просит char. Я понимаю, что мужчины принесут M в этом поле и женщины F. Для замечаний не необходимо создавать такую структуру как делая, что я сделал, состояло в том, чтобы помещать вектор внутри структуры, которая будет содержать 10 замечаний каждого ученика. Также я добавил переменную типа float, где будут сохранять среднюю величину 10 замечаний.

Первое, что tenes, что делать значит занимать тебя груза учеников, как ты не знаешь, что они идут вводить количество учеников в компьютер насильно, ты будешь должен использовать динамическую память.

Для этого, первого, что tenes, которую делать это состоит в том, чтобы признавать переменной типа ученик:

struct alumno primer_dato;

Потом вы просите его пользователя, который вводит имя ученика в компьютер. Если имя отличное от КОНЦА (условие окончания как лозунг), ты хранишь имя в созданной переменной и вы просите его пользователя, который вводит в компьютер пол и 10 замечаний (там ты вычисляешь среднюю величину) и вводишь все данные в той же структуре. В этом моменте у тебя будет вся нагруженная структура и ты будешь должен просить память используя функцию malloc, чтобы потом добавлять узел к списку, который ты будешь должен создавать. Этот процесс повторится всегда до тех пор, пока вошедшее имя не будет КОНЦОМ.

Когда готовые ты она будет полностью загружена всеми учениками, ты обрезал продолжать с точками 2, 3 и 4 из твоего лозунга.

0
ответ дан 24.11.2019, 12:54

Как делать вектор? Какой формы делать, чтобы не помещать nota1;nota2;nota3;etc?

Я прихожу к заключению (может который ошибочно) о том что ты хочешь знать, как делать вектор в динамической памяти, так как в других частях твоего кода я вижу, что уже ты умеешь делать вектора в статической памяти.

Чтобы создавать вектор в динамической памяти ты будешь должен использовать функцию malloc, которая берется за то, чтобы поселять память (memory allocation).

Функция malloc принадлежи заголовку <stdlib.h>:

void* malloc( size_t recuento_de_bytes ); 

Мёд recuento_de_bytes байт памяти, не инициализировавшей (это: что будет содержать данные с неопределенной стоимостью). Если он сможет поселить попросившую память, он возвратит себе указатель в начало блока попросившей памяти.

Так что, если ты хочешь 10 целых типов стоимости для твоей средней величины, ты был бы должен делать следующее:

// Aloja memoria para 10 int
int *promedio = malloc(10 * sizeof(int));

Инструкция sizeof(int) возврати размер типа int, что обычно 4 байт (в большинстве систем 32 бит), так что количество необходимых байт, чтобы поселять 10 целых чисел, было бы 40 байт (10 * sizeof(int)).

Ты сможешь соглашаться на каждое из 10 целых чисел используя квадратные скобки ([ и ]) рассказывая, что первое целое число будет индексом 0 и последний индекс 9:

/* Ponemos todos los datos a 0 porque
malloc devuelve memoria no inicializada. */
for (int indice = 0; indice < 10; ++indice)
    promedio[indice] = 0;

Не нужно забывать, что память, попросившая из-за malloc она не освобождена если только он так не был показан. Чтобы освобождать память нужно использовать функцию free:

void free( void* puntero_a_memoria_dinamica );

Также принадлежи заголовку <stdlib.h> и освободит попросившую память dinámicamente, для этого нужно перемещать его указатель обозначаясь в начало блока памяти, которая попросилась dinámicamente.

Вводить в компьютер данные консистентных учеников учреждения в NOMBRE (string 30 символов), SEXO (char), и NOTAS 10 кодифицированные материи 0 в 9 (int). Ввод информации закончится, когда будет введено в компьютер имя FIN.

Из-за которого я могу видеть это, ты считаешь это почти решенным, но не подтверждаешь, что они ввели тебе имя в компьютер FIN чтобы прекращать просить данные. Чтобы сравнивать текст, введенный в компьютер против определенного текста ты будешь должен использовать strcmp или лучше strncmp, оба принадлежат заголовку <string.h>.

strcmp это функция сравнения цепей символов, получает указатель в первый характер, который нужно сравнивать первой цепи и указателя с первым характером, который нужно сравнивать второй цепи. Результат - целое число:

int strcmp( const char *cadena_izquierda, const char *cadena_derecha );

Результат может obtiener стоимость -1, 0 или 1 в зависимости от результата сравнения: cadena_izquierda несовершеннолетний в cadena_derecha, cadena_izquierda и cadena_derecha будь равен или cadena_izquierda больше в cadena_derecha соответственно.

strncmp это безопасная версия strcmp что добавляет параметр с максимальным числом символов, которое нужно сравнивать:

int strncmp( const char *cadena_izquierda, const char *cadena_derecha, size_t maximo );

Зная, что NOMBRE это будет всегда цепь 30 символов ты мог бы использовать эту функцию.

Показывать количество учеников, которое есть в учреждении, средняя величина которого была больше или равно как 4 и несовершеннолетний, который 7.

Однажды у тебя есть все замечания в твоем векторе, только ты будешь должен пробегать их и считать количество элементов, которые выполняли бы условие:

int promedio_entre_4_y_7 = 0;

for (int indice = 0; indice < cantidad_de_alumnos; ++indice)
    if ((promedio[indice] >= 4) && (promedio[indice] < 7))
        ++promedio_entre_4_y_7;

В условие я поместил скобку между каждым из сравнений, но он не необходим из-за предшествования операторов так как >= и < у них есть предшествование большее, которое &&.

0
ответ дан 24.11.2019, 12:54
  • 1
    Спасибо за ответ, я все еще не манипулирую указателями и динамической памятью, но ты объяснил достаточно мне. За него благодарен. Salu2! – Gabriel Forzza 26.10.2016, 19:57