1. 程式人生 > 其它 >宣告結構體的幾種方法

宣告結構體的幾種方法

技術標籤:c++連結串列

目錄


前言

  在C語言中,常常使用陣列儲存若干個同種型別的資料,若想儲存不同型別的資料,就要用到結構體了,結構體是一些值的集合,這些值稱為它的成員,下面敘述宣告結構體的誤區:

1struct{
     int a;
     char b;
}ss;
2struct{
int a;
char b;
}st;

  宣告1建立了一個名為ss的變數,宣告2建立了一個名為st的變數,它們都包含兩個成員:int型的a和char型的b。需要注意,雖然ss和st的成員完全相同,但是這樣宣告會被編譯器處理為兩種不同的資料型別,不能相互賦值,示例如下:

#include <stdio.h>
struct {
	int a;
	char b;
}st;
struct 
{
	int a;
	char b;
}ss;
int main(void)
{
	scanf("%d %c", &ss.a, &ss.b);
	printf("ss的值分別為:%d %c\n", ss.a, ss.b);
	st = ss;
	return 0;
}

  會報如下型別不匹配的錯誤:
在這裡插入圖片描述

標籤

  如果想建立同一種類型的結構體變數,需要用到標籤,示例如下:

struct hhh{
int a;
char
b; }

  這種方法並沒有建立任何變數,而是把標籤和成員列表繫結在一起,標籤的作用就是標識了一種型別,以後使用相同標籤宣告的變數就是同一種類型的結構體變數。定義變數示例如下:

struct hhh ss,st;

  此時ss和st就是同一種類型的變量了,就可以相互賦值,示例如下:

#include <stdio.h>
struct hhh{
	int a;
	char b;
};
struct hhh ss, st;
int main(void)
{
	scanf("%d %c", &ss.a,&ss.b);
	printf("ss的值分別為:%d %c\n"
, ss.a, ss.b); st = ss; printf("st的值分別為:%d %c\n", st.a, st.b); return 0; }

  執行結果如下:
在這裡插入圖片描述

typedef

  使用typedef是另外一種建立相同型別的結構體變數的方法,示例如下:

typedef struct{
int a;
char b;
}hhh;

  該方法和標籤方法的區別是hhh是一個型別名,而不是標籤,因此定義變數的方法就不同了,定義變數示例如下:

hhh ss,st;

結構體的自引用

方法一

  在使用C/C++編寫連結串列程式時,會經常用到結構體的自引用,也就是一個結構體的成員包含該型別的結構體變數,一個錯誤用法如下:

struct hhh{
int data;
struct hhh next;
}

  上述方法是錯誤的,因為next是一個結構體變數,但是"struct hhh"型別的長度不確定,結構體變數next內部也是相同結構,因此編譯器會一直遞迴尋找該型別的長度,卻沒有終點。

struct hhh{
int data;
struct hhh *next;
}

  這種方法是正確的,和上述程式的區別是next是指標變數,指標變數的長度是一個確定的值,在32位系統下,任何型別的指標變數都是4個位元組,因此該結構體的長度是確定的,next儲存的是一個該型別變數的地址。

方法二

  也可使用typedef方法完成結構體的自引用,首先展示一個錯誤用法,示例如下:

typedef struct{
int data;
ss *next;
}ss;

  這種方法是錯誤的,因為型別名ss在該結構體宣告的末尾才定義,卻在結構體內部使用了,此時ss還沒定義,自然會報錯了,正確用法的例項如下:

typedef struct hhh{
int data;
struct hhh *next;
}ss,*st;

  這種方法將typedef和標籤結合起來,結構體內部使用標籤宣告變數,該方法聲明瞭ss型別的結構體和指向ss型別的指標st,形式簡單,經常用於連結串列的程式設計。