const 變數和指標

BirdsLife發表於2020-09-30

由於經常在使用const限定符會有一些不確定的想法,需要查詢書籍或網上才能確定到底是限定了那個,特此在這裡驗證,待後續發表日記記錄 ,const 的限定的是資料還是地址,還是同時限定

總結

  1. int* const ptr_var; 或者可以寫為 const int* ptr_var;(指標常量)
    a. 指標相當於一個常量(eg:指標指向某一塊地址後不能在改變指向,即指向var1後,不能在重新指向var2,var3…等其他變數)
    b. 可以通過指標解引用修改變數的值(eg: *ptr_var = x, ptr_var指向的變數var1 值也跟隨改變)
  2. int const *ptr_var;(常量指標)
    a. 該指標可以值指向其他地址(可以指向var1,var2…)
    b. 可以通過指標指向的變數來改變指標指向地址的值(eg:當指標指向var2時,可以通過改變var的值來改變*ptr_var對應的值)
    c. 不能通過指標解應用對指標指向地址的值進行修改(eg:不能通過*ptr_var = x的賦值運算來改變值)
  3. const int* cosnt ptr;
    a. 指向一個地址後不能在改變指向
    b. 不能通過解引用重新更改地址對應的值
    c. 可以通過改變指向變數的值來更換地址中指向的值
#include<stdio.h>

void scan_out();

void test_var_const();
void test_const_var();

void test_ptr_const_var();
void test_const_ptr_var();

void test_const_ptr_const_var();

int main()
{
    // 由於經常在使用const限定符會有一些不確定的想法,
    // 需要查詢書籍或網上才能確定到底是限定了那個,
    // 特此在這裡驗證,待後續發表日記記錄 
    // const 的限定的是資料還是地址,還是同時限定

    char flag = 'y';
    while (flag == 'y' || flag == 'Y'){
        scan_out();
        
        short test_number; // short 對應的格式化字串 %hd
        printf("輸入對應的測試用例:");
        scanf("%hd", &test_number);

        switch(test_number) {
            case 1:
                test_const_var();
                break;
            case 2:
                test_var_const();
                break;
            case 3:
                test_ptr_const_var();
                break;
            case 4:
                test_const_ptr_var();
                break;
            case 5:
                test_const_ptr_const_var();
                break;
            default:
                break;
        }
        getchar(); // 接受輸入測試用例編號 test_number後的回車符Enter
        printf("是否繼續執行測試用例(y/n):");
        flag = getchar();
    }

}

void scan_out()
{ 
    printf("----------C Const test------------\n");
    printf("1. const 常量(eg: const int a).\n");
    printf("2. const 常量(eg: int const a)\n");
    
    printf("\n");
    printf("3. const 指標常量(eg: int *const ptr_var).\n");
    printf("4. const 指標常量(eg: int const *tr_var).\n");

    printf("\n");
    printf("5.指向常量的const指標(eg: const int* const ptr_var).\n");
}

void test_const_var()
{
    // 給定一個常量,判斷值是否能改變
    const int var = 10;
    printf("開始改變常量的值 var = %d\n", var);
    // var = 20;  // 編譯的時候會報錯:assignment of read-only var
}

void test_var_const()
{
     // 給定一個常量,判斷值是否可以更改
     int const var = 30;
     printf("開始改變變數的值 var = %d\n", var);
     // var = 14; // 編譯的時候會報錯:assigment of read-only var
}
void test_ptr_const_var()
{
    int var1 = 10;
    int var2 = 20;
    int* const ptr_var = &var1;
    
    printf("開始改變* const_ptr_var的指向 *const_ptr_var = %d\n", *ptr_var);

    // ptr_var = &var2; // 編譯會報錯:assignment of read-only variable 'ptr_var'
    
    // 使用指向的變數改變指標指向地址的值
    var1 = 30; // 可以改變指標指向地址的值
    printf("開始改變* const_ptr_var的指向地址的值 *const_ptr_var = %d\n", *ptr_var);
    
    // 使用指標改變指標指向地址的值
    *ptr_var = 520;
    printf("開始改變* const_ptr_var的指向地址的值 *const_ptr_var = %d\n", *ptr_var);

    // 在指向變數的指標改變指向變數的之後,是否也改變了變數的值?
    // 變數的值已經被改變
    printf("通過指標改變變數的值後變數對應的值是:var1 = %d\n", var1);
}
/* int* const ptr_var; 或者可以寫為 const int* ptr_var;(指標常量)
 * 1. 指標相當於一個常量(eg:指標指向某一塊地址後不能在改變指向,即指向var1後,不能在重新指向var2,var3...等其他變數)
 * 2. 可以通過指標解引用修改變數的值(eg: *ptr_var = x,  ptr_var指向的變數var1 值也跟隨改變)
 */


void test_const_ptr_var()
{
    int var1 = 13;
    int var2 = 14;

    int const *ptr_var = &var1;
    printf("開始改變* const_*ptr_var的指向 const_*ptr_var = %d\n", *ptr_var);

    var1 = 20;
    printf("開始改變* const_ptr_var的指向 *const_ptr_var = %d\n", *ptr_var);
    
    ptr_var = &var2;
    printf("開始改變* const_ptr_var的指向 *const_ptr_var = %d\n", *ptr_var);
    
    //  通過改變變數的值,改變指標指向的值
    var2 = 520;
    printf("對 var2 變數重新賦值:var2 = %d\n", *ptr_var);
    
    // 通過指標改變變數的值
    // *ptr_var = 520; //不能通過指標改變變數的值
    printf("通過指標改變變數的值後變數對應的值是:var2 = %d\n", var2);
    // printf("開始改變* const_ptr_var的指向 *const_ptr_var = %d\n", *ptr_var);
}
/* 
 * int const *ptr_var;(常量指標)
 * 1. 該指標可以值指向其他地址(可以指向var1,var2...)
 * 2. 可以通過指標指向的變數來改變指標指向地址的值(eg:當指標指向var2時,可以通過改變var的值來改變*ptr_var對應的值)
 * 3. 不能通過指標解應用對指標指向地址的值進行修改(eg:不能通過*ptr_var = x的賦值運算來改變值)
 **/

void test_const_ptr_const_var()
{
    int var1 = 34;
    int var2 = 54;
    const int *const ptr_var = &var1;
    printf("*ptr_var = %d, var1 = %d, var2 = %d\n", *ptr_var, var1, var2);
    // ptr_var = &var2; // 編譯報錯:assignment of read-only varible 'ptr_var'
    // *ptr_var = 56; // 編譯報錯:assignment of read-only location '*ptr_var'
    var1 = var2;
    printf("對var賦值後 *ptr_var = %d, var1 = %d, var2 = %d\n", *ptr_var, var1, var2);
}
/*
 * 1. 指向一個地址後不能在改變指向
 * 2. 不能通過解引用重新更改地址對應的值
 * 3. 可以通過改變指向變數的值來更換地址中指向的值
 */

相關文章