如下定義了一個 School 結構體:
typedef struct School
{
int a;
int b;
}SCHOOL_S;
SCHOOL_S stSch;
下面我們來輸出一下 stSch 以及成員變數 a 和 b 的地址:
int main()
{
printf("stSch 的地址[%p]\n", &stSch);
printf(" a 的地址[%p]\n", &stSch.a);
printf(" b 的地址[%p]\n", &stSch.b);
return 0;
}
輸出結果如下:
有沒有發現什麼不得了的事情——結構體 school 的地址與第一個成員變數 a 的地址相同,也就是說變數 a 的地址既是 school * 型別,又是 int * 型別。腦海中突然冒出一個大膽的想法,如果我將 a 的地址強制型別轉化為 SCHOOL_S * 型別呢:
int main()
{
stSch.a = 10;
stSch.b = 20;
SCHOOL_S *pstSch = (SCHOOL_S *)&stSch.a;
printf("a = %d\n", pstSch->a);
printf("b = %d\n", pstSch->b);
return 0;
}
輸出結果如下:
Amazing~
通過上邊的小測試,我們發現了 struct 的第一個成員變數的地址有雙重身份,那麼該如何使用呢?
對於兩個不同的結構體:
typedef struct Teacher
{
char name[10]; /* 姓名 */
int id; /* 職工編號 */
}TEACHER_S;
typedef struct School
{
char name[10]; /* 校名 */
int cnt; /* 教職工個數 */
}SCHOOL_S;
SCHOOL_S school;
TEACHER_S teacher;
void Init()
{
strncpy(stSchool.name, "School", sizeof(stSchool.name) - 1);
stSchool.cnt = 1;
strncpy(stTeacher.name, "Teacher", sizeof(stTeacher.name));
stTeacher.id = 1;
}
如何在得知 school 的情況下得到 teacher 的資訊呢?你或許可以這麼做:在 School 中新增 Teacher 的指標變數,使其指向 teacher。
typedef struct School
{
char name[10]; /* 校名 */
int cnt; /* 教職工個數 */
struct Teacher *pstTeacher; /* 【Add】指向 Teacher 的指標變數 */
}SCHOOL_S;
int main()
{
Init();
stSchool.pstTeacher = &stTeacher;
}
這也不失為一種方法,但怎麼樣才能用到第一個成員變數的「雙重身份」這個資訊呢?
下面讓我們對結構體 School 和 Teacher 做個簡單修改:
typedef struct List
{
struct List *next;
}LIST_S;
typedef struct Teacher
{
LIST_S head; /* 【Add】單連結串列頭結點 */
char name[10]; /* 姓名 */
int id; /* 職工編號 */
}TEACHER_S;
typedef struct School
{
LIST_S head; /* 【Add】單連結串列頭結點 */
char name[10]; /* 校名 */
int cnt; /* 教職工個數 */
}SCHOOL_S;
int main()
{
Init();
stSchool.head.next = &stTeacher.head;
TEACHER_S *pstTeacher = (TEACHER_S *)stSchool.head.next;
printf(" stTeacher 的地址為[%p]\n", &stTeacher);
printf("pstTeacher 的地址為[%p]\n", pstTeacher);
return 0;
}
輸出結果如下:
是不是很神奇~