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、有關指針的小結