首页
/
每日頭條
/
圖文
/
c語言指針用法大全
c語言指針用法大全
更新时间:2024-05-02 06:11:07

指針是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
推荐阅读
2米高的女兒牆可以用砌體施工麼(砌體女兒牆的限制)
2米高的女兒牆可以用砌體施工麼(砌體女兒牆的限制)
  什麼情況下可采用磚做女兒牆?有何構造要求?      《非結構構件抗震設計規範》JGJ 339-2015第4.4.2條,女兒牆高度超過0.5m時、人流出入口、通道處或9度時,出屋面砌體女兒牆應設置構造柱與主體結構錨固,構造柱間距宜取2.0m~2.5m;高層建築的女兒牆,不得采用砌體女兒牆。      22G614-1具體規定   1、砌體女兒牆頂部應采用...
2024-05-02
故宮中的養心殿是用來幹什麼的(故宮最精美的養心殿将閉門精修)
故宮中的養心殿是用來幹什麼的(故宮最精美的養心殿将閉門精修)
  故宮博物院院長單霁翔說:“養心殿是故宮最精美、工藝難度最高的建築,因為有了修複壽康宮、慈甯宮的經驗,這才敢啟動養心殿的修繕。”      圖為養心殿中慈禧垂簾聽政的地方。 文彙報首席記者 江勝信攝   ■文彙報首席記者 江勝信   故宮城牆暗藏險情,養心殿出現多處隐患,古建修繕人才卻青黃不接,怎麼辦?故宮文物總數超過180萬件套,因前殿後宮不可能大規模改...
2024-05-02
朱竹清終于接受戴沐白(朱竹清為何稱和星羅學院是生死之戰)
朱竹清終于接受戴沐白(朱竹清為何稱和星羅學院是生死之戰)
  導讀:随着鬥羅大陸動畫96集的更新,戴沐白的哥哥戴維斯和朱竹清的姐姐朱竹雲也相繼登場。他們所在的星羅皇家學院和史萊克學院在第三輪狹路相逢。本來隻是一場普通的魂師交流大賽,為何戴沐白卻說是生死大戰呢?      戴沐白和朱竹清的家族   一場魂師交流大賽,卻為何要以命相搏?主要是因為戴沐白和星羅學院隊長戴維斯的關系。戴沐白和朱竹清都是星羅帝國人,分别屬于兩...
2024-05-02
玉娆和甄母現實中是親生母女嗎(為什麼隻有三小姐玉娆赢得了最終的幸福)
玉娆和甄母現實中是親生母女嗎(為什麼隻有三小姐玉娆赢得了最終的幸福)
  #頭條創作挑戰賽##我在頭條搞創作##甄嬛傳#   甄家一共三個女兒,長女甄嬛為了妹妹的家族的前途進宮選秀,成為帝王無數個女人當中的一個。次女浣碧乃是見不得光的私生子,耍了陰狠手段讓自己如願嫁給了果郡王,奈何對方心裡完全沒有她。隻有第三個女兒玉娆,她拒絕了皇帝的心意,依照自己的本心嫁給了心愛的男人慎貝勒。   為什麼甄家三姝裡隻有最小的玉娆得到了幸...
2024-05-02
田言嫁給誰了(究竟誰在套路誰)
田言嫁給誰了(究竟誰在套路誰)
  導語:在秦時明月最新的劇情當中,農家衆人集體上演了感人的一幕。原本農家六堂人多勢衆,在江湖上也算是基礎雄厚。可是六堂之人卻各自争鬥,每位堂主都對俠魁之位觊觎已久,因此,農家不得不分為兩大派。但随着劇情的發展,實力占優的田言這一派逐漸掌握了大局。因此心有不服的朱家也不得不審時度勢,将神農堂投向田言的懷抱,雙方彼此化解了往日的恩怨。      可事實上真的有...
2024-05-02
Copyright 2023-2024 - www.tftnews.com All Rights Reserved