---
# System prepended metadata

title: C 語言 雜七雜八

---

:::info
\+\+i：先計算再取值
i\+\+：先取值在計算
:::
# #if #endif
以#開頭的都是前置處理器，會在編譯前執行
`#if`的用法稱為條件編譯，比如說要code要在不同的平台輸出相同的顏色，但是不同平台控制顏色的代碼不一樣，所以可以寫成if-else。
```cpp
#include <stdio.h>
int main(){
    #if _WIN32
        system("color 0c");
        printf("hello world\n");
    
    #elif __linux__
        printf("\033[22;31mhello world\n\033[22;30m");
    
    #else
        printf("hello world\n");
    
    #endif
        
    return 0;
} // main
```
若是用一般的if-else寫法，程式會報錯，因為windows看不懂`__linux__`，而linux看不懂`_WIN32`，而#if是預處理命令，他只會保留true的程式碼並進行編譯。

# Switch Case
switch case的文法如下
```cpp
switch(expression){    
    case value1:    
        //code to be executed;    
        break;  //optional  
    case value2:    
        //code to be executed;    
        break;  //optional  
    ......    

    default:     
        code to be executed if all cases are not matched;   
}
```
在C語言中，switch語句是直通句尾的，所以在沒有加break的情況下，只要符合一個case條件，其他的case都將被執行。
> it's true 

**該敘述待驗證**
```cpp!
// verification code
#include<stdio.h>  
#include<conio.h>  
void main() {
    int number = 0;

    printf("Enter a number:");
    scanf("%d", &number);

    switch (number) {
    case 10:
        printf("number is equals to 10\n");
        // break;
    case 50:
        printf("number is equal to 50\n");
        // break;
    case 100:
        printf("number is equal to 100\n");
        // break;
    default:
        printf("number is not equal to 10, 50 or 100\n");
    }
}
```

# C語言 變數範圍
### static
1. function中的static==變數==
    該變數的生命週期不會隨著function結束而結束(a little like call by reference )，而在main中是無法存取該變數的；static變數的初始化只能assign constant literals，constant literals代表在整個程式中不會改變的值，ex：a = 2，2就是constant literals。
    
2. static ==function==
    在宣告function時，前面加上static表示該function只能供此檔案使用，是一種access control。 
    
### extern
可以在宣告變數或是function時加在前面，該關鍵字表示這個變數或function可以被其他檔案使用，且編譯器看到該關鍵字時會到declaration以外的檔案找它的defination。
:::warning
若使用了extern關鍵字，declaration和defination不可混用，一定得在declaration以外的檔案去定義，或是在宣告時直接定義，否則會報error。
:::

### volatile
volarile變數會強制從記憶體中讀取該變數的值，考慮以下的程式碼
```clike
#include <stdio.h>
int main(void)
{
    const int local = 10;
    int *ptr = (int *)&local;

    printf("Initial value of local : %d \n", local);
    *ptr = 100;
    printf("Modified value of local: %d \n", local);
    return 0;
}
//Exmaple from geeksforgeeks
```
output:
```cpp
Initial value of local : 10 
Modified value of local: 100 
```
在沒有優化的情況下結果如上所示，但在優化之後，我們預期編譯器會到暫存器存取變數的值，此時輸出會如下所示
output:
```cpp
Initial value of local : 10 
Modified value of local: 10 
```
如果再變數前加上volatile就可以強制編譯器到記憶體去存取變數的值，就能避免優化帶來的影響。

# XDATA type
XDATA告訴編譯器，該變數儲存在外部的記憶體(external ram)，所以要用其他instruction去存取。 因為8051有三個不同的位址空間，可以在這些空間裡定義不同的變量，所以加上XDATA能夠指定某個空間的變數，這樣的型別有
* ==data==：internal ram direct,存取core ram，速度最快代價最小
* ==idata==：internal ram indirect
* ==xdata==：存取external ram
* ==bdata?==：bit addressing ram
> xdata為外部儲存ram

# Function Pointer
程式碼如下
``` C=
# include <iostream>

using namespace std ;

typedef void (*funcPtr_v_v)(void) ;
typedef int (*funcPtr_i_i)(int) ;

void F1(void) {
    cout << "F1 test\n" ;
}

int F2(int num) {
    num += 1 ;
    return num ;
}

int main() {
    funcPtr_v_v fp = F1 ;
    fp() ;
    
    funcPtr_i_i fp1 = F2 ;
    cout << fp1( 0 ) ;
} // int 
```

幾時能用上這個技巧呢?
我也還在發掘，各位有想到怎麼樣方便的用法可以DC聯絡我。
若CODE有誤也請聯絡我。


# Brian Liao
``` cpp=
map<int, string> myHash ;
myHash.insert( pair<int, string>( 0, "HELLO" ) ) ;
myHash.find( 0 ) -> second ;

auto it = myHash.find( 0 ) ;
if ( it != myHash.end() ) {
    // something
} // if

-----------------------------------------------------

set<int> myS ;
myS.find( 10 ) ;
```

可以在struct中宣告只佔1bit的變數
``` c=
struct {
    unsigned char bit0: 1 ;
    unsigned char bit1: 1 ;
    unsigned char bit2: 1 ;
    unsigned char bit3: 1 ;
    unsigned char bit4: 1 ;
    unsigned char bit5: 1 ;
    unsigned char bit6: 1 ;
    unsigned char bit7: 1 ;
} fbit ;
```