QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: zy_sunshine

一个C++编程问题 用&方式传递字符串数组

[复制链接]
 楼主| 发表于 2009-12-8 14:12:38 | 显示全部楼层
继续引申,下面是模板的实现方式,但是这里的 模板也太强大了吧?
  1. template <typename T, size_t M, size_t N>
  2. void print(const T (& r)[M][N]) {
  3.     cout << "\nthis is the output of template function:" << endl;
  4.     for (size_t i = 0; i < M; ++i) {
  5.         for(size_t j=0; j< N; ++j) {
  6.             cout << r[i][j] << "   ";
  7.         }
  8.         cout << endl;
  9.     }
  10. }
  11. 在vc,也就是微软的编译器下编译不能通过,gnu编译器下正常。不知道是不是没有C++特性的问题,看样要升级一下VC了。
  12. D:\Program Files\Microsoft Visual Studio\MyProjects\give_string\give_string.cpp(28) : error C2265: '<Unknown>' : reference to a zero-sized array is illegal
  13. D:\Program Files\Microsoft Visual Studio\MyProjects\give_string\give_string.cpp(28) : error C2087: '<Unknown>' : missing subscript
复制代码

[ 本帖最后由 zy_sunshine 于 2010-3-12 20:53 编辑 ]
回复

使用道具 举报

发表于 2009-12-8 18:12:11 | 显示全部楼层
c++ 编译器不允许 c++ 语言使用 c99 标准....

gcc main.c -o main -std=c99
  1. #include <stdio.h>
  2. #include <string.h>

  3. void pass_str1(int m, int n, char* str[m][n])
  4. {
  5.     printf( "this is the function & output:\n" );
  6.    
  7.     for(int i=0; i<m; ++i)
  8.     {
  9.         for(int j=0; j<n; ++j){
  10.             if(j==0){
  11.                 printf( "\n" );
  12.             }
  13.             printf( "%s  ", str[i][j] );
  14.         }
  15.     }
  16. }

  17. int main()
  18. {
  19.     const char name[] = "name";
  20.     char x[] = "0 0";
  21.     char y[] = "11 11";
  22.     char z[] = "000";

  23.     char* ia[12][12] = {0};

  24.     for(int k=0; k<12; ++k)
  25.     {
  26.         ia[0][k]=x;
  27.     }
  28.     for(int k=0; k<12; ++k)
  29.     {
  30.         ia[11][k]=y;
  31.     }
  32.     for(int i=1; i<11; ++i)
  33.     {
  34.         for(int j=1; j<11; ++j)
  35.             ia[i][j]=z;
  36.     }

  37.     pass_str1( 12, 12, ia );

  38.     return 0;
  39. }
复制代码
回复

使用道具 举报

发表于 2009-12-8 18:20:49 | 显示全部楼层
模板非常强大,c++ 比较困难的东西.....
回复

使用道具 举报

 楼主| 发表于 2009-12-8 21:50:51 | 显示全部楼层

回复 17# nihui 的帖子

yeah ,nihui写的很漂亮哈
回复

使用道具 举报

 楼主| 发表于 2009-12-8 22:21:09 | 显示全部楼层
原来还有C有而C++没有的,这个C99标准我一直是理解错的,以为是C++的
回复

使用道具 举报

发表于 2009-12-9 00:06:02 | 显示全部楼层
还是认为不应该用string数组来管理字符串列表。

[ 本帖最后由 haulm 于 2009-12-9 00:10 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2009-12-9 00:29:51 | 显示全部楼层
感觉用string管理字符串列表更C++化

我用vector做了一下,出现问题,二维vector的iterator没法遍历
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <sstream>
  5. using namespace std;

  6. //二维vector的 iterator不知道怎么遍历了
  7. void pass_str4(const vector<vector<string> >::iterator &it_begin, const vector<vector<string> >::iterator &it_end)
  8. {
  9.         cout << endl;
  10.         cout << "this is the function vector output:" << endl;

  11.         vector<vector<string> >::iterator it = it_begin;
  12.         for(int i=0; it != it_end; ++it, ++i){
  13.                 for (int j=0; j < it[i].size(); ++j){
  14.                         cout << it[i][j] << "   ";
  15.                 }
  16.                 cout << endl;
  17.         }
  18. }

  19. int main(int argc, char* argv[])
  20. {
  21.         string ia[12][12];
  22.         stringstream i_strm;
  23.         stringstream j_strm;

  24.         for(int i=0; i<12; ++i)
  25.         {
  26.             i_strm.clear();//重置流的状态标志
  27.             i_strm.str("");//清空流内容
  28.             i_strm << i;
  29.             for(int j=0; j<12; ++j){
  30.                  j_strm.clear();
  31.                  j_strm.str("");
  32.                  j_strm << j;
  33.                  ia[i][j]=i_strm.str()+" "+j_strm.str();
  34.             }
  35.         }


  36.         vector<vector<string> > vec_str(12, vector<string>(12));
  37.         for(i=0; i < vec_str.size(); i++){
  38.                 for(int j=0; j < vec_str[i].size(); j++){
  39.                         vec_str[i][j]=ia[i][j];
  40.                 }
  41.         }

  42. pass_str4(vec_str.begin(), vec_str.end());



  43.         for(int i=0; i < 12; ++i){                //输出二维vector
  44.         for(int j=0; j < 12; ++j){
  45.             cout << vec_str[i][j] << "   ";
  46.         }
  47.         cout << endl;
  48.     }

  49.         return 0;
  50. }
复制代码
结果:
  1. 0 0   0 1   0 2   0 3   0 4   0 5   0 6   0 7   0 8   0 9   0 10   0 11
  2. 2 0   2 1   2 2   2 3   2 4   2 5   2 6   2 7   2 8   2 9   2 10   2 11
  3. 4 0   4 1   4 2   4 3   4 4   4 5   4 6   4 7   4 8   4 9   4 10   4 11
  4. 6 0   6 1   6 2   6 3   6 4   6 5   6 6   6 7   6 8   6 9   6 10   6 11
  5. 8 0   8 1   8 2   8 3   8 4   8 5   8 6   8 7   8 8   8 9   8 10   8 11
  6. 10 0   10 1   10 2   10 3   10 4   10 5   10 6   10 7   10 8   10 9   10 10   10 11
复制代码
看样是对iterator的理解不到位了

[ 本帖最后由 zy_sunshine 于 2009-12-9 00:37 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2009-12-9 00:34:00 | 显示全部楼层
halm给个管理二维string的实例看看?
回复

使用道具 举报

发表于 2009-12-9 08:25:53 | 显示全部楼层

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <sstream>
  5. using namespace std;

  6. void pass_str4(const vector< vector<string> >::const_iterator &it_begin, const vector< vector<string> >::const_iterator &it_end)
  7. {
  8.     cout << "this is the function vector output:" << endl;
  9.    
  10.     vector<vector<string> >::const_iterator it1 = it_begin;
  11.     vector<vector<string> >::const_iterator it1_end = it_end;
  12.     for( ; it1 != it1_end; ++it1 ) {
  13.         // it1 is an iterator, *it1 is the vector<string> of vector< vector<string> >
  14.         vector<string>::const_iterator it2 = (*it1).begin();
  15.         vector<string>::const_iterator it2_end = (*it1).end();
  16.         for ( ; it2 != it2_end; ++it2 ) {
  17.             // it2 is an iterator, *it2 is the string of vector<string>
  18.             cout << *it2 << '\t';
  19.         }
  20.         cout << endl;
  21.     }
  22. }

  23. int main(int argc, char* argv[])
  24. {
  25.     string ia[12][12];
  26.     stringstream i_strm;
  27.     stringstream j_strm;
  28.    
  29.     for(int i=0; i<12; ++i)
  30.     {
  31.         i_strm.clear();
  32.         i_strm.str("");
  33.         i_strm << i;
  34.         for(int j=0; j<12; ++j){
  35.             j_strm.clear();
  36.             j_strm.str("");
  37.             j_strm << j;
  38.             ia[i][j]=i_strm.str()+" "+j_strm.str();
  39.         }
  40.     }
  41.    
  42.     // represent array as vector
  43.     vector< vector<string> > vec_str(12, vector<string>(12));
  44.     for(int i=0; i < vec_str.size(); i++){
  45.         for(int j=0; j < vec_str[i].size(); j++){
  46.             vec_str[i][j]=ia[i][j];
  47.         }
  48.     }
  49.    
  50.     pass_str4(vec_str.begin(), vec_str.end());
  51.    
  52.     // print vector content
  53.     for(int i=0; i < 12; ++i){
  54.         for(int j=0; j < 12; ++j){
  55.             cout << vec_str[i][j] << '\t';
  56.         }
  57.         cout << endl;
  58.     }
  59.    
  60.     return 0;
  61. }

复制代码
回复

使用道具 举报

 楼主| 发表于 2009-12-9 09:22:16 | 显示全部楼层

回复 24# nihui 的帖子

感激涕零,回去看书写代码了......
回复

使用道具 举报

发表于 2009-12-10 12:12:49 | 显示全部楼层
学习了。
回复

使用道具 举报

发表于 2009-12-10 13:11:11 | 显示全部楼层
原帖由 zy_sunshine 于 2009-12-9 09:22 发表
感激涕零,回去看书写代码了......:P
:shock:

我把你的代码整理了一下,要不我看得头晕目炫。
函数体里没分配内存时运行打印非常慢,所以pass_str3的方式值得推敲。
疑问是,如果我用的不是string数组,而是char数组的话,是否也存在这种问题呢。
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. void pass_str1(const string str[12][12])  //这个值传的
  5. {
  6.         cout << endl;
  7.         cout << "this is the function output:" << endl;
  8.       
  9.         for(int i=0; i<12; ++i)
  10.         {
  11.                 for(int j=0; j<12; ++j){
  12.                         if(j==0){
  13.                                 cout << endl;
  14.                         }
  15.                         cout << str[i][j] << "   " ;
  16.                 }
  17.         }
  18. }

  19. void pass_str2(const string* str)       //这个传的首地址,但是发现,如果string数组元素没有赋值是不会分配内存的,输出上有点小麻烦。
  20. {
  21.         cout << *(str+12*12-1) << endl;
  22. }

  23. void pass_str3(int m, int n, string (& str)[12][12])
  24. {
  25.         cout << endl;
  26.         cout << "this is the function & output:" << endl;

  27.         for(int i=0; i<m; ++i)
  28.         {
  29.                 for(int j=0; j<n; ++j){
  30.                         if(j==0){
  31.                                 cout << endl;
  32.                         }
  33.                         cout << str[i][j] << "   " ;
  34.                 }
  35.         }
  36. }

  37. int main(int argc, char* argv[])
  38. {
  39.         string name("name");
  40.         string ia[12][12];
  41.         for(int k=0; k<12; ++k)
  42.         {
  43.                 for(int s=0; s<12; ++s){
  44.                 ia[k][s]="abcd";
  45.         }
  46. }
  47.         cout<<ia[11][11];
  48.         pass_str1(ia);
  49.         pass_str1(&ia[0]);
  50.         pass_str2(ia[0]);
  51.         pass_str2(&ia[0][0]);
  52.         pass_str3(10,12,ia);
  53.          return 0;
  54. }
复制代码

[ 本帖最后由 haulm 于 2009-12-10 13:41 编辑 ]
回复

使用道具 举报

发表于 2009-12-10 13:47:07 | 显示全部楼层
nihui 的代码 void pass_str3(int m, int n, string (& str)[m][n])
这样的写法是不被允许的                                   
a.cpp:4: 错误:数组边界不是一个整数常量
回复

使用道具 举报

 楼主| 发表于 2009-12-10 19:01:07 | 显示全部楼层

回复 27# haulm 的帖子

传值这东西如果 调用频率不想inline这么频繁的话   应该没什么问题。

传值过去的时候在堆栈中已经压入string数组的值,相当于已经分配内存了,在函数返回平衡堆栈的时候会清除这些传入变量。

进入函数前的堆栈
main(int 1, char * * 0x003812c0) line 52 + 12 bytes
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 7c817077()

进入函数后的堆栈
pass_str1(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > [12]* 0x0012f664) line 5
main(int 1, char * * 0x003812c0) line 52 + 12 bytes
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 7c817077()

这个是在vc里面看到的堆栈,我猜的。。没有看反汇编的程序还不能确定(俺的汇编基本功也不行)。

nnd,明天考试,金融的,整本书都还没看呢,去自习了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-4-26 16:01 , Processed in 0.284480 second(s), 12 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表