如何解决指针错误-即使我认为它已初始化,也“使用未初始化的值”? 旧代码:修改后的代码:编辑数组代码:
我正在谈论这段代码:
#include <iostream>
using namespace std;
void citire(int& n,int* a)
{
cin >> n;
a = new int[100];
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
}
int main()
{
int n,*a;
citire(n,a);
for (int i = 0; i < n; i++)
{
cout << *a << " ";
}
return 0;
}
我收到一个错误消息,说a
未初始化,我似乎不明白为什么。我在该函数中使用了a = new int[100]
,并且a
是一个指针,所以无论在哪里初始化它都无所谓(只要在使用它的值之前就可以了)。
如果我在citire(n,a)
中的函数调用int main()
之前添加该行,则代码将起作用。
我可能想到的唯一产生错误的原因是函数中发生了初始化。因此,如果我不打电话给citire(n,a)
,那么a
将会被初始化。这是错误的原因吗?
还是我为什么要得到它?
编辑:
之所以出现混乱,是因为我知道数组基本上是指针,并且在将数组作为参数传递时是这样的:
#include <iostream>
using namespace std;
void citire(int& n,int a[])
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
}
int main()
{
int n;
int a[100];
citire(n,a);
for (int i = 0; i < n; i++)
{
cout << *a << " ";
}
return 0;
}
我不需要通过引用传递它-创建了浅表副本。
为什么默认情况下数组会发生这种情况,但指针却不会发生这种情况? (尽管现在很清楚为什么我的程序崩溃了。)
解决方法
我修复了您的代码,并打印了一些地址,供您理解。
旧代码:
#include <iostream>
using namespace std;
void citire(int& n,int* a)
{
cin >> n;
a = new int[100];
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
cout << "In citire Address of a = " << &a <<endl;
cout << "In citire Address of n = " << &n <<endl;
}
int main()
{
int n,*a;
cout << "Address of a = " << &a <<endl;
cout << "Address of n = " << &n <<endl;
citire(n,a);
for (int i = 0; i < n; i++)
{
cout << *a << " ";
}
return 0;
}
输出:
Address of a = 0x7ffee5ab6b90
Address of n = 0x7ffee5ab6b98
5
1 2 3 4 5
In citire Address of a = 0x7ffee5ab6b50
In citire Address of n = 0x7ffee5ab6b98
0 0 0 0 0
请注意a
中和n
函数内部的变量main()
和citire()
的地址。
修改后的代码:
#include <iostream>
using namespace std;
void citire(int &n,int* &a)
{
cin >> n;
a = new int[n];
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
cout << "In citire Address of a = " << &a <<endl;
cout << "In citire Address of n = " << &n <<endl;
}
int main()
{
int n,*a;
cout << "Address of a = " << &a <<endl;
cout << "Address of n = " << &n <<endl;
citire(n,a);
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
delete [] a;
return 0;
}
输出:
Address of a = 0x7ffee0eb1b90
Address of n = 0x7ffee0eb1b98
5
1 2 3 4 5
In citire Address of a = 0x7ffee0eb1b90
In citire Address of n = 0x7ffee0eb1b98
1 2 3 4 5
请注意,在这种情况下,n
和a
的地址在函数内部以及在main
中都是相同的。由于它们是passed by reference
,因此实际变量(只是别名)在存储位置不变的情况下传递,对它们所做的任何更改也将反映在main
中。
关键点:除非您强制pointers
传递value
,否则reference
也会传递给函数!
编辑(数组代码):
#include <iostream>
using namespace std;
void citire(int& n,int a[])
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
cout << "In citire Address of a = " << &a <<endl;
cout << "In citire Address of n = " << &n <<endl;
cout << "In citire Address of first element of a = " << &a[0] <<endl;
}
int main()
{
int n;
int a[100];
cout << "Address of a = " << &a <<endl;
cout << "Address of n = " << &n <<endl;
cout << "Address of first element of a = " << &a[0] <<endl;
citire(n,a);
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
return 0;
}
输出:
Address of a = 0x7ffeef1cda00
Address of n = 0x7ffeef1cd9f8
Address of first element of a = 0x7ffeef1cda00
5
1 2 3 4 5
In citire Address of a = 0x7ffeef1cd9b0
In citire Address of n = 0x7ffeef1cd9f8
In citire Address of first element of a = 0x7ffeef1cda00
1 2 3 4 5
请注意,在array
的情况下,即使它们是按值传递的,从某种意义上说,a
的地址在函数调用中也会改变,该区域的地址(即100静态声明的整数),基本上数组的第一个元素(&a[0]
)的地址不变。这样想吧:
- 您有一个黑匣子,其中存储着一个数字,该数字是
a[0]
的地址,它是a
指向的实际区域。 - 现在说黑匣子本身有一个标识号
XXX
。 - 在函数调用期间,您将黑匣子
XXX
的内容放入另一个黑匣子中,例如带有标识号YYY
。 - 无法理解
YYY
具有相同的尖头区域,即&a[0]
。 - 您可以将新的
YYY
黑盒交付使用,该功能使用和操纵以&a[0]
开头的区域中的数据。
因此您将结果反映在main()
中。另外请注意,array
和pointer
类型不同。
我认为您应该进一步了解如何在C函数中传递参数。
首先,尽管a
是一个指针,但是它的内存分配发生在citire()
中,其中为a分配了新的内存地址。
但是a作为值传递到citire()
中。
当程序返回到main()
时,您仍具有先前的值a
。
第二,如果将未初始化的指针传递给函数,则编译器会警告您,因为它假定您将使用指针(e.g. *a = 8
),并且由于未初始化,可能导致崩溃。
您最好更改函数原型:
int * cintire(int& n);
void cintire(int& n,int *& a);
Z。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。