这个程序我是声明了一个结构,然后初始化了一个结构数组,并用指针p指向了这个结构数组的内存块,并让它指

向结构数组的第一个元素,那么p[1]就是指向&a[1]的地址对吧,那么为什么
p[1].kind能够访问结构的成员呢。它不是地址吗,还有就是*p[1].kind为什么只有一个字母,而且只能访问kind,其他的话还会错误???这问题搞得我一脑子雾水,期望各位大师帮帮忙,教教小弟,我先谢过啦
#include <iostream>
#include <string>
#define Candybar Cb
using namespace std;
struct Cb
{
char kind[40];
float heavy;
int calory;
};
int main()
{
Cb a[3]=
{
{"Mocha",2.3F,350},
{"Munch",4.5F,740},
{"Flip",9.4F,1006}
};
Cb* p=new Cb[3];
p=&a[0];
cout<<p[1].kind;
return 0;
}

1 p是一个Cb类型的指针,当它指向一个数组时,实质是指向该数组的第一个元素的地址。而p[n]则是该数组的第n个元素,不是指针。所以p[1].kind就是a[1].kind,是可以访问结构体成员的;
2 同理kind作为一个数组名,同样本身是一个指向该数组首地址的一个char型指针,而*kind就是该数组的第一个元素,等同于kind[0],只不过在编译时,cout<<kind电脑会将整个数组都输出,而*p[1].kind就是p[1]中*kind,是结构体p[1]中kind数组中第一个元素,等同于p[1].kind[0]故只输出第一个;
3 至于heavy,calory不是数组,其本身根本就不是指针,故在cout<<*heavy时系统会报错。
其实重点是理解一个数组的数组名同时也是指向该数组首地址的指针。
明白了吗追问

恩,你说的不错,但是我还有些问题,在1中你说p[0]是指针,那么我输入p[0].heavy正确,而p[0]->heavy却是错误(在我看的书中他是这样说的,“结构标识符是结构名,则使用句点操作符;如果标识符是指向结构的指针,则使用箭头操作符”),那么他不是指针吗,用箭头却没用,为什么?在2中你说“*p[1].kind就是p[1]中*kind,是结构体p[1]中kind数组中第一个元素”,现在我明白p[1]不是指针,那么是不是程序自动的把*移交给了kind?

追答

第一点,我没说p[0]是指针呀,我说p是指针,指向首地址,此时*p等同于p[0],是数组中的第一个元素,即p[0]是数据,不是指针,但我的话中仍有一个错误,应该是“p[n]则是该数组的第n+1(不是第n个)个元素”,当执行cout<<*p[1].kind;时输出的M其实是第二个即“Munch”的M,不是"Mocha"的M,
第二点,我不太清楚你所问的问题,怎么个“程序自动的把*移交给了kind”,不好意思请说清楚点
我根据自己的理解说一下,当kind是一个数组名时,cout<<kind 会将整个数组输出,cout<<*kind,将第一个元素输出,cout<<[n] 会将第n+1个元素输出

追问

哦,是这样的,那么就是说p指向3个相连的内存块,分别是p[0],p[1],p[2],即3个相连的地址(两两相差类型字节数),那么我第2个问题,现在的理解是p[1].kind和*p[1].kind的区别在于前一个是地址去访问kind数组(那么当它输出完char型字符串后即停止,这是自己想的),所以输出了Munch,而后一个却是用一个结构对象(对不?)去访问kind数组却输出了M?,不好意思,比较笨,又拐住了,用地址和结构对象去访问为什么有这么大的区别

追答

不是的,比如说int a=1;int* p=&a; 这个&是取址符,当加在一个数据前,表示这个数据的地址,同理,相应的是*符,当加在一个指针前,表示这个指针指向的数据,故 此时 *p等同于a,值为1,p等同于&a(要清楚p是个指针,a是个数据);在这上面这个程序中,kind是指向数组第一个元素的指针,所以,*kind表示第一个元素,所以是输出了M,明白了吗

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-01-24
Cb* p=new Cb[3]; p 既是指针,又被分配了存储单元:3个Cb大小的结构。
如果你要把 p 作为 3个Cb大小的结构 使用,你应当用:
p[0]=a[0];p[1]=a[1];p[2]=a[2]; 的方法 按 结构块 来赋值。

你现在用 p=&a[0]; 的方法,相当于 p=a,让p 指向 结构数组 a 的首地址, p[1] 指向 a[0]+sizeof(Cb).
=====
看,下两个程序结果会不同:
(1)
Cb* p=new Cb[3];
p=&a[0];
cout<<p[1].kind <<endl;
cout<<p[1].heavy <<endl;
p[1].heavy =6.789F;
cout<<a[1].heavy <<endl; // p 变 a 也变了
(2)
Cb* p=new Cb[3];
p[0]=a[0];p[1]=a[1];p[2]=a[2];
cout<<p[1].kind <<endl;
cout<<p[1].heavy <<endl;
p[1].heavy =6.789F;
cout<<a[1].heavy <<endl; // p 变 a 不变追问

我现在才刚学指针,在我的意识里只知道能将变量的地址赋给指针,而不知道可以直接赋值?

第2个回答  2012-01-24
完全可以这样定义的:有三种方法取值
int main()
{
Cb a[3]=
{
{"Mocha",2.3F,350},
{"Munch",4.5F,740},
{"Flip",9.4F,1006}
};
Cb* p=a;
cout<<p[0].kind<<endl;
cout<<p->kind<<endl;
cout<<(*p).kind<<endl;
return 0;
}
第3个回答  2012-01-24
向结构数组的第一个元素,那么p[1]就是指向&a[1]的地址对吧,那么为什么
p[1].kind能够访问结构的成员呢。它不是地址吗//
首先p[1]不是地址,相当于结构体变量a[1];//想得到p[1]的地址,可以printf("%p\n",p[1]);//a[1]的地址相同
Cb结构体类型的指针p new三个Cb类型的结构体,存放a[3]这个结构体数组的三个结构体变量。p=&a[0];可以改成p=a,//这相当于取二维数组的首地址,p[0]对应a[0],p[1]对应a[1]....
//知道二维数组的首地址,就可以找到这个二维数组的其他元素
//知道第一列的地址,也就是每一行的行地址,p[0]相当于结构体变量a[0],用结构体变量调用结构体成员
//p[1].kind p[1].heavy;//不是*p[1].kind

而楼上的例子 没说明白 例子 一 p变 a也变 p=&a[0]是因为是地址赋值,
//例子二 p变 a不变 是值的赋值p[0]=a[0],相当于拷贝了a[0]这一行数据赋值给p[0], p与a没关系,所以,a没变,与结构块没什么关系
//还有不明白的?
相似回答