更好的方法来使用指针?

时间:2011-09-13 15:16:37

标签: c++ pointers

我正在尝试创建一个显示条形图的程序,*最大数量*可以是40.我已经完成了所有工作,但对代码有疑问。有没有更好的方法,因为你可以看到我必须使用以下两次回到原始地址:

    p_bar_length = p_bar_length - size;

有更好的方法吗?

#include <iostream>

using namespace std;

const int MAX_SPLATS = 40;

void bar_chart(double values[], int size)
{
    double largest = values[0]; //assign first element to be the largest

    //Find the largest value
    for (int i = 1; i < size; i++)
    {
        if (largest < values[i]) // check to see if there is something larger
        {
            largest = values[i];
        }
    }

    // Find the number of spalts to use
    // with the precent based on the largest value
    int* p_bar_length = new (nothrow) int[size];
    for (int i = 0; i < size; i++)
    {
        *p_bar_length = (values[i] / largest) * MAX_SPLATS;
        p_bar_length++; // Go to next memory address
    }

    // Go back to the orignal memory address
    p_bar_length = p_bar_length - size;

    // Pritnt the correct number of splats
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < *p_bar_length; j++)
        {
            cout << "*";
        }
        p_bar_length++;
        cout << endl;
    }

    // Go back to the orignal memory address
    p_bar_length = p_bar_length - size;

    delete[] p_bar_length;
}

int main()
{
    double values[6] = { 22, 40, 28, 26, 14, 46};
    int val_size = 6;

    bar_chart(values, val_size);

    system("pause");

    return 0;
}

8 个答案:

答案 0 :(得分:8)

由于这是C ++,最好的方法是来使用指针;相反,使用std::vector

也就是说,您也可以将指针视为数组,只需访问p_bar_length[i]给定位置0 <= i < length,而不是递增指针。

答案 1 :(得分:6)

使用数组索引:

,而不是递增指针
p_bar_length[i] = (values[i] / largest) * MAX_SPLATS;

或使用指针算法:

*(p_bar_length + i) = (values[i] / largest) * MAX_SPLATS;

答案 2 :(得分:4)

由于您将其标记为C ++,我建议您使用标准库。

你的程序比C ++更加C,但是如果c对你来说没什么可改进的话 另一方面,使用vectoralgorithm,您不需要乱用指针。使用C ++ 11,它可以删除以前与模板和迭代器相关联的粗糙边缘。

快速拍摄:

#include <iostream>
#include <vector>
#include <algorithm>

const int MAX_SPLATS = 40;

template <typename C>
    void bar_chart(const C& values)
{
    if (std::distance(values.begin(), values.end())<1)
        return; // do some error handling

    auto largest = *std::max_element(values.begin(), values.end());

    // Find the number of splats to use with the percent based on
    // the largest value
    std::vector<int> bars(values.size());
    std::transform(values.begin(), values.end(), bars.begin(),
        [=] (double d) { return (d/largest)*MAX_SPLATS; });

    // Print the correct number of splats
    std::for_each(bars.begin(), bars.end(), 
        [](int val){ std::cout << std::string(val, '*') << std::endl; });
}

int main()
{
    std::vector<double> values = { 22, 40, 28, 26, 14, 46 };

    bar_chart(values);

    std::cin.get();
    return 0;
}

答案 3 :(得分:4)

如果您使用for中的std :: max_element,则不需要第一个<algorithm>循环。

如果计算第三个for循环中的条形长度,则不需要第二个for循环。

这样的事情:

void bar_chart(double values[], int size)
{
    //Find the largest value
    double largest = *std::max_element(values, values + size);

    // Print the correct number of splats
    for (int i = 0; i < size; i++)
    {
        int p_bar_length = (values[i] / largest) * MAX_SPLATS;
        cout << string(p_bar_length, '*') << endl;
    }
}

这样你根本不需要p_bar_length数组。这只是一个简单的int

编辑:您甚至可以替换内部for循环(示例已修改)

答案 4 :(得分:2)

制作指针的另一个副本,以便在循环中使用。更不容易出错。

int* p_bar_length = new (nothrow) int[size];
int* p = p_bar_length;
for (int i = 0; i < size; i++)
{
    *p = (values[i] / largest) * MAX_SPLATS;
    p++; // Go to next memory address
}

P.S。你为什么使用nothrow?由于您没有检查从new返回的值,因此异常将比您返回NULL指针时的乱码要好得多。

答案 5 :(得分:2)

您可以将p_bar_length视为数组,并使用一致的表示法

int* p_bar_length = new (nothrow) int[size];
for (int i = 0; i < size; i++)
{
    p_bar_length[i] = (values[i] / largest) * MAX_SPLATS;
}

答案 6 :(得分:0)

二合一怎么样?

int* p_bar_length = new (nothrow) int[size];
for (int i = 0; i < size; i++)
{
    *p_bar_length = (values[i] / largest) * MAX_SPLATS;
     for (int j = 0; j < *p_bar_length; j++) cout << "*";
     cout << endl;
     p_bar_length++; // Go to next memory address
}

答案 7 :(得分:0)

这与@mkaes的帖子非常相似,但更进了一步。而不是使用std::transform创建适当长度的向量,然后std::for_each创建一个字符串,从每个字符串中获得适当的长度,这将直接从输入创建一个字符串,并直接从std::transform

#include <iostream>
#include <array>
#include <algorithm>
#include <string>
#include <iterator>

const int MAX_SPLATS = 40;

template <typename C>
void bar_chart(const C& values)
{
    if (std::distance(values.begin(), values.end())<1)
        return; // do some error handling

    auto largest = *std::max_element(values.begin(), values.end());

    std::transform(values.begin(), values.end(), 
        std::ostream_iterator<std::string>(std::cout, "\n"), 
        [=](double d) { return std::string((d/largest)*MAX_SPLATS, '*');} );
}

int main() {
    std::array<double, 6> values = {22, 40, 28, 26, 14, 46};

    bar_chart(values);

    return 0;
}

因为它无论如何都在使用C ++ 11,所以我决定使用std::array,因为它似乎非常适合手头的工作。