修飾子

Sprout 2021/04/17

複習 -- 資料型態

字元 char 1 byte
整數 int 4 bytes
單精度浮點數 float 4 bytes
倍精度浮點數 double 8 bytes

修飾子

  • 宣告額外性質
  • 種類
    • 改變所佔的記憶體空間
      • short/long
    • 改變數值範圍
      • unsigned
    • 把資料改成不可更動的常數
      • const
    • 不隨函式結束而消失的變數
      • static

改變所佔的記憶體空間

short/long

sizeof(型態)

  • 顯示資料型態佔的空間
字元 char 1 byte
整數 int 4 bytes
單精度浮點數 float 4 bytes
倍精度浮點數 double 8 bytes
#include <iostream>
using namespace std;
int main() {
    cout << sizeof(char) << "\n";
    cout << sizeof(int) << "\n";
    cout << sizeof(float) << "\n";
    cout << sizeof(double) << "\n";
}

short/long

  • sizeof(short) ≦ sizeof(int) ≦ sizeof(long) ≦ sizeof(long long)
  • default: int
    • short ➜ short int
    • long ➜ long int
int  4 bytes
short int ? bytes
long int ? bytes
long long int ? bytes

short/long

  • sizeof(short) ≦ sizeof(int) ≦ sizeof(long) ≦ sizeof(long long)
  • default: int
    • short ➜ short int
    • long ➜ long int
int  4 bytes
short int 2 bytes
long int 4 bytes / 8 bytes
long long int 8 bytes

改變數值範圍

unsigned

unsigned

  • 只存非負整數
    • 所以上限變兩倍
int 4 bytes = 32 bits -2^31 ~ 2^31 - 1
unsigned int 4 bytes = 32 bits 0 ~ 2^32 - 1

unsigned num = -5; // ???

二補數 2's complement

binary decimal binary decimal
0111 7 1111 -1
0110 6 1110 -2
0101 5 1101 -3
0100 4 1100 -4
0011 3 1011 -5
0010 2 1010 -6
0001 1 1001 -7
0000 0 1000 -8

二補數 2's complement

  • 最高位是 0 ➜ 正數
  • 最高位是 1 ➜ 負數
  • 正數變負數 ➜ 1 變 0、0 變 1 再加 1
binary decimal binary decimal
0111 7 1111 -1
0110 6 1110 -2
0101 5 1101 -3
0100 4 1100 -4
0011 3 1011 -5
0010 2 1010 -6
0001 1 1001 -7
0000 0 1000 -8

short/long/unsigned

int 4 bytes -2^31 ~ 2^31 - 1
unsigned int 4 bytes 0 ~ 2^32 - 1
short int 2 bytes -2^15 ~ 2^15 - 1
unsigned short int 2 bytes 0 ~ 2^16 - 1
long long int 8 bytes -2^63 ~ 2^63 - 1
unsigned long long int 8 bytes 0 ~ 2^64 - 1

<limits.h>

#include <iostream>
#include <limits.h>
using namespace std;

int main() {
    cout << "int range\t\t" << INT_MIN << "\t" << INT_MAX << "\n";
    cout << "unsigned int range\t" << 0 << "\t\t" << UINT_MAX << "\n";
    cout << "short int range\t\t" << SHRT_MIN << "\t\t" << SHRT_MAX << "\n";
}
  • 定義了整數資料型別的上下界
    • 可能會因為不同硬體、作業系統、編譯器而有不同的結果
    • cppreference

Overflow

  • 超過上下界
  • undefined behavior
#include <iostream>
#include <limits.h>
using namespace std;

int main() {
    int a = INT_MAX;
    cout << "a = " << a << "\n";
    cout << "a + 1 = " << a + 1 << "\n";

    if (a < a + 1)
        cout << "a < a + 1\n";
    else
        cout << "a >= a + 1\n";
}

不可更動的常數

const

const

  • 避免更動到定值 ex. PI

宣告

  • const double PI = 3.14;
  • double const PI = 3.14;

注意!

  • const 變數一定要有初始值
#include <iostream>
using namespace std;
int main() {
    const double PI;
}

注意!

  • 更改到 const 變數會噴錯提醒
#include <iostream>
using namespace std;
int main() {
    const double PI = 3.14;
    PI = 6.28;
}

在函數中使用

#include <iostream>
using namespace std;

int area(const int w, const int h) {
    return w * h;
}

int main() {
    cout << area(3, 4);
}

不隨函式結束而消失的變數

static

Static (in function)

  • 宣告/初始化一次
    • 生命週期為整個程式碼
    • 可以用於統計

Example

#include <iostream>
using namespace std;

void count() {
    int cnt = 0;
    cout << cnt++;
}

int main() {
    for(int i = 0; i < 5; i++)
        count();
}

Example

#include <iostream>
using namespace std;

void count() {
    static int cnt = 0;
    cout << cnt++;
}

int main() {
    for(int i = 0; i < 5; i++)
        count();
}

Static (in global)

  • static 全域變數不能被其他檔案使用

Example

// PI.cpp
#include <iostream>
double PI = 3.14;
// print_PI.cpp
#include <iostream>
using namespace std;
int main() {
    extern double PI;
    cout << PI << "\n";
}
> g++ PI.cpp call_PI.cpp
> ./a.out
> 3.14

Example

// PI.cpp
#include <iostream>
using namespace std;
static double PI = 3.14;
// print_PI.cpp
#include <iostream>
using namespace std;
int main() {
    extern double PI;
    cout << PI << "\n";
}

總結

總結

  • short/long 可以改變所佔的記憶體空間
    • ​sizeof(資料型態、變數)
  • unsigned 可以改變數值範圍
    • 二補數
    • Overflow
  • const 把資料改成不可更動的常數
  • static 讓資料不隨函式結束而消失

總結

  • 可以同時使用多個修飾子
    • const unsigned long long int LARGE = 9876543210;
  • 其他修飾子
    • extern
    • volatile
    • ...

修飾子

By hsutzu

修飾子

Sprout 2021/04/17

  • 609