C++ 带双精度的紧凑指针表示法
快速提问。当您访问字符数组时,我知道您可以将指针设置为数组中的第一个元素,然后使用while look并执行以下操作C++ 带双精度的紧凑指针表示法,c++,pointers,C++,Pointers,快速提问。当您访问字符数组时,我知道您可以将指针设置为数组中的第一个元素,然后使用while look并执行以下操作 while (*ptr != '\0') { do something } 现在有double或int等价物吗 #define ARRAY_SIZE 10 double someArray[ARRAY_SIZE] = {0}; double *ptr = someArray; // then not sure what to do here? I guess I am
while (*ptr != '\0') {
do something
}
现在有double或int等价物吗
#define ARRAY_SIZE 10
double someArray[ARRAY_SIZE] = {0};
double *ptr = someArray;
// then not sure what to do here? I guess I am looking for an equivalent of the above while loop, but don't want to just do:
for (int i = 0; i < ARRAY_SIZE); *ptr++)
cout << *ptr;
#定义数组大小10
双数组[ARRAY_SIZE]={0};
double*ptr=someArray;
//那我不知道该怎么办?我想我正在寻找上述while循环的等价物,但我不想只做:
for(int i=0;i<数组大小)*ptr++)
cout除非您能保证数组中不会出现特定值(例如以空结尾的字符串中的“0”字节),否则在不存储数组大小的情况下,没有通用的方法可以知道数组的大小 是的,在双精度数组中有完全相同的指针表示法
以下是您的程序的更正版本:
#include <iostream>
#define ARRAY_SIZE 10
int main(void) {
double someArray[ARRAY_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
double *ptr = someArray;
for (int i = 0; i < ARRAY_SIZE; i++, *ptr++)
std::cout << *ptr;
}
如果我理解正确,您希望遍历数组并在*ptr具有特定值时停止。这并不总是可能的。对于字符数组(字符串),一个常见的约定是将字符串“以null结尾”;也就是说,它的末尾将有一个0字节('\0')。您可以将这样一个哨兵添加到int或双值数组中(如果您可以挑出一个“特殊”的值,否则将不会使用),但这不是一种普遍适用的技术
顺便说一下,for循环可能不是您想要的:
for(int i=0;i<数组大小)*ptr++)
如果要遍历数组,则需要增加指针(ptr++),而不是它所指向的值(*ptr++)。对于C样式字符串,惯例是字符串以0
结尾。这意味着在C样式字符串中不能有0
如果您有一个不需要的double
值,您可以将其存储在数组的末尾,并进行检查。例如,您可能可以使用0
,或NaN(不是数字)。了解如何在中或中使用NaN。如果确实使用非NaN数作为哨兵,则在比较浮点数是否相等之前,应先阅读
当然,既然你在使用C++,而且你不想记住数组的大小,你应该考虑使用<代码> STD::vector < /C> >。
< p>你不清楚你在寻找什么。
第一个循环(“字符数组”版本)的结构取决于这样一个事实,即您不是使用抽象字符数组,而是使用驻留在该数组中的C字符串。C字符串是以零字符结尾的字符序列(在数组中)。此零字符是结束第一个周期的字符
使用显式指针处理double
数组没有问题。在第二个示例中,您是自己做的(尽管有错误)。如果您的double
数组具体包含一系列以0.0
值结尾的double
值,那么您的double
循环甚至可能看起来与char
循环完全相同
double *ptr = someArray;
while (*ptr != 0.0)
cout << *ptr++;
或
for(double*ptr=someArray,*ptr\u end=ptr+ARRAY\u SIZE;ptr!=ptr\u end;++ptr)
cout在C中,根据定义,字符串以'\0'字符结尾。有一个特殊值(在本例中为“\0”字符)表示序列的结束,有时称为使用哨兵。在其他数据结构中使用Sentinel并不少见,但它决不是通用的
如果有一组以已知值结尾的int或double,则可以使用类似于遍历字符串中的字符直到碰到“\0”的技术遍历该序列。问题是,您必须确保它以sentinel正确终止的序列,并且您的sentinel不能是您可能在序列中作为实际数据段找到的值
常见的哨兵值包括:
- 0(零)
- -一,
- 最大值
但您可以使用对应用程序有意义的任何东西。假设您的应用程序只处理非负双精度,您可以使用负值作为哨兵:
double *ptr = someArray;
while (*ptr >= 0.0) {
cout << *ptr;
++ptr;
}
double*ptr=someArray;
而(*ptr>=0.0){
cout(这里没有其他答案中没有提到的新内容,但我将尝试简洁地提供解释和示例,而不会失去清晰度。)
在字符数组中循环检查'\0'
是有效的,因为C样式字符串有一个约定,int、double和大多数其他类型都没有:null终止。(该'\0'
字符称为“null”或“NUL”,但很少称为“null”,以避免与该名称的宏混淆。)
由于int和double数组没有此约定,因此必须使用其他方法。以下是最简单的替代方法:
// pass arrays with their size
void ex1(double const* data, int size) {
for (int n = 0; n < size; ++n) {
use(data[n]);
}
}
// use a container class which has a size() method
void ex2(vector<double> const& v) {
for (int n = 0; n < v.size(); ++n) {
use(data[n]);
}
// or:
for (vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
use(*i);
}
// or, sometimes a slight tweak:
for (vector<double>::const_iterator i = v.begin(), end = v.end();
i != end; ++i
) {
use(*i);
}
}
// pass an iterator range, once you are familiar with iterators
void ex3(double const* begin, int const* end) {
for (double const* i = begin; i != end; ++i) {
use(*i);
}
}
//传递数组及其大小
void ex1(双常量*数据,整数大小){
用于(int n=0;n
以及如何使用它们:
void ex4() {
double data[] = {3, 5, 42}; // if you don't want to specify the size, then use
int length = len(data); // this special len function to get the array length
// len defined below
ex1(data, length); // easy to pass with size now
ex2(vector<double>(data, data + length)); // easy to create a container too
ex3(data, data + length);
// notice the container creation takes a similar iterator range
double buncha_zeros[42] = {}; // or even if you specify the length
length = len(buncha_zeros); // you still don't have to repeat yourself
}
template<class T, int N>
N len(T (&)[N]) {
return N;
}
// note: this exists in boost in a better, more general form as boost::size
void ex4(){
double data[]={3,5,42};//如果不想指定大小,请使用
int length=len(data);//此特殊的len函数用于获取数组长度
//len定义如下
ex1(数据,长度);//现在很容易通过大小传递
ex2(vector(data,data+length));//创建容器也很容易
ex3(数据,数据+长度);
//注意,容器的创建采用了类似的迭代器r
double *ptr;
for (unsigned i = 0, ptr = someArray; i < ARRAY_SIZE; ++i, ++ptr)
cout << *ptr;
double *ptr = someArray;
while (*ptr >= 0.0) {
cout << *ptr;
++ptr;
}
// pass arrays with their size
void ex1(double const* data, int size) {
for (int n = 0; n < size; ++n) {
use(data[n]);
}
}
// use a container class which has a size() method
void ex2(vector<double> const& v) {
for (int n = 0; n < v.size(); ++n) {
use(data[n]);
}
// or:
for (vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
use(*i);
}
// or, sometimes a slight tweak:
for (vector<double>::const_iterator i = v.begin(), end = v.end();
i != end; ++i
) {
use(*i);
}
}
// pass an iterator range, once you are familiar with iterators
void ex3(double const* begin, int const* end) {
for (double const* i = begin; i != end; ++i) {
use(*i);
}
}
void ex4() {
double data[] = {3, 5, 42}; // if you don't want to specify the size, then use
int length = len(data); // this special len function to get the array length
// len defined below
ex1(data, length); // easy to pass with size now
ex2(vector<double>(data, data + length)); // easy to create a container too
ex3(data, data + length);
// notice the container creation takes a similar iterator range
double buncha_zeros[42] = {}; // or even if you specify the length
length = len(buncha_zeros); // you still don't have to repeat yourself
}
template<class T, int N>
N len(T (&)[N]) {
return N;
}
// note: this exists in boost in a better, more general form as boost::size