1. 程式人生 > >C語言指標例項詳解

C語言指標例項詳解

#include <stdio.h>

//*a是指標變數  a就代表儲存地址
void test1(int *a) {
    *a = 2;
    return;
}

* test2(int *a) {
    *a = 323;
    return a;
}
int main()
{
    
    printf("------------------------地址--------------------------\n");
    int var1;
    int var2[10];
    printf("var1變數的地址: %p\n", &var1);
    printf("var2變數的地址: %p\n", &var2);


    printf("------------------------指標與地址--------------------------\n");
    int var = 20; /*實際變數的宣告*/
    int *ip;  /*指標變數的宣告*/
    /*

        int var = 20;
        int ip;
        var 等價於 ip
        &ip  等價於 &var
        &ip 就相當於儲存地址


        int var = 20; 
        int *ip;  
        var 等價於 *ip  *ip 相當於一種特殊的變數名  而ip就相當於 省略了& 的儲存地址
        ip  等價於 &var
        ip 就相當於儲存地址
        
    */
    ip = &var;//指向地址
    printf("var 變數的地址:%p\n", &var);
    printf("在指標變數中儲存的地址 %p\n", ip);
    printf("使用指標訪問值 %d\n", *ip);
    printf("--------------------------------------------------\n");
    int *ptr = NULL;
    printf("ptr 的地址是 %p\n", ptr);
    printf("--------------------------------------------------\n");


    int  var12[] = { 10, 100, 200 };
    int  i, *ptr1;

    /* 
    指標中的陣列地址  var12 預設 第一塊地址    
    */
    ptr1 = var12;
    printf("var12 等於 &var12[i] 第一塊地址是 %p\n", var12);
    printf("&var12[1] 指定第二塊地址是 %p\n", &var12[1]);
    for (i = 0; i < 3; i++)
    {

        printf("儲存地址:var12[%d] = %p\n", i, ptr1);
        printf("儲存值:var12[%d] = %d\n", i, *ptr1);

        /* 移動到下一個位置 32位 c int 型別是 4個位元組  所以地址是以 四個累加輸出 */
        ptr1++;
    }

    printf("-----------------指標陣列和陣列指標---------------------------------\n");
    printf("-----------陣列指標-----------\n");

    /* 陣列指標 */
    int a[2][2] = { {1,2},{13,14} };
    int(*b)[2];
    b = a;
    //b = &a[0][0];
    //指向地址
    //b[0] 相當於 第一行陣列的地址  
    printf("b儲存值:(指向地址)= %p,%p\n",  b[0], (b[0] + 1));
    printf("a儲存值:(指向地址)= %p,%p\n", a[0], (a[0] + 1));

    //b[1] 相當於 第二行陣列的地址  地址加一 依次輸出地址
    printf("儲存值:(指向地址)= %p,%p\n", b[1], (b[1]+1));

    //b[0] 相當於 第一行陣列的地址  b[0][0] 相當於 第一行陣列的第一個值
    printf("儲存值:(輸出第一行陣列的地址的值)= %d,%d\n", b[0][0], b[0][1]);
    //因為前面加了地址符所以輸出的是 第一行陣列的 各個地址
    printf("儲存值:(輸出第一行陣列每個的地址)= %p,%p\n", &b[0][0], &b[0][1]);


    //指向陣列的 指標陣列  *b[0] 指向第一個陣列  預設的是第一個數
    printf("儲存值:(指向陣列的值)= %d,%d\n", *b[0], (*b[0]+1));
    printf("儲存值:(指向陣列的值)= %d,%d\n", *b[1], (*b[1]+1));


    printf("-----------指標陣列-----------\n");
    /* 指標陣列 */
    int c[2][2] = { {5,6},{17,18} };
    int *d[2];
    *d = c;//
    //*d(這代表 整個陣列 的地址) *d[0] 代表地址的第一個值  *d[0](預設的) 
    printf("d儲存值:(預設輸出第一個地址的第一個值)= %d\n", *d[0]);
    printf("&[0][0]正經的第一個地址:(指向陣列的地址)= %p\n", &d[0][0]);
    printf("d[0]預設的第一個地址:(指向陣列的地址)= %p\n", d[0]);
    printf("*d預設的第一個地址:(指向陣列的地址)= %p\n", *d);
    printf("-----------拓展-----------\n");
    printf("*(*d+1)輸出地址的值:(指向陣列的值)= %d\n", *(*d+1));
    printf("*(&d[0][0])輸出地址的值:(指向陣列的值)= %d\n", *(&d[0][0]));
    printf("&(*(*d + 1))指向陣列的地址:(指向陣列的地址)= %p\n", &(*(*d + 1)));
    printf("d野指標:(指向陣列的地址)= %p\n", d);
    printf("-----------函式指標-----------\n");
    int h = 3;
    printf("h未呼叫之前 %d,地址 %p\n", h, &h);
    test1(&h);
    printf("h呼叫之後 %d,地址 %p\n", h, &h);
    printf("-----------函式返回指標-----------\n");
    int *u =2321;//指向常量
    printf("u未呼叫之前 %d \n", u);
    //printf("*u未呼叫之前 %d\n", *u); --- 報錯
    printf("&u未呼叫之前的地址 %p\n", &u); 
    int *u1;
    u1 = &u;//指向地址
    printf("*u1未呼叫之前的值 %d\n", *u1);
    printf("u1未呼叫之前的地址 %p\n", u1);


    //printf("u1未呼叫之前 %d \n", u1);
    //printf("*u未呼叫之前 %d\n", *u);
    //printf("*u1未呼叫之前 %p\n", *(&u1));

    u = test2(&h);
    printf("*u呼叫之後 %d,地址 %p\n", *u, u);
    system("pause");
    return 0; 
    
}


/*
備註
32位編譯器

char :1個位元組
char*(即指標變數): 4個位元組(32位的定址空間是2^32, 即32個bit,也就是4個位元組。同理64位編譯器)
short int : 2個位元組
int:  4個位元組
unsigned int : 4個位元組
float:  4個位元組
double:   8個位元組
long:   4個位元組
long long:  8個位元組
unsigned long:  4個位元組


64位編譯器

char :1個位元組
char*(即指標變數): 8個位元組
short int : 2個位元組
int:  4個位元組
unsigned int : 4個位元組
float:  4個位元組
double:   8個位元組
long:   8個位元組
long long:  8個位元組
unsigned long:  8個位元組
*/