数组作为函数参数进行传递
今天编程序时发生了个这样的错误:
在头文件里 定义了一个数组:
1 char s[]="1234567890";
又定义了一个现显示组的函数:
1 void Display(char* c);
通过下面这两条语句分别在现实函数和主函数中现实数组的大小:
1 sizeof(c);
2 sizeof(s);
现实结果却大相径庭,在主函数中为11,在现实函数中却为4。
经过思考发现,在主函数中s代表的是一个数组,而在现实函数中c代表的是一个指向数组头的指针。数组的大小为11,指针的大小为4。
主程序如下:
1 #include<iostream>
2 #include<stdlib.h>
3 using namespace std;
4
5 char s[]="1234567890";
6 void Display(char* c);
7
8 void main()
9 {
10 char a;
11 cout<<"这个是在主函数中对数组长度的测试:"<<sizeof(s)<<endl;
12 Display(s);
13 cin>>a;
14 }
15
16
17 void Display(char* c)
18 {
19 cout<<"这个是在子函数中对数组长度的测试:"<<sizeof(c)<<endl;
20 }
现实结果:
我的问题是怎样可以在主函数和子函数中都指的是数组而不是一个指向数组头的指针???
在网上查了几种将数组作为函数参数进行传递的方法,列举如下:
1 #include<iostream>
2 #include<stdlib.h>
3 #include<vector>
4 using namespace std;
5
6 char s[]="1234567890";
7 int a[10]={0,1};
8 int b[10]={0,1};
9 void Display(char* c);
10 void PutArray1(int *p,int length1);
11 void PutArray2(int p[],int length1);
12 void PutArray3(int p[10]);
13 void PutArray4(int (&p)[10]);
14 void PutArray5(vector<int>verc);
15
16 void main()
17 {
18 char q;
19 cout<<"这个是在主函数中对数组长度的测试:"<<sizeof(s)<<endl;
20 Display(s);
21 cout<<"*********************************************"<<endl;
22 PutArray1(a,10);
23 PutArray2(a,10);
24 PutArray3(a);
25 PutArray4(b);
26 cin>>q;
27 }
28
29
30 void Display(char* c)
31 {
32 cout<<"这个是在子函数中对数组长度的测试:"<<sizeof(c)<<endl;
33 }
34 void PutArray1(int *p,int length1)
35 {
36 int length2=sizeof(p);
37 cout<<"第一种方法的输出:"<<endl;
38 cout<<"第一种方法数组的长度为:"<<length2<<endl;
39 for(int i=0;i<length1;i++)
40 {
41 cout<<p[i];
42 }
43 cout<<endl;
44 }
45 void PutArray2(int p[],int length1)
46 {
47 int length2=sizeof(p);
48 cout<<"第二种方法的输出:"<<endl;
49 cout<<"第二种方法数组的长度为:"<<length2<<endl;
50 for(int i=0;i<length1;i++)
51 {
52 cout<<p[i];
53 }
54 cout<<endl;
55 }
56 void PutArray3(int p[10])
57 {
58 int length2=sizeof(p);
59 cout<<"第三种方法的输出:"<<endl;
60 cout<<"第三种方法数组的长度为:"<<length2<<endl;
61 for(int i=0;i<9;i++)
62 {
63 cout<<p[i];
64 }
65 cout<<endl;
66 }
67 void PutArray4(int (&p)[10])
68 {
69 int length2=sizeof(p);
70 cout<<"第四种方法的输出:"<<endl;
71 cout<<"第四种方法数组的长度为:"<<length2<<endl;
72 for(int i=0;i<9;i++)
73 {
74 cout<<p[i];
75 }
76 cout<<endl;
77 }
78 void PutArray5(vector<int>verc)
79 {
80 vector<int>::iterator begin_iter=verc.begin();
81 vector<int>::iterator end_iter=verc.end();
82 int size=verc.size();
83 cout<<"第五种方法的输出:"<<endl;
84 cout<<"第五种方法数组的长度为:"<<size<<endl;
85 cout<<"下面这种方法是采用向量遍历的方法遍历数组:"<<endl;
86 for(vector<int>::iterator iter=begin_iter;iter!=end_iter;iter++)
87 {
88 cout<<*iter;
89 }
90 cout<<endl;
91 cout<<"下面这种方法是采用普通遍历数组的方法遍历数组:"<<endl;
92 for(int i=0;i<size-1;i++)
93 {
94 cout<<verc[i];
95 }
96 cout<<endl;
97 }
在这里,int *arr和int arr[]的含义相同,编译器自动将 int arr[]替换为int *arr,所以这也解释了上面在主函数和子函数中利用数组名求数组长度会得到不同结果的原因。这种情况只有在数组作为函数参数进行传递时才会发生(C++ Primer Plus,P192)。
其中第四种方法没有理解,疑问暂时留在这里吧。
另外虽然上面四种方法都可以正确地在子函数中传递数组作为参数,但是仍然不能满足博客刚开始的要求:在子函数中可以测的参数数组的长度。后来查看C++ Primer Plus发现书上已经明确指出没有实现这种想法的方法,数组的长度必须在函数中作为参数进行传递。
另外由于第五种方法需要重新定义向量模版,和主题不符,所以在主函数里并没有调用它。例程中给的程序如下所示:
1 vector<int> verc1(a,a+10);
2 vector<int> verc2(b,b+8);
3 PutArray5(verc1);
4 PutArray5(verc2);
上面这五种调用数组的方法只是在传递数组的方式上不同,可以归纳为传递数组的一种方法,即:传递指向数组头的指针和数组的长度。另外一种传递数组的方法是将指向数组头的指针和指向数组尾的指针作为两个参数进行传递,函数定义如下:
1 int sum_arr(const int* begin,const int* end);
在学习这个知识点时是有一些感想的,虽说C++ Primer已经看了一遍,里面的知识点也认真地消化过,但是一到用的时候就使不上劲。看来应该在看书的同时多实践书上的代码,这样才能对代码的应用有更好的理解。