程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 不可或缺 Windows Native (7),windowsnative

不可或缺 Windows Native (7),windowsnative

編輯:關於C語言

不可或缺 Windows Native (7),windowsnative


[源碼下載]


不可或缺 Windows Native (7) - C 語言: 指針



作者:webabcd


介紹
不可或缺 Windows Native 之 C 語言

  • 指針



示例
cPointer.h

#ifndef _MYHEAD_POINTER_
#define _MYHEAD_POINTER_ 

#ifdef __cplusplus  
extern "C"
#endif  

char *demo_cPointer();

#endif  


cPointer.c

/*
 * 指針
 */

#include "pch.h"
#include "cPointer.h"
#include "cHelper.h"


void pointer_demo1();
void pointer_demo2();
void pointer_demo3();
void pointer_demo4();
void pointer_demo5();
void pointer_demo6();
void pointer_demo7();
void pointer_demo8();
void pointer_demo9();
void pointer_demo10();

char *demo_cPointer()
{
    // 指針的基本概念
    pointer_demo1();

    // 字符串指針
    pointer_demo2();

    // 把指針做為參數傳遞
    pointer_demo3();

    // 數組指針的運算
    pointer_demo4();

    // 二維數組的指針
    pointer_demo5();

    // 函數指針(指向函數的指針)
    pointer_demo6();

    // 指針型函數(函數返回值可以是一個指針)
    pointer_demo7();

    // 指針數組
    pointer_demo8();

    // 指針的指針
    pointer_demo9();

    // void 類型的指針
    pointer_demo10();

    return "看代碼及注釋吧";
}


// 指針的基本概念
void pointer_demo1()
{
    /*
     * 注:
     * 1、未經賦值的指針變量不能使用
     * 2、一個指針變量只能指向相同類型的變量,比如指針 p 如果指向了整形變量,就不能再指向字符變量或其他非整型類型的變量了
     */


    // 定義一個指針,並將其賦值為一個空指針(對應的宏定義 #define NULL 0)。所謂空指針就是不指向任何內容的指針
    int *p_empty = NULL; // 相當於 int *p = 0;


    // 定義一個整型變量,並初始化
    int i = 100;

    // *p - 代表定義一個名為 p 的指針。此處的“*”是類型說明符,表示 p 是一個指針
    // &i - 代表取變量 i 的地址。此處的“&”是取地址運算符,表示取變量 i 的地址
    int *p = &i;

    // *p - 代表取指針 p 所指向的內容。此處的“*”是取內容運算符,表示取指針 p 所指向的內容
    int j = *p;
}


// 字符串指針
void pointer_demo2()
{
    // 定義一個字符串指針(字符串是以'\0'結尾的)
    char *p = "i am webabcd";

    // p 就是字符串指針,p + 5 所指向的結果就是 webabcd
    char *name = p + 5;
    // 字符串長度
    int length = strlen(name); // 7,不包括 '\0'
    // 指針占用的內存空間
    int memory = sizeof(name); // 我這裡是 4 字節

    char *p_address = (char *)malloc(32);
    sprintf(p_address, "%p", name); // 指針 name 的地址值,我這裡是 32 位的,類似 6416C99D
    free(p_address);
}


// 把指針做為參數傳遞
void pointer_demo3()
{
    int m = 1;
    int n = 2;

    int *x = &m;
    int *y = &n;

    // 調用 swap 後: *x = m = 2, *y = n = 1
    void swap(int *i, int *j);
    swap(x, y);
}
void swap(int *i, int *j) // 交換兩個指針指向的整型值
{
    // 形參是實參的副本,被調用期間分配內存單元,調用結束立即釋放
    // 對於指針來說也是這樣的,只不過是 copy 了地址做為副本

    int temp;
    temp = *i;
    *i = *j;
    *j = temp;
}


// 數組指針的運算
void pointer_demo4()
{
    int ary[] = { 11, 22, 33, 44, 55, 66 };
    // 因為 ary 是數組的首地址,所以 ary == &ary[0]
    if (ary == &ary[0])
    {
        // ary 是數組的首地址,即數組第一個元素的地址,對其取內容後就是數組第一個元素的內容,結果為 11
        int x1 = *ary;

        // 數組指針是可運算的,運算的是元素在數組中的位置索引,拿 ary + 2 舉例,ary 數組第 1 個元素的指針,加 2 後就是數組第 3 個元素的指針,取其內容後結果為 33
        int x2 = *(ary + 2);

        char *p0_address = (char *)malloc(32);
        sprintf(p0_address, "%p", ary); // 假定此處指針本身的值為:0535DC30 的話
        free(p0_address);

        char *p1_address = (char *)malloc(32);
        sprintf(p1_address, "%p", ary + 1); // 那麼如果整型是 4 字節的話,則此處指針本身的值為 0535DC34  
        free(p1_address);
    }


    // 再來一個指針運算的例子(將字符串 str1 復制到字符串 str2)
    char str1[] = "i am webabcd", str2[20], *p1, *p2;
    p1 = str1; p2 = str2;
    for (; *p1 != '\0'; p1++, p2++)
        *p2 = *p1;
    *p2 = '\0';
    p1 = str1; p2 = str2; // 指回數組首地址
}


// 二維數組的指針
void pointer_demo5()
{
    int ary[2][6] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

    // 定義一個二維數組的指針:類型說明符(*指針變量名)[列數,即二維長度]
    int(*p)[6] = ary;

    // p 就是 ary
    if (p == ary)
    {
        // 這裡要好好理解(拿指針的指針去理解,ary 相當於二級指針,ary[i] 相當於一級指針)
        // ary[1] 是二維數組第 2 行的一維數組的首地址,也就是說其相當於 &ary[1][0]
        // ary + 1 指向的是 ary[1],對其取內容 *(ary + 1) 就是 ary[1] 了
        // ary[1] = &ary[1][0] = *(ary + 1)

        // 再加深理解一下:ary 是二維數組的首地址,*ary 是二維數組第 1 行的一維數組的首地址,*(ary + 1) 是二維數組第 2 行的一維數組的首地址


        // 取第 2 行,第 6 列的數據,結果為 11
        int x = p[1][5];


        // 再加深理解一遍
        // p 是指向二維數組的指針
        // p + 1 指向的是 ary[1],所以 *(p + 1) 就是 ary[1]
        // *(p + 1) + 5 指向的是 p[1][5],所以 *(*(p + 1) + 5) 就是 p[1][5],結果為 11
        int y = *(*(p + 1) + 5); 
        
        // ary[i] = *(ary+i), ary[i]+j = *(ary+i)+j, ary[i][j] = *(*(ary+i)+j)
    }
}


// 函數指針(指向函數的指針)
void pointer_demo6()
{
    // 定義一個函數指針:類型說明符(*指針變量名)();
    int(*pmax)(int a, int b);

    // 讓函數指針指向函數 my_max
    int my_max(int a, int b);
    pmax = my_max;

    int x = 10, y = 100;
    // (*pmax) 就是函數 my_max,結果為 100
    int z = (*pmax)(x, y); 


    // 函數指針當然也是指針,可以取其地址
    char *p_address = (char *)malloc(32);
    sprintf(p_address, "%p", &pmax);
    free(p_address);
}
int my_max(int a, int b) // 取兩個整型的最大值
{
    if (a > b)
        return a;
    return b;
}


// 指針型函數(函數返回值可以是一個指針)
void pointer_demo7()
{
    // 函數名之前加“*”號表明這是一個指針型函數,即返回值是一個指針。類型說明符表示了返回的指針值所指向的數據類型

    char *day_name(int n);
    // 結果:星期五
    char *result = day_name(5);
}
char *day_name(int n)
{
    static char *name[] =
    { 
        "星期日",
        "星期一",
        "星期二",
        "星期三",
        "星期四",
        "星期五",
        "星期六"
    };

    return ((n < 0 || n > 6) ? "unknown" : name[n]);
}


// 指針數組
void pointer_demo8()
{
    char *str1 = "webabcd";
    char *str2 = "wanglei";

    // 定義一個指針數組,即數組中的每一個元素都是一個指針
    char *p[2] = { str1, str2 }; // str1 和 str2 都是指針

    // 結果為 wanglei
    char *x = p[1]; // p[1] - 指針數組中的第 2 個指針
}


// 指針的指針
void pointer_demo9()
{
    // 指針數組其實就是指針的指針
    char *name[] = { "webabcd", "wanglei" };

    // 通過“**”定義一個指針的指針
    char **p = name;
    p++;

    // 結果為 wanglei
    char *myName = *p; // p 是指針的指針(二級指針),*p 是指針(一級指針)
}


// void 類型的指針
void pointer_demo10()
{
    void *void_pointer();

    // void 類型的指針 - 內存中的數據的類型要由用戶來指定
    char *name = (char *)void_pointer();
}
void *void_pointer() // 返回 void 類型的指針
{
    return "wanglei";
}



OK
[源碼下載]

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved