定義結構

想要建立只有資料的物件時,使用 struct;其他狀況一律使用 class。

結構是「自訂」(客製化)資料結構類型,大括號{}包含這個結構中需要的成員變數,成員變數類型可以是指標、陣列、整數、字元、double、float,也可以是結構。

定義結構有以下三種方式:

方式1

宣告結構

關鍵字struct宣告,分號於struct後的是結構名稱,變數的宣告都在大括號{}內,大括號{}結尾一定要加上分號;

struct 結構名 {
  變數宣告
};
1
2
3
4
5
6
struct Student {
  // 學生姓名
  char* name;
  // 學號
  int id;
};

結構放置位置

放在main()上面,或者放在標頭檔。

定義結構變數

方式一:

結構名 變數名;
Student student;
1
2
3
4
int main() {
  Student student;
  return 0;
}

方式二:
前面加上struct。

struct 結構名 變數名
struct Student s1;

存取結構成員

存取方式有二種

點運算子

使用點運算子(dot operator)指派或修改結構成員的值。

1
2
3
  Student student;
  student.name = "Mary";
  student.id = 1;

cout讀取結構成員。

1
2
  cout << student.name << endl;
  cout << student.id << endl;

完整程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
struct Student {
  //學生姓名
  char* name;
  //學號
  int id;
};
int main() {
  Student student;
  student.name = "Mary";
  student.id = 1;
  cout << student.name << endl;
  cout << student.id << endl;
  return 0;
}
Mary
1

大括號

使用大括號修改結構。

結構名 = {值1,值2,值3, ...};
1
student = {"Bill",2};

完整程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
struct Student {
  //學生姓名
  char* name;
  //學號
  int id;
};
int main() {
  Student student;
  student.name = "Mary";
  student.id = 1;
  cout << "Before:" << endl;
  cout << student.name << endl;
  cout << student.id << endl;
  student = {"Bill",2};
  cout << "After:" << endl;
  cout << student.name << endl;
  cout << student.id << endl;
  return 0;
}

Struct Memory layout

結構記憶體大小

s1變數指向Student結構中第1個成員變數的記憶體位址。
每一個成員變數都有自己的記憶體位址,成員變數name是指標類型,占8byte,id是整數類型,占4byte,addr是指標類型,占8byte。
但結構會以最大的記憶體位址大小 8byte來作為單位。

結構記憶體大小計算:
8byte * 成員變數的數量3 = 24 byte

所以成員的記憶體位址相差是8byte。

結構與字串常數指標

name是指標變數,存放字串常數的記憶體位址,字串常數放置在RODATA唯讀區塊。
id是整數,整數是基本型態,所以直接存放1。
addr是指標變數,存放字串常數的記憶體位址,字串常數放置在RODATA唯讀區塊。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Student {
  char* name;
  int id;
  char* addr;
};
int main() {
  struct Student s1;
  // 5byte,包含\0字串結尾
  s1.name = "Mary";
  s1.id = 1;
  // 12byte
  s1.addr = "Taiwan,Tapei";
  printf("&s1 = %p, &name = %p, &id = %p, &addr = %p \n",&s1, &s1.name, &s1.id, &s1.addr);
  printf("name = %p, addr = %p \n",s1.name, s1.addr);
  return 0;
}
&s1 = 0x1000, &name = 0x1000, &id = 0x1008, &addr = 0x1010
name = 0x2000, addr = 0x2005

各自獨立記憶體空間

結構就像是一種模板,用結構宣告的變數s1、變數s2,變數s1與變數s2擁有相同的成員變數名,但變數的記憶體位址是完全不一樣,變數s1與s2有各自獨立記憶體空間。

img

方式2

同時宣告結構與定義結構變數

在大括號的結尾輸入結構變數,在main()函式不用定義結構變數,直接使用結構變數。

struct 結構名{
	變數宣告
}結構變數;
1
2
3
4
5
6
struct Student {
  //學生姓名
  char* name;
  //學號
  int id;
}student;

存取結構成員

在main()函式不用定義結構變數,直接使用結構變數。

1
2
3
4
5
6
7
int main() {
  student.name = "Mary";
  student.id = 1;
  cout << student.name << endl;
  cout << student.id << endl;
  return 0;
}

完整程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;
struct Student {
  //學生姓名
  char* name;
  //學號
  int id;
} student;
int main() {
  student.name = "Mary";
  student.id = 1;
  cout << student.name << endl;
  cout << student.id << endl;
  return 0;
}

方式3

宣告結構

使用typedef(型別定義)關鍵字,後面緊跟著struct關鍵字,再來是大括號{},變數的宣告在大括號{}中,結構名放在大括號結尾,最後加上分號;結束。

typedef struct {
	變數宣告
} 結構名;
1
2
3
4
5
6
typedef struct {
  //學生姓名
  char* name;
  //學號
  int id;
} Student;

定義結構變數

結構名 變數名;
1
Student student;

存取結構成員

方式一相同。

完整程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
typedef struct {
  //學生姓名
  char* name;
  //學號
  int id;
} Student;
int main() {
  Student student;
  student.name = "Mary";
  student.id = 1;
  cout << student.name << endl;
  cout << student.id << endl;
  return 0;
}

匿名結構

沒有結構名,一次性,只能使用1次,沒有結構名,無法重覆使用。

struct{
  成員變數
} 變數;

以下程式碼,結構變數s1,是在main()函式中宣告。
struct後面是沒有結構名。

1
2
3
4
5
6
7
8
9
10
11
12
int main() {
  struct {
    char* name;
    int id;
    char* addr;
  } s1;
  s1.name = "Mary";
  s1.id = 1;
  s1.addr = "Taiwan,Tapei";
  printf("name = %s, id = %d, addr = %s \n",s1.name, s1.id, s1.addr);
  return 0;
}
name = Mary, id = 1, addr = Taiwan,Tapei 

results matching ""

    No results matching ""