C语言—指针基础
如果想更詳細(xì)的了解指針的知識(shí)點(diǎn)可以觀看我的另外一篇博客。
指針高級(jí):https://blog.csdn.net/qq_46485161/article/details/115037692
內(nèi)容目錄
- 地址和指針的概念
- 指針和指針變量
- 給指針賦值
- 指針運(yùn)算符
- 指針的算術(shù)運(yùn)算
- 指針比較
- 指針按地址傳遞
- 指針與一維數(shù)組
- 數(shù)組作參數(shù)傳遞
- 整型數(shù)組作為返回值
- 指向字符串常量的字符指針
- 字符數(shù)組與字符指針的區(qū)別
- 字符數(shù)組作為返回值
地址和指針的概念
為了說(shuō)清楚什么是指針,必須弄清楚數(shù)據(jù)在內(nèi)存中是如何存儲(chǔ)的,又是如何讀取的。
內(nèi)存區(qū)的每一個(gè)字節(jié)有一個(gè)編號(hào),這就是“地址” 。如果在程序中定義了一個(gè)變量,在對(duì)程序進(jìn)行編譯時(shí),系統(tǒng)就會(huì)給這個(gè)變量分配內(nèi)存單元。
1、按變量地址存取變量值的方式稱(chēng)為“直接訪(fǎng)問(wèn)”方式 ,例如:
printf(″%d″,i); scanf(″%d″,&i); k=i+j;2、另一種存取變量值的方式稱(chēng)為“間接訪(fǎng)問(wèn)”的方式。即,將變量i的地址存放在另一個(gè)變量中。
在C語(yǔ)言中,指針變量是一種特殊的變量,它是存放地址的。假設(shè)我們定義了一個(gè)指針變量i_pointer用來(lái)存放整型變量的地址,它被分配地址為(3010)、(3011)的兩個(gè)字節(jié)。可以通過(guò)語(yǔ)句:i_pointer =&i;
將i的地址(2000)存放到i_pointer中。這時(shí), i_pointer的值就是(2000) ,即變量i所占用單元的起始地址。要存取變量i的值,可以采用間接方式:先找到存放“i的地址”的變量i_pointer ,從中取出i的地址(2000),然后到2000 、 2001字節(jié)取出i的值
指針和指針變量
指針和指針變量的定義:
一個(gè)變量的地址稱(chēng)為該變量的“指針”。
例如,地址2000是變量i的指針。
如果有一個(gè)變量專(zhuān)門(mén)用來(lái)存放另一變量的地址(即指針),則它稱(chēng)為“指針變量”。
上述的i_pointer就是一個(gè)指針變量。
指針變量的值(即指針變量中存放的值)是地址(即指針)。
請(qǐng)區(qū)分“指針”和“指針變量”這兩個(gè)概念。
變量的指針和指向變量的指針變量
1、定義一個(gè)指針變量
定義指針變量的一般形式為
基類(lèi)型 *指針變量名;
int *ptr;
說(shuō)明
指針變量的類(lèi)型:指明了該指針指向的內(nèi)存空間所存儲(chǔ)的數(shù)據(jù)類(lèi)型。
定義中的“”表示所定義的變量是指針變量。變量名是ptr,而非ptr。
注意:指針變量中只能存放地址(指針),不要將一個(gè)整數(shù)(或任何其他非地址類(lèi)型的數(shù)據(jù))賦給一個(gè)指針變量
給指針賦值
1、通過(guò) & 運(yùn)算符為指針賦值,例如:
ptr_var = &var;
2、通過(guò)另一個(gè)指向相同類(lèi)型數(shù)據(jù)項(xiàng)的指針變量對(duì)指針進(jìn)行賦值,例如:
ptr_var2 = ptr_var;
3、給指針變量賦值為符號(hào)常量NULL
例如:float *ptr_var3=NULL;
說(shuō)明:NULL是一個(gè)空指針,表示該指針變量的值沒(méi)有意義。作用是為了避免對(duì)沒(méi)有被初始化的指針變量的非法引用。NULL 的定義在“stdio.h”中。
4、通過(guò)指針為變量賦值
例如:
指針運(yùn)算符
&是一元運(yùn)算符,它返回操作數(shù)的內(nèi)存地址
例如:
*是 &的反運(yùn)算符,它也是一元運(yùn)算符,返回指針指向的內(nèi)存位置中的值
例如:
對(duì)“&”和“”運(yùn)算符說(shuō)明:
(“&”和“”兩個(gè)運(yùn)算符的優(yōu)先級(jí)別相同,但按自右而左方向結(jié)合)
如果已執(zhí)行了語(yǔ)句 pointer_1=&a; pointer_2=&a ;
(1) pointer_2 =&* pointer_1 ?
先進(jìn)行* pointer_1的運(yùn)算,它就是變量a,再執(zhí)行&運(yùn)算。&* pointer_1與&a相同,即變量a的地址,就是將&a(a的地址)賦給pointer_2
(2) &a? &a?
先進(jìn)行&a運(yùn)算,得a的地址,再進(jìn)行運(yùn)算。即&a所指向的變量,也就是變量a。&a和pointer_1的作用是一樣的,它們都等價(jià)于變量a。即&a與a等價(jià)。
(3) (pointer_1)++ 和 pointer_1++
pointer_1++:++和為同一優(yōu)先級(jí)別,而結(jié)合方向?yàn)樽杂叶?#xff0c;因此它相當(dāng)于(pointer_1++)。由于++在pointer_1的右側(cè),是“后加”,因此先對(duì)pointer_1的原值進(jìn)行運(yùn)算,得到a的值,然后使pointer_1的值改變,這樣pointer_1不再指向a了。
(*pointer_1)++: *pointer_1相當(dāng)a,所以整個(gè)表達(dá)式相當(dāng)于a++
指針的算術(shù)運(yùn)算
兩種形式:指針±整數(shù) 或者 指針 - 指針
注:①指針與整型值加減的結(jié)果是指針,表示使該指針指向該指針下移或上移存儲(chǔ)單元個(gè)數(shù)(整型值)之后的內(nèi)存地址。存儲(chǔ)單元的大小就是該指針的數(shù)據(jù)類(lèi)型所需的內(nèi)存大小。
②指針與指針的減運(yùn)算要求相減的兩個(gè)指針屬于同一類(lèi)型,其結(jié)果是整數(shù),表示兩個(gè)指針之間的數(shù)據(jù)的個(gè)數(shù)。
例如:
指針遞增時(shí),將指向其類(lèi)型的下一個(gè)元素的內(nèi)存位置,反之亦然
指針比較
前提:兩個(gè)指針都指向相同類(lèi)型的變量
假設(shè)ptr_a和ptr_b分別指向a和b
指針按地址傳遞
指針可以作為參數(shù)
把實(shí)參的地址傳給形參
允許函數(shù)訪(fǎng)問(wèn)內(nèi)存位置
被調(diào)函數(shù)能夠修改主調(diào)程序的參數(shù)的值
示例:
指針與一維數(shù)組
一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素都在內(nèi)存中占用存儲(chǔ)單元,它們都有相應(yīng)的地址。指針變量既然可以指向變量,當(dāng)然也可以指向數(shù)組和數(shù)組元素。
所謂數(shù)組的指針(數(shù)組的名稱(chēng))是指數(shù)組的起始地址,也就是第一個(gè)元素的地址。數(shù)組的指針是個(gè)常量指針
數(shù)組元素的地址可以用兩種方式表示:
①在數(shù)組元素前面加“&”符號(hào), 例如:&ary[2]
②數(shù)組名 + 下標(biāo) ,例如:ary + 2
示例:
#include <stdio.h>int main() {static int ary[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int i;int *p=NULL;for (i = 0; i < 10; i ++){printf("\ni=%d,ary[i]=%d,*(ary+i)=%d ",i,ary[i],*(ary + i));printf(" &ary[i]= %X,ary+i=%X",&ary[i],ary+i);}for (p = ary; p < ary+10 ; p++){ /*能否使用ary++?*/printf("\naddress:%x,value:%d",p,*p);}return 0; }數(shù)組作參數(shù)傳遞
一維數(shù)組元素作參數(shù)傳遞時(shí),按值傳遞
整個(gè)數(shù)組(數(shù)組名)當(dāng)參數(shù)傳遞時(shí),按地址傳遞,有以下三種等價(jià)的寫(xiě)法:
void TestArray(char ary[ ]); void TestArray(char ary[LEN]); void TestArray(char *ary);整型數(shù)組作為返回值
歸納起來(lái),如果有一個(gè)實(shí)參數(shù)組,想在函數(shù)中改變此數(shù)組中的元素的值,實(shí)參與形參的對(duì)應(yīng)關(guān)系有以下4種情況:
① 形參和實(shí)參都用數(shù)組名,如:
②實(shí)參用數(shù)組名,形參用指針變量。如:
void f(int *x,int n) { ···· } void main() {int a[10];·····f(a,10) }③實(shí)參形參都用指針變量。例如:
void f(int *x,int n) { ···· } void main() {int a[10],*p=a;·····f(a,10) }④實(shí)參為指針變量,形參為數(shù)組名。如:
void f(int x[],int n) { ···· } void main() {int a[10],*p=a;·····f(a,10) }指向字符串常量的字符指針
可以聲明字符指針直接指向字符串常量,例如char* pStr=“Welcome”;字符指針pStr將指向字符常量“Welcome”。“Welcome”為字符串常量,因此其值不能修改。
可以使用字符指針來(lái)存儲(chǔ)和訪(fǎng)問(wèn)字符串
聲明字符指針語(yǔ)法:char* pStr;
聲明字符串:char str[10]=“hello”;
使用字符指針指向字符串:pStr=str;
可以使用字符指針訪(fǎng)問(wèn)字符串,例如pStr[0]=‘a(chǎn)’; 該代碼將第一個(gè)字符修改為’a’
字符數(shù)組與字符指針的區(qū)別
字符數(shù)組作為返回值
#include <stdio.h> char *print() {char acStr[]="hello world";return acStr; —>返回整個(gè)數(shù)組(數(shù)組首地址) } void main() {char *pcStr;pcStr = print();puts(pcStr);return; }結(jié)果:
不能打印hello world原因:
在函數(shù)中的數(shù)組是局部變量,函數(shù)結(jié)束系統(tǒng)自動(dòng)清除。如果此時(shí)返回一一個(gè)地址,可能會(huì)訪(fǎng)問(wèn)到系統(tǒng)下次分配到的數(shù)據(jù),如果
修改該位置還可能導(dǎo)致巨大的錯(cuò)誤。
這里可以把char acStr[]="hello world"; 改為char *acStr="hello world";
總結(jié)
- 上一篇: python学习笔记(一)——操作符和运
- 下一篇: 多路I/O转接服务器——epoll