Почему глобальные указатели ведут себя беспорядочно в этой функции? - PullRequest
0 голосов
/ 03 июля 2019

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

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

#include <stdio.h>
#include <math.h>
int *q;
int *u;
int *p;
void test () {
    printf("Insert #1?\t"); scanf("%d", &u); 
/*should be scanf("%d", u) for u is a pointer*/ 
    printf("Insert #2?\t"); scanf("%d", &p); 
/*should be scanf("%d", p) for p is a pointer*/ 
}
int main () {
    test ();
    printf("%d\n", u); 
/*should be printf("%d\n", *u) since I am trying to dereference the value of u*/
    printf("%d\n", p);
    printf("%d\n", q);
}

Выходные данные должны быть 3 числами, 2 первых числа являются входными данными от пользователя, а третье должно быть бессмысленным числом, так как 3-й указатель никуда не указывает.

Обновление: работает !!!!! Спасибо большое за вашу помощь :).

Ответы [ 5 ]

3 голосов
/ 03 июля 2019

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

В частности, если у вас есть такое объявление:

int *x;

Тогда, независимо от того, что вы делаете , вам сначала нужно назначить действительный указатель на x 1 .

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

#include <stdio.h>

int q;
int u;
int p;

void test () {
    printf("Insert #1?\t"); scanf("%d", &u); 
    printf("Insert #2?\t"); scanf("%d", &p); 
}

int main () {
    test();
    printf("%d\n", u); 
    printf("%d\n", p);
    printf("%d\n", q);
}

По иронии судьбы комментарии в исходном коде уже указывают на проблему, они просто предлагают неправильное решение.Это немного загадка, откуда эти комментарии.; -)


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

1 голос
/ 03 июля 2019

Указатели должны указывать на что-то, например, на другую переменную или память, динамически выделяемую с помощью malloc().

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

Таким образом, вы можете написать что-то вроде этого:

#include <stdio.h>
#include <math.h>
int q;
int *qp = &q;
int *up;
int p;
int *pp = &p;
void test () {
    printf("Insert #1?\t"); scanf("%d", up); 
    printf("Insert #2?\t"); scanf("%d", pp); 
}
int main () {
    up = malloc(sizeof(*up));
    test ();
    printf("%d\n", *up); 
    printf("%d\n", p);
    printf("%d\n", q);
}
1 голос
/ 03 июля 2019

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

int someNumber = 5;
int* u = &someNumber; // u points to a valid address statically allocated
scanf("%d", u); // Scans the number inputed to someNumber because u points to it
getchar(); // Avoid buffer overflow
printf("%d\n", *u); // A * dereferences u - gets the value of the variable it's pointing to
0 голосов
/ 03 июля 2019

Вашим указателям не присвоено значение.

0 голосов
/ 03 июля 2019

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

. Вы должны заменить его либо на scanf("%d", u);, либо изменить объявление на int u.

Вы должны быть осторожны, принимая значения указателя от пользователя.В противном случае вы можете рисковать такими вещами, как разыменование нулевого указателя.Например, если вы введете 0, когда вы scanf("%d", &u);, тогда значение u будет NULL.

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