更好的方法是使用指针

Better way to use a pointer?

本文关键字:指针 方法 更好      更新时间:2023-10-16

我试图创建一个程序,将显示条形图* *的最大数量可以是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;
}

由于这是c++,最好的方法是而不是使用指针;使用std::vector

也就是说,您也可以始终将指针视为数组,并且只访问给定位置0 <= i < lengthp_bar_length[i],而不是增加指针。

不使用指针自增,而是使用数组index:

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

或使用指针算术:

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

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

如果在第三个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

Edit:你甚至可以替换内部的for循环(修改过的例子)

既然你把它标记为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;
}

再复制一个指针,以便在循环中使用。更不容易出错。

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
}

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

可以将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;
}

二合一怎么样?

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
}

这与@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,因为它似乎很适合手头的工作。