1. 程式人生 > >C筆記列表

C筆記列表

OS 現在 add variable 高級 理解 什麽 char 返回值

筆記列表

   



    指針是一個變量,其值為另一個變量的地址,即,內存位置的直接地址。就像其他變量或常量一樣,您必須在使用指針存儲其他變量地址之前,對其進行聲明。

    要理解指針就要先理解計算機的內存。計算機內存會被劃分為按順序編號的內存單元。每個變量都是存儲在內存單元中的,稱之為地址。

    #include <stdio.h>

    int main ()
    {
        int var = 20;   /* 實際變量的聲明 此時的 VAR 這個變量是存在某個地址的,地址對應某個內存單元,該單元中存儲了數據20 */
        int *ip;         /*
指針變量的聲明 定義了一個指針 即一個內存單元的地址變量 */ ip = &var; /* 在指針變量中存儲 var 的地址 就是將地址值賦值給指針這個變量*/ /* 在指針變量中存儲的地址 利用&符號直接輸出了var所存儲的數據的內存單元的地址*/ printf("Address of var variable: %p\n", &var ); /* 在指針變量中存儲的地址 ip代表的是這個賦值到的地址的值 所以輸出的是地址值 */ printf("Address stored in ip variable: %p\n
", ip ); /* 使用指針訪問值 *ip代表的是定義到這個內存單元之後,內存單元中所存儲的數據的值也就是將20賦值給var中20這個值 */ printf("Value of *ip variable: %d\n", *ip ); return 0; } 指針是一個變量,所以可以使用任何合法的變量名。在大多數的操作系統上,程序不允許訪問地址為 0 的內存,因為該內存是操作系統保留的。 然而,內存地址 0 有特別重要的意義,它表明該指針不指向一個可訪問的內存位置。 但按照慣例,如果指針包含空值(零值),則假定它不指向任何東西。 所有指針在創建時都要初始化,如果不知道他指向什麽就講
0 賦值給他。必須初始化指針,沒有被初始化的指針被稱為失控指針(野指針)。 #include <stdio.h> int main () { int *p = 0; int a ; p = &a; printf ("輸入一個數字\n"); scanf ("%d",p); printf("%d\n",*p); } 實例定義了變量 a 和指針變量 p。p = &a;表示指針變量指向了變量 a,p 中存放的地址為 a 的地址 &a,*p 所指的是 p 中存放的地址 a 內存單元中的值。 /*按照偏移值訪問函數形參內容實驗*/ //二級指針 void Pros(char* a,int b,int e,char et) { char **p=&a; //a==*p printf("%p %p %p %p \n%p\n",&a,p,a,*p,&b); printf("%s\n",*p); p++; printf("%d\n",*p); p++; printf("%d\n",*p); p++; printf("%c\n",*p); return; } //一級指針訪問 void Test(char* a,int b) { char *p=(char*)&a; //a!=*p; //printf("%p %p %p %p\n",&a,p,a,*p); //printf("%p\n",&b); //得出結果一級指針自加+1 二級指針自按照元素內容大小自加 //printf("%d %p\n",*(++p),p); //printf("%d %p\n",*(p+8),p+8); //a=a[0]一個printf函數以‘\0‘結束 //此時p=&a把元素首地址給了p或者說a只記錄一個元素首地址的地址 //同等匯編語句 a:db ‘Hello‘ b:db ‘16‘ //所以 p=&a != p=a ; /* char *a="Hello"; char *b=(char*)&a; printf("%p %p %p %p",&a,b,a,&(a[0])); */ //printf("%c %p %p\n",*a,a,&(a[0])); //printf("%c %p %p\n",*(a+1),a+1,&(a[1])); printf("%c\n",*(*(char**)p)); //if p=a; *p=a; p=a; printf("%s",p); return; } int main() { //Pros("Hello",5,66666,‘a‘); Test("Hello",16); //指針轉換問題 /* char *a="Hello";//&a變量裏面存儲著a所指向的變量地址 //char **p=&a; char *b=(char*)&a; char **p=&a; printf("%p %p %p %p\n",&a,b,a,*b); printf("%p %c\n",&(*a),*(&(*(a+1)))); printf("%p %c\n",a,*a);//此時a->H,*a=H; printf("%p %c\n",(*p),*(*p)); //p=&a,*p=a所指向的第一個元素的地址還需要一解才能訪問正確數據 //所以1級指針需要解2次 所以進行強制轉換 printf("%c \n",*(*(char**)b)); //原試解 現在b=&a,*b= &a->a所以如果此時想正確訪問H必須在解 */ return 1; } 參考地址 指針的一些復雜說明: int p; -- 這是一個普通的整型變量 int *p; -- 首先從 p 處開始,先與*結合,所以說明 p 是一個指針, 然後再與 int 結合, 說明指針所指向的內容的類型為 int 型。所以 p 是一個返回整型數據的指針。 int p[3] -- 首先從 p 處開始,先與[] 結合,說明 p 是一個數組, 然後與 int 結合, 說明數組裏的元素是整型的, 所以 p 是一個由整型數據組成的數組。 int *p[3]; -- 首先從 p 處開始, 先與 [] 結合, 因為其優先級比 * 高,所以 p 是一個數組, 然後再與 * 結合, 說明數組裏的元素是指針類型, 然後再與 int 結合, 說明指針所指向的內容的類型是整型的, 所以 p 是一個由返回整型數據的指針所組成的數組。 int (*p)[3]; -- 首先從 p 處開始, 先與 * 結合,說明 p 是一個指針然後再與 [] 結合(與"()"這步可以忽略,只是為了改變優先級), 說明指針所指向的內容是一個數組, 然後再與int 結合, 說明數組裏的元素是整型的。所以 p 是一個指向由整型數據組成的數組的指針。 int **p; -- 首先從 p 開始, 先與 * 結合, 說是 p 是一個指針, 然後再與 * 結合, 說明指針所指向的元素是指針, 然後再與 int 結合, 說明該指針所指向的元素是整型數據。由於二級指針以及更高級的指針極少用在復雜的類型中, 所以後面更復雜的類型我們就不考慮多級指針了, 最多只考慮一級指針。 int p(int); -- 從 p 處起,先與 () 結合, 說明 p 是一個函數, 然後進入 () 裏分析, 說明該函數有一個整型變量的參數, 然後再與外面的 int 結合, 說明函數的返回值是一個整型數據。 int (*p)(int); -- 從 p 處開始, 先與指針結合, 說明 p 是一個指針, 然後與()結合, 說明指針指向的是一個函數, 然後再與()裏的 int 結合, 說明函數有一個int 型的參數, 再與最外層的 int 結合, 說明函數的返回類型是整型, 所以 p 是一個指向有一個整型參數且返回類型為整型的函數的指針。 int *(*p(int))[3]; -- 可以先跳過, 不看這個類型, 過於復雜從 p 開始,先與 () 結合, 說明 p 是一個函數, 然後進入 () 裏面, 與 int 結合, 說明函數有一個整型變量參數, 然後再與外面的 * 結合, 說明函數返回的是一個指針, 然後到最外面一層, 先與[]結合, 說明返回的指針指向的是一個數組, 然後再與 * 結合, 說明數組裏的元素是指針, 然後再與 int 結合, 說明指針指向的內容是整型數據。所以 p 是一個參數為一個整數據且返回一個指向由整型指針變量組成的數組的指針變量的函數。

C筆記列表