You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ avag函数未定义引用错误及指针使用问题求助

C++指针与函数链接错误及指针使用问题

错误信息

编译时出现链接错误:

main.cpp|83|undefined reference to `avag(double, double, int, double)'

错误出现在调用avag函数计算数组平均值的位置,已在mojafunkcja.h中声明该函数,mojafunkcja.cpp中实现,但链接阶段无法找到对应函数实现,同时存在指针使用困惑。

相关代码

main.cpp

#include <iostream>
#include <string>
#include "mojafunkcja.h"

using namespace std;

double tab[0];
int naCo, CoChceszRobic;
double cm, M, Km, Cl, Mi, Jd, St;

int main(){

    cout<<"Co chcesz robic?: 1. Zamiana jednostek \n 2. Min/Max/Avg z tablicy ORAZ SORTOWANIE \n 3. "<<endl;
    cin>>CoChceszRobic;
    if(CoChceszRobic==1)
    {
        cout<<"Witaj! Podaj jaka jednostke chcesz zamienic:"<<endl;
        cout<<"1. Centymetry na Cale \n 2. Metry  na Stopki \n 3. Kilometry na Mile \n 4. Cale na Centymetry  \n 5. Stopy na metry \n 6. Mile na Kilometry \n 7. Jardy na Kilometry"<<endl;
        cin>>naCo;
        if(naCo==1)
        {
            cout<<"Podaj cm: ";
            cin>>cm;
            cout<<cm<<" cm ma "<<centymetryNaCale(cm)<<" cali";
        }
        if(naCo==2)
        {
            cout<<"Podaj M: ";
            cin>>M;
            cout<<M<<" M ma "<<metryNaStopy(M)<<" Stop(y)";
        }
        if(naCo==3)
        {
            cout<<"Podaj Km: ";
            cin>>Km;
            cout<<Km<<" Km ma "<<kilometryNaMile(Km)<<" Mil(i)";
        }
        if(naCo==4)
        {
            cout<<"Podaj Cale: ";
            cin>>Cl;
            cout<<Cl<<" cali ma "<<caleNaCentymetry(Cl)<<" Centymetrow";
        }
        if(naCo==5)
        {
            cout<<"Podaj Stopy: ";
            cin>>St;
            cout<<St<<" Stop(y) ma "<<stopyNaMetry(St)<<" Metrow(y)";
        }
        if(naCo==6)
        {
            cout<<"Podaj Mile: ";
            cin>>Mi;
            cout<<Mi<<" Mil ma "<<MileNaKilometry(Mi)<<" Kilometrow(y)";
        }
        if(naCo==7)
        {
            cout<<"Podaj Jardy: ";
            cin>>Jd;
            cout<<Jd<<" Jard ow ma "<<jardyNaKilometry(Jd)<<" Kilometrow(y)";
        }
        if(naCo>7 || naCo<1){
            cout<<"Podales zla wartosc :( "<<endl<<endl<<endl<<endl;
            main();
        }
    }
    if(CoChceszRobic==2)
    {
        int JakaDuza=1;
        double avg=0;
        double sum=0;
        double tab[JakaDuza];
        double *wsk;
        wsk=tab;
        cout<<"Jaka duza ma byc tablica? ";
        cin>>JakaDuza;
        for(int i=0; i<JakaDuza; i++)
        {
            cout<<i+1<<". ";
            cin>>*(wsk+i);;
            sum+=tab[i];
        }
        cout<<avag(avg,sum,JakaDuza,*wsk); // 错误位置
    }
}

mojafunkcja.h

double centymetryNaCale(double);
double metryNaStopy(double);
double kilometryNaMile(double);
double caleNaCentymetry(double);
double stopyNaMetry(double);
double MileNaKilometry(double);
double jardyNaKilometry(double);
double avag(double,double,int,double);

mojafunkcja.cpp

#include <iostream>
#include <string>
#include "mojafunkcja.h"

using namespace std;

double centymetryNaCale(double centy)
{
    return centy/2.54;
}

double metryNaStopy(double metry)
{
    return metry*3.2808;
}
double kilometryNaMile(double Kilo)
{
    return Kilo*0.6213;
}
double caleNaCentymetry(double cale)
{
    return cale*2.54;
}

double stopyNaMetry(double stop)
{
    return stop/3.2808;
}
double MileNaKilometry(double Kilo)
{
    return Kilo/0.621371192;
}
double jardyNaKilometry(double Kilo)
{
    return Kilo*1093.6;
}

double avag(double avg, double sum, int n, double wsk[]){

    for(int i=0;i<n;i++)
    {
        sum+= wsk[i];
    }
    avg=sum/n;
    return avg;
}

问题分析

  1. 链接错误根源:函数声明与实现的参数类型不匹配。头文件中avag的第四个参数是double,但cpp实现中是double wsk[](等价于double*),编译器会认为这是两个不同的函数,导致链接时找不到对应实现。
  2. 调用参数错误:调用avag(avg,sum,JakaDuza,*wsk)时,*wsk传递的是数组第一个元素的值(double类型),但函数需要的是数组指针/数组名,类型不匹配。
  3. 数组初始化问题:double tab[JakaDuza];属于C++标准不支持的变长数组(VLA),数组大小在编译时就已固定,后续输入的JakaDuza无法修改数组大小,会导致越界访问。
  4. 函数逻辑冗余:avag函数内部重新累加sum,但main中已经完成了累加,会导致平均值计算错误;同时avg参数是传值传递,函数内部修改不影响外部变量,且函数已返回结果,该参数无意义。

修复方案

1. 修正函数声明与实现的参数匹配

修改mojafunkcja.h中的avag声明:

// 去掉无用的avg参数,调整第四个参数为数组/指针类型
double avag(double sum, int n, double wsk[]);

对应修改mojafunkcja.cpp中的实现:

// 移除avg参数,直接返回计算结果
double avag(double sum, int n, double wsk[]){
    // 若main中已完成sum累加,无需再循环,直接计算平均值
    return sum / n;
}

如果希望函数自己计算总和,可进一步简化:

// 头文件声明
double avag(int n, double wsk[]);

// cpp实现
double avag(int n, double wsk[]){
    double sum = 0;
    for(int i=0;i<n;i++){
        sum += wsk[i];
    }
    return sum / n;
}

2. 修正函数调用参数

调用时传递数组指针/数组名,而非单个元素:

// 对应第一种修复方式
cout << avag(sum, JakaDuza, wsk);
// 或对应第二种简化方式
cout << avag(JakaDuza, wsk);

3. 修复数组初始化问题

用动态分配替代变长数组:

if(CoChceszRobic==2)
{
    int JakaDuza;
    double sum=0;
    cout<<"Jaka duza ma byc tablica? ";
    cin>>JakaDuza;
    // 动态分配数组
    double* tab = new double[JakaDuza];
    double *wsk = tab;
    
    for(int i=0; i<JakaDuza; i++)
    {
        cout<<i+1<<". ";
        cin>>*(wsk+i);
        sum+=tab[i];
    }
    cout<<avag(sum, JakaDuza, wsk);
    // 释放动态分配的内存
    delete[] tab;
}

也可以使用更安全的std::vector:

#include <vector> // 需包含头文件

if(CoChceszRobic==2)
{
    int JakaDuza;
    double sum=0;
    cout<<"Jaka duza ma byc tablica? ";
    cin>>JakaDuza;
    vector<double> tab(JakaDuza);
    
    for(int i=0; i<JakaDuza; i++)
    {
        cout<<i+1<<". ";
        cin>>tab[i];
        sum+=tab[i];
    }
    cout<<avag(sum, JakaDuza, tab.data()); // tab.data()获取数组指针
}

指针使用说明

  • double* wsk; wsk = tab;中,wsk指向数组tab的第一个元素,*(wsk+i)、wsk[i]、tab[i]三者等价,都表示数组的第i个元素。
  • 数组传递给函数时,会自动退化为指针,因此函数参数double wsk[]和double* wsk完全等价。
  • 避免使用变长数组(VLA),C++标准不支持该特性,使用动态分配或std::vector更安全、符合标准。

内容的提问来源于stack exchange,提问作者Jacobs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 23:27:33