我有很多关于c ++的问题让我很困惑

时间:2010-10-13 13:23:54

标签: c++ arrays initialization unresolved-external

我在大约3周前开始学习c ++,经过2年的java考试。它看起来如此不同,但即将到达那里。我的讲师是一个可爱的家伙,但任何时候我问一个问题,为什么有这样的方式或这样。他只是回应“因为它是”。

下面的代码中有很多评论带有一些随机问题,但主要问题是我得到两个构建错误,一个说没有初始化arraytotal(即使我找到了它的值),另一个说主要的外部参考。

有人会介意阅读代码并在其中回答一些评论,也许我会遇到整体问题吗?

#include<string>
#include<fstream>
#include<ostream>

using namespace std;

//double decimals[5] ={2,4,6,8,10};

const int arraySize = 5;
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?

//double decimals[arraySize];

/*
   this array is being created in the function averageN() but why?
   cant i just create it up top and reference it in?
 */

// why do you have to write the name of the function up here before you even create it?
double averageN();

int main()
{
    averageN();
    return 0;
}

// why does the array have to be created here?
double averageN(double decimals[arraySize])
{

    double average;
    double arrayTotal;
    for (int i = 0; i<5;i++)
    {
        // fills with random numbers from 0 - 10
        decimals[i] = (0+(rand()%10));
    }

    // find the total of all the elements in the array
    for (int i = 0; i < arraySize;i++)
    {
        double currentElement = decimals[i];
        arrayTotal = (currentElement+arrayTotal);
        //arrayTotal +=decimals[i]) ;
    }
    // return the average
    average = (arrayTotal/arraySize);
    return 0.0;
}

8 个答案:

答案 0 :(得分:6)

  1. //一个arraySize必须始终是const吗?它是如此在数组创建后它不会变形? 是的,它必须是const,而且,它必须是一个常量表达式,这意味着它的大小必须在编译时知道(而不是在运行时)。 如果要调整数组大小,那么最好使用标准容器std :: vector。或者如果你想要一个固定大小的数组,则使用动态分配的数组,但是直到运行时才知道大小

  2. / * 这个数组是在函数averageN()中创建的,但为什么呢? 我不能创建它顶部并引用它? * / 如果你说小数,那么不,它是一个全局变量,你可以从任何地方使用它。

  3. //为什么在创建之前必须在这里写出函数的名称? 您必须在使用之前在C ++中声明任何名称。由于您在main中调用此函数,因此必须至少事先声明它。您还可以在main之前提供定义(正文)。

  4. //为什么必须在这里创建数组?

  5. 哎呀,你的代码中似乎有一个很大的混乱。事实上,你有两个名为averageN的函数,一个是不带参数的averageN,另一个是带有double数组的AveraeN。你从未定义过第一个,只是声明了。

    错误:

    1. 未初始化doubleTotal。嗯,事实并非如此 double arrayTotal;更改为

      double arrayTotal = 0.0;

    2. 在main中未解决的extenal - 这是您正在进行的主要的AverageN功能。你从来没有写过它的身体。您创建了一个带有数组的函数,由于您的数组是全局数组,因此该数组无用。只需从AverageN定义中删除数组参数。

    3. HTH

      P.S。阅读S. Lippmann的C ++入门。对于C ++来说,这是初学者的最佳书籍。 IMO:)

答案 1 :(得分:2)

  • const为编译器提供了一条线索,表明该项不应该被更改,如果代码尝试它,那么编译器可以标记错误。

  • 在实际声明之前提到函数名称,main()函数需要在编译器实际编译之前引用它(稍后在代码文件中)。您可以在main()之前移动整个函数以避免这种情况。

  • double averageN(double decimals [arraySize])表示此函数采用数组。它并没有说它创建了数组。如果查看函数,它将获取数组,并将计算值添加到其中(decimals[i] = (0+(rand()%10)))。此函数还计算数组的平均值,并将其作为double返回。

所以回答你的大问题是什么问题 - 阅读最后一点并查看你正在进行的通话 - averageN(); - 你能看到这不是正确的电话吗? < / p>

答案 2 :(得分:1)

好的,这是你对arrayTotal的唯一分配:

 arrayTotal = (currentElement+arrayTotal);

现在,此作业后arrayTotal的价值是多少?那么,它取决于它在赋值之前的价值。在第一次任务之前它的价值是什么?你不知道。它可能是任何,因为你从来没有给它一个初始值。

答案 3 :(得分:1)

  const int arraySize = 5;
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?

C ++基本上支持两种数组:固定大小的数组,声明为type name[size],动态数组用new[]分配。
对于固定大小的数组,您必须为编译器提供它们的大小,以便它可以为数组留出足够的内存。由于编译器必须知道大小,因此只能使用const变量或文字指定它 虽然可以通过调用new[]来自己创建动态分配的数组,但这会让您感到头痛,从而使内存管理正常运行。最好使用为您执行此操作的现有类,例如std::vector

 //double decimals[arraySize];

/*
 this array is being created in the function averageN() but why?
 cant i just create it up top and reference it in?
 */

你可以在这里创建它,但这会让任何人都可以访问该数组。对于像这样的小程序来说这不是一个大问题,但考虑到还有十几个其他文件也可以访问数组并在意外时刻进行更改。

基本上是同一个问题,为什么你不在Java中公开所有类和成员:限制谁有权访问。

// why do you have to write the name of the function up here before you even create it?
double averageN();

您必须先声明该功能,然后才能使用它。 C ++要求您使用的所有名称必须在首次使用之前声明给编译器,编译器将按顺序从上到下读取文件。

请注意,此声明与您在下面给出的函数定义不匹配。由于C ++支持函数重载,因此它们被认为是不同的函数,因为它们接受不同的参数(无指针与指针)

 int main()
 {
    averageN();
    return 0;
 }

 // why does the array have to be created here?
 double averageN(double decimals[arraySize])
     {

创建一个数组。相反,它指定函数期望使用指针参数调用(arraySize完全被忽略,并且您无法将数组传递给C ++中的函数,因此参数调整为读取double *decimals )。

要获得有效的程序,您需要将上面的两行更改为

 double averageN()
     {
    double decimals[arraySize];

double average;
double arrayTotal;

averagearrayTotal都未初始化。这意味着他们将以一些未知的价值开始 对于average,这不是问题,因为你用它做的第一件事就是分配一个新值。但是对于arrayTotal,您要为其添加值,因此您必须以已知值开头。

for (int i = 0; i<5;i++)
{
    // fills with random numbers from 0 - 10
    decimals[i] = (0+(rand()%10));
}

// find the total of all the elements in the array
for (int i = 0; i < arraySize;i++)
{
    double currentElement = decimals[i];
    arrayTotal = (currentElement+arrayTotal);
    //arrayTotal +=decimals[i]) ;
}
// return the average
average = (arrayTotal/arraySize);
return 0.0;
 }

答案 4 :(得分:0)

我的快速回答没有经过双重检查(自从我用C ++开发以来已经有一段时间了)是:

  1. arraytotal尚未初始化

    我怀疑你的编译器将此标记为错误以确保你这样做。如果不这样做,则无法确定它将被初始化为什么。传统上,对于调试版本,C / C ++将内存初始化为某些调试值,以帮助识别未初始化的变量。初始化时设置arrayTotal = 0,它应该消失。 (最佳实践)

    e.g。 double arrayTotal = 0;

  2. 主要

    中的外部参考

    我怀疑这是因为你的averageN的原型与后面定义的方法不匹配。原型需要包括参数的类型以及返回类型。将原型从 double averageN(); 更改为 double averageN(double []); ,我相信这样可以解决该问题。

  3. arraySize必须始终是const吗?是这样在创建数组后它不会变形吗?

    因为你用它来定义传递给averageN的数组的大小,是的。像这样设置数组的大小需要一个恒定的值。

  4. 这个数组是在函数averageN()中创建的,但为什么呢? 我不能把它创建到顶部并引用它?

    它不是在averageN中创建的。它是averageN的形式参数。 averageN的调用者需要提供适当的变量并将其传入。然后从方法中,通过小数访问它。

  5. 为什么在创建之前必须在这里写出函数的名称?

    这是函数原型。如果在定义函数之前在代码中引用函数,则必须执行此操作。这也可以通过其他方式解决,例如在使用它之前移动averageN的定义。

答案 5 :(得分:0)

一些问题:

  • 您对averageN的前向声明不正确

代码:

double averageN();

下面提供的版本带有一个参数。

  • 你的平均N声明不太正常 声明类型数组的参数并不是直观明显的 通常人们会让数组降级为指向数组的指针,并将长度作为第二个参数传递。

代码:

double averageN(double *decimals, int arraySize)

如果您只想传递特定大小的数组,则需要参考:

double averageN(double (&decimals)[arraySize])
  • 您对main中的averageN()的调用。
    您传递零参数。现在这与前向声明匹配,但不符合实际定义。

结果我会改变这样的代码:

extern double averageN(double (&decimals)[arraySize]);

int main()
{
    double data[arraySize];
    averageN(data);
    return 0;
}

// why does the array have to be created here?
double averageN(double (&decimals)[arraySize])
{

答案 6 :(得分:0)

除了其他答案的技术细节之外,在第一段中回答投诉:获得“为什么”C ++问题的质量答案的一种方法是在其中一个Usenet组中询问,因为,与StackOverflow一样那里有真正的专家,但与StackOverflow不同,甚至初学者的问题也很可能从标准化委员会成员那里得到答案,如果你很幸运,那么即使是那些已经写过标准的人也是如此(如Andrew Koenig或目前的Pete Becker)。在早些时候,Bjarne也在那里。但近年来他没有发布太多内容。

基本新手“为什么”问题:alt.comp.lang.learn.c-c++。 Francis Glassborow在那里闲逛。他是一名委员会成员,也是几本成功的C ++入门书籍的作者。他也知道一些数学,并且因为发布频率很低(StackOverflow会有什么!),你几乎可以肯定任何中途有趣的问题几乎可以立即 - 而且正确 - 由Francis快速回答。 : - )

有关C ++语言的一般问题:comp.lang.c++和/或comp.lang.c++.moderated。后一组受审核并有章程。适度减少噪音 - 例如没有垃圾邮件 - 但增加了延迟。一些委员会成员倾向于主要在未经调整的小组(例如James Kanze)上发帖,有些人,如Pete Becker和Howard Hinnant,两组中的帖子,以及一些着名的专家,例如Andrei Alexandrescu,现在显然只是在主持组中。

关于标准意味着什么的问题,关于标准中的错误的报告等(在早些时候这也是你正式报告标准中的缺陷的地方):[comp.std.c ++]。这也是一个受审核的群体,不幸的是,现在的mod延迟几乎无法忍受。但作为一个新手,你可能对正式细节不太感兴趣,对理论和解释更感兴趣,[comp.lang.c ++]和[comp.lang.c ++。moderated]是很好的团队(我认为StackOverflow的主要部分)优势在于,当您想知道“此代码中的错误是什么”或原则上只需阅读相关文档即可解决的问题。)

最后,我已经链接到提供基于网络的界面的Google网上论坛,但您可以直接从诸如Thunderbird之类的Usenet客户端(或者例如具有内置客户端的Opera浏览器)访问这些组。要通过本地客户端访问Usenet,您所要做的就是配置客户端,告诉它有关服务器的信息,例如免费的EternalSeptember。或者AIOE。

干杯&amp;第h。,

- Alf

答案 7 :(得分:0)

似乎没有人评论过:averageN末尾的return语句是错误的。你说你正在返回平均值,然后计算半径,然后return 0.0;。试试return average;return arrayTotal/arraySize;