学习C++primer 第8天 之 小问题

jinjunweiruan 2008-07-10 07:15:33
1.书上有这么一句话:“不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。”
没有默认构造函数??系统不是都会自动加上去的么???

2.书上有这么一句话:"数组的维 数必须用值大于等于1的常量表达式定义。此常量表达式只能包含整数型字面值常量、枚举常量或者用常量表达式初始化的整型const 对象
为什么要求是const?是为了不能改变(应为数组定义后,大小就不能改.)?为了不出错?那我不去改就是了啊!。。

3. int &vi=ival,&vi2=ival2;
vi=vi2;
这个怎么理解?(vi=vi2这句.是让它们相等。。这个我知道了。)我看不太懂。。

4.书上“指针本身也是可用指针指指向的内在对象”。
这个就是指针的指针吧。
我想问下,指针的指针也是一个指针,不也是可以?就变成了指针的指针的指针。。它也是个指针。。就变成了指针的指针的指针的指针。。。
这不是没完没了了??.....


5.int *p=&ia[2];
int j=p[1];//与这2个p[1]=*(p+1) ,ia[3] 一样
int k=p[-2];
这里有了指针数组???他怎么没定义这个指针数组就拿来用了?这样的数组是不需要定义的么???

6.
//判断2个 VECTOR是否相等
//使用迭代器访问VECTOR中的元素
#include <iostream>
#include <vector>
using namespace std;

int main()
{
vector<int> ivec1, ivec2;
int ival;
//读入2个 VECTOR的元素值
cout <<"Enter numbers for vector(-1 to end):"<<endl;
cin>>ival;
while(ival !=-1){
ivec1.push_back(ival);
cin>>ival;
}
cout <<"Enter numbers for vector2(-1 to end):"<<endl;
cin>>ival;
while(ival !=-1){
ivec2.push_back(ival);
cin>>ival;
}
//判断2个VECTOR是否相等
if (ivec1.size()!=ivec2.size())
cout <<"Vector1 is not equal to vector2:"<<endl;//长度不等的VECTOR不相等
else if(ivec1.size()==0)//长度都为0的VECTOR相等
cout <<"Vector1 is equal to vector2."<<endl;
else {//2个VECTOR长度相等且不为0
vector<int>::iterator iter1,iter2;
iter1=ivec1.begin();
iter2=ivec2.begin();
while(*iter1 == *iter2 && iter1!=ivec1.end() && iter2!=ivec2.end()){
++iter1;
++iter2;
}
if(iter1 == ivec1.end())//所有元素相等
cout <<"Vector1 is equal to vector2."<<endl;
else
cout <<"Vector1 is not equal to vector2."<<endl;
}
return 0;
}


红色的部分,怎么只要判断(iter1 == ivec1.end()这个就可以让所有元素相等?还是和前面哪有关系?我没看出来。。。指教



问题有点多啊 。。。
一人回答1.2个就可以了。。。下楼的可以对上楼的进行补充。。。
谢谢。昨天去押宝了。分数就这么多了 。。。
XX
...全文
303 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinjunweiruan 2008-07-11
  • 打赏
  • 举报
回复
回答的人多,,分数少,
没办法啊。。。
jy01807853 2008-07-10
  • 打赏
  • 举报
回复
[Quote]
1.书上有这么一句话:“不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。”
没有默认构造函数??系统不是都会自动加上去的么???
当你自己定义了类的构造函数以后,系统默认的构造函数就被屏蔽了。
[/Quote]

21楼的兄弟你拿去运行看下
#include <iostream>
using namespace std;

class Foo
{
public:
int val;

// Foo()
// {
// };
virtual ~Foo()
{
};

protected:
private:
};

int main()
{
Foo bar ;
if ( bar.val == 0)
{
cout << "Data member val has been initialized to 0" << endl;
}
else
{
cout << "Data member val hasn't been initialized to 0" << endl;
}
}


gccli 2008-07-10
  • 打赏
  • 举报
回复
默认构造函数,在编译器需要的时候会加上,在程序需要时不会加上。什么时候编译器需要?当类中有成员数据有默认构造函数时,编译器会为类生成一个构造函数。否则不会,我给你一个例子,你自己体会一个。
class String{
public:
String(){ str = "String"; }
char* str;
};

class X{
public:
int m_int;
String m_str;
};
int main(int argc, char* argv[])
{
X x;
cout<<x.m_int<<" ";
cout<<x.m_str.str<<"\n";
}

你可以把String类中的构造函数屏蔽看看效果。对于其它提问我就不参与了
mingguang7213 2008-07-10
  • 打赏
  • 举报
回复
1.书上有这么一句话:“不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。”
没有默认构造函数??系统不是都会自动加上去的么???
当你自己定义了类的构造函数以后,系统默认的构造函数就被屏蔽了。
2.书上有这么一句话:"数组的维 数必须用值大于等于1的常量表达式定义。此常量表达式只能包含整数型字面值常量、枚举常量或者用常量表达式初始化的整型const 对象。
为什么要求是const?是为了不能改变(应为数组定义后,大小就不能改.)?为了不出错?那我不去改就是了啊!。。

只是一个语法规定;


4.书上“指针本身也是可用指针指指向的内在对象”。
这个就是指针的指针吧。
我想问下,指针的指针也是一个指针,不也是可以?就变成了指针的指针的指针。。它也是个指针。。就变成了指针的指针的指针的指针。。。
这不是没完没了了??.....
的确如此

5.int *p=&ia[2];
int j=p[1];//与这2个p[1]=*(p+1) ,ia[3] 一样
int k=p[-2];
这里有了指针数组???他怎么没定义这个指针数组就拿来用了?这样的数组是不需要定义的么???
这是指向一个数组的指针,并非指针数组
bendise 2008-07-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jinjunweiruan 的回复:]
第3题我知道他是引用。
int &vi=ival,&vi2=ival2;
vi=vi2;
问题是vi=vi2这个。。。让他们相等。怎么有这样的写法。
456OK了,懂了。。。
[/Quote]

vi=vi2 //就是把vi2的内存地址赋值给了vi,这时候vi和vi2指向了同一个内存地址
Vitamin_C_PP 2008-07-10
  • 打赏
  • 举报
回复
3.书上也有这么一句话:“作用在引用上的所有操作事实上都是作用在该应用绑定的对象上”
6. while(*iter1 == *iter2 && iter1!=ivec1.end() && iter2!=ivec2.end())
{
++iter1;
++iter2;
}
//while跳出有两个条件*iter1 != *iter2或者 iter1==ivec1.end(),接下来的if语句判断的是while语句是为何跳出的,是遇到不相等的元素还是已经遍历到了文件末尾。
if(iter1 == ivec1.end())
cout <<"Vector1 is equal to vector2." <<endl;
else
cout <<"Vector1 is not equal to vector2." <<endl;
}
K行天下 2008-07-10
  • 打赏
  • 举报
回复
1.书上有这么一句话:“不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。”
没有默认构造函数??系统不是都会自动加上去的么???
如果你自己为类定义了构造函数,这个构造函数不是默认构造函数,那么编译器不会再提供默认构造函数,你必须自己再定义一个!!!


2.书上有这么一句话:"数组的维 数必须用值大于等于1的常量表达式定义。此常量表达式只能包含整数型字面值常量、枚举常量或者用常量表达式初始化的整型const 对象。
为什么要求是const?是为了不能改变(应为数组定义后,大小就不能改.)?为了不出错?那我不去改就是了啊!。。
首先是语法规定这样,你不能用动态数组,除非你是动态内存分配的 malloc new 来实现动态数组,编译器要求你一开始就确定数组的维数,这个值是不能变的!


3. int &vi=ival,&vi2=ival2;
vi=vi2;
这个怎么理解?(vi=vi2这句.是让它们相等。。这个我知道了。)我看不太懂。。
vi是ival的引用, vi2是ival2的引用, 注意引用看做变量的别名,另一个名字!!改变引用,就是改变其引用的变量!!!
将vi2赋值给vi其实就是将ival2的值赋给ival!!
yuyunliuhen 2008-07-10
  • 打赏
  • 举报
回复
1 需提供一个默认构造函数或者在构造函数提供默认值
2 尽可能的用CONST
matrixdwy 2008-07-10
  • 打赏
  • 举报
回复
3.  int &vi=ival,&vi2=ival2; 
vi=vi2;
这个怎么理解?(vi=vi2这句.是让它们相等。。这个我知道了。)我看不太懂。。

vi 和 vi2不仅仅是一个别名,他们是引用,ival 和 ival2的引用
引用类似于指针,比如你可以写成这样

int *vi = &ival, *vi2 = &ival2;
*vi = *iv2;

看到区别了吗?引用省去了*号。
但是引用和指针的区别不仅仅局限于此:
1.引用在定义的时候必须进行初始化
2.引用一旦被初始化过之后,就不能更改其引用的对象
而已上两点指针是可以的。
BetterMind 2008-07-10
  • 打赏
  • 举报
回复
up
jy01807853 2008-07-10
  • 打赏
  • 举报
回复
[Quote]
书上有这么一句话:“不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。”
没有默认构造函数??系统不是都会自动加上去的么???
[/Quote]



//楼主你把我这段代码拿去
//运行看下结果在说
#include <iostream>
using namespace std;

class Foo
{
public:
int val;

// Foo()
// {
// };
virtual ~Foo()
{
};

protected:
private:
};

int main()
{
Foo bar ;
if ( bar.val == 0)
{
cout << "Data member val has been initialized to 0" << endl;
}
else
{
cout << "Data member val hasn't been initialized to 0" << endl;
}
}


matrixdwy 2008-07-10
  • 打赏
  • 举报
回复
[quota]
2.书上有这么一句话:"数组的维 数必须用值大于等于1的常量表达式定义。此常量表达式只能包含整数型字面值常量、枚举常量或者用常量表达式初始化的整型const 对象。
为什么要求是const?是为了不能改变(应为数组定义后,大小就不能改.)?为了不出错?那我不去改就是了啊!。。
[/quota]

数组的大小必须在编译时就确定,并且不能够更改,若使用非const常量,比如:
int a = 10;
int arr[a];
因为a是非const的,所以a在运行时是可以变的,这样一来编译器就无法在编译时确定a到底是几,现在是10,但不能保证运行时它会变成别的值
还有一个原因就是const变量必须在定义时就对其进行初始化(赋值),而非const的则可以不用,如果你没有对a初始化,那你下面一个创建数组
的语句就是非法的,因为a的值是没有用处的,使用const保证了数据创建的合法性,同理适用于enum。
pengzhixi 2008-07-10
  • 打赏
  • 举报
回复
1,2如一楼所说,3句你可以看成是ival=ival2对ival重新赋值了。4点象你说的没错,就象多唯数组一样可以其实是数组的数组。第5点没定义指针数组,只定义了一个指向数组的指针,这个指针其实和int *p;int a[10];p=a;中的指针p 是一样的,只不过这里不是指向数组的第一个元素,而是指向数组的第3个元素。第6点我个人理解是判断容器里的元素是否被遍历完
jy01807853 2008-07-10
  • 打赏
  • 举报
回复

//希望可以帮到楼主
//楼主学习很认真, 很积极很好
//有错误楼下指出,谢谢
#include <iostream>
#include <vector>
using namespace std;

int main()
{
vector <int> ivec1, ivec2;
int ival;
//读入2个 VECTOR的元素值
cout <<"Enter numbers for vector(-1 to end):" <<endl;
cin>>ival;
while(ival !=-1)
{
ivec1.push_back(ival);
cin>>ival;
}
cout <<"Enter numbers for vector2(-1 to end):" <<endl;
cin>>ival;
while(ival !=-1)
{
ivec2.push_back(ival);
cin>>ival;
}
/*第一次根据第一个判断确定两个容器是否相等,如果是就继续第2次判断
如果第一个容器为0两个容器也就为0所以相等,经过第2次判断不满足两个
容器为0的情况,进行第3个判断
*iter1 == *iter2 && iter1!=ivec1.end() && iter2!=ivec2.end()
两个迭带器的值相等与两个容器的开始位置不等于结束位置进行循环
完了以后进行第4次判断
if(iter1 == ivec1.end())
经过第3个判断得出的结果,如果iter1==ivec1.end()
就证明循环就完全进行完的,没有停过,所以会到元素的下一个位置
所以可以的出最后的结论*/

//判断2个VECTOR是否相等
if (ivec1.size()!=ivec2.size())//判断2个VECTOR的大小是否相等
cout <<"Vector1 is not equal to vector2:" <<endl;//长度不等的VECTOR不相等

else if(ivec1.size()==0)//长度都为0的VECTOR相等
cout <<"Vector1 is equal to vector2." <<endl;

else
{//2个VECTOR长度相等且不为0
vector <int>::iterator iter1,iter2;
iter1=ivec1.begin();
iter2=ivec2.begin();
while(*iter1 == *iter2 && iter1!=ivec1.end() && iter2!=ivec2.end())
{
++iter1;
++iter2;
}
//根据上面的几次判断剩下的情况
//就一定是相等的
if(iter1 == ivec1.end())//所有元素相等
cout <<"Vector1 is equal to vector2." <<endl;
else
cout <<"Vector1 is not equal to vector2." <<endl;
}
return 0;
}

matrixdwy 2008-07-10
  • 打赏
  • 举报
回复
[Quote=引用楼主 jinjunweiruan 的帖子:]
1.书上有这么一句话:“不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。”
没有默认构造函数??系统不是都会自动加上去的么???
[/Quote]


class A{};
A arr[10]; //可以,系统自己生成了默认构造函数



class A{
public:
A(){ //... }
};
A arr[10]; //可以,你自己写了一个默认构造函数



class A {
int a;
int b;
public:
A(int s, int t) {
a = s;
b = t;
}
};
//A arr[10]; 不可以,因为你屏蔽了系统为你创建的默认构造函数,就不能对数组元素进行初始化了
A arr[10] = {A(2,3), A(2,3), ...}; //这样可以,因为你对其进行了初始化


jinjunweiruan 2008-07-10
  • 打赏
  • 举报
回复
说实话,C++primer还没讲到默认构造函数。。。
lingol 2008-07-10
  • 打赏
  • 举报
回复
楼主,慢慢来,欲速则不达。
1、去前面的章节看什么情况下编译器会提供默认构造函数。
2、1楼说得很清楚了,是因为创建数组时要知道数组的维数。
3、这是引用,我不信前面的章节没提及。
4、理论上,指针的指针是可以没完没了。
5、指针数组……是这样用的么?你确定你明白第一句什么意思?

int *p=&ia[2]; // p = ia + 2
int j=p[1]; // j = p + 1 = ia + 2 + 1 = ia[3]
int k=p[-2]; // j = p - 2 = ia + 2 - 2 = ia[0]

6、这一段你没看明白是什么意思?逐个比较两个容器的元素,直到到达某个容器的底部。

while(*iter1 == *iter2 && iter1!=ivec1.end() && iter2!=ivec2.end()){
++iter1;
++iter2;
}
jinjunweiruan 2008-07-10
  • 打赏
  • 举报
回复
第3题我知道他是引用。
int &vi=ival,&vi2=ival2;
vi=vi2;
问题是vi=vi2这个。。。让他们相等。怎么有这样的写法。
456OK了,懂了。。。
jinjunweiruan 2008-07-10
  • 打赏
  • 举报
回复
下面的继续补充吧。。。。
有点迷糊、
GoAssemblyNow 2008-07-10
  • 打赏
  • 举报
回复
楼主好学不倦,早上7点就爬起来发帖。精神可嘉。
1,老实说,我也不清楚。
2,你知道不可以改,但是别人呢?如果他使用了你写的文件。他可能在并不知情的情况下修改它。
3,int &vi=ival,&vi2=ival2;
ival是vi的引用,也就是vi 的别名,对ival的任何操作完全等价于对vi的操作。
4,可以这么说,只是我们最多使用二维指针,即指向指针的指针,更复杂的指针极少用到,并且不容易把握,也降低了代码的可读性。
5,int *p=&ia[2]; //p本身作为ia[2]的地址
int j=p[1];
int k=p[-2]; //必须解释一下,p[1]和p[-2]并不是指针数组,而是int类型的整数,这两个整数分别保存在以p为基址,分别保存在右移1个int型数据长度和左移2个int型数据长度的地址里面。另外不要看到[]就以为是数组。
6, 观察这个循环判断表达式:while(*iter1 == *iter2 && iter1!=ivec1.end() && iter2!=ivec2.end())
*iter1 == *iter2 。//这是进入循环先决条件之一,如果这个条件不成立,则循环根本不会进行。
if(iter1 == ivec1.end()//,iter1顺利的到达了超尾,说明上面先决条件(*iter1 == *iter2 )每次循环都是成立的,(如果某次不成立,则++iter1绝对不会被执行,iter也永远不会顺利到达超尾了。)
解释的不好,大家多批评。楼主加油!!
加载更多回复(4)

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧