首页
/
每日頭條
/
圖文
/
c語言指針用法大全
c語言指針用法大全
更新时间:2025-11-30 14:51:05

指針是C語言最重要也是最難理解的部分,它在我們平時的工作中無處不在。

有人說學會了指針,C語言也就學會一半。為什麼說指針難。因為指針與數組相結合就涉及數組指針與指針數組。指針與結構體結合就涉及結構體指針。指針與字符結合涉及字符指針。指針與const結合涉及常量指針與指針常量。指針與函數結合涉及函數指針與指針函數,同時也會涉及回調函數。指針和指針結合涉及到二維指針。

c語言指針用法大全(C語言基礎知識最核心的)1

作者曾經因為上面的這些問題,困擾了許久。因而在網上找了許多的博客來解答疑惑。這篇文章,我試圖将上面的知識點以例子的方式呈現給大家,我相信通過閱讀本文,大家會對指針有更深一步的了解。文中涉及的例子均來源于網上。

1 指針的定義

我們知道,普通的變量存儲的是一個值。而指針變量,它存儲的也是一個值,隻是這是一個特殊的值:它的值是另一個變量的地址

指針的定義形式如下:

datatype *name; 或 datatype *name = value;

其意思就是name是一個指針,它指向的是一個類型為dataype的地址。

指針存儲的是一個地址,如果需要獲取這個地址對應的内容,可以通過解引用符*獲取:

int a = 12; int *pa = &a; printf("*pa:%u.", *pa); // 輸出是12; *pa = 14; // 此時a的值為14了

這裡需要注意的一點,也是我以前經常迷惑的一點:定義指針時,編譯器并不為指針所指向的對象分配空間,它隻是分配指針本身的空間,除非在定義時同時賦給一個字符串常量進行初始化。比如:

int *a; ... *a = 12;

上面這個代碼段說明了一個極為常見的錯誤:我們聲明了這個變量,但從未對它進行初始化,所以沒法預測12這個值将存儲于什麼地方。如果變量是靜态的,它會被初始化為0,;如果變量是自動地,它根本不會被初始化。無論哪種情況,聲明一個指向整型的指針都不會"創建"用于存儲整型值的内存空間。

但是, 下面的定義創建了一個字符串常量(為其分配了内存):

char *p = "breadfruit";

始化指針時所創建的字符串常量被定義為隻讀。如果試圖通過指針修改這個字符串的值,程序就會出現未定義的行為。

除了上述的定義是對的外,其他的定義都是錯誤的:

float *pip = 3.14; // 錯誤!無法通過編譯

2 指針的運算

指針 (-) 整數指針存儲的是一個地址,這個地址本質上是一個整數,所以可以加上或減去一個整數。但是它不是普通的加法或減法,指針加上或減去一個整數結果是另一個指針。但是,運算後的指針指向哪裡呢?當一個指針和一個整數執行算術運算時,整數在執行加法(減法)運算前會根據合适的大小進行調整。這個"合适的大小"就是指針所指向類型的大小,"調整"就是把整數值和"合适的大小"相乘。

#include <stdio.h> int main() { int a = 10; int *pa = &a; double b = 99.9; double *pb = &b; char c = '@'; char *pc = &c; printf("sizeof(int)= %u, sizeof(double)=%u, sizeof(char)=%u\n", sizeof(int), sizeof(double), sizeof(char)); //最初的值 printf("&a=%p, &b=%p, &c=%p\n", &a, &b, &c); printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc); //加法運算 pa ; pb ; pc ; printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc); //減法運算 pa -= 2; pb -= 2; pc -= 2; printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc); return 0; }

運算結果:

sizeof(int)= 4, sizeof(double)=8, sizeof(char)=1 &a=000000000061FE04, &b=000000000061FDF8, &c=000000000061FDF7 pa=000000000061FE04, pb=000000000061FDF8, pc=000000000061FDF7 pa=000000000061FE08, pb=000000000061FE00, pc=000000000061FDF8 pa=000000000061FE00, pb=000000000061FDF0, pc=000000000061FDF6

由上面的結果可以看到,當對指針pa,pb,pc進行加1時,實際地址增加的是對應類型的大小。減法也一樣。

指針 - 指針

隻有當兩個指針都指向同一個數組中的元素時,才允許從一個指針減去另一個指針。兩個指針相減的結果是兩個指針之間的元素個數。比如,如果p1指向array[i]而p2指向array[j],那麼p2-p1的值就是j-i的值。如果兩個指針所指向的不是同一個數組中的元素,那麼它們之間相減的結果是未定義的,也是毫無意義的。

3 指針與數組3.1 數組指針(指向數組的指針)

數組指針,它是一個指針,指向的是一個數組。即它存的是一個數組變量的地址。所以這個指針每加一步的步長就是數組的長度。由于它每跨一步都是整個數組,所以又稱行數組。

#include <stdio.h> int main() { int a[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}; int (*pa)[4]; pa = a; printf("a:%p, &a:%p, &a[0][0]:%p\n", a, &a, &a[0][0]); printf("pa:%p, (*pa)[0]:%u\n", pa, (*pa)[0]); pa ; printf("&a[1]:%p, &a[1][0]:%p\n", &a[1], &a[1][0]); printf("pa:%p, (*pa)[0]:%u\n", pa, (*pa)[0]); return 0; }

運行結果:

a:000000000061FDE0, &a:000000000061FDE0, &a[0][0]:000000000061FDE0 pa:000000000061FDE0, (*pa)[0]:1 &a[1]:000000000061FDF0, &a[1][0]:000000000061FDF0 pa:000000000061FDF0, (*pa)[0]:5

首先,pa是一個數組指針,它首先存的是數組a的首元素的地址,由于數組名也是數組的首地址,所以a, &a, &a[0][0]的地址相同。pa中存的也是這個地址。然後對pa進行解引用,*pa之後得到這個數組,然後(*pa)[i]就是獲得這個數組下标為i的元素。

3.2 指針數組

指針數組,它本質上是一個數組,隻不過整個數組存的類型是一個指針而已。

#include<stdio.h> int main(void) { char *p1 = "Himanshu"; char *p2 = "Arora"; char *p3 = "India"; char *arr[3]; arr[0] = p1; arr[1] = p2; arr[2] = p3; printf("\n p1 = [%s] \n",p1); printf("\n p2 = [%s] \n",p2); printf("\n p3 = [%s] \n",p3); printf("\n arr[0] = [%s] \n",arr[0]); printf("\n arr[1] = [%s] \n",arr[1]); printf("\n arr[2] = [%s] \n",arr[2]); return 0; }

運行結果:

p1 = [Himanshu] p2 = [Arora] p3 = [India] arr[0] = [Himanshu] arr[1] = [Arora] arr[2] = [India]

4 指針與字符

在C語言中,表示字符串一般有兩種形式,一種是數組的形式,一種是字符指針的形式。

數組形式:

char arr[] = "hello,world";

字符指針形式:

char *str = "hello,world";

雖然上面兩種形式都能表示字符串,但是它們還是有些區别的:

存儲方式字符數組由若幹元素組成,每個元素存放一個字符,而字符指針變量隻存放字符串的首地址,不是整個字符串。

存儲位置。數組是在内存中開辟了一段空間存放字符串, 是存在棧區。而字符指針是在字面值常量區開辟了一段空間存放字符串,将字符串的首地址付給指針變量str。

賦值方式。對于數組,下面的賦值方式是錯誤的:

char str[10]; str="hello"; // 錯誤!

而對字符指針變量,可以采用下面方法賦值:

char *a; a = "hello";

可否被修改。指針變量指向的字符串内容不能被修改,但指針變量的值(即存放的地址或者指向)是可以被修改的。

來源:稀土掘金,作者:Elec


對啦對啦!另外的話為了幫助大家,輕松,高效學習C語言/C ,我給大家分享我收集的資源,從最零基礎開始的教程到C語言項目案例,幫助大家在學習C語言的道路上披荊斬棘!可以來我粉絲群領取哦~

編程學習書籍分享:

c語言指針用法大全(C語言基礎知識最核心的)2

編程學習視頻分享:

c語言指針用法大全(C語言基礎知識最核心的)3

整理分享(多年學習的源碼、項目實戰視頻、項目筆記,基礎入門教程)最重要的是你可以在群裡面交流提問編程問題哦!

對于C/C 感興趣可以關注小編在後台私信我:【編程交流】一起來學習哦!可以領取一些C/C 的項目學習視頻資料哦!已經設置好了關鍵詞自動回複,自動領取就好了!

,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
讓女生心動的撩人情話表白必備(讓女生無法拒絕的表白情話)
讓女生心動的撩人情話表白必備(讓女生無法拒絕的表白情話)
     1、遇上你的感覺,大概是走了很久的路,終于到家了!   2、我是很慢熱的人,但是我保溫性能很好,一旦熱起來,就不會涼下去,比如喜歡你!   3、我雖然不善言辭,但關于愛你,我無法掩飾!   4、我沒有取悅你的天分,但我比誰都認真。   5、對你遷就一生,是我能給你的,蕞好的聘禮!   6、我的生活,就像一杯白開水,但是你的出現,像是在裡面偷偷加了一...
2025-11-30
有志者立遠志無志者常立志(人要立長志不能常立志)
有志者立遠志無志者常立志(人要立長志不能常立志)
  有句話說得好“有志者立長志,無志者常立志。”      有遠見的人總是立長志,他們不因暫時的困難而退縮,他們不被可恥的懶惰所迷惑,他們認準目标發奮努力,他們積極争取從不放棄。盡管經曆了許多酸苦,但最終他們撥散了層層的迷霧,找到了自己萬事如意的歸宿。      無大志的人總是常立志,他們好似有遠大的抱負,總是好高骛遠、眼高手低;他們好似有長遠的志向,總是憤...
2025-11-30
交通運輸部十四五規劃建設項目(交通運輸部十四五)
交通運輸部十四五規劃建設項目(交通運輸部十四五)
     據交通運輸部微信公衆号20日消息,為深入貫徹黨中央、國務院關于加快推進“十四五”規劃重大工程項目建設的決策部署,近日,交通運輸部印發《關于紮實推動“十四五”規劃交通運輸重大工程項目實施的工作方案》,以“服務大局、當好先鋒,穩定投資、保障民生,創新引領、綠色安全,系統推進、銜接融合”為基本原則,堅持穩字當頭、穩中求進,适度超前開展交通基礎設施投資,實...
2025-11-30
譚松韻本來就長得很可愛(譚松韻在我們這十年裡面飾演創業女神)
譚松韻本來就長得很可愛(譚松韻在我們這十年裡面飾演創業女神)
  電視劇《我們這十年》播出之後,我們發現,每個演員的表演都很精彩,難怪這部劇能如此火爆。   之前單元劇裡面,我們看到白百何、侯勇、焦俊豔、黃志忠等實力演員,感歎他們已經很驚豔了,如今,我們再一次看到《甄嬛傳》和《延禧攻略》組團演繹《心之所向》單元。      《我們這十年之心之所向》這個單元,譚松韻飾演創業女神李心遙,具有樸實無華的形象,讓人看了心情舒爽...
2025-11-30
nba曆史37歲球員狀态最好的球員(2022
nba曆史37歲球員狀态最好的球員(2022
  14.韋斯利·馬修斯 - 36歲  在猶他爵士隊的新秀賽季中出場82場比賽後,韋斯利·馬修斯的職業生涯一直是兩位數的得分手和高于平均水平的射手。馬修斯在他 13 年的職業生涯中曾在 7 支球隊效力,并在 2010 年代在開拓者隊和獨行俠隊達到頂峰。在他的職業生涯中,他場均12.0分,真實投籃命中率為55.9%。馬修斯在他職業生涯的前11個賽季都是首發球員...
2025-11-30
Copyright 2023-2025 - www.tftnews.com All Rights Reserved