main函數,常量指針與指針常量,野指針等,void與void的區別

指針(續)

main函數原型

定義

main函數有多種定義格式,main函數也是函數,函數相關的結論對main函數也有效。

main函數的完整寫法:

 int main(int argc, char *argv[]){..}int main(int argc, char **argv){..}

擴展寫法:

 main(){}  等價 int main(){}   // C11之后不再支持 缺省 返回類型int main(void){}   等價 int main(){}void main(void){}  等價 void main(){}int main(int a){}int main(int a, int b, int c){}...

說明

① argc,argv是形參,他們倆可以修改

② main函數的擴展寫法有些編譯器不支持,編譯報警告

③ argc和argv的常規寫法

  • argc:存儲了參數的個數,默認是1個,也就是運行程序的名字
  • argv:存儲了所有參數的字符串形式

④ main函數是系統通過函數指針的回調調用。

演示

代碼:

#include <stdio.h>int main(int argc, char **argv)  // {"abc","aaa"}   對行地址解引用,得到首列地址
{// 訪問參數個數 argcprintf("argc=%d\n", argc);// 遍歷參數(每一個參數都是一個字符串常量)for(int i=0;i< argc; i++){printf("%s,%s\n", argv[i], *(argv+i));}printf("\n");
}

運行結果:

在這里插入圖片描述

在這里插入圖片描述

常量指針與指針常量

常量類型

① 字面量:直接使用固定值(如:12,hello,orange, 楊家輝三角),符號常量和枚舉在編譯器轉換為了字面量

② 只讀常量:用const修飾的變量,初始化之后不可修改。

const int a = 10;  // 只讀常量
a = 21;  // 編譯報錯

常量指針

  • 本質:指向常量數據的指針

  • 語法:

    const 數據類型 *變量名;
    const 數據類型* 變量名;
    
  • 舉例:

    const int *p;   // p是常量指針
    
  • 特性:

    • 指向對象的數據不可改變(int a = 10; const int *p = &a; *p = 20;,非法)
    • 指針本身的指向可以改變(int a = 10, b = 20; const int *p = &a; p = &b;,合法)
  • 案例:

    #include <stdio.h>int main()
    {int a = 10;        // 變量const int *p = &a; // 常量指針// *p = 100;       // 錯誤,指針指向的數據不可改變printf("%d\n", *p);// 10int b = 20;        // 變量p = &b;            // 正確,指針指向可以改變printf("%d\n", *p);// 20
    }
    

指針常量

  • 本質:指針本身是常量,指向固定地址

  • 語法:

    數據類型* const 變量名;
    數據類型 *const 變量名;
    
  • 特性:

    • 指向對象的數據可以改變(int a = 10; int* const p = &a; *p = 20;,合法)
    • 指針本身的指向不可改變(int a = 10, b = 20; int* const p = &a; p = &b;,非法)
  • 注意:

    定義時必須初始化:

    int a = 10;
    int* const p = &a;  // 正確
    
  • 案例:

    #include <stdio.h>int main()
    {int a = 10;        // 變量int* const p = &a; // 指針常量*p = 100;          // 正確,指針指向的數據可以改變printf("%d\n", *p);// 100int b = 20;        // 變量// p = &b;            // 錯誤,指針指向不可改變printf("%d\n", *p);// 100
    }
    

常量指針常量

  • 本質:指針指向和指向對象的數據都不可改變

  • 語法:

    const 數據類型* const 變量名;
    const 數據類型 *const 變量名;
    
  • 舉例:

    const int* const p;  // p是常量指針常量
    
  • 特性:

    • 指向對象的數據不可改變(int a = 10; int* const p = &a; *p = 20;,非法)
    • 指針本身的指向不可改變(int a = 10, b = 20; int* const p = &a; p = &b;,非法)
  • 注意:

    定義時需要初始化:

    int a = 10;
    const int *const p = &a; // 正確
    

    簡單理解:不管是常量指針、指針常量還是常量指針常量,本質上都是一個賦值受到限制的指針變量。

總結對比

類型語法指向可變數據可變
常量指針const int *p???
指針常量int *const p???
常量指針常量const int *const p??

關鍵點

  1. const* 左側:修飾數據(常量指針)
  2. const* 右側:修飾指針(指針常量)
  3. 函數參數優先使用常量指針,提高代碼安全性
  4. 指針常量必須初始化,且不可重新指向

野指針、空指針、空懸指針

野指針

定義

指向無效內存區域(比如未初始化、已釋放或者越界訪問)的指針稱之為野指針。野指針會導致未定義(UB)行為。

危害:

  • 訪問野指針可能引發段錯誤(Segmentation Fault)
  • 可能破壞關鍵內存數據,導致程序崩潰。

產生場景:

  1. 指針變量未初始化

    int *p;    // p未初始化,是野指針
    printf("%d\n", *p); // 危險操作:p就是野指針
    
  2. 指針指向已釋放的內存

    int *p = malloc(sizeof(int)); // 在堆區申請1個int大小的內存空間,將該空間地址賦值給指針變量p
    free(p); // 釋放指針p指向的空間內存
    printf("%d\n", *p); // 危險操作:p就是野指針
    
  3. 返回局部變量的地址

    int* fun(int a, int b)
    {int sum = a + b; // sum就是一個局部變量return &sum;  // 將局部變量的地址返回給主調函數
    }int main()
    {int *p = fun(2,3);printf("%d\n", *p); // 危險操作:p就是野指針
    }
    

如何避免野指針:

  1. 初始化指針為NULL

  2. 釋放內存后立即置指針為NULL

  3. 避免返回局部變量的地址

  4. 使用前檢查指針有效性(非空校驗,邊界檢查)。

    int fun(int *pt)
    {int *p = pt;// 校驗指針if(p == NULL) // 結果為假   等價于 if(!p)  其實底層: if(p == 0){printf("錯誤!");return -1;}printf("%d\n", *p);return 0;
    }
    

空指針

**定義:**值為NULL的指針,指向地址0x000000000000(系統保留,不可訪問)

**作用:**明確表示指針當前不指向有效內存,一般用作指針的初始化。

示例:

int *p = NULL;  // 初始化為空指針free(p);   // 釋放后置空
p = NULL;

空懸指針

**定義:**指針指向的內存已經被釋放,但未重新賦值。空懸指針是野指針的一種特例。

示例:

char *p = malloc(100); // 在堆區分配100個char的空間給p
free(p); // 釋放指針p指向的內存空間
printf("%p,%d\n", p, *p); // p可以正常輸出,*p此時屬于危險操作 
// p指向的內存空間被回收,但是p指向空間的地址依然保留,此時這個指針被稱作空懸指針

void與void*的區別

定義

  • void: 表示“無類型/空類型”,用于函數返回類型或者參數。

    void func(void);    // 沒有返回值也沒有參數,一般簡寫:void func();
    
  • *void:**通用指針類型(萬能指針),可指向任意類型數據,但需要強制類型轉換后才能解引用。

    void* ptr = malloc(4);  // ptr指向4個字節大小的堆內存空間  
    // 存放int類型數據
    int *p = (int*)ptr;
    *p = 10;// 存放float類型數據
    float* p1 = (float*)ptr;
    *p = 12.5f;// 存放char類型數組
    char* p2 = (char*)ptr;// 以下寫法完全錯誤
    float* ptr = malloc(4);
    int *p = (int*)ptr;  // 此時編譯報錯,類型不兼容 float* int*
    

    注意:只能是具體的類型(int*,double*,float*,char*...)和void*之間轉換

注意事項

  • void不能直接解引用(*ptr 會報錯
  • 函數返回void*需要外部接收的時候明確類型(不明確類型,就無法解引用)

示例

#include <stdio.h>/*** 定義一個返回類型為void*類型的指針函數*/
void* proces_data(void* p)
{return p;
}int main(int argc, char *argv[])
{// int類型int m = 10;int* p_int = &m;int* result_int = (int*)proces_data(p_int);printf("Integer value:%d\n", *result_int);// double類型double pi = 3.1415926;double* p_double = &pi;double* result_double = (double*)proces_data(p_double);printf("Double value:%lf\n", *result_double);// void* p_void = proces_data(p_double);// printf("Void value:%lf\n", *p_void);// *p_void = 20;// 注意:void* 修飾的指針是可以進行賦值操作的,但是不能對其解引用return 0;
}

運行結果:

在這里插入圖片描述

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

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

相關文章

Mac m系列芯片安裝node14版本使用nvm + Rosetta 2

由于蘋果 M 系列芯片&#xff08;包括 M4&#xff09;使用的是 ARM 架構&#xff0c;而 Node.js 14 是在英特爾 x86 架構時代發布的&#xff0c;因此在 M 系列 Mac 上安裝 Node.js 14 可能會遇到兼容性問題 解決方法&#xff1a;使用 nvm Rosetta 2右鍵點擊「終端」→「顯示簡…

前端基礎之《Vue(26)—Vue3兩種語法范式》

一、選項式1、HTML寫法<!-- 跟 Vue 說 Hello World&#xff01; --><script type"module"> import { createApp } from vuecreateApp({data() {return {message: Hello World!}} }).mount(#app) </script><div id"app"><h1>…

題目:BUUCTF之rip(pwn)

網址 BUUCTF在線評測https://buuoj.cn/challenges#rip打開&#xff0c;如圖所示 提示&#xff1a;先別啟動靶機&#xff0c;靶機可以最后在啟動&#xff0c;先分析下載的附件pwn1。 點擊下載&#xff0c;下載完成之后&#xff0c;該文件后綴類型改為exe&#xff08;就是將pwn…

el-button長按觸發事件(含未響應的解決方案)

參考代碼實現按鈕長按觸發邏輯 <template><el-button mousedown"handleMouseDown" mouseup"handleMouseUp">長按我</el-button> </template>data(){return{isPressed: false,timer: null,}},methods:{handleMouseDown() {this.isP…

List和 ObservableCollection 的區別

1. 變更通知機制?? ??ObservableCollection<T>?? 實現了INotifyCollectionChanged和INotifyPropertyChanged接口&#xff0c;當集合元素被添加、刪除、替換或重置時&#xff0c;會自動觸發CollectionChanged事件&#xff0c;通知綁定的UI控件更新&#xff08;如WPF…

支付寶沙箱(白屏,用戶訂單參數錯誤等)

情況&#xff1a;Laravel項目的line 對接 支付寶沙箱測試 手機網站支付 1&#xff1a;沙箱地址&#xff0c;小到我找不到&#xff1a;沙箱應用 - 開放平臺 2&#xff1a;雖然提供了系統密鑰&#xff0c;但是只是測API鏈接的&#xff0c;要沙箱測試轉賬什么的&#xff0c;得用…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 微博評論IP地圖可視化分析實現

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解微博評論IP地圖可視化分析實現 視頻在線地…

【代碼隨想錄】刷題筆記——二叉樹篇

目錄 144. 二叉樹的前序遍歷 94. 二叉樹的中序遍歷 145. 二叉樹的后序遍歷 102. 二叉樹的層序遍歷 226. 翻轉二叉樹 101. 對稱二叉樹 104. 二叉樹的最大深度 111. 二叉樹的最小深度 222. 完全二叉樹的節點個數 110. 平衡二叉樹 257. 二叉樹的所有路徑 404. 左葉子之…

基于deepseek的文本解析 - 超長文本的md結構化

pdf超長合同或其他超100頁非結構化文檔&#xff0c;很難全量提交deepseek進行分析&#xff0c;一般需要先進行分割。然而&#xff0c;不管是langchain還是llamaindex提供的文本分割工具&#xff0c;很難直接對非結構化文本進行準確的內容分割&#xff0c;很多原始整體段落被劃分…

介紹一個圖像修復開源項目,從模糊到清晰僅需1.7秒:HYPIR圖像修復技術如何改變數字世界?

文章概要 作為一名長期關注圖像處理技術的愛好者&#xff0c;當我第一次接觸到HYPIR這一革命性圖像修復工具時&#xff0c;我被其驚人的速度和質量所震撼。本文將全面介紹由中國科學院深圳先進技術研究院董超研究員團隊研發的HYPIR圖像修復大模型&#xff0c;詳細解析其核心技術…

基于UDP的SNMP協議

SNMP協議詳解 SNMP (Simple Network Management Protocol)&#xff0c;“簡單網絡管理協議”&#xff0c;是廣泛應用于TCP/IP網絡中&#xff0c;用于管理和監控網絡設備的一種標準協議。它允許網絡管理員查詢網絡設備的狀態信息、配置參數、接收故障告警等&#xff0c;從而實現…

3D空間中的變換矩陣

3D 空間中的變換矩陣詳解 在 3D 計算機圖形學中&#xff0c;所有幾何變換都可以通過 44 齊次變換矩陣 來表示。以下詳細介紹各種變換矩陣及其原理。 核心變換矩陣 1. 單位矩陣&#xff08;不變變換&#xff09; I[1000010000100001] I \begin{bmatrix} 1 & 0 & 0 &…

長連接(Long Connection)詳解

一、長連接基本概念長連接&#xff08;也稱為持久連接&#xff09;是指在一個TCP連接上可以連續發送多個HTTP請求/響應&#xff0c;而不是每次通信都建立新的連接。這是HTTP/1.1的默認行為&#xff0c;通過Connection: keep-alive頭部實現。二、工作原理1. 傳統短連接流程客戶端…

【匯總】接口自動化測試 + 持續集成(文末視頻演示)

技術棧&#xff1a;java testng httpclient allure fastjson jsonpath poi/yaml log4j 有建議請聯系wx&#xff1a;ren168632201 java接口自動化系列(01)&#xff1a;自動化測試框架設計(入門版) java接口自動化系列(02)&#xff1a;測試數據文件設計(excel/yam) java接…

科研快報 |無人機+AI:廣東防控基孔熱背后的技術革命

Prism Path 科 研 快 報 CS跨學科頂尖期刊論文資訊 -NO.2025001- 人工智能在登革熱預防、控制與管理中的作用&#xff1a;一項技術性敘述綜述 The role of artificial intelligence for dengue prevention, control, and management: A technical narrative review 期刊…

常見的中間件漏洞

建議&#xff1a;啟動下一個環境時&#xff0c;將上一個環境關閉&#xff0c;防止端口沖突和運行卡頓1.TomcatTomcat put方法任意文件寫入漏洞Apache Tomcat 7.0.0 - 7.0.79 Apache Tomcat 8.5.19環境&#xff1a;cd vulhub-master/tomcat/CVE-2017-12615 docker-compose up -d…

7寸工業模組 XA070Y2-L01芯顯科技詳細參數資料

芯顯7寸工業液晶屏 XA070Y2-L01 技術規格單 基礎信息 項目 參數 制造商 芯顯 型號 XA070Y2-L01 顯示技術 a-Si TN TFT-LCD 應用場景 車載中控 / 工業HMI 屏幕尺寸 7.0英寸 機械結構 特性 指標 顯示區域 152.4 91.44 mm 整機尺寸 165 104.09 9.1 mm 公差范圍 0.5 mm 表面處理…

機器學習基礎-numpy

一、相關知識點二、例子&#xff1a;import matplotlib.pyplot as plt import numpy as npplt.rcParams[font.sans-serif] [KaiTi] # 使用黑體 plt.rcParams[axes.unicode_minus] False # 解決負號顯示問題math np.random.randint(low60,high100,size50) english np.rand…

Cockpit管理服務器

Cockpit 是一個開源工具&#xff0c;通過Web Console管理Linux服務器。部署 Cockpit[rootserver ~ 11:05:26]# yum -y install cockpit?[rootserver ~ 11:30:26]# systemctl enable cockpit.socket --nowCreated symlink from /etc/systemd/system/sockets.target.wants/cockp…

處理訂單過期但支付成功的系統設計:平衡用戶體驗與業務規則

設計一個處理訂單過期但用戶支付成功的場景&#xff0c;需要平衡用戶體驗、系統一致性和業務規則。以下是一個系統化的設計方案&#xff0c;涵蓋關鍵流程、異常處理和用戶溝通&#xff1a;1. 場景分析 背景&#xff1a;用戶在下單后&#xff0c;訂單因超時而被標記為“過期”&a…