Суммируйте все целые числа в диапазоне [p, q], где p и q могут быть введены в любом порядке - PullRequest
2 голосов
/ 25 апреля 2020

Только начал изучать C, и было бы здорово, если бы вы могли помочь мне со следующим:

Я только что написал программу, которая вычисляет сумму всех целых чисел в диапазоне [p, q]. И p, и q вводятся в любом порядке, который хочет пользователь. Пока что программа работает нормально, когда p < q, но не работает, когда p > q. Чтобы изменить порядок значений p и q, я использую функцию reorder_range(), но, похоже, она не работает.

Кроме того, я не уверен, правильно ли я организовал код это правильная функция: main(), которая вызывает все подпрограммы для запуска, вместо того, чтобы иметь все внутри main().

Я с нетерпением жду любых предложений по улучшению этого куска кода!

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

main() {
    int sum, range, i, p, q, aux;

    printf("Enter two integers:");
    range = scanf("%d%d", &p, &q);

    check_if_valid_value(range);  
    reorder_range(p, q, aux);
    dothesum(p, q, i, sum);
}

check_if_valid_value(range) {
    if (range != 2) {
        printf("You have not entered two integers.\n");
        exit(1);
    }
}          

int reorder_range(int p, int q, int aux) {
    if (p > q) {
        aux = p;
        p = q;
        q = aux;
    }
}

int dothesum(int p, int q, int i, int sum) {  
    for (i = p; i <= q; ++i) {
        sum = sum + i;
        printf("%d\n", sum);
    }
}

Ответы [ 5 ]

2 голосов
/ 25 апреля 2020

Здесь мы рассматриваем более одной проблемы. Например, есть переменные (p и q), которые должны быть переданы по ссылке (как упоминалось в других ответах), есть переменные (aux, i, sum), которые не требуются для передается, возвращаемый тип функций (check_if_valid_value(range)) не верен, а некоторые локальные переменные (sum) не были инициализированы перед использованием.

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

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

void check_if_valid_value(int range)
{
        if (range != 2) 
        {
                printf("You have not entered two integers.\n");
                exit(1);
        }
}          

void reorder_range(int *p, int *q)
{
        int aux;

        if (*p > *q)
        {
                aux = *p;
                *p = *q;
                *q = aux;
        }
}

void dothesum(int p,int q)
{  
        int i, sum;
        sum = 0;

        for (i = p; i <= q; ++i)
        {
                sum=sum+i;
                printf("%d\n", sum);
        }

}

int main(void)
{

        int range, p, q;

        printf("Enter two integers:");
        range=scanf("%d%d",&p,&q);

        check_if_valid_value(range);
        reorder_range(&p, &q);
        dothesum(p,q);

        return 0;
}
2 голосов
/ 25 апреля 2020

Во многих задачах программирования, особенно связанных с математикой, таких как эта, лучшее решение также требует математического анализа. В этом случае, как правильно заметил @phuclv, вы вычисляете сумму арифмети c прогрессии . Таким образом, реальное решение требует только немедленного применения формулы.

Причина, по которой ваше решение не работает, в любом случае, является концептуальной ошибкой. Я объясню это так, что его понимание поможет вам в будущем


In C Параметры функции передаются значением . Это означает, что значение параметра сохраняется в его копии , а затем используется в функции.

Как следствие, любое изменение, выполненное для параметра, будет «жить» до функция возвращает, когда копии параметров будут потеряны. Таким образом, исходные параметры не изменятся.

Ваша функция

int reorder_range(int p, int q, int aux)
{
    if (p>q)
    {
       aux=p;
        p=q;
        q=aux;
    }
}

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


Решение

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

int reorder_range(int *p, int *q)
{
    if (p>q)
    {
        int aux = *p;
        *p = *q;
        *q = aux;
    }
}

Из вашего main () просто вызовите функцию, передавая адреса переменных, содержащих ограничения вашего диапазон:

reorder_range( &p, &q);
0 голосов
/ 25 апреля 2020

Основная проблема в вашем коде заключается в функции reorder_range: вы меняете только значения внутри этой функции, без какого-либо побочного влияния на переменные в вызывающей функции. Аргументы передаются по значению в C, поэтому изменение аргументов внутри функции не приводит к изменению переменных в вызывающей функции. Передача указателей на переменные для переупорядочения является способом решения этой проблемы.

Существуют и другие проблемы:

  • пропуск типа возврата при определении функции является устаревшим синтаксисом , main должен быть определен как int main() или int main(void), reorder_range должен иметь тип возврата void.

  • do_the_sum() должен принимать только границы диапазона, не индекс, а сумма переменных. Вы должны определить их как локальные переменные.

  • Вы должны определить или хотя бы объявить функции перед их вызовом.

Вот исправленная версия :

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

void check_if_valid_value(int res) {
    if (res != 2) {
        printf("You have not entered two integers.\n");
        exit(1);
    }
}          

int reorder_range(int *p, int *q) {
    if (*p > *q) {
        int aux = *p;
        *p = *q;
        *q = aux;
    }
}

int dothesum(int p, int q) { 
    int i, sum = 0; 
    for (i = p; i <= q; ++i) {
        sum = sum + i;
    }
    return sum;
}

int main() {
    int res, p, q;

    printf("Enter two integers:");
    res = scanf("%d%d", &p, &q);
    check_if_valid_value(res);  
    reorder_range(&p, &q);
    printf("%d\n", dothesum(p, q));
    return 0;
}

Обратите внимание, однако, что вам не нужно больше одной функции для вашей задачи:

#include <stdio.h>

int main() {
    int p, q, i, sum;

    printf("Enter two integers: ");
    if (scanf("%d%d", &p, &q) != 2) {
        printf("You have not entered two integers.\n");
        return 1;
    }
    if (p > q) {
        int aux = p;
        p = q;
        q = aux;
    }
    sum = 0;
    for (i = p; i <= q; i++) {
        sum += i;
    }
    printf("%d\n", sum);
    return 0;
}

Наконец, for l oop можно опустить и результат вычисляется напрямую следующим образом:

printf("%d\n", (p + q) * (p - q + 1));

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

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

int main() {
    int p, q;

    printf("Enter two integers: ");
    if (scanf("%d%d", &p, &q) != 2) {
        printf("You have not entered two integers.\n");
        return 1;
    }
    printf("%d\n", (p + q) * (abs(p - q) + 1));
    return 0;
}
0 голосов
/ 25 апреля 2020

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

Я даю вам одну рекомендацию:

  • функции, которые у вас есть, ничего не возвращают, так что вы следует ставить void вместо int
  • , прототипы функций должны быть объявлены до того, как основной
  • параметр check_if_valid_value не будет объявлен
0 голосов
/ 25 апреля 2020

В функции reorder_range измененные значения p, q не влияют на значения p, q в основном методе.

Когда вы передаете аргумент в методе со значениями, он не изменяет значение в первую очередь.

В качестве решения вы можете передать ссылку на ваши переменные p, q , В методе main перед вызовом reorder_range,

int *pp = &p;
int *pq = &q;

, затем измените вашу функцию reorder_range, чтобы принимать аргументы в качестве ссылок. тогда это будет работать. Для получения дополнительной информации об указателе используйте следующую ссылку.

TutorialsPoint c - указатели

Или вы можете создать глобальные переменные для p и q, а затем изменить их в функции reorder_range

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...