2013-06-19 3 views
1

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

Суть его в том, что я пытаюсь определить указатели в одной функции и называть эту функцию в моей основной для использования этих указателей. Точные инструкции для моего назначения являются следующие:

написать две функции, одна из которых читает три номера с клавиатуры и тот, который печатает некоторую информацию об этих трех чисел.

Вход Функция

Написать функцию, которая имеет три параметра целочисленный указатель, и что просит пользователя ввести три целых чисел. Значения, введенные на клавиатуре , следует считывать по адресам, указанным в параметрах указателя .

Примечание: напомним, что scanf требует адрес переменной и что указатели хранят адреса.

Печати Значение

Написать вторую функцию под названием a2question2, без возвращаемого значения и без параметров. Функция должна объявлять три целочисленные переменные , а затем использовать вашу функцию ввода для чтения значений в эти переменные. Затем функция должна распечатать сумму, среднее значение, произведение и наименьшее и самое большое из этих чисел.

Вот то, что я до сих пор:

int pntloc (int *x, int *y, int *z){ 
    int a = 0; 
    int b = 0; 
    int c = 0; 

    printf("Please enter integer #1: "); 
    scanf ("%d", & a); 
    printf ("Please enter integer #2: "); 
    scanf ("%d", & b); 
    printf("Please enter integer #3: "); 
    scanf ("%d", & c); 

    *x = &a; 
    *y = &b; 
    *z = &c; 

    return *x, *y, *z; 
} 

// Fourth function 
main(){ 
    int x, y, z; 
    pntloc(x, y, z); 

    int sum = 0; 
    int average = 0; 
    int product = 0; 
    int smallest = 0; 
    int largest = 0; 

    printf ("%d", x); 
} 

Однако, после того, как программа спросит меня за три целых числа, он выходит из строя, не делая ничего.

Первая функция прекрасно работает его самостоятельно (протестировал его, сделав его основную функцию без параметров и печатал значение указателей), то есть:

printf ("%d", *x); 

Так что я думаю, что значения просто не переходя из одной функции к следующему. Я пробовал различные способы написания первой и второй функции, но ничего не работает.

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

Любые идеи, как это сделать?

+2

'* x = & a' должно быть' x = & a' и так далее ... Есть много ошибок. Ваша функция возвращает 'int', и у вас есть' return * x, * y, * z; ' – Bill

+0

a b и c будут недоступны после того, как мы выйдем из функции, поэтому * x и т. Д. Будут недействительными. – John3136

ответ

1
*x = &a; 
*y = &b; 
*z = &c; 

Возникнет хаос и смерть! a b и c являются локальными переменными, поэтому вы устанавливаете содержимое x y и z на адреса, которые будут недействительными после возврата из функции, где определены значения b и c. Возможно, вы имели в виду:

*x = a; 
*y = b; 
*z = c; 
0

в основной(),

pntloc(&x, &y, &z); 

и

*x = a; 
... 
printf ("%d", x); 

в то время как вы проходите * х в качестве параметра в pntloc(), вы не можете измените значение x после вызова функции.

и pntloc() не нужно возвращать, возврат 0 или 1 достаточно.

5

Ваша программа, вероятно, сбой из-за двух ошибок:

1) Вы возвращаете локальный адрес переменныхa, b и c:

*x = &a; // This line says follow the 'x' pointer, and set the value there to 
     // the address of 'a' 

Поскольку a определяется локально (т.е. внутри функции), этот адрес недействителен после возвращения функции.

То, что вы, вероятно, имел в виду,:

*x = a; // Follow the 'x' pointer, and set the value there to the value of 'a' 

2) Вы не передавая указатели на pntloc() (ваш компилятор должен быть предупреждаю об этом один)

int x, y, z; 
pntloc(x, y, z); // The passes the VALUES of x, y and z 

вероятно Вы имели в виду :

pntloc(&x, &y, &z); // Pass the ADDRESSES of x, y and z 

Некоторые другие улучшения, которые не вызывают ваш аварии:

Вы можете массово сократить pntloc() не используя локальные переменные:

void pntloc (int *x, int *y, int *z){ 
    printf("Please enter integer #1: "); 
    scanf ("%d", x); 
    printf ("Please enter integer #2: "); 
    scanf ("%d", y); 
    printf("Please enter integer #3: "); 
    scanf ("%d", z); 
} 

Обратите внимание, что & был удален внутри scanf() вызова. Вы спросили об этом в комментариях, так что вот немного больше объяснений: &x говорит «адрес x», но когда у вас есть указатель, у вас уже есть адрес. Быстрый пример:

int a;  // 'a' is an integer variable 
int *b = &a; // 'b' is a pointer to the integer variable 'a' 

scanf("%d",&a); // This statement reads an integer into 'a'. 
       // We pass it the address of 'a', which is written &a 
scanf("%d",b); // This statement also reads an integer into 'a'. 
       // We pass it the address of 'a', which is stored 
       // in the pointer 'b'. 

Поскольку мы имеем указатели, передаваемые в функцию:

void pntloc (int *x, int *y, int *z){ // Three pointers to ints 

мы можем передать их прямо в к scanf(), и не нужно (и не должны) использовать & если сделаете.

Обратите внимание, что я также снял оператор возврата:

return *x, *y, *z; 

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

Но почему он компилируется, спросите вы? Ну, вот что происходит - но не стесняйтесь игнорировать этот бит, если он путается: comma operator оценивает влево-вправо, отбрасывая результат левой руки, когда он идет. Таким образом, ваше возвращение утверждение эквивалентно:

*x; 
*y; 
return *z; 

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

Поскольку вы не использовали возвращаемое значение из функции, когда вы назвали его:

pntloc(&x,&y,&z); 

я извлекал возвращение полностью, и установить тип возвращаемого значения void.

+0

Спасибо за обширную запись. Это очень помогло мне, и я кое-что узнал. Быстрый вопрос, однако, почему scanf отличается в вашем примере. Вы удаляете «&», что в конечном итоге привело меня к правильному ответу. Разве это не обязательно при использовании указателей? –

+0

Добро пожаловать. Дайте мне знать, если у вас есть какие-либо вопросы по поводу этого. –

+0

'& x' говорит« адрес x », но когда у вас есть указатель, у вас уже есть адрес. Я расширюсь дальше, дайте мне минутку. –

Смежные вопросы