C语言 为什么我会听到“铿锵:错误:链接器命令失败,退出代码为1”?

krugob8w  于 2023-01-20  发布在  其他
关注(0)|答案(6)|浏览(276)

使用Xcode执行K&R时,在 Functions 部分中,我输入了幂函数示例的代码,如下所示。

#include <stdio.h>

int power(int m, int n);

int main()
{
    int i;

    for (i=0; 1<10; ++i)
        printf("%d %d %d\n", i, power(2, i), power(-3, i));

    return 0;
}

当我尝试运行它时,出现以下错误:

Undefined symbols for architecture x86_64:
  "_power", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我已经读了很多关于这个问题的答案,但是看不出它如何适用于我这样一个小程序的情况。我该如何解决这个问题?

wtlkbnrh

wtlkbnrh1#

为什么我会听到"铿锵:错误:链接器命令失败,退出代码为1 "?
您刚刚声明了函数,代码中没有任何定义,在链接过程中,编译器(这里是Clang)无法将power函数链接到它的定义,所以这种情况下链接器会抛出错误,如果您定义了

int power(int x, int y)
{
    /* Do calculation */
}

然后链接器可以将您的power函数声明链接到它的定义,并且您不会得到任何错误。
对于一个整数,我做了一个函数:

#include <stdio.h>

int power(int base, int exp);

int main()
{
    int i;

    for (i=0; i<10; ++i)
        printf("%d %d %d\n", i, power(2, i), power(-3, i));

    return 0;
}

int power(int base, int exp)
{
    int result = 1;
    while (exp)
    {
        if (exp & 1)
            result *= base;
        exp >>= 1;
        base *= base;
    }
    return result;
}

使用gcc file.c编译此代码。

z9smfwbn

z9smfwbn2#

你错过了函数int power (int base, int n)的定义,它是在书的下一页你的主结束之后给出的。
当你声明一个函数的原型时,你需要定义它应该做什么,你只声明了幂函数,却从来没有定义它,这就是为什么你会得到错误。
包括下面的定义,您的代码将按照您希望的方式编译。

int power (int base, int n) {
    int i, p;
    p = 1;
    for (i=1; i<=n; ++i)
        p = p*base;
    return p;
}

预编辑答案
虽然这无关紧要,但很有用

我认为您需要使用在math.h中定义的函数pow()

double pow(double a, double b)

C库函数pow(double a, double b)返回ab次幂。此函数返回一个双精度值,以便打印正确的说明符"%lf"
在这种情况下,您只需要包括头文件

#include <math.h>

在你的程序里。
不需要给予函数声明int power(int m, int n);
您遇到的错误是由于将I作为pow()的参数,因为当您编译代码时(在包含math.h并使用pow()之后),将i替换为任何整数将编译代码并提供正确的输出。

printf("%lf %lf %lf\n", i, pow(2, 3), pow(3, 2));

这将给予正确的结果,但当您使用

for (i=0; i<10; ++i) {
    printf("%lf %lf %lf\n", i, pow(2, i), pow(-3, i));
}

它抛出相同的错误,所以我认为pow()只接受常量作为输入,所以它不会在for循环中运行。
如果你不想包含math.h,你可以简单地声明

extern double pow (double base, double exponent);

这将正确地与库代码链接,而不使用math.h包含文件,下面是一个示例。

int main() {
    extern double pow (double base, double exponent);
    printf("%lf", pow(8.0, 8.0));
    return 0;
}

有关pow()的更多信息,您可以查看Linux上的手册页,即man pow

bq3bfh9z

bq3bfh9z3#

有一个标准的库函数可以做到这一点...

#include <math.h>
double pow(double x, double y)

必须显式地链接它,因为默认的linker(即在没有给定其他选项时调用的ld)不与标准数学库链接。
所以你得像这样...
gcc file.c -lm

xa9qqrwz

xa9qqrwz4#

您可以定义power函数

int power(int m, int n) {
    // Implement the function body
}

然后你的问题就能解决了。
你会得到一个错误,因为定义的函数没有任何减速,所以按照上面的方法加上减速。

ecfsfe2w

ecfsfe2w5#

首先,你得到这个错误是因为编译器找不到你正在使用的幂函数的定义。

int power(int m, int n);

出现错误是因为你没有定义函数。在定义的末尾缺少{},即使你把它放在定义的末尾,你也会得到一个错误,因为你没有为int函数返回任何东西。所以,至少如果你想定义一个函数,你必须这样做:

int power(int m, int n){return 0};

然后,你就可以在main函数中使用power()函数了。但是,你在power()函数中什么也没做,所以调用它也不会得到什么。如果你想计算一个数的幂,你可以使用cmath库中的函数pow()。一个简单的方法是这样的:

#include <stdio.h>  // printf
#include <cmath>    // pow()
#include <iostream> // cout

void main()
{
    for (int i = 0; i < 10; i++)
        std::cout << i << " " << pow(2, i) << " " << pow(-3, i) << std::endl;
}

我包含了 iostream,以便使用在 std 名称空间中定义的对象 cout 以不同的方式打印输出。注意,pow()函数对其定义有一些要求,因此要小心使用的类型。您可以查看 * pow * 以了解更多细节。

oewdyzsn

oewdyzsn6#

函数应该完成了。我今天遇到了同样的问题,只是因为我没有在代码中定义函数 main

相关问题