0

我的一个朋友正在开始他的编程/C++ 之旅,所以我告诉他玩循环和数组。

他制作了一个简单的控制台程序来读取整数并计算平均值。

#include "stdafx.h"
#include <iostream>
#include <math.h>

using namespace std;
int largeurTab;
int nombre;
int affNombre = 1;
int tableau [] = {nombre};
float moyenne;


int _tmain(int argc, _TCHAR* argv[])
{
    //Saisi de la largeur du tableau
    cout << "Veuillez saisir la largeur desire pour le tableau!" << endl << "Largeur : ";
    cin >> largeurTab;

    //Saisi des nombres du tableau
    for (int i = 0; i < largeurTab; i++)
    {
        cout << endl << "Nombre " << affNombre << endl;
        cin >> nombre;
        tableau [i] = nombre;
        affNombre += 1;
    }

    //Affichage * pour ligne séparation
    for (int i = 0; i < 45; i++)
    {
        cout << "*";
    }

    cout << endl << "Voici le(s) nombre(s) que vous avez saisi :" << endl;

    affNombre = 1;
    //Affichage des nombres du tableau
    for (int i = 0; i < largeurTab; i++)
    {
        cout << endl << "Nombre " << affNombre << endl << tableau[i] << endl << endl;
        moyenne += tableau[i];
        affNombre += 1;
    }

    //Affichage * pour ligne séparation
    for (int i = 0; i < 45; i++)
    {
        cout << "*";
    }

    //Affichage et calcul de la moyenne des nombres saisi dans le tableau
    cout << endl << "La moyenne des nombres saisi est de : " << moyenne/largeurTab << endl;

    system("PAUSE");
    return 0;
}

我一直认为 C++ 数组是静态的,如果我想要动态的东西,我必须使用指针或向量等。发现这有点分享我的想法。

困扰我的部分是

int nombre;
int affNombre = 1;
int tableau [] = {nombre};

起初我以为因为 nombre 没有初始化,所以默认情况下它被设置为一个非常大的整数,所以他的数组有一个非常大的容量......但经过一些调试后我不太确定。

那么这是如何工作的呢?

编辑:我知道这是错误的。我知道他应该使用向量。但是这段代码是有效的。输出值有效。我只是想从技术上知道这件事是如何工作的。

4

4 回答 4

3
int tableau [] = {nombre};

它没有声明一个元素大小为nombre的数组。

它声明了一个包含 1 项的数组,该数组初始化为nombre.

于 2013-08-14T20:18:05.380 回答
2
int nombre;
int affNombre = 1;
int tableau [] = {nombre};

这不会创建动态数组;它将指向数组的指针初始化为 1。如果您的朋友想学习 C++,我鼓励他们利用 C++ 结构(例如vector)。整个程序可以使用 C++ 结构用大约 7 行 C++ 编写:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

int main()
{
    std::vector<int> v;
    std::cout << "Enter values to average (Ctrl+Z to finish):  ";
    std::copy(std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), std::back_inserter<std::vector<int>>(v));
    double result = std::accumulate(v.begin(), v.end(), 0.0) / v.size();
    std::cout.precision(8);
    std::cout << "Average = " << std::fixed << result;
    return 0;
}
于 2013-08-14T20:23:04.510 回答
1
int nombre;
int affNombre = 1;
int tableau [] = {nombre};

上面的代码声明了大小为 1 的“tableau”数组,其值为 nombre。

但是,我认为您使用以下代码会遇到内存损坏

//Saisi des nombres du tableau
for (int i = 0; i < largeurTab; i++)
{
cout << endl << "Nombre " << affNombre << endl;
cin >> nombre;
tableau [i] = nombre;
affNombre += 1;
}

您有一个大小为 1 的元素的数组画面。但是您正在循环使用 largeurTab 并在 tableau 中插入那么多元素,但它只能合法地保存单个元素。所以你实际上遇到了缓冲区溢出。

您的程序运行良好只是运气。请使用其他人已经推荐的向量或动态分配数组。

于 2013-08-14T20:28:40.867 回答
0

这里发生的事情tableau是被视为指针,并且您正在写入它指向的任何位置。

这是一篇关于如何在内存中布置变量的文章:
http ://www.geeksforgeeks.org/memory-layout-of-c-program/

在文章中tableau列出了具有读写访问权限的“初始化数据”(只是= {nombre};因为它tableau具有 更糟糕的是,如果您对其中一个使用了足够大的索引,或者您可能会开始覆盖另一个全局索引。foobartableaufoobartableaufoobar

这是foobar过度写入的示例tableau

#include <iostream>
#include <math.h>

using namespace std;
int largeurTab;
int nombre = 0;
int affNombre = 1;
int tableau [] = {nombre};
int foobar [] = {nombre};
float moyenne;


int main(int argc, char* argv[])
{
    cout << "addrs of affNombre   " << &affNombre << endl;
    cout << "address of tableau   " << tableau << endl;
    cout << "address of foobar[1] " << &foobar[1] << endl;
    cout << "address of foobar    " << foobar << endl;
    cout << "address of moyenne   " << &moyenne << endl;

    foobar[1] = 666; // this is all evil
    cout << "foobar[0]  " << foobar[1] << endl;
    cout << "tableau[0] " << tableau[0] << endl;
    return 0;
}

最终输出将是tableau[0] = 666并且注意我们没有直接写入它。

这是在 Microsoft Visual Studio 中编译的。

这是它在 Codepad.org 上运行的示例,其中 moyenne 被覆盖:http: //codepad.org/Y1JMC8V5

于 2013-08-14T20:52:13.643 回答