C++ pointer/for-loop 混乱
C++ pointer/for-loop confusion
我正在尝试编写一个程序,使用指针从 cin 中读取值,然后输出这些值及其在数组中的位置。我不明白为什么 printNumbers1 有效但 printNumbers2 无效。这是程序(底部附近的相关代码):
#include <iostream>
using namespace std;
int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);
int main()
{
int *numbers = readNumbers(5);
printNumbers1(numbers);
printNumbers2(numbers);
return 0;
}
int *readNumbers(int n)
{
int a[n];
int *numbers;
numbers = &a[0];
for (int i=0; i<n; i++)
{
cin >> *(numbers+i);
}
return numbers;
}
void printNumbers1(int *numbers)
{
cout << 0 << ' ' << *(numbers) << endl
<< 1 << ' ' << *(numbers+1) << endl
<< 2 << ' ' << *(numbers+2) << endl
<< 3 << ' ' << *(numbers+3) << endl
<< 4 << ' ' << *(numbers+4) << endl;
}
void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
cout << i << ' ' << *(numbers+i) << endl;
}
}
当我 运行 程序时,它按 printNumbers1 的预期工作,但为 printNumbers2 输出看似随机数和 0 的组合。我觉得这两个 printNumbers 函数应该具有相同的功能,但事实并非如此。我错过了什么?
发生这种情况是因为两件事的结合:
- C++ 不允许可变长度数组 - 这是一个流行的扩展,但声明
int a[n]
不标准。
- 您不能 return 从函数指向局部变量的指针 -
readNumbers
中的指针 numbers
指向 a
, 一个局部变量。您可以在函数内部使用此指针,但在函数外部它变得无效,因为 a
超出范围。
使用范围外的变量会导致未定义的行为。 This Q&A 很好地解释了正在发生的事情,以及为什么程序看起来运行良好。
如果你想使用内置指针,去掉int a[n]
,然后改变numbers
的声明如下:
int *numbers = new int[n];
您还需要添加
delete[] numbers;
在 return 0
行之前以避免内存泄漏。
我假设您在学习练习中编写了这段代码。不过,一般来说,C++ 中更好的方法是使用 std::vector<int>
,它在代码中隐藏指针操作,并为您处理资源管理。
readNumbers returns 一个指向具有自动存储持续时间的变量的指针。
取消引用该指针的行为未定义。
改用std::vector。依靠 return 值优化来避免获取任何多余的值副本。
这里你在函数内部创建了数组a[n],所以它是一个局部变量,因此这个数组可能会也可能不会在函数范围ends.Never使用地址后被删除函数外的局部变量。此代码有效:
#include <iostream>
using namespace std;
int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);
int main()
{
int *numbers = readNumbers(5);
printNumbers1(numbers);
printNumbers2(numbers);
return 0;
}
int *numbers;
int *readNumbers(int n)
{
numbers = new int[n];
for (int i=0; i<n; i++)
{
cin >> *(numbers+i);
}
return numbers;
}
void printNumbers1(int *numbers)
{
cout << 0 << ' ' << *(numbers) << endl
<< 1 << ' ' << *(numbers+1) << endl
<< 2 << ' ' << *(numbers+2) << endl
<< 3 << ' ' << *(numbers+3) << endl
<< 4 << ' ' << *(numbers+4) << endl;
}
void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
cout << i << ' ' << *(numbers+i) << endl;
}
}
我正在尝试编写一个程序,使用指针从 cin 中读取值,然后输出这些值及其在数组中的位置。我不明白为什么 printNumbers1 有效但 printNumbers2 无效。这是程序(底部附近的相关代码):
#include <iostream>
using namespace std;
int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);
int main()
{
int *numbers = readNumbers(5);
printNumbers1(numbers);
printNumbers2(numbers);
return 0;
}
int *readNumbers(int n)
{
int a[n];
int *numbers;
numbers = &a[0];
for (int i=0; i<n; i++)
{
cin >> *(numbers+i);
}
return numbers;
}
void printNumbers1(int *numbers)
{
cout << 0 << ' ' << *(numbers) << endl
<< 1 << ' ' << *(numbers+1) << endl
<< 2 << ' ' << *(numbers+2) << endl
<< 3 << ' ' << *(numbers+3) << endl
<< 4 << ' ' << *(numbers+4) << endl;
}
void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
cout << i << ' ' << *(numbers+i) << endl;
}
}
当我 运行 程序时,它按 printNumbers1 的预期工作,但为 printNumbers2 输出看似随机数和 0 的组合。我觉得这两个 printNumbers 函数应该具有相同的功能,但事实并非如此。我错过了什么?
发生这种情况是因为两件事的结合:
- C++ 不允许可变长度数组 - 这是一个流行的扩展,但声明
int a[n]
不标准。 - 您不能 return 从函数指向局部变量的指针 -
readNumbers
中的指针numbers
指向a
, 一个局部变量。您可以在函数内部使用此指针,但在函数外部它变得无效,因为a
超出范围。
使用范围外的变量会导致未定义的行为。 This Q&A 很好地解释了正在发生的事情,以及为什么程序看起来运行良好。
如果你想使用内置指针,去掉int a[n]
,然后改变numbers
的声明如下:
int *numbers = new int[n];
您还需要添加
delete[] numbers;
在 return 0
行之前以避免内存泄漏。
我假设您在学习练习中编写了这段代码。不过,一般来说,C++ 中更好的方法是使用 std::vector<int>
,它在代码中隐藏指针操作,并为您处理资源管理。
readNumbers returns 一个指向具有自动存储持续时间的变量的指针。
取消引用该指针的行为未定义。
改用std::vector。依靠 return 值优化来避免获取任何多余的值副本。
这里你在函数内部创建了数组a[n],所以它是一个局部变量,因此这个数组可能会也可能不会在函数范围ends.Never使用地址后被删除函数外的局部变量。此代码有效:
#include <iostream>
using namespace std;
int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);
int main()
{
int *numbers = readNumbers(5);
printNumbers1(numbers);
printNumbers2(numbers);
return 0;
}
int *numbers;
int *readNumbers(int n)
{
numbers = new int[n];
for (int i=0; i<n; i++)
{
cin >> *(numbers+i);
}
return numbers;
}
void printNumbers1(int *numbers)
{
cout << 0 << ' ' << *(numbers) << endl
<< 1 << ' ' << *(numbers+1) << endl
<< 2 << ' ' << *(numbers+2) << endl
<< 3 << ' ' << *(numbers+3) << endl
<< 4 << ' ' << *(numbers+4) << endl;
}
void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
cout << i << ' ' << *(numbers+i) << endl;
}
}