Функции и возвращаемые значения в C - PullRequest
0 голосов
/ 27 апреля 2011

Я пытаюсь распечатать деталь в конце этой программы.Я ввожу C17, и часть выходит как 0, когда должно быть 1. Почему это?

С уважением

Деннис

# include <stdio.h>
int Part; 
int getPartType(int Part);
int calcPrice(int Part);


int main(int argc, char * argv[]){

    getPartType(Part);     
    calcPrice(Part);
    return 0;
}

// Part1: Asks for input from user for part type
int getPartType(int Part) {
    int nvr;
    char character_one;
    char character_two;
    int number;

    printf("Enter the part type (C17, F25, DN3, GG7 or MV4): ");
    nvr = scanf("%c%c%d",&character_one,&character_two,&number);

    if (number==7 && character_two=='1') {
        Part=1;
    }else if (number==5 && character_two=='2') {
        Part=2;
    }else if (number==3 && character_two=='N') {
        Part=3;
    }else if (number==7 && character_two=='G') {
        Part=4;
    }else if (number==4 && character_two=='V') {
        Part=5;
    }else{
        printf("Wrong Part Type\n");
        Part=0;
    }

    return Part;
}

int calcPrice(int Part) {

    printf("%d\n",Part);
    return 0;
}    

Ответы [ 3 ]

5 голосов
/ 27 апреля 2011

getPartType(Part); возвращает целое число и не присваивает оригиналу Part. Поэтому вы должны изменить эту строку:

getPartType(Part);

до

Part = getPartType(Part);

Если вы хотите изменить исходное значение детали, вы должны использовать указатели . Вы можете прочитать больше об этом в любой приличной книге C (я рекомендую K & R). Например:

// takes pointer to integer and sets it to 5
void settofive(int *someInteger) {
    *someInteger = 5; // dereference someInteger and set to 5
}

int main(int argc, char *argv[]) {
    int test = 0;
    int *ptrTotest = &test; // take address of test and store in ptrTotest

    printf("%d\n", test); // prints out zero
    settofive(ptrTotest);
    printf("%d\n", test); // prints out five

    return 0;
}
3 голосов
/ 27 апреля 2011

У вас небольшое недопонимание передачи аргументов функции.

Когда вы вызываете функцию типа

getPartType(Part); 

C создаст копию Part в стеке, и все вычисления внутри функции будут выполнены для этой копии. Поэтому вы не будете изменять переменную Part. Это называется Call-by-value.

Чтобы изменить эту проблему, есть два способа. Вы можете просто использовать:

Part = getPartType(Part);

Это создаст копию Part, функция будет работать с этой копией, а затем вернет что-то. Это что-то будет сохранено в оригинальной части. В вашем случае вы можете просто использовать int getPartType(void) в качестве объявления функции, потому что вы не работаете с Part.

Другой способ - передать указатель:

getPartType(&Part);

Это передает указатель на оригинальную деталь, поэтому вы можете манипулировать оригинальной деталью (используя * -оператор) Это будет означать, что ваша декларация будет выглядеть как void getPartType(int *). Но я бы сказал, что первый метод предпочтительнее, если вы имеете дело только с одной базовой переменной

0 голосов
/ 27 апреля 2011

C - вызов по значению . Это означает, что функция не может изменить значение переменной в контексте вызывающей стороны, если только вызывающая сторона не передает адрес этого значения.

Поскольку вашей функции на самом деле не нужен входной аргумент, его следует удалить. Все, что вам нужно, это возвращаемое значение.

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

if (number==7 && character_two=='1') {
    return 1;
}else if (number==5 && character_two=='2') {
    return 2;

и т. Д.

Кроме того, использование «магических» числовых констант обычно является плохой идеей. Было бы лучше ввести перечисление до main(), например:

enum Part { PART_C17 = 1, PART_F25, PART_DN3, PART_GG7, PART_MV4 };

Затем измените функцию, чтобы она возвращала значение этого нового типа:

enum Part getPartType(void)
{
  /* ... */
}

и обновите код в if -адрес соответственно:

if (number==7 && character_two=='1') {
    return PART_C17;
}else if (number==5 && character_two=='2') {
    return PART_F25;

и т. Д.

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