Начинающему программисту на C нужна помощь с указателями (я думаю)

Я начинающий программист и изучаю свой первый язык C.

Я учусь в основном по книге Deitel and Deitel C How to Programming, но также использую примеры задач и вещи из университета, однако я застрял на одном.

У меня очень базовое понимание указателей - добавление & перед переменной заставляет ее печатать адрес, а * использует указатель для использования значения, хранящегося по этому адресу или тому подобному.

Кусок кода, который я написал, предназначен для вычисления наибольшего (наибольшего?) Общего знаменателя двух чисел, и на самом деле он вообще не требует и не включает указатели. Он использует две функции, и вся логика правильная, потому что он выводит правильный ответ на экран, если я делаю это из второй функции, а не возвращаю его в основную. Вот в чем проблема.

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

Спасибо, если вы дочитали до этого места. Я слишком много бродил.

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

Код

#include <stdio.h>
int greatestCD (int num1, int num2);

int main(void)
{
    int a=0, b=0;
    int result;
    printf("Please enter two numbers to calculate the greatest common denominator from\n");
    scanf("%d%d", &a, &b);
    result = greatestCD (a,b);
    printf("Using the correct in main way:\nThe greatest common denominator of %d and %d is %d\n",a,b, result);
}

int greatestCD (int num1 ,int num2)
{ 

    if (num2==0){
        printf("Using the cheaty in gcd function way:\nThe greatest common denominator is %d\n",num1);
        return num1;
    } else {
        greatestCD(num2,(num1%num2));
    }    
}

Вывод (используя 12 и 15 - ответ должен быть 3)

C:\Users\Sam\Documents\C programs>gcd
Please enter two numbers to calculate the greatest common denominator from
12
15
Using the cheaty in gcd function way:
The greatest common denominator is 3
Using the correct in main way:
The greatest common denominator of 12 and 15 is 2293524

Такое простое решение от frankodwyer. Это такие крошечные вещи, которые я либо не могу заметить, либо не знаю. Итак, то, что возвращалось, не было указателем, а было просто мусором?

Бесконечно благодарен.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
1 044
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы ничего не возвращаете из своей функции, поэтому значение 2293524 - это просто случайный мусор. Разве ваш компилятор не предупреждает вас об отсутствии возвращаемого значения?

Ответ принят как подходящий

Вам не хватает оператора return в последней строке функции maximumCD ()

greatestCD(num2,(num1%num2));

Сделай это

return greatestCD(num2,(num1%num2));

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

edit: Я также предлагаю, чтобы при компиляции в будущем вы включали все предупреждения компилятора ... если вы используете gcc, попробуйте добавить флаг -Стена в свою команду компиляции. Это должно предупредить вас, когда вы делаете что-то, что может привести к подобным ошибкам. (Не каждое такое предупреждение обязательно является ошибкой, отсюда «предупреждение», но обычно оно указывает на возможную проблему.)

Огромное спасибо. То есть то, что возвращалось, было просто мусором, а не указателем?

Drake 26.12.2008 23:06

Скорее всего, это был указатель, но это просто то, что уже было в местоположении возвращаемого значения. Например, на x86 вы получили то значение, которое компилятор поместил в регистр eax.

Serafina Brocious 26.12.2008 23:20

Более странно то, что программа работает на моей Linux-машине. Ошибка или особенность gcc?

/dev/shm $ gcc x.c
/dev/shm $ ./a.out
Please enter two numbers to calculate the greatest common denominator from
12
15
Using the cheaty in gcd function way:
The greatest common denominator is 3
Using the correct in main way:
The greatest common denominator of 12 and 15 is 3
/dev/shm $ gcc --version
gcc (Debian 4.3.2-1) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

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

frankodwyer 26.12.2008 22:38

Я изменил код, чтобы проверить версию функции gcd, в которой отсутствует ключевое слово return, с исправленной версией, и для всех i, j <5000 функция работает правильно.

user49117 26.12.2008 23:21

Он также работал правильно (с отсутствующим возвратом или без него) на OSX с использованием gcc.

joel.neely 27.12.2008 01:25

Неопределенное поведение позволяет программе случайно работать правильно. Не полагайтесь на него - поведение не определено, и GCC не требуется для поддержания согласованности между выпусками, и он может сломаться, когда захочет. Любой другой компилятор может делать все, что ему нравится: искать «гнусные демоны» в Google.

Jonathan Leffler 28.12.2008 20:35

Поскольку вы изучаете C, независимо от ошибки, связанной с отсутствием возврата, вот несколько наблюдений и советов:

  • Указатели - это самая сложная особенность языка для изучения, особенно когда вы попадаете в malloc() и free(). Не расстраивайтесь.

  • Выбросьте Deitel и Deitel и получите себе копию Керниган и Ричи. Это одна из лучших когда-либо написанных языковых книг.

  • Включите все предупреждения постоянно. Если вы можете использовать MacOS или Linux, gcc -Wall -Werror -O вполне подойдет.

  • Запустите каждую программу C под Valgrind. Valgrind - замечательный инструмент, разработанный для ловить ошибки в том, как вы используете указатели. Это спасет ваш бекон!

Удачи!

Есть ли конкретная причина, по которой вы говорите, чтобы выбросить Deitel и Deitel, или это просто потому, что язык программирования C - это ТАКАЯ книга?

Drake 27.12.2008 00:01

Deitel и Deitel известны как фабрика по производству учебников. Я предпочитаю получать информацию от людей, которые приложили руку к разработке языка или, по крайней мере, проделали большую его разработку. Я также считаю, что книги короче - лучше. Никогда не видел любой Deitel & Deitel мне нравилось ...

Norman Ramsey 27.12.2008 09:02

См. Вопрос Не следует ли мне использовать книгу Херба Шильдта, чтобы учиться? и, в частности, список, указанный в http://www.cs.technion.ac.il/users/yechiel/CS/BadBooksC+C++.html. Хотя в нем указана книга Deitel и Deitel о C++, существует тенденция сильного семейного сходства между книгами данной пары авторов. Я был бы склонен купить себе хорошую книгу по C. Я научился у Керниган и Ритчи (первое издание, когда было только одно издание), поэтому я бы порекомендовал ее - она ​​краткая и точная (как и сама C).

Спасибо за полезные ссылки. У меня будет копия Kernighan & Ritchie по дороге из Amazon в новом году.

Drake 27.12.2008 01:46

Другие вопросы по теме