【 提问 1 】在上面main函数中赋值时为何只能写成, “pStudent[i]->X”的形式,“(pStudent+i)->X = ……”这种写法为何编译错误?在函数中作形参时为何可以?
所有的 a[b] 的表达式都等于 *(a+b) 的形式
所以 a[b] 和 (a+b) 都不是同一个东西,不能互换
你要理解的是 struct Student_Data *pStudent[3];
首先 struct Student_Data 是一个 结构体
struct Student_Data * 是结构体的指针
pStudent[3] 是一个3长度的数组,并且数组成员类型是 [ 指针 ]
而 这个 [ 指针 ] 是 结构体[struct Student_Data] 类型的指针
------------------------------------------------
想像成你创建了一个3个长度大小的数组
pStudent[2] 获取这个数组的第二个元素的值
而这个值是个指向 [structStudent_Data] 结构体类型的指针
然后对 [结构体类型的指针] 可以采用 -> 运算符号
------------------------------------------------
你肯定会困惑 (pStudent + 2) 又代表着什么
首先 pStudent 是一个数组的名称吧
假设你知道类似
int arr[10] 这样的数组,它的成员是 int
那么 arr 也可以是 int 类型的指针 ( int * )
那么 pStudent 也是一个指针 它的成员类型是 [structStudent_Data *]
所以 pStudent 是 [ structStudent_Data ** ] 类型
也就是 [ 结构体 ] 的 [ 指针 ] 的 [ 指针 ]
你可能会为 [指针] 还能指向 [指针] 感到疑惑
但事实上这个是可能存在的
只有 [结构体的指针] 可以使用 -> 运算符 对结构体内成员操作
但是 [结构体的指针的指针] 是不能使用 -> 运算符的
--------------------------------------------------------
【 提问 2 】printf语句输出为何只能输出结构体数组最后一个值?
我大概能猜到为什么,总结一句
[ 你在玩火 访问未知的内存区域 而且没有崩溃 已经谢天谢地了 ]
首先看到你定义的 pStudent
这是一个数组,里面的成员是指针,不用管是什么的指针
你通过 pStudent[2] 拿到了一个指针的值
现在你有一个指针,可以对这个指针 [ 指向的数据进行访问 ]
但现在问题是 [ 你知道这个指针指向哪里吗? ]
--------------------------------------------------------
你可能会说 [ 当我分配数组的时刻,里面的每个指针成员,
都应该有分配好,成员指向的数据的内存空间 ]
--------------------------------------------------------
但告诉你的是,没有,只有这个数组的内存空间分配咯
也就是这3个指针的值可以存放下
但是这些指针指向的数据的存储空间并没有
也就是这个3个 [struct Student_Data *] 结构体的指针
可以指向任意未知的结构体储存空间
当然有极大概率,那里是并不是存储空间,而且这个地址不应该被访问
[ 如果程序访问不属于它的内存空间,会引发崩溃的 ]
--------------------------------------------------------
你很幸运的是,这三个指针指向的内存空间,还算是可以访问的
并且恰巧它们还是相同的值。比如全 0 或者 全 1
也就是指向相同的内存空间的指针
那么你的每一个操作都会写向同一个内存空间,也就最后的写操作被保留了下来
所以你看到了全部都是 7
--------------------------------------------------------
我猜测 struct Student_Data pStudent[3]; 类型才是你需要的
pointer to student 指向结构体的指针
--------------------------------------------------------
如果你的确要初始化 struct Student_Data *pStudent[3];
至少要这样
struct Student_Data storage[3];
struct Student_Data *ppStudent[3] = {storage, storage+1, storage+2};
---------------------------------------------------------
以上
第一问
Student_Data *pStudent[3] 其作为形参可表现为 Student_Data ** pStudent
Student_Data pStudent[3] 其作为形参可表现为 Student_Data *pstudent
所以为什么main函数不可以 是因为他们两个不是一样的(你这里只是把名字定义成一样了,要记住)
第二问
Student_Data *pStudent[3] 里面是3个指针
所以他是3个没有负值的指针。
这时候本应该不能直接操作的。
比如 int* a;
难道你直接就 *a =10;
你至少也得用 a = (int)malloc(....) 或者 int b; a =&b吧
才去设置值吧。
所以你访问的地址肯定是错误的,访问到了别的内存块的地址了.输出错误也是正常。崩溃都是正常的。
也许程序一运行,指针没赋值之前,你那三个指针就是指向一样的地址(别的地址),故而同一个地址3此赋值,值也就等于最后一次的。