使用指针动态数组同时输出整数值列表?
Output a list of integer values at the same time by using a pointer dynamic array?
在 C++ 中,遵循以下代码:
char *p = new char();
*p = 'a';
*(p+1)= 'b';
*(p+2) ='[=10=]';
cout<<p<<endl;
我们可以得到输出结果:ab
当我想写这样的代码时:
int *p = new int();
*p = 1;
*(p+1)= 2;
cout<<p<<endl;
它给出了结果,但不是 12 或以 12 开头的东西
问题是为什么把char转integer结果出错了?如何使用指针动态数组实现输出值列表的目的?
这是因为char *
有点特殊。
在 C 时代,char *
是我们真正需要处理字符串的唯一类型。 C++ 通过提供专门处理 char *
值的流运算符,流出每个字符直到遇到空字符 ('[=16=]'
),从而更容易与遗留代码进行互操作。
当你流出 p
时它是一个 int *
没有特殊情况——你只是得到显示的原始指针值。
如果你想要单行显示标准容器中的元素,你可以结合使用 std::copy()
和 std::ostream_iterator
:
std::copy(std::begin(some_array),
std::end(some_array),
std::ostream_iterator<int>(std::cout));
由于您的数组分配在堆上并存储在指针中,因此 std::begin()
和 std::end()
对您不起作用;您必须手动提供结束迭代器:
std::copy(p, p + 2, std::ostream_iterator<int>(std::cout));
(See a demo.)
但请注意,您问题中的两个代码示例都是未定义的行为,因为您分配了 char
或 int
类型的 单个 对象,然后尝试分配 超越 它。您写入尚未分配的内存。 不要这样做。
要修复您的案例,您需要为要存储的对象分配足够的空间:
// Case one
char *p = new char[3];
// Case two
int *p = new int[2];
当然,不要忘记在这两种情况下都使用 delete[] p
——或者您可以在第一种情况下使用 std::string
,在第二种情况下使用 std::vector<int>
。
好的,首先,这是不安全的:
*(p+1)= 'b';
您只分配了一个字节,现在您正在占用不属于您的内存 - 这是未定义的行为。如果你想分配3个字节,这样做:
char* p = new char[3];
其次,这个:
int* pi = new int;
cout << pi << endl;
将打印指针的地址。 char*
的特殊之处在于 cout
实际上会打印指向的 C 风格字符串,但对于其他类型 - 您只需获取地址即可。
如果要打印 12,则必须取消引用指针:
int* pi = new int(12);
cout << *pi << endl;
如果要分别输出1和2,需要一个数组:
int* pi = new int[2];
pi[0] = 1;
pi[1] = 2;
cout << pi[0] << ", " << pi[1] << endl;
请注意,您的代码中的 *(p + 1) = 2
再次占用了您不拥有的内存。
在 C++ 中,遵循以下代码:
char *p = new char();
*p = 'a';
*(p+1)= 'b';
*(p+2) ='[=10=]';
cout<<p<<endl;
我们可以得到输出结果:ab
当我想写这样的代码时:
int *p = new int();
*p = 1;
*(p+1)= 2;
cout<<p<<endl;
它给出了结果,但不是 12 或以 12 开头的东西
问题是为什么把char转integer结果出错了?如何使用指针动态数组实现输出值列表的目的?
这是因为char *
有点特殊。
在 C 时代,char *
是我们真正需要处理字符串的唯一类型。 C++ 通过提供专门处理 char *
值的流运算符,流出每个字符直到遇到空字符 ('[=16=]'
),从而更容易与遗留代码进行互操作。
当你流出 p
时它是一个 int *
没有特殊情况——你只是得到显示的原始指针值。
如果你想要单行显示标准容器中的元素,你可以结合使用 std::copy()
和 std::ostream_iterator
:
std::copy(std::begin(some_array),
std::end(some_array),
std::ostream_iterator<int>(std::cout));
由于您的数组分配在堆上并存储在指针中,因此 std::begin()
和 std::end()
对您不起作用;您必须手动提供结束迭代器:
std::copy(p, p + 2, std::ostream_iterator<int>(std::cout));
(See a demo.)
但请注意,您问题中的两个代码示例都是未定义的行为,因为您分配了 char
或 int
类型的 单个 对象,然后尝试分配 超越 它。您写入尚未分配的内存。 不要这样做。
要修复您的案例,您需要为要存储的对象分配足够的空间:
// Case one
char *p = new char[3];
// Case two
int *p = new int[2];
当然,不要忘记在这两种情况下都使用 delete[] p
——或者您可以在第一种情况下使用 std::string
,在第二种情况下使用 std::vector<int>
。
好的,首先,这是不安全的:
*(p+1)= 'b';
您只分配了一个字节,现在您正在占用不属于您的内存 - 这是未定义的行为。如果你想分配3个字节,这样做:
char* p = new char[3];
其次,这个:
int* pi = new int;
cout << pi << endl;
将打印指针的地址。 char*
的特殊之处在于 cout
实际上会打印指向的 C 风格字符串,但对于其他类型 - 您只需获取地址即可。
如果要打印 12,则必须取消引用指针:
int* pi = new int(12);
cout << *pi << endl;
如果要分别输出1和2,需要一个数组:
int* pi = new int[2];
pi[0] = 1;
pi[1] = 2;
cout << pi[0] << ", " << pi[1] << endl;
请注意,您的代码中的 *(p + 1) = 2
再次占用了您不拥有的内存。