#include<stdlib.h>
#include<pthread.h>
#include<stdio.h>
typedef struct
{
/* data */
double a;
double b;
}test;
int main(void)
{
test array[2];
array[0].a = 1.1;
array[0].b = 2.2;
array[1].a = 2.3;
array[1].b = 4.4;
/*------------------case 1 结构体数组------------------------*/
test* barry;
barry = array;
printf("barry->a = %lf\n",barry->a);//barry是一个指针变量,并且是array[0]的地址。
// printf("barry[0]->a = %lf\n",barry[0]->a);//错误,因为barry虽然是结构体指针,但barry[0]指的是array[0],是一个结构体,后面应该用.而非->,如下,这里也可以看出,array和barry在使用上的等效的,也就是说数组名与指向这个数组的结构体指针,在使用上是等效的。
printf("barry[0].a = %lf\n",barry[0].a);
/*------------------case 2 结构体指针 ----------------------*/
test c;
c.a = 5.5;
test* c_ptr = &c;
printf("c_ptr->a = %lf\n",c_ptr->a);
// printf("c.a = %lf\n",c_ptr.a);//错误,c_ptr是一个指针,应该用->
printf("(*c_ptr).a = %lf\n",(*c_ptr).a);//*c_ptr是一个结构体
/*-------------------case 3 结构体指针数组-----------------------*/
test* array_ptr[2];
array_ptr[0] = &array[0];
array_ptr[1] = &array[1];
//array_ptr++;是错误的,因为此操作会改变array_ptr的值,但是数组名对应的值是一个常量,不是有效的左值。
test** p;
p = array_ptr;//p与array_ptr在使用上是等效的
printf("array_ptr = %p\n",array_ptr);
printf("p = %p\n",p);
printf("++p = %p\n",++p);//++p的值比p的值大8,因为p是从数组array_ptr的维度进行++运算的,所以会跳过两个指针变量的大小,也就是8个字节。
p--;//及时恢复p的取值
printf("(*p++) = %p\n",(*p++));//按照从右到左,p++ = p,*p++也就是*p,相当于array_ptr[0]的值。
p--;//及时恢复p的取值
printf("(*p) = %p\n",(*p));//同上
printf("p[0]->a = %lf\n",p[0]->a);
//printf("p->a = %lf\n",p->a);
printf("(*p[0]++).a = %lf\n",(*p[0]++).a);
p[0]--;
printf("p[1]->a = %lf\n",p[1]->a);//p[0]是array_ptr[0]
//!!! printf("p->a = %lf\n",p->a);//错误,p是一个结构体二级指针,不是一个结构体指针,p->a是错误的
printf("(*p[1]++).a = %lf\n",(*p[1]++).a);//相当于**p[1]->a,相当于array[1].a
//printf("(**p).a = %lf\n",((**p).a));
printf("p++ = %p\n",p++);//等于p
p--;
printf("array_ptr[0] addr = %p\n",array_ptr[0]);
printf("array_ptr[1] addr = %p\n",array_ptr[1]);
printf("p[0] = %p\n",p[0]);
printf("p[1] = %p\n",p[1]);
int C[2] = {6,7};
int* e = C;
printf("e[0] = %d\n",e[0]);//指针和数组是等效的
printf("e[0] = %d\n",e[1]);//说明对于数组元素的引用,也是把数组名当成一个指针变量,表示为一个地址来看的。
return 0;
}
结果如下:
barry->a = 1.100000
barry[0].a = 1.100000
c_ptr->a = 5.500000
(*c_ptr).a = 5.500000
array_ptr = 0x7ffe3f82d2b0
p = 0x7ffe3f82d2b0
++p = 0x7ffe3f82d2b8
(*p++) = 0x7ffe3f82d2c0
(*p) = 0x7ffe3f82d2c0
p[0]->a = 1.100000
(*p[0]++).a = 1.100000
p[1]->a = 2.300000
(*p[1]++).a = 2.300000
p++ = 0x7ffe3f82d2b0
array_ptr[0] addr = 0x7ffe3f82d2c0
array_ptr[1] addr = 0x7ffe3f82d2e0
p[0] = 0x7ffe3f82d2c0
p[1] = 0x7ffe3f82d2e0
e[0] = 6
e[0] = 7
case1:
test* array:
array[0] | array[1] |
case2:test* c_ptr: 指向结构体c
case3: test* array_ptr[2]: array_ptr是结构体指针类型的数组的数组名,实际是一个二级指针。
test* array_ptr[0] | test* array_ptr[1] |
test** p = array_ptr。
总结:
(1)数组名不能更改,不能作为左值,但是指针可以;
(2)指针的加减运算,以其指向的数据类型的维度为单位进行变化;
(3)数组和指向数组的指针变量,在使用上是等效的;
(4)结构体指针采用->引用结构体成员,结构体变量采用.引用结构体成员,在判断使用->或者.前,确认好是结构体指针还是结构体变量;
(5)结构体的地址=结构体首元素的地址≠结构体名。不同于数组,结构体名称只是一个名称,不能等同于指针去使用,因为数组在内存中是连续的,但结构体在内存中,成员之间不一定是连续的,涉及到边界对其。