【问题标题】:Beginner C Programmer needs help with pointers ( I think )初学者 C 程序员需要指针帮助(我认为)
【发布时间】:2010-09-28 11:48:06
【问题描述】:

我是一名初级程序员,我正在学习我的第一语言 C。

我主要从 Deitel 和 Deitel 的 C How to Program 一书中学习,但也使用大学中的示例任务和东西,但是我被困在一个上。

我对指针有一个非常非常基本的了解——在变量前面添加 & 使它打印一个地址,并且 * 使用一个指针来使用存储在该地址等处的值。

我编写的这段代码用于计算两个数字的最大(最大?)公分母,实际上根本不需要或涉及指针。它使用两个函数并且逻辑都是正确的,因为如果我从第二个函数执行它,它会在屏幕上打印出正确的答案,而不是将其返回到主函数。这就是问题所在。

当第二个函数返回答案值时,由于某种原因它返回我只能假设是一个指针。我不知道它为什么这样做。我将能够使用它并将其转换为查找值 - 但是它似乎是第二个函数的本地指针并被覆盖。我在网络上或我的书中找不到任何东西可以让我知道如何解决这个问题。

感谢您读到这里。我已经走得太远了。

这是我的代码和输出。任何帮助或指示(请原谅双关语)将不胜感激。我知道我可以让它在第二个函数中打印,但我更想知道它如何以及为什么它没有像我想要的那样返回值。

代码

#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 的这样一个简单的解决方案。这是我无法发现或不知道的微小事物。那么返回的不是指针,而是垃圾?

谢谢一百万。

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    您在函数 greatCD() 的最后一行缺少“return”语句

    greatestCD(num2,(num1%num2));
    

    做起来

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

    (您可能还有进一步的调试工作要做,但这就是它返回垃圾的原因......您没有告诉它还有什么要返回)

    edit:我还建议在将来编译时打开所有编译器警告...如果您使用的是 gcc,请尝试将标志 -Wall 添加到您的编译命令中。当你做的事情可能会导致这样的错误时,这应该会警告你。 (并非每个此类警告都必然是错误,因此是“警告”,但它通常表示可能存在问题。)

    【讨论】:

    • 非常感谢。那么返回的只是垃圾而不是指针?
    • 它很可能是一个指针,但它只是返回值位置中已经存在的任何内容。例如,在 x86 上,您得到的值是编译器碰巧放入 eax 寄存器的值。
    【解决方案2】:

    由于您正在学习 C,因此与缺少返回错误无关,这里有一些观察和建议:

    • 指针是语言中最难学习的功能,尤其是当您进入malloc()free() 时。 不要气馁

    • 扔掉 Deitel 和 Deitel,给自己弄一份Kernighan and Ritchie。这是有史以来最好的语言书籍之一。

    • 始终打开所有警告。如果您可以使用 MacOS 或 Linux,gcc -Wall -Werror -O 非常好。

    • 运行valgrind下的每个C程序。 Valgrind 是一款出色的工具,旨在以您使用指针的方式捕获错误。它会拯救你的培根!

    祝你好运!

    【讨论】:

    • 你说要扔掉 Deitel 和 Deitel 有什么特别的原因,还是仅仅因为《C 编程语言》是一本值得拥有的书?
    • Deitel和Deitel被称为教科书工厂。我更喜欢从参与过语言设计的人那里获取我的信息,或者至少从那些在这方面进行了大量开发的人那里获取信息。我也认为短的书更好。我从来没有见过我喜欢的任何 Deitel & Deitel...
    【解决方案3】:

    您的函数不会返回任何内容,因此值 2293524 只是随机垃圾。你的编译器没有给你一个关于缺少返回值的警告吗?

    【讨论】:

      【解决方案4】:

      请参阅问题Should I Not Use a Herb Schildt Book to Learn From,尤其是http://www.cs.technion.ac.il/users/yechiel/CS/BadBooksC+C++.html 中引用的列表。尽管它列出了 Deitel 和 Deitel 的 C++ 书籍,但特定作者的书籍之间往往存在很强的家族相似性。我倾向于给自己买一本关于 C 的好书。我从 Kernighan & Ritchie 那里学到了(第一版,当时只有一个版本),所以我会推荐它——它简洁准确(就像 C 本身一样)。

      【讨论】:

      • 感谢您提供有用的链接。新的一年,我会在亚马逊的路上买一本 Kernighan & Ritchie。
      【解决方案5】:

      更奇怪的是该程序在我的 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.
      

      【讨论】:

      • 很可能返回值当时恰好在正确的寄存器中。
      • 我更改了代码以测试 gcd 函数缺少 return 关键字的版本与更正的版本,并且对于所有 i, j
      • 它在使用 gcc 的 OSX 上也能正常工作(有或没有缺少返回)。
      • 未定义的行为允许程序意外地正常工作。不要依赖它 - 行为是未定义的,GCC 不需要保持跨版本的一致性,它可以随时中断。任何其他编译器都可以为所欲为:在 Google 上搜索“鼻恶魔”。
      猜你喜欢
      • 1970-01-01
      • 2021-04-11
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多