1、什麼是指針? 指針就是地址。 為了說清楚什麼是指針,必須先弄清楚數據在記憶體中是如何存儲的,又是如何讀取的。 如果在程式中定義了一個變數,在對程式進行編譯時,系統就會給這個變數分配記憶體單元。編譯系統根據程式中定義的變數的類型,分配一定長度的空間。 記憶體區的每一個位元組都會有一個編號,這就是“地址”, ...
1、什麼是指針?
指針就是地址。
為了說清楚什麼是指針,必須先弄清楚數據在記憶體中是如何存儲的,又是如何讀取的。
如果在程式中定義了一個變數,在對程式進行編譯時,系統就會給這個變數分配記憶體單元。編譯系統根據程式中定義的變數的類型,分配一定長度的空間。
記憶體區的每一個位元組都會有一個編號,這就是“地址”,它相當於旅館中的房間號,在地址所標誌的記憶體單元中存放的數據則相當於旅館房間中居住的旅客。
一個變數的地址,稱為該變數的指針。
2、指針變數
(1)、存放地址的變數就叫指針變數。
(2)、定義指針變數的一般形式為:類型名 *指針變數名; 例如:int * pointer_1;
(3)、指針變數前面的“*”表示該變數的類型為指針類型。
(4)、一個變數的指針的含義包括兩個方面:一是以存儲單元編號表示的地址;二是它指向的存儲單元的數據類型。
(5)、如何表示指針類型。指向整型數據的指針類型表示為“int *”,讀作:指向int的指針或int 指針。
2.1、如何引用指針變數
(1)、給指針變數賦值
int a =10; int *p;//定義一個指針變數 p p=&a;//把a的地址賦給指針變數p
指針變數p的值是變數a的地址,p指向a;
(2)、引用指針變數指向的變數
printf("%d\n",*p);//輸出變數a的值
(3)、引用指針變數的值
printf("%o\n",p);//以八進位形式輸出變數a的地址,即指針變數p的值
註意:(1)、& 取地址運算符。&a是變數a的地址。 (2)、*指針運算符。
3、通過指針引用數組
(1)、數組元素的指針
1、一個變數有地址,一個數組包含若幹個元素,每個數組元素都在記憶體中占用著記憶體單元,它們都有相應的地址。指針變數既可以指向變數,當然也可以指向數組元素。所謂數組元素的指針其實就是數組元素的地址。
2、引用數組元素有兩種方法:(1)、下標法;(2)、指針法。
3、註意:數組名不代表整個數組,只代表數組的首地址,
(2)、在引用數組元素時指針的運算
在指針指向數組元素時,我們可以進行如下運算:
int a[10]; int *p; p =&a;//等價於p=&a[0]
1、p+1則指向a[1],即p指向了數組元素中的一個元素,則p+1則指向數組元素中的下一個元素,p-1則指向數組元素中的上一個元素。
2、如果p的初始值為&a[0],則p+i和a+i就是數組元素a[i]的地址。也就是說p+i和a+i指向a數組序號為i的元素。註意:這裡說的a代表的是數組首元素的地址。
3、*(p+i)和*(a+i)是p+i和a+i所指向的數組元素,即a[i]。
(3)、通過指針引用數組元素
通過指針引用數組元素,有2種方法:
1、下標法:
#include <stdio.h> int main(int argc,char **argv) { int a[10]; int i; printf("Please input 10 integer numbers: "); for(i=0;i<10;i++) { scanf("%d",&a[i]); } for(i=0;i<10;i++) { printf("%d\n",a[i]); } return 0; }
2、指針法
(1)、通過數組名計算數組元素的地址,找出元素的值。
#include<stdio.h> int main(int argc,char *argv[]) { int a[10]; int i; printf("Please input 10 integer numbers: "); for(i=0;i<10;i++) { scanf("%d",&a[i]); } for(i=0;i<10;i++) { printf("%d",*(a+i)); } printf("\n"); return 0; }
(2)、用指針變數指向數組元素
#include<stdio.h> int main(int argc,char *argv[]) { int a[10]; int i; int *p; printf("Please input 10 integer numbers: "); for(i=0;i<10;i++) { scanf("%d",&a[i]); } for(p=a;p<(a+10);p++) { printf("%d",*p); } printf("\n"); return 0; }
(4)、用數組名作函數參數
int main() { void fun(int arr[],int n);//對fun函數的聲明 int array[10];//定義array數組 . . . fun(array,10);//用數組名做函數的參數 return 0; } //定義fun函數 void fun(int arr[],int n) { .... }
array是實參數組名,arr為形參數組名。當用數組名作形參時,如果形參數組中各元素的值發生變化,實參數組元素的值隨之變化。為什麼會這樣呢?
在該函數被調用時,系統會在fun函數中建立一個指針變數arr,用來存放從主調函數傳遞過來的實參數組首元素的地址。
當arr接收了實參數組的首元素地址後,arr就指向實參數組首元素,也就是指向array[0]。因此,*arr就是array[0]。arr+1指向array[1],arr+2指向array[2],arr+3指向array[3]。也就是說:*(arr+1)、*(arr+2)、*(arr+3)分別是array[1]、array[2]、array[3]。
C語言調用函數時虛實結合的方法都是採用“值傳遞”方式,當用變數名作為函數參數時傳遞的是變數的值,當用數組名作為函數參數時,有於數組名代表的是數組首元素地址,因此傳遞的值是地址,所以要求形參為指針變數。
(5)、通過指針引用多維數組
指針變數可以指向一維數組中的元素,也可以指向多維數組中的元素。
4、通過指針引用字元串
(1)、字元串的引用方式
(2)、字元指針作函數參數
(3)、使用字元指針變數和字元數組的比較
5、指向函數的指針
(1)、什麼是函數指針?
如果在程式中定義了一個函數,在編譯時,編譯系統為函數代碼分配一段存儲空間,這段存儲空間的起始地址(又稱入口地址)稱為這個函數的指針。
可以定義一個指向函數的指針變數,用來存放某一函數的起始地址,這就意味著此指針變數指向該函數,例如:
int (*p)(int ,int);
定義p是一個指向函數的指針變數,它可以指向函數的類型為整形且有兩個整型參數的函數。p的類型用int (*)(int int)表示。
在這裡我們得瞭解一下指針函數與函數指針的區別。
(2)、用函數指針變數調用函數
(3)、怎樣定義和使用指向函數的指針變數
(4)、用指向函數的指針作函數參數
6、返回指針值的函數
7、指針數組和多重指針
(1)、什麼是指針數組
(2)、指向指針數據的指針
(3)、指針數組作main函數的參數
1、int main()
或
int main(void)
括弧中是空的或有"void",表示main函數沒有參數,調用main函數時不必給出實參。
2、int main(int argc,char *argv[])
其中argc和argv就是main函數的參數,它們是程式的“命令行參數”。
argc(argument count的縮寫,意思是參數個數);
argv(argument vector的縮寫,意思是參數向量),它是一個*char 指針數組,數組中每一個元素(其值為指針),指向命令行中的一個字元串。
-----------------------------------------------
8、動態記憶體分配與指向它的指針變數
(1)、什麼是記憶體的動態分配
(2)、怎樣建立記憶體的動態分配
(3)、void指針類型
9、有關指針的小結