浅谈C语言指针
什么是指針?
??在計算機科學中,指針(Pointer)是編程語言中的一個對象,利用地址,它的值直接指向存在電腦存儲器中的另一個地方的值。由于通過地址能找到所需的變量單位,可以說,地址指向該變量單元。因此,降低至形象化的稱為“指針”。意思是通過它能找到以它位地址的內存單元。
圖解指針:
代碼解析
#include <stdio.h>int main() {int a = 20; //在內存中開辟一段空間int *p = &a; //“&a”:將變量a的地址取出,使用“&”取地址操作符 //將a的地址存放在p變量中,p就是一個指針變量return 0; }總結
??指針就是變量,用來存放地址的變量。所以說,存放在指針中的值都會被當做地址來處理
為什么存在指針?
生活中例子
現實生活中我們管理土地的方式是:
國家→省→市→縣(區)→街道→樓→房間
??這樣做我們可以很好地將土地分區管理,然后通過一個地址就能找到對應的位置。可以方便有快捷的管理。
其實計算機中的內存管理也是采用了這樣的思路:
??將計算機中的內存分成很多小單元,每個單元都對應一個獨一無二的地址,這樣就一個地址表示一塊空間。
指針的運算
指針±整數
#include <stdio.h>int main() {int a = 10;char *pc = (char*)&n;int *pi = &n;printf("%p\n", &n); //0x00FFF121printf("%p\n", pc); //0x00FFF121printf("%p\n", pc+1); //0x00FFF122printf("%p\n", pi); //0x00FFF121printf("%p\n", pi+1); //0x00FFF125return 0; }指針-指針
用模擬實現strlen解析
int my_strlen(char *s) assert(s != NULL); {char *p = s;while(*p = '\0')p++;return p-s; }總結
??指針的類型決定了指針向前或者向后走一步有多大,也就是說指針的類型決定了在對指針進行使用時的權限有多大(能操作幾個字節)
??指針之間相加減是在計算兩個指針之間相差多少元素,并且只能在同一塊空間中進行。
在關系運算中,有以下標準規定:
??允許指向數組元素的指針與指向數組最后一個元素后面的那個內存位置的指針比較,但是不允許與指向第一個元素之前的那個內存位置的指針進行比較
二級指針
??指針變量也是變量,是變量就有地址,那么指針變量的地址存放在哪里?
??這就是二級指針!!!!
圖解二級指針
??a的地址存放在pa中,pa的地址存放在ppa中。所以說pa是一級指針,而ppa是二級指針。通過對ppa中的地址解應用可以找到pa,所以*ppa訪問的就是pa,再對pa進行解引用就可以找到a,也就是說:**ppa就是a
指針表達式解析
??當有代碼
char ch = 'a'; char *cp = &ch;??下面的代碼那些可以做左值?那些可以做右值?
&ch; //&ch是地址常量,不能做左值,只能做右值 cp; //cp是變量,可以做左值,也可以做右值 &cp; //&cp是地址常量,不能做左值,只能做右值 *cp+1; //*cp+1表達式的結果是常量,不能做左值,但可以做右值 *(cp+1); //*(cp+1)表示的是ch之后的一塊空間,可以做左值,也可以做右值 ++cp; //++cp在c語言中變量的前置++不能作為左值,只可以作為右值,但在c++中變量的前置++可以作為左值 cp++; //cp++在c語言中變量的后置++不能作為左值,只可以作為右值 *++cp; //*++cp表示的是ch的下一塊空間,可以做左值,也可以做右值 *cp++; //*cp++中++是后置的,是先用*cp在做++,所以既可以做左值,也可以做右值 ++*cp; //++*cp表達式是對*cp的前置++,所以不能做左值,只能做右值 (*cp)++; //(*cp)++表達式是對*cp的后置++,所以不能做左值,只能做右值 ++*++cp; //++*++cp是對ch的下一塊空間的內容做的前置++,所以不能做左值,只能做右值 ++*cp++; //++*cp++是對ch的內容做前置++,同時也是對cp進行后置++,所以不能做左值,只能做右值左值:強調的是空間/位置
右值:強調的是內容/結果
指針數組與數組指針
指針數組
??指針數組是一個存放指針的數組,例如:int arr[20],是一個類型為"int*"、名為“arr”、存放了20各元素的數組
數組指針
??數組指針是一個指針,我們知道整形指針“int *point”是一個能夠指向整形數據的指針,當然數組指針“int (*p)[10]”就是一個能夠指向數組的指針
代碼解析
int (*p)[10]; //1、p先和*結合,說明p是一個指針變量,然后指向的是一個大小為10個整數的數組,所以平時一個指針,指向一個數組,叫做數組指針 //要注意的是,[]的優先級要高于*,所以必須要加上()來保證p先和*結合,否則p將先和[]結合成為“int* p[10] ”,這樣就成了一個指針數組數組指針的使用
先分析一下以下代碼
int arr[10] = {0}; //arr: 表示數組首元素的地址 //&arr:表示數組的地址 //具體差異在哪里? printf("%p\n", arr);//輸出的是第一個元素的地址 printf("%p\n", arr+1);//輸出的是第二個元素的地址 printf("%p\n", &arr+1);//輸出的是整個之后的地址??從這里我們可以看出產生的結果是截然不同的,雖然數組的地址和首元素的地址值是相同的,但是意義不相同。既然出現了數組的地址,就需要存儲數組地址的容器,這時我們會考慮到用數組指針來存放數組的地址,由數組指針的定義得知,使用數組指針來存放數組的地址是再合適不過了。
??現在我們要將一個二維數組傳參,我們應該怎么做?
??通過上面的認識,來看一下下面的代碼
int arr[10];//數組 int *parr1[10];//指針數組 int (*parr2)[10];//數組指針 int (*parr3[10])[10];//存放數組指針的數組 //parr3是名字先和[10]結合,說明這是一個擁有10個元素的數組, //對于數組來說,去掉名字和[],其他的就是這個數組中存放的元素的類型,由(*)[]可知,這個數組中存放的是數組指針總結
- 上一篇: Scrapy 爬虫教程导航
- 下一篇: Linux 系统调用 Ptrace 详解