更好的方法是使用指针
Better way to use a pointer?
我试图创建一个程序,将显示条形图* *的最大数量可以是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 < length
的p_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对你来说还行,那就没有太多需要改进的了。
另一方面,使用vector
和algorithm
,您不需要乱搞指针。使用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
,因为它似乎很适合手头的工作。
- 在C#中处理C++指针而不使用unsafe的最佳方法
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 将成员函数指针作为参数传递给模板方法
- 通过函数指针定义类范围之外的方法
- 模板方法访问正向声明的类仅在没有此指针的情况下无法编译
- 如何访问由共享指针保存的类方法?
- 初始化指向类实例的智能指针并访问其方法
- 我无法使用C++指针指向类方法返回的 std::vector
- 如何在工厂方法中返回指向基于基础操作系统的派生类的有效指针
- 有没有将变量名称转换为双指针的简短方法?
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 如何在成为指向基类的指针后保留对子类方法的使用?
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 类指针方法崩溃程序
- 证明两指针方法有效(对和)
- Qt 删除指针方法
- 我如何将一些类的指针方法转换为指针函数