读书人

小弟我遇到了一个非常奇怪的异常

发布时间: 2013-08-09 15:16:24 作者: rapoo

我遇到了一个非常奇怪的错误



#include <iostream>
#include <list>
#include <cstddef>
using namespace std;

void getItem(list<int>La,list<int>::size_type i, int n)
{
list<int>::size_type k = i+1;
list<int>::iterator it = La.begin();
for (int j = 0;j<k;++j) {
++it;
}
n = *it;
//cout<< n;
}

void MergeList(list<int> La,list<int>Lb,list<int>Lc)
{
cout<<"nimabide";
list<int>::size_type i = 0,j = 0;
int ai = 0,bi = 0;cout<<bi;
list<int>::size_type La_Len = La.size();
list<int>::size_type Lb_Len = Lb.size();

while ((i<=La_Len)&&(j<=Lb_Len))
{
getItem(La,i,ai);
getItem(Lb,j,bi);
if (ai<bi)
{
Lc.push_back(ai);
i++;
}
else
{
Lc.push_back(bi);
j++;
}
}

while (i<=La_Len)
{
getItem(La, i, ai);
Lc.push_back(ai);
}
while (j<=Lb_Len)
{
getItem(Lb, j, bi);
Lc.push_back(bi);
}
}

int main(int argc, const char * argv[])
{

// insert code here...
std::cout << "Hello, World!\n";


list<int> listA = {3,5,8,11};
list<int> listB = {2,6,8,9,11,15,20};
list<int> listC(10,0);

MergeList(listA, listB , listC);

for (list<int>::iterator it = listC.begin(); it != listC.end(); ++it) {
cout<<*it;
}


return 0;
}



为谁么我那句hello world输出了,MergeList里面那句就没输出呢?
[解决办法]
引用:
Quote: 引用:


list<int> listA = {3,5,8,11}; // 三个list, 你没有一个一个的add,直接这样赋值可以么?
list<int> listB = {2,6,8,9,11,15,20};
list<int> listC(10,0);
可以的 ,直接初始化了,而且我验证过了,没问题




std::cout<<"nimabide \n";
//这样吧! 估计是在缓冲区里,没有刷出来吧!

[解决办法]
你的函数都用值传递进去,外面的不会变的啊
[解决办法]
引用:
Quote: 引用:

你的函数都用值传递进去,外面的不会变的啊

我把MergeList的第三个参数改成list<int> &Lc还是不行啊
getItem也要改
[解决办法]




#include <iostream>
#include <list>
#include <cstddef>
using namespace std;

void getItem(list<int> La, list<int>::size_type i, unsigned int &n)
{
list<int>::iterator it = La.begin();
for (int j = 0; j < i; ++j) { // 改动
++it;


}
n = *it;
//cout<< n;
}

void MergeList(list<int> &La,list<int> &Lb,list<int> &Lc) // 改动
{
cout << "nimabide" << endl;
list<int>::size_type i = 0,j = 0;
unsigned int ai = 0, bi = 0;
cout<<bi;
list<int>::size_type La_Len = La.size();
list<int>::size_type Lb_Len = Lb.size();

while ( (i < La_Len) && (j < Lb_Len) ) // 改动
{
getItem(La, i, ai);
getItem(Lb, j, bi);
if (ai<bi)
{
Lc.push_back(ai);
i++;
}
else
{
Lc.push_back(bi);
j++;
}
}

while (i < La_Len) // 改动
{
getItem(La, i, ai);
Lc.push_back(ai);
i++;// 改动
}
while (j < Lb_Len) // 改动
{
getItem(Lb, j, bi);
Lc.push_back(bi);
j++;// 改动
}
}

int main(int argc, const char * argv[])
{

// insert code here...
std::cout << "Hello, World!\n";
//list<int> listA = {3,5,8,11};
list<int> listA;
listA.push_back(3);
listA.push_back(5);
listA.push_back(8);
listA.push_back(11);
//list<int> listB = {2,6,8,9,11,15,20};


list<int> listB;
listB.push_back(2);
listB.push_back(6);
listB.push_back(8);
listB.push_back(9);
listB.push_back(11);
listB.push_back(15);
listB.push_back(20);
list<int> listC;

MergeList(listA, listB , listC);

for (list<int>::iterator it = listC.begin(); it != listC.end(); ++it) {
cout << *it << " ";
}


return 0;
}


list不能那样初始化吧,我改了代码可以运行,改动的部分在代码中表示出来了
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

你的函数都用值传递进去,外面的不会变的啊

我把MergeList的第三个参数改成list<int> &Lc还是不行啊
getItem也要改
对,刚改了忘了传上来了,现在这个代码我感觉应该没错,可他还是不行,为什么呢?
[/code]

#include <iostream>
#include <list>
#include <cstddef>
using namespace std;
//得到La中的第i个元素,并把值赋给n
void getItem(const list<int>& La, list<int>::size_type i, int& n)
{
list<int>::const_iterator it = La.begin();
for (int j = 0; j < i; ++j)
++it;
n = *it;
}
//将La和Lb归并进Lc
void MergeList(const list<int>& La, const list<int>&Lb, list<int>& Lc)
{
list<int>::size_type i = 0,j = 0;
int ai = 0,bi = 0;
list<int>::size_type La_Len = La.size();
list<int>::size_type Lb_Len = Lb.size();

while ((i<La_Len)&&(j<Lb_Len))
{
getItem(La,i,ai);
getItem(Lb,j,bi);
if (ai<=bi)
{
Lc.push_back(ai);


i++;
}
else
{
Lc.push_back(bi);
j++;
}
}

while (i<La_Len)
{
getItem(La, i, ai);
Lc.push_back(ai);
i++;
}
while (j<Lb_Len)
{
getItem(Lb, j, bi);
Lc.push_back(bi);
j++;
}
}

int main(int argc, const char * argv[])
{
// insert code here...
std::cout << "Hello, World!"<<endl;
list<int> listA = {3,5,8,11};
list<int> listB = {2,6,8,9,11,15,20};
list<int> listC;

MergeList(listA, listB , listC);//把listA、listB的数据归并进listC

for (list<int>::iterator it = listC.begin(); it != listC.end(); ++it) {
cout<<*it<<endl;//输出listC
}


return 0;
}


[解决办法]
你的目的是想练习一下归并的写法吗?
你用下标来进行遍历,这是效率很差的做法,如果真的想学习,可以参考一下std::merge的代码
用list的迭代器,而不是用下标进行访问
[解决办法]
引用:




#include <iostream>
#include <list>
#include <cstddef>
using namespace std;

void getItem(list<int> La, list<int>::size_type i, unsigned int &n)
{
list<int>::iterator it = La.begin();
for (int j = 0; j < i; ++j) { // 改动
++it;


}
n = *it;
//cout<< n;
}

void MergeList(list<int> &La,list<int> &Lb,list<int> &Lc) // 改动
{
cout << "nimabide" << endl;
list<int>::size_type i = 0,j = 0;
unsigned int ai = 0, bi = 0;
cout<<bi;
list<int>::size_type La_Len = La.size();
list<int>::size_type Lb_Len = Lb.size();

while ( (i < La_Len) && (j < Lb_Len) ) // 改动
{
getItem(La, i, ai);
getItem(Lb, j, bi);
if (ai<bi)
{
Lc.push_back(ai);
i++;
}
else
{
Lc.push_back(bi);
j++;
}
}

while (i < La_Len) // 改动
{
getItem(La, i, ai);
Lc.push_back(ai);
i++;// 改动
}
while (j < Lb_Len) // 改动
{
getItem(Lb, j, bi);
Lc.push_back(bi);
j++;// 改动
}
}

int main(int argc, const char * argv[])
{

// insert code here...
std::cout << "Hello, World!\n";
//list<int> listA = {3,5,8,11};
list<int> listA;
listA.push_back(3);
listA.push_back(5);
listA.push_back(8);
listA.push_back(11);
//list<int> listB = {2,6,8,9,11,15,20};


list<int> listB;
listB.push_back(2);
listB.push_back(6);
listB.push_back(8);
listB.push_back(9);
listB.push_back(11);
listB.push_back(15);
listB.push_back(20);
list<int> listC;

MergeList(listA, listB , listC);

for (list<int>::iterator it = listC.begin(); it != listC.end(); ++it) {
cout << *it << " ";
}


return 0;
}


list不能那样初始化吧,我改了代码可以运行,改动的部分在代码中表示出来了
可以
c++11的新语法
[解决办法]

void getItem(list<int>La,list<int>::size_type i, int n)//
{//此函数逻辑混乱,一个很明显会出错的case是当i为0的时候,你取的不是第一个值!!!
list<int>::size_type k = i+1;//不应该给i加一!!!!!
list<int>::iterator it = La.begin();
for (int j = 0;j<k;++j) {
++it;
}
n = *it;//赋值给形参,但是此处n是值传递,估计楼主笔误了,形参n应该声明为int& n
//cout<< n;
}


void MergeList(list<int> La,list<int>Lb,list<int>Lc)//这里的形参Lc跟上面的形参n的道理是一样的
{
cout<<"nimabide";//……
list<int>::size_type i = 0,j = 0;
int ai = 0,bi = 0;cout<<bi;
list<int>::size_type La_Len = La.size();
list<int>::size_type Lb_Len = Lb.size();

while ((i<=La_Len)&&(j<=Lb_Len))//这里不应该是小于等于,楼主对于循环边界的把握多练练基本功
{
getItem(La,i,ai);
getItem(Lb,j,bi);
if (ai<bi)
{
Lc.push_back(ai);
i++;
}
else
{


Lc.push_back(bi);
j++;
}
}

while (i<=La_Len)//应该是小于
{//这里可能会陷入死循环
getItem(La, i, ai);
Lc.push_back(ai);//应该增加一行i++
}
while (j<=Lb_Len)//应该是小于
{//这里可能会陷入死循环
getItem(Lb, j, bi);
Lc.push_back(bi);//应该增加一行j++
}
}


//最后楼主对于在Lc增加元素采用push_back的方法很挫!!!!!
[解决办法]
引用:
Quote: 引用:





#include <iostream>
#include <list>
#include <cstddef>
using namespace std;

void getItem(list<int> La, list<int>::size_type i, unsigned int &n)
{
list<int>::iterator it = La.begin();
for (int j = 0; j < i; ++j) { // 改动
++it;
}
n = *it;
//cout<< n;
}

void MergeList(list<int> &La,list<int> &Lb,list<int> &Lc) // 改动
{
cout << "nimabide" << endl;
list<int>::size_type i = 0,j = 0;
unsigned int ai = 0, bi = 0;
cout<<bi;
list<int>::size_type La_Len = La.size();
list<int>::size_type Lb_Len = Lb.size();

while ( (i < La_Len) && (j < Lb_Len) ) // 改动
{
getItem(La, i, ai);
getItem(Lb, j, bi);
if (ai<bi)
{
Lc.push_back(ai);


i++;
}
else
{
Lc.push_back(bi);
j++;
}
}

while (i < La_Len) // 改动
{
getItem(La, i, ai);
Lc.push_back(ai);
i++;// 改动
}
while (j < Lb_Len) // 改动
{
getItem(Lb, j, bi);
Lc.push_back(bi);
j++;// 改动
}
}

int main(int argc, const char * argv[])
{

// insert code here...
std::cout << "Hello, World!\n";
//list<int> listA = {3,5,8,11};
list<int> listA;
listA.push_back(3);
listA.push_back(5);
listA.push_back(8);
listA.push_back(11);
//list<int> listB = {2,6,8,9,11,15,20};
list<int> listB;
listB.push_back(2);
listB.push_back(6);
listB.push_back(8);
listB.push_back(9);
listB.push_back(11);
listB.push_back(15);
listB.push_back(20);
list<int> listC;

MergeList(listA, listB , listC);

for (list<int>::iterator it = listC.begin(); it != listC.end(); ++it) {
cout << *it << " ";
}


return 0;
}


list不能那样初始化吧,我改了代码可以运行,改动的部分在代码中表示出来了
谢谢!问题解决了,太疏忽大意了,忘了给i、j更新了,所以才会一直卡在第二个while循环里,非常感谢!顺便说一下,有几个地方不用改的:1.list初始化可以这么做,没问题。2.MereList中的ai、bi不用设置为unsigned。3La、Lb不用设为引用,我只想更改Lc,La、Lb不用改。就这些,谢谢!
每次传递整个list会消耗大量时间在拷贝上,这个习惯希望能够养成
[解决办法]
3La、Lb不用设为引用,我只想更改Lc,La、Lb不用改。就这些,谢谢!
------------------------------


不改也不应当传值,对象传值是拷贝一次的,效率太低。
不改就传 const 引用。

应该像上面有人贴的那么声明
void MergeList(const list<int>& La, const list<int>&Lb, list<int>& Lc)


[解决办法]
赵老师的那段话呢……自己学习学习~~
[解决办法]

引用:
Quote: 引用:

Quote: 引用:

赵老师的那段话呢……自己学习学习~~
哪个赵老师,什么话?

就是有一个怎么调试程序,单步执行断点什么的……

计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

读书人网 >C++

热点推荐