重生之我在異世界學編程之C語言:深入指針篇(上)

大家好,這里是小編的博客頻道
小編的博客:就愛學編程

很高興在CSDN這個大家庭與大家相識,希望能在這里與大家共同進步,共同收獲更好的自己!!!

本文目錄

  • 引言
  • 正文
    • (1)內置數據類型指針
      • (2) 自定義類型指針
        • 1.數組指針與指針數組
        • 2. 結構體指針
        • 3.聯合體指針
          • (1)聯合體指針的定義
          • (2)聯合體指針的使用
          • (3)聯合體指針的注意事項
      • (3)函數指針
        • 1.函數指針的定義
        • 2.函數指針的賦值
        • 3.函數指針的使用
        • 4.函數指針作為參數
        • 5.函數指針作為返回值
        • 6.函數指針的注意事項
      • (4)空指針(`NULL`)
          • (1)空指針的使用
          • (2)空指針與空字符
          • (3)空指針的注意事項
      • (5)二級指針
        • (1)二級指針的定義
        • (2)二級指針的內存分配
        • (3)二級指針的使用
        • (4)二級指針作為函數參數
        • (5)二級指針的注意事項
      • (6)常量指針與指向常量的指針(const 的用法)
        • 1.指向常量的指針(Pointer to a Constant)
        • 2.常量指針(Constant Pointer)
        • 3.常量指針指向常量(Constant Pointer to a Constant)
        • 4.使用場景和注意事項
  • 快樂的時光總是短暫,咱們下篇博文再見啦!!!不要忘了,給小編點點贊和收藏支持一下,在此非常感謝!!!

引言

指針作為C語言語法學習中的一塊既極重要又極難懂的知識點,讓初學C語言的我們常常苦不堪言。而本文就是為了讓像曾經的作者一樣的寶子們深刻理解指針這一章節的內容而作,那接下來就跟隨作者的視角,一起把各種類型的指針理解透徹!

在這里插入圖片描述


那接下來就讓我們開始遨游在知識的海洋!

正文

指針的類型繁復,為了避免出現知識點的遺漏,這里小編采根據指向的內容進行分類,把指針分為了以下6種。讓我們一一來學習吧!!


內置類型數據是我們最為常用的數據類型,所以指針的學習我們就從它開始。

(1)內置數據類型指針

顧名思義,這些指針指向內置類型的變量,如整型指針,字符指針等。

詳見:

類型內涵及應用
整型指針int*指向整數的指針
浮點型指針float*double*指向浮點數的指針
字符(型)指針char*指向字符的指針,常用于字符串處理
布爾型指針bool*指向布爾值的指針

其次就是自定義類型指針,一起來看看吧!!

(2) 自定義類型指針

自定義類型數據類型有:數組,結構體,枚舉,聯合體。但是枚舉沒有對應的枚舉指針變量。


這里小編先從數組與指針開始講起。

1.數組指針與指針數組

數組指針和指針數組是C編程中兩個重要的概念,它們雖然名字相似,但含義和用法卻有很大的不同。我們先來看看這兩個的定義:

  • 數組指針指的是指向數組的指針。它是一個指針,指向一個數組類型的數據。聲明一個數組指針時,需要指定數組的元素類型和大小。例如,int (*arrayPtr)[10]表示一個指向包含10個整數的數組的指針。使用數組指針時,可以通過(*arrayPtr)[index]來訪問數組中的元素。
  • 指針數組則是指存儲指針的數組。它是一個數組,其中的每個元素都是指針。聲明指針數組時,需要指定數組的大小和指針指向的類型。例如,int *pointerArray[10]表示一個包含10個指向整數的指針的數組。訪問指針數組中的元素,可以直接使用pointerArray[index],然后通過解引用來訪問指針指向的數據。

主要區別在于它們的使用場景和內存布局

數組指針通常用于函數參數,以傳遞多維數組,而指針數組則常用于創建動態的數據結構,如鏈表和樹。

在內存中,數組指針指向的是連續的內存塊,而指針數組中的每個指針可以指向任意位置的內存。因此,數組指針在內存訪問上更為高效,而指針數組則在數據組織上更為靈活。

  • 總之,理解數組指針和指針數組的區別對于編寫高效的C語言程序至關重要。掌握它們各自的特性和適用場景,可以幫助我們更好地設計和實現程序。

2. 結構體指針

定義:結構體指針允許我們通過指針來訪問和操作結構體中的數據。結構體是一種復合數據類型,它允許我們將多個不同類型的數據項組合成一個單一的類型。結構體指針則是指向這種復合數據類型的指針。

在C中,結構體指針的聲明方式是在結構體類型的前面加上一個星號()。例如,如果有一個名為Person的結構體,聲明一個指向該結構體的指針可以寫作Person *ptr;。這個指針可以用來指向一個Person類型的結構體實例。

我們以一個代碼為例:

#include<stdio.h>
struct book {char name[20];char author[20];int prince;
};
void print(struct book* p) {printf("%s %s %d\n", (*p).name, (*p).author, (*p).prince);printf("%s %s %d\n", p->name, p->author, p->prince);    //“->”操作符可用在:結構體指針指向我們想要訪問的結構體中的元素;
}int main() {struct book b1 = {"C語言", "張三", 10};printf("%s %s %d\n", b1.name, b1.author, b1.prince);     //“.”操作符可用在:找到我們想要訪問的結構體的元素。print(&b1);return 0;
}

這里的struct book* p就是一個結構體指針變量

主要優點:是它們提供了一種通過內存地址間接訪問和修改結構體成員的方法。這在處理大型數據結構時尤其有用,因為它們可以減少內存復制,提高程序的效率。

使用結構體指針時,我們可以通過箭頭操作符(->)來訪問結構體的成員。例如,如果Person結構體有一個名為name的成員,我們可以通過ptr->name來訪問或修改它。

結構體指針也常用于動態內存分配。使用new關鍵字可以動態創建結構體實例,并返回指向該實例的指針。例如,Person *ptr = new Person;會創建一個新的Person結構體,并使ptr指向它。當不再需要這個結構體時,應該使用delete來釋放內存,避免內存泄漏。

結構體指針還可以作為函數參數,允許函數直接修改傳入的結構體實例。這在設計模塊化和可重用代碼時非常有用,因為它允許函數與調用者共享數據,而無需復制整個結構體。

  • 總之,結構體指針提供了一種高效、靈活的方式來訪問和操作結構體數據,是編寫高效、模塊化代碼的關鍵。理解結構體指針的工作原理和正確使用它們,對于任何C/C++程序員來說都是一項基本技能。

3.聯合體指針

聯合體(Union)指針是指向聯合體類型的指針。聯合體是一種特殊的數據結構,允許在相同的內存位置存儲不同的數據類型。這使得聯合體成為一種節省空間的數據類型,因為聯合體的大小等于其最大成員的大小,而不是所有成員的總和。

(1)聯合體指針的定義

在C/C++中,聯合體指針的聲明方式是在聯合體類型的前面加上一個星號()。例如,如果有一個名為Data的聯合體,聲明一個指向該聯合體的指針可以寫作Data *ptr;。這個指針可以用來指向一個Data類型的聯合體實例。

(2)聯合體指針的使用

使用聯合體指針時,我們可以通過箭頭操作符(->)來訪問聯合體的成員。例如,如果Data聯合體有一個名為num的成員,我們可以通過ptr->num來訪問或修改它。

聯合體指針的使用特點:

  • 內存共享:聯合體指針允許我們通過指針訪問聯合體成員,這些成員共享相同的內存位置。這意味著對一個成員的修改會影響其他成員。
  • 類型安全:盡管聯合體可以存儲不同類型的數據,但使用聯合體指針時,編譯器會根據聯合體的聲明來檢查成員訪問的類型安全。
  • 動態內存分配:與結構體類似,聯合體指針也常用于動態內存分配。使用new關鍵字可以動態創建聯合體實例,并返回指向該實例的指針。
  • 靈活性:聯合體指針提供了一種靈活的方式來處理不同類型的數據,尤其是在需要節省空間或者需要通過同一個內存位置存儲不同類型數據的場景中。
(3)聯合體指針的注意事項
  • 初始化:在使用聯合體指針之前,應該確保指針已經被正確初始化,指向一個有效的聯合體實例。
  • 內存釋放:如果使用new動態分配了聯合體實例,那么在不再需要時,應該使用delete來釋放內存,避免內存泄漏。
  • 成員訪問:在使用聯合體指針訪問成員時,必須確保訪問的是當前存儲在聯合體中的成員類型,否則可能會導致未定義行為。
  • 聯合體指針提供了一種節省空間且靈活的方式來處理不同類型的數據。

(3)函數指針

函數指針是C語言中一個強大的特性,它允許將函數的地址賦給一個變量,使得可以通過這個變量來調用函數。這種機制提供了一種靈活的方式來處理函數,使得函數可以像數據一樣被傳遞和操作。

1.函數指針的定義

函數指針的聲明需要指定函數的返回類型、指針類型(即*),以及函數的參數列表。例如,如果有一個返回int類型、接受兩個int參數的函數add,那么對應的函數指針聲明如下:int (*funcPtr)(int, int);

這里,funcPtr是一個指向函數的指針,它可以存儲add函數的地址。

2.函數指針的賦值

要將函數的地址賦給函數指針,可以直接使用函數名。

這是因為:在C語言中,函數名本身就是一個指向函數的指針,因此可以直接賦值給函數指針。

3.函數指針的使用

使用函數指針調用函數時,需要使用括號來包圍函數指針和參數。

例如,int result = funcPtr(5, 3); // 調用add函數

4.函數指針作為參數

函數指針常用作其他函數的參數,這使得函數可以接收另一個函數作為輸入,從而提供高度的靈活性。例如,可以定義一個接受函數指針作為參數的函數:

void applyFunction(int x, int y, int (*func)(int, int)) {int result = func(x, y);// 處理結果
}

在這個例子中,applyFunction接受兩個int參數和一個函數指針參數,然后調用這個函數指針指向的函數。

5.函數指針作為返回值

函數指針也可以作為函數的返回值,這允許函數返回一個函數。這種技術可以用來實現回調函數和策略模式。

小編已經在之前的函數篇提及。

6.函數指針的注意事項
  • 類型匹配:函數指針必須指向與聲明匹配的函數類型,否則會導致編譯錯誤或運行時錯誤。
  • 空函數指針:函數指針可以被初始化為NULL,表示它不指向任何函數。
  • 內存管理:如果函數指針用于動態分配的函數對象,需要確保正確管理內存,避免內存泄漏。

在C語言中,空指針(Null Pointer)是一個特殊的指針值,它不指向任何有效的對象或函數。空指針的主要作用是表示“沒有指向任何東西”或“沒有有效的地址”。在C語言中,空指針常被用來表示一個指針變量尚未被分配具體的內存地址,或者用來表示某個指針變量不再指向任何對象。

(4)空指針(NULL

定義:在C語言中,空指針被定義為NULL,它是一個宏,在標準庫<stddef.h>中定義。NULL的具體值是0,這意味著在大多數平臺上,空指針和數值0是等價的。然而,NULL的使用更加明確,因為它專門用來表示空指針,而0可能在其他上下文中有其他含義。

(1)空指針的使用

空指針通常用于以下幾種情況:

  • 初始化指針:在聲明指針變量時,如果沒有立即分配內存,可以將指針初始化為NULL,以表明該指針當前不指向任何對象。

函數返回值:當一個函數需要返回一個指針,但沒有有效的對象可以返回時,可以返回NULL

  • 檢查指針有效性:在使用指針之前,檢查它是否為NULL是一個好習慣,這可以防止解引用空指針導致的程序崩潰。
(2)空指針與空字符

需要注意的是:空指針(NULL)和空字符('\0')是兩個完全不同的概念。空指針是一個指針值,表示沒有指向任何對象,而空字符是一個字符值,通常用來表示字符串的結束。

(3)空指針的注意事項
  • 空指針賦值:不要將NULL賦值給非指針類型的變量,這會導致編譯錯誤。
  • 平臺依賴性:雖然在大多數平臺上NULL被定義為0,但在某些系統上,NULL可能有不同的定義。因此,最好始終使用NULL而不是直接使用0
  • 空指針與空數組:不要將空指針與空數組混淆。空數組是指一個長度為零的數組,而空指針是一個不指向任何對象的指針。

結論:

  • 空指針可以幫助程序員處理指針變量的未初始化狀態和錯誤情況。

(5)二級指針

在C語言中,二級指針(Double Pointer)是指指向指針的指針它是一個指針變量,存儲的值是另一個指針變量的地址。二級指針在處理動態內存分配、多維數組、函數參數傳遞等方面非常有用。理解二級指針對于深入掌握C語言的指針操作至關重要。

(1)二級指針的定義

二級指針的聲明涉及到兩個星號()。例如,int **ptr;聲明了一個指向int類型指針的指針。這里,ptr是一個二級指針,它可以存儲一個int*類型的地址。

(2)二級指針的內存分配

二級指針常用于動態分配多維數組。例如,創建一個二維數組可以通過分配一個指針數組(一級指針),然后為每個指針分配一個一維數組(二級指針)。

(3)二級指針的使用

使用二級指針時,可以通過連續的解引用來訪問最終指向的數據。例如,*arr會得到一個int*類型的指針,而**arr會得到一個int類型的值。

(4)二級指針作為函數參數

二級指針也常用于函數參數,特別是需要修改指針指向的值或者需要傳遞多維數組時。

(5)二級指針的注意事項
  • 初始化:在使用二級指針之前,應該確保它們已經被正確初始化,指向有效的內存地址。
  • 內存釋放:如果使用malloccalloc分配了內存,應該在不再需要時使用free來釋放內存,避免內存泄漏。
  • 解引用:在使用二級指針時,必須確保已經正確解引用,否則可能會導致訪問無效內存,引起程序崩潰。

在C語言中,常量指針和指向常量的指針是兩個不同的概念,它們在聲明和使用上有所區別,但都與指針和常量的關系有關。

(6)常量指針與指向常量的指針(const 的用法)

1.指向常量的指針(Pointer to a Constant)

指向常量的指針是指指針本身可以被修改,但其指向的數據(常量)不能被修改。這種指針的聲明方式是在指針的聲明中,將const關鍵字放在指針的后面,緊挨著指針的類型前面。例如:const int *ptr;

這里,ptr是一個指向int類型的常量的指針。這意味著你可以通過ptr來改變它所指向的地址,但是不能通過ptr來改變所指向地址處的值。

2.常量指針(Constant Pointer)

常量指針是指指針本身的值不能被修改,即一旦指針被初始化后,就不能指向另一個地址。這種指針的聲明方式是將const關鍵字放在指針的聲明中,緊挨著指針變量的前面。例如:int value = 10; int *const ptr = &value;

這里,ptr是一個常量指針,它被初始化為指向value的地址,之后你不能再讓ptr指向另一個地址,但可以通過ptr來修改value的值。

3.常量指針指向常量(Constant Pointer to a Constant)

這種指針既不能改變指向的地址,也不能通過這個指針來改變指向地址處的值。聲明時,const關鍵字同時放在指針類型和指針變量之間,以及指針類型和指針指向的類型之間。例如:const int *const ptr = &value;

在這個例子中,ptr是一個常量指針,指向一個int類型的常量。這意味著ptr的值(即它所指向的地址)不能被改變,同時ptr所指向的數據也不能被修改。

4.使用場景和注意事項
  • 指向常量的指針:當你需要一個指針來讀取但不能修改某些數據時使用,例如,函數參數中傳遞的只讀數據。
  • 常量指針:當你需要一個指針的地址固定不變時使用,例如,指向全局變量或靜態變量的指針。
  • 常量指針指向常量:當你需要一個既不能改變指向地址,也不能通過指針改變數據的指針時使用,例如,防止函數內部修改傳入的參數。
  • 常量指針與指向常量的指針提供了不同的保護級別,幫助程序員控制數據的訪問和修改。

快樂的時光總是短暫,咱們下篇博文再見啦!!!不要忘了,給小編點點贊和收藏支持一下,在此非常感謝!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67901.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67901.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67901.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

密碼學的數學基礎1-素數和RSA加密

數學公式推導是密碼學的基礎, 故開一個新的課題 – 密碼學的數學基礎系列 素數 / 質數 質數又稱素數。 一個大于1的自然數&#xff0c;除了1和它自身外&#xff0c;不能被其他自然數整除的數叫做質數&#xff1b;否則稱為合數&#xff08;規定1既不是質數也不是合數&#xff0…

kamailio源文件modules.lst的內容解釋

在執行make cfg 后&#xff0c;在kamailio/src目錄下有一個文件modules.lst&#xff0c;內容如下&#xff1a; # this file is autogenerated by make modules-cfg# the list of sub-directories with modules modules_dirs:modules# the list of module groups to compile cf…

音視頻入門基礎:RTP專題(7)——RTP協議簡介

一、引言 本文對RTP協議進行簡介。在簡介之前&#xff0c;請各位先下載RTP的官方文檔《RFC 3550》和《RFC 3551》。《RFC 3550》總共有89頁&#xff0c;《RFC 3551》總共有44頁。本文下面所說的“頁數”是指在pdf閱讀器中顯示的頁數&#xff1a; 二、RTP協議簡介 根據《RFC 35…

HTTP協議的無狀態和無連接

無連接 ①無連接的含義 這里所說的無連接并不是指不連接&#xff0c;客戶與服務器之間的HTTP連接是一種一次性連接&#xff0c;它限制每次連接只處理一個請求&#xff0c;當服務器返回本次請求的應答后便立即關閉連接&#xff0c;下次請求再重新建立連接。這種一次性連接主要考…

Java知識速記:Lambda表達式

Java知識速記&#xff1a;Lambda表達式 一、什么是Lambda表達式&#xff1f; Lambda表達式是Java 8引入的一種簡潔的表示函數式接口的方法&#xff0c;它使得可以將函數作為參數傳遞&#xff0c;并且可以在代碼中以更簡潔的方式實現函數式編程。Lambda表達式的基本語法如下&a…

第31章 星騙計劃的推進與團隊協作

我回到自己的辦公室&#xff0c;在座位上剛坐下沒多久&#xff0c;還沒來得及好好整理一下思緒&#xff0c;就聽到一陣敲門聲。“請進。” 我抬頭說道&#xff0c;聲音中帶著一絲疲憊。借助情緒監測系統&#xff0c;我察覺到自己的壓力指數正處于高位&#xff0c;于是暗自提醒自…

半導體器件與物理篇7 微波二極管、量子效應和熱電子器件

基本微波技術 微波頻率&#xff1a;微波頻率涵蓋約從0.1GHz到3000GHz&#xff0c;相當于波長從300cm到0.01cm。 分布效應&#xff1a;電子部件在微波頻率&#xff0c;與其在較低頻率的工作行為不同。 輸運線&#xff1a;一個由電阻、電容、電感三種等效基本電路部件所組成的…

【C++】B2122 單詞翻轉

博客主頁&#xff1a; [小????????] 本文專欄: C 文章目錄 &#x1f4af;前言&#x1f4af;題目描述輸入格式輸出格式樣例 #1樣例輸入 #1樣例輸出 #1 &#x1f4af;一、我的做法代碼實現&#xff1a;代碼解析思路分析 &#x1f4af;二、老師的第一種做法代碼實現&a…

麥芯(MachCore)應用開發教程5 --- 工位和晶圓傳輸

麥芯是構建在windows系統上的設備應用操作系統&#xff0c;利用該系統可以快速高效的開發一款設備專用軟件。希望進一步了解請email: acloud163.com 黃國強 2025/02/03 一、工位與子設備的關系 想象工廠中的流水線工作站&#xff0c;每個工位&#xff08;Station&#xff09…

Python從0到100(八十七):CNN網絡詳細介紹及WISDM數據集模型仿真

前言&#xff1a; 零基礎學Python&#xff1a;Python從0到100最新最全教程。 想做這件事情很久了&#xff0c;這次我更新了自己所寫過的所有博客&#xff0c;匯集成了Python從0到100&#xff0c;共一百節課&#xff0c;幫助大家一個月時間里從零基礎到學習Python基礎語法、Pyth…

C++ Primer 迭代器

歡迎閱讀我的 【CPrimer】專欄 專欄簡介&#xff1a;本專欄主要面向C初學者&#xff0c;解釋C的一些基本概念和基礎語言特性&#xff0c;涉及C標準庫的用法&#xff0c;面向對象特性&#xff0c;泛型特性高級用法。通過使用標準庫中定義的抽象設施&#xff0c;使你更加適應高級…

【C++篇】位圖與布隆過濾器

目錄 一&#xff0c;位圖 1.1&#xff0c;位圖的概念 1.2&#xff0c;位圖的設計與實現 1.5&#xff0c;位圖的應用舉例 1.4&#xff0c;位圖常用應用場景 二&#xff0c;布隆過濾器 2.1&#xff0c;定義&#xff1a; 2.2&#xff0c;布隆過濾器的實現 2.3&#xff0c; 應…

VR觸感數據手套:觸感反饋賦予虛擬交互沉浸式體驗

隨著動作捕捉技術的蓬勃發展&#xff0c;動捕數據手套成為了手部動作捕捉與虛擬交互的便捷工具&#xff0c;為人們打開了通往虛擬世界的新大門。在眾多產品中&#xff0c;mHand Pro作為一款多功能兼具的VR動作捕捉數據手套&#xff0c;憑借其卓越的性能&#xff0c;在手部動作捕…

C# 結構體介紹

.NET學習資料 .NET學習資料 .NET學習資料 一、結構體的定義與基本使用 &#xff08;一&#xff09;定義結構體 在 C# 中&#xff0c;使用struct關鍵字來創建結構體。它就像是一個模板&#xff0c;能定義出符合特定需求的數據結構。比如&#xff0c;若要跟蹤圖書館中書的信息…

圖像噪聲處理技術:讓圖像更清晰的藝術

在這個數字化時代&#xff0c;圖像作為信息傳遞的重要載體&#xff0c;其質量直接影響著我們的視覺體驗和信息解讀。然而&#xff0c;在圖像采集、傳輸或處理過程中&#xff0c;難免會遇到各種噪聲干擾&#xff0c;如高斯噪聲、椒鹽噪聲等&#xff0c;這些噪聲會降低圖像的清晰…

追逐低空經濟,無人機研學技術詳解

追逐低空經濟&#xff0c;無人機研學技術成為了一個備受關注的領域。以下是對無人機研學技術的詳細解析&#xff1a; 一、無人機研學技術概述 無人機研學技術是以無人機為核心&#xff0c;結合航空科技、電子技術、機械原理等多領域知識的一種教育實踐活動。它旨在通過理論學習…

(done) MIT6.S081 2023 學習筆記 (Day7: LAB6 Multithreading)

網頁&#xff1a;https://pdos.csail.mit.edu/6.S081/2023/labs/thread.html (任務1教會了你如何用 C 語言調用匯編&#xff0c;編譯后鏈接即可) 任務1&#xff1a;Uthread: switching between threads (完成) 在這個練習中&#xff0c;你將設計一個用戶級線程系統中的上下文切…

Kubernetes學習之通過Service訪問Pod

一、基礎概述 1.當通過deployment等controller動態創建和銷毀pod使得每個pod都有自己的ip地址&#xff0c;當controller用新的pod替代發生故障的pod時&#xff0c;新的pod會分配到新的ip地址&#xff0c;那么客戶端如何穩定的找到并訪問pod提供的服務。 2.創建service service從…

【優先算法】專題——前綴和

目錄 一、【模版】前綴和 參考代碼&#xff1a; 二、【模版】 二維前綴和 參考代碼&#xff1a; 三、尋找數組的中心下標 參考代碼&#xff1a; 四、除自身以外數組的乘積 參考代碼&#xff1a; 五、和為K的子數組 參考代碼&#xff1a; 六、和可被K整除的子數組 參…

CDDIS從2025年2月開始數據遷移

CDDIS 將從 2025 年 2 月開始將我們的網站從 cddis.nasa.gov 遷移到 earthdata.nasa.gov&#xff0c;并于 2025 年 6 月結束。 期間可能對GAMIT聯網數據下載造成影響。