C語言指針的理解

一:指針是什麼

1. 指針是**變量**
2. 指針是用來存放地址的變量(存放變量的地址),用來表示指定內存空間的地址。
3. 地址的大小是**固定**的:佔4個字節(32位系統)或者8個字節(64位系統)
4. 指針**存在類型**,如整型指針、字符指針等,其類型決定了指針加減運算時移動的步長大小。同時指針能夠進行**算術、關係運算**。

二:字符指針

字符指針:是指存放char類型變量的地址的變量,稱爲字符指針。

字符指針能夠有如下3中方式進行表示:
方式1:segmentfault

char  a = 'c';
char* p = &a;   // 把字符變量a的地址賦值給字符指針p
*p = 'd';            // 修改字符指針p所指向內存空間存儲的內容
printf("%c\n", *p);  // 輸出:d

方式2:數組

char arr[] = "abcdef";  // arr數組的長度爲7,不是6
char *p = arr;    // 數組名就是數組首元素的地址
printf("%c\n", *p);  // 解引用後獲得字符a                                輸出:a
printf("%s\n", p);   // 輸出字符指針p所指向的字符串               輸出:abcdef
printf("%s\n", arr); // 數組名就是首元素的地址,故與p相同:輸出:abcdef

方式3:ide

char *p = "abcdef"; // 該字符串是一個常量字符串,且把該字符串的首字符的地址放到字符指針p中
// 該字符串在內存中的表示是:a b c d e f \0,把該字符串的地址存到字符變量p中,該地址爲字符串首字符的地址。
printf("%c\n", *p);  // p指向的是字符串首字符的地址,即'a'的地址,則解引用後,獲得字符'a'; 輸出:a
printf("%s\n", p);   // 把字符指針p所指向的字符串給打印出來, 輸出:abcdef

2.1 常量字符串

  1. 常量字符串的內容是不能被修改的;
  2. 內存中只存在一份,多個字符指針指向相同的字符串,則這些指針中存放的地址相同;
  3. 將其賦值給字符指針時,是把其首字符的地址(其地址)賦值給(傳給)字符指針。
    以下面例子:網站

    int main()
    {
    char* p = "abcdef"; // 該字符串是一個常量字符串,且把該字符串的首字符的地址放到字符指針p中
    *p = '1';
    printf("%s\n", p);   // 把字符指針p所指向的字符串給打印出來, 輸出:abcdef
    return 0;
    }

    C語言指針的理解
    C語言指針的理解
    C語言指針的理解
    C語言指針的理解
    因此正確的寫法:指針

    int main()
    {
    const char* p = "abcdef"; // 
    *p = '1';                          // 此時編譯都過不去的。
    printf("%s\n", p);   // 把字符指針p所指向的字符串給打印出來, 輸出:abcdef
    return 0;
    }

    例子2:code

    int main()
    {
    // 對於常量字符串,C會把其存儲到單獨的一個內存區域,當多個指針同時指向同一個字符串時,它們指向的是同一塊內存
    // 可是用相同的常量字符串去初始化不一樣的數組時,就會指向不一樣的內存塊。
    char arr1[] = "hello world"; // 將字符串放到數組arr1中,不是常量字符串
    char arr2[] = "hello world"; // 
    const char* p1 = "hello world"; // 爲常量字符串
    const char* p2 = "hello world"; // 爲常量字符串,和上面的爲同一個,爲了節省內存空間,在內存中只儲存一份
    
    if (arr1 == arr2)
        printf("arr1 == arr2\n"); 
    else
        printf("arr1 != arr2\n");// 執行
    if (p1 == p2)
        printf("p1 == p2\n");// 執行
    else
        printf("p1 != p2\n");
    printf("arr1 and arr2's address = %p and %p\n", arr1, arr2); // 
    printf("p1   and p2's   address = %p and %p\n", p1, p2);
    return 0;
    }

    C語言指針的理解
    註釋:兩個技術論壇網站:
    segmentfault.com(中國網站,段錯誤)
    stackoverflow.com(國外網站,棧溢出錯誤)blog

    三:指針數組

    指針數組:是指存放指針的數組,是一個數組,數組的元素是地址。
    如:內存

    int arr1[5] = {0}; // 整型數組,由於數組的元素是整型
    char arr2[5] = {0}; // 字符數組,由於數組的元素是字符類型
    int* arr3[3];           // 存放整型指針的數組----指針數組
    char* arr4[4];        // 存放字符指針的數組----指針數組

    理解指針數組的例子(但實際不是這麼用指針數組的):字符串

    int main()
    {
    int  a = 10;
    int  b = 20;
    int  c = 30;
    int* arr[3] = { &a, &b, &c }; // arr就是一個指針數組,且爲一個整型指針數組,由於存放的是整型變量的地址。
    int i = 0;
    for (i = 0; i < 3; i++)
    {
        printf("%d\t", *(arr[i]));// 10 20 30
    }
    return 0;
    }

    指針數組的應用:get

    int main()
    {
    int arr1[] = { 1,2,3,4,5 };
    int arr2[] = { 6,7,8,9,10};
    int arr3[] = { 11,12,13,14,15 };
    int* parr[3] = { arr1, arr2, arr3 };
    int i, j;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 5; j++)
        {
            // 如下三種寫法都對:均可以一次打印每一個數組的元素
            // 找到數組的每一個元素:parr[i],其中每個元素是一個數組(arr1..3)
            // +j表示找到指定數組中第j個元素的地址,在對其進行解引用,則找到對應的值
            //printf("%d\t", *(parr[i] + j)); // 獲得第i行的地址後向後偏移j的地址,再進行解引用
    
            //printf("%d\t", parr[i][j]);
            printf("%d\t", *(*(parr+i)+j));
        }
        printf("\n");
    }
    return 0;
    }

    C語言指針的理解

四:數組指針

數組指針:是一個指針,該指針指向的是一個數組

相關文章
相關標籤/搜索