---
# System prepended metadata

title: 結構 Structrue
tags: [c++ coding]

---

---
title: cpp pointer
tags: c++ coding
---
{%hackmd nzwXYrKQTGqIftPO5fCdKA %}

# 結構 Structrue
#### 利用c++所提供的結構，就可以<span style="color:#F29">將型態不同的資料</span>組合再一起


## 13-1結構宣告
### 1.1宣告新結構
$\qquad\;$![](https://hackmd.io/_uploads/r1z5q6w6h.png =80%x)

```cpp=
/*11.1.2 結構變數之使用及初始設定*/

struct mydata{
  string  name;
  int math;
} student;

int main()
{
    cout<<"Student's name:";
    cin>>student.name;
    cout<<"Math score:";
    cin>>student.math;

    cout<<student.name<<"'s Math score is "<<student.math;
    return 0;
}
```
:::    success
INPUT:
Student's name:*Warren*
Math score:*125*

OUTPUT:
Warren's Math score is 125
:::

+ 一個結構占用記憶體有多少呢? Ans: 我也不知道 你加加看阿
+ 可以在宣告結構時直接宣告變數
+ 再來可以在宣告變數時直接宣告結構內的變數
```cpp=
/*11.1.2 結構變數之使用及初始設定*/

struct mydata{
  string  name;
    int math;
} student={"Harry",97};  /*<<<<======*/

int main(){
    cout<<student.name<<"'s Math score is "<<student.math;
    return 0;
}
```
+ 如果兩個結構欄位相同，可以直接指定 e.g. x=y;
<br>

## 13-2 結構與函數
### 2.1 傳遞結構變數進入函數
+ 類似變數的傳值，而不是傳址
```cpp=
/*11.2.1 傳遞整個結構到函數*/

struct mydata{
  string  name;
    int age;
};

void function(struct mydata);

int main(){
    struct mydata superman={"Jacky",12};
    cout<<"Before process..."<<superman.name<<"'s age is "<<superman.age<<endl;
    function(superman);
    cout<<"After process..."<<superman.name<<"'s age is "<<superman.age<<endl;
    
    return 0;
}
void function (struct mydata d){
    d.age+=10;
    cout<<"In function,"<<d.name<<"'s age is "<<d.age<<endl<<endl;
    return;
}
```
+ 然後就發現了，欸嘿
:::success
OUTPUT:
Before process...Jacky's age is 12

In function,Jacky's age is 22

After process...Jacky's age is 12
:::
+ 我們只修改到函數內的值，外面完全沒改到 (QAQ
<br>

### 2.2 傳遞部分結構進入函數
+ 同樣也會是傳值呼叫
+ 結構內的值不會改變
```cpp=
/*11.2.1 傳遞部分結構欄位到函數*/

struct mydata{
    string  name;
    int math;
    int english;
};

float avg(int, int);

int main(){
    struct mydata student={"Benson",41,78};
    cout<<student.name<<"'s Math score: "<<student.math<<endl;
    cout<<"English score: "<<student.english<<endl;
    cout<<"Average: "<<avg(student.math,student.english)<<endl;
    return 0;
}

float avg(int a, int b){
    return (float)(a+b)/2;
}
```
:::    success
OUTPUT:
Benson's Math score: 41
English score: 78
Average: 59.5
:::
<br>


### 2.3 傳遞結構的位置進入函數
+ 結構的位置: <span class="program">*&結構名*</span>
```cpp=
/*11.2.3 傳遞結構位址到函數*/

struct mydata{
    string name;
    int a,b;
};

void change(struct mydata * ), printstr(struct mydata);//函數原型

int main(){
    struct mydata first={"David",5,21};
    printstr(first);
    cout<<"After process..."<<endl<<endl;
    change(&first);
    printstr(first);
    return 0;
}
void printstr(struct mydata info){
    //print mydata
    cout<<"Name: "<<info.name<<endl;
    cout<<"a: "<<info.a<<"\t";
    cout<<"b: "<<info.b<<endl<<endl;
    return;
}

void change(struct mydata * ptr){
    //exchange a and b
    int tmp;
    tmp = ptr->a;        //ptr->a 取出ptr所指向結構的a
    ptr->a = ptr->b;
    ptr->b = tmp;
    return;
}
```
:::success
OUTPUT:
Name: David
a: 5    b: 21

After process...

Name: David
a: 21   b: 5
:::
<br>

## 13-3 共同空間 Union
### 3.1共同空間的宣告
+ 宣告方式與結構相同，把"struct"改成"union"

$\qquad\;$![](https://hackmd.io/_uploads/Hk3hYL5p2.png =80%x)
+ 共同空間裡面的許多欄位們，不會同時存在
+ 如果一定要使用，<span class="rbrdr">資料就會被覆蓋!!!</span>，可以節省不必要的空間
```cpp=
/*11.3.2 共同空間的使用*/

union mydata{
    char grade;
    int score;
} student;

int main(){
    int sex;
    do{
        cout<<"Your sex is (1)Male (2)Female: ";
        cin>>sex;
    }while(sex>2||sex<1);
    
    if (sex==1){
        cout<<"Input score:";
        cin>>student.score;
    }
    else{
        cout<<"Input grade:";
        cin>>student.grade;
    }cout<<endl;
    
    if (sex==1){
        cout<<"Score is "<<student.score;
    }
    else{
        cout<<"Grade is "<<student.grade;
    }
    return 0;
}
```
:::success
Your sex is (1)Male (2)Female: *2*
Input grade:*1*

Grade is 1
:::
<br>

### 3.2 共同空間的記憶體配置
+ 共同空間的配置起始會在同一個地方
+ 如何配置取決於取出甚麼欄位

```cpp=
/*11.3.3 共同空間的大小位址*/


union mydata{
    short math;
    float avg;
} student;

int main()
{
    cout<<"sizeof (student) = "<<sizeof(student)<<endl;
    cout<<"address of student.math= "<< &student.math<<endl;
    cout<<"address of student.avg= "<< &student.avg<<endl;
    return 0;
}
```
:::success
OUTPUT:
sizeof (student) = 4
address of student.math= ee15154$\;\;\Longleftarrow$同樣的位址
address of student.avg= ee15154 $\quad\Longleftarrow$同樣的位址
:::

![](https://hackmd.io/_uploads/HJdJIKjT3.png  =50%x)<span>![](https://hackmd.io/_uploads/rkglHYo63.png)</span>
<span style="padding:0 168px">union</span><span style="padding:0 0px 0 159px">struct</span>
+ <span class=" rbrdr" style="font-size:20px">比較</span> 結構的記憶體配置


```cpp=
/*11.3.3 結構空間的大小位址*/

struct mydata{
    short math;
    float avg;
} student;

int main()
{
    cout<<"sizeof (student) = "<<sizeof(student)<<endl;
    cout<<"address of student.math= "<< &student.math<<endl;
    cout<<"address of student.avg= "<< &student.avg<<endl;
    return 0;
}
```

:::success
OUTPUT:
sizeof (student) = 8
address of student.math= ca3158$\;\;\Longleftarrow$"不"同樣的位址
address of student.avg= ca315c $\quad\Longleftarrow$"不"同樣的位址
:::
## 13-4 列舉型態 Enumeration
### 4.1 列舉型態的宣告
+ 還是一樣阿，跟結構完全一樣阿 要看圖嗎
+ 但我暫時沒看出他要幹嘛欸
+ 所以說。。。。。跳過!
## 13-5 自訂型態 Typedef
### 5.1 自訂型態的宣告
+ 可以改變原先定義的資料型態(e.g. int, char...)
+ <span class="pgreen">*typedef 資料型態 名字;*</span>
+ 在某些情況下，#define 可以有效取代 typedef
```cpp=
/*11.5.1 使用自訂的型態*/

int main(){
    
    typedef float temper; //compiler
    
    temper f,c;
    cout<<"Input Celsius degrees:";
    cin>>c;
    f = (float)(9.0/5.0)*c+32;
    cout<< c <<" Celsius is equal to ";
    cout<< f <<" Fahrenheit degrees" <<endl;
    return 0;
}
```
```cpp=
/*11.5.1 使用自訂的型態*/
#define TEMPER float //前置處理器
int main(){
    TEMPER f,c;
    cout<<"Input Celsius degrees:";
    cin>>c;
    f = (float)(9.0/5.0)*c+32;
    cout<< c <<" Celsius is equal to ";
    cout<< f <<" Fahrenheit degrees" <<endl;
    return 0;
}

```
:::success
OUTPUT:
Input Celsius degrees:*398*
398 Celsius is equal to 748.4 Fahrenheit degrees
:::
### 5.2 使用自訂型態宣告結構
<style>
    .rbrdr{
        padding: 0 5px ;
    }
</style>