c語言 char *str = ““ 和 char *str = NULL 以及 char str[] = {} 區別

目錄

  • 前言
  • char *str = "" 和 char *str = NULL 區別
  • char *str = NULL 和 char str[] = {} 區別
  • char *str = "" 和 char str[] = {} 區別
  • char *str = "" 和 const char *str = "" 區別

前言

C語言指針的使用非常常見且易出錯,這里對常見的用法做個總結。

指針就是固定大小(一般系統占據4字節)的一塊空間,保存的是其他變量的地址。一個指向性的東西。

  • C語言里面“”表示字符串,保存在常量區,不能修改;
  • {}表示數組,自動分配棧空間,可以修改;
  • 指針本身是個變量,一般固定占用4個字節,保存其他變量的地址,可以修改從而指向不同的地址空間(非const修飾保存在棧空間)。
char *p1 = NULL;
char *p2 = "";strlen(p1);    // 段錯誤(訪問0地址)
strlen(p2);    // 返回0(安全)
sizeof(p1);	   // 安全,strlen計算的是指針指向的字符串空間的長度,而sizeof計算的是指針本身的長度*p1 = 'a';     // 段錯誤
*p2 = 'a';     // 段錯誤(只讀內存)// 指針是個變量,本身保存在棧空間里,修改指針本身從而指向不同的地方
char *reason_str = "";
switch (reset_reason)
{case ESP_RST_UNKNOWN:   reason_str = "UNKNOWN"; break;case ESP_RST_POWERON:   reason_str = "POWERON"; break;case ESP_RST_EXT:       reason_str = "PIN"; break;case ESP_RST_SW:        reason_str = "SW"; break;case ESP_RST_PANIC:     reason_str = "PANIC"; break;case ESP_RST_WDT:       reason_str = "WDT"; break;case ESP_RST_DEEPSLEEP: reason_str = "DEEPSLEEP"; break;case ESP_RST_BROWNOUT:  reason_str = "BROWNOUT"; break;case ESP_RST_SDIO:      reason_str = "SDIO"; break;
}

char *str = “” 和 char *str = NULL 區別

在C語言中,char *str = “” 和 char *str = NULL 有本質區別,主要體現在內存分配、使用場景和操作安全性上。以下是詳細對比:

?1. 內存表現

特性char *str = NULLchar *str = “”
?指針值0x00000000(無效地址)有效地址(如 0x00405060)
?指向內容無內存分配1字節的 ‘\0’(空字符串)
??內存區域只讀數據段(.rodata)

?2. 核心區別

  • ?NULL?

    • 表示指針未初始化或指向無效地址。
    • ?解引用會崩潰?(如 strlen(NULL) 觸發段錯誤)。
    • 典型用途:標識錯誤返回值或未初始化的狀態。
  • ?""?

    • 指向合法的空字符串(僅含終止符 ‘\0’)。
    • ?可安全操作?(如 strlen(“”) 返回 0)。
    • 典型用途:表示邏輯上的“空值”而非“無值”。

?3. 使用場景對比?
?場景1:函數返回值

const char* get_error_msg(int code) {if (code == 0) return NULL;  // 無錯誤消息if (code == 1) return "";    // 空錯誤消息(合法但無內容)return "Error occurred";
}

NULL:表示“無消息”
“”:表示“有消息但內容為空”

場景2:字符串處理

void print_str(const char *s) {if (s == NULL) {printf("NULL input\n");} else if (s[0] == '\0') {printf("Empty string\n");} else {printf("%s\n", s);}
}

輸入 NULL → 輸出 NULL input
輸入 “” → 輸出 Empty string

?場景3:默認值初始化

char *log_msg = NULL;   // 默認未記錄日志
char *user_input = "";  // 默認空輸入(避免NULL解引用崩潰)

?4. 操作安全性

操作NULL 結果“” 結果
?strlen(str)段錯誤返回 0
?strcpy(dest, str)段錯誤復制 ‘\0’
??printf(“%s”, str)段錯誤輸出空(無崩潰)

?5. 總結?
?- 用 NULL 當?:

    • 需要明確表示“無值”或“無效”。
    • 作為錯誤返回值或未初始化狀態。
      ?- 用 “” 當?:
    • 需要安全處理字符串操作(避免NULL檢查)。
    • 表示邏輯上的“空字符串”而非“無字符串”。
      ?

關鍵區別?:NULL 是“指針無意義”,“” 是“指針有意義但內容為空”。

char *str = NULL 和 char str[] = {} 區別

在C語言中,char *str = NULL和char str[] = {}有本質區別,主要體現在內存分配、可修改性和使用場景上:

?1. 內存分配方式

特性char *str = NULLchar str[] = {}
??類型指針(未指向有效內存)數組(自動分配棧內存)
?內存區域無實際分配棧空間(通常可讀寫)
大小指針大小(如4/8字節)1字節(僅含\0)

?2. 核心區別?

  • ?char *str = NULL?

    • 定義了一個未初始化的?指針變量?,值為0x0
    • ?不能直接操作內容?(解引用會崩潰,如str[0]觸發段錯誤)
    • 典型用途:動態內存分配的占位符或錯誤標識
  • ?char str[] = {}?

    • 定義了一個?空字符數組?,實際包含1字節的’\0’
    • ?可安全操作內容?(如str[0] = 'a’修改棧內存)
    • 典型用途:局部緩沖區的空初始化

3. 操作對比?
?示例代碼

#include <stdio.h>int main() {char *ptr = NULL;    // 指針未指向有效內存char arr[] = {};     // 空數組(含'\0')// 操作測試printf("ptr size: %zu\n", sizeof(ptr));  // 輸出指針大小(如8)printf("arr size: %zu\n", sizeof(arr));  // 輸出1(含'\0')// arr[0] = 'a';     // 合法(修改棧內存)// ptr[0] = 'a';     // 崩潰(解引用NULL)return 0;
}

關鍵操作安全性

操作NULL 結果{} 結果
sizeof返回指針大小返回1(含\0)
下標訪問(如[0])段錯誤可讀寫
strlen段錯誤返回0

4. 使用場景

?用 char *str = NULL 當?:

  • 需要后續動態分配內存(如str = malloc(10))

  • 作為函數參數表示“未初始化”狀態
    ?
    用 char str[] = {} 當?:

  • 需要局部空字符串緩沖區

  • 避免指針解引用風險時(如嵌入式開發)

?5. 特殊注意

C99/C11標準中,char str[] = {}是?非標準語法?(但部分編譯器支持),更規范的寫法是:

char str[] = "";  // 標準寫法,等效含'\0'的空數組

若需明確空數組初始化,建議使用:

char str[1] = {0};  // 顯式初始化為0

總結?
NULL指針表示“無內存關聯”,而空數組{}是“已分配的可操作內存”。前者需動態分配后使用,后者直接具備棧內存安全性。

char *str = “” 和 char str[] = {} 區別

在C語言中,char *str = ""和char str[] = {}有以下核心區別:

1、?內存分配與生命周期?
char *str = “”:指針指向只讀數據段的空字符串常量(.rodata段),生命周期為整個程序運行期
char str[] = {}:數組分配在棧空間(自動存儲期),生命周期限于當前作用域
?2、可修改性?
char *str = “”:內容不可修改(嘗試修改會導致未定義行為)
char str[] = {}:內容可修改(棧內存可讀寫)
3、?語法有效性?
char *str = “”:標準C語法
char str[] = {}:非標準語法(部分編譯器擴展支持),更規范的寫法是char str[] = ""或char str[1] = {0}
4、?sizeof行為?
sizeof(str)在指針情況下返回指針大小(如8字節)
sizeof(str)在數組情況下返回實際分配大小(空數組為1字節,含’\0’)
?5、典型使用場景?
指針形式常用于定義全局字符串常量
數組形式常用于局部可修改緩沖區

注意:空數組初始化{}在C99/C11中不是標準語法,建議改用""或{0}明確初始化。

char *str = “” 和 const char *str = “” 區別

在C語言中,char *str = ""和const char *str = ""的關鍵區別在于?類型安全性和編譯器約束?,具體對比如下:

1. 本質區別

特性char *str = “”const char *str = “”
?類型修飾普通指針常量指針
?內容可修改性語法允許修改(但實際會引發未定義行為)明確禁止修改(編譯器報錯)
編譯器檢查無保護強制類型檢查

?2. 實際表現?

?示例代碼

char *p = "";         // 無const修飾
const char *cp = "";  // 有const修飾// p[0] = 'a';       // 編譯通過,但運行時可能崩潰(字符串常量區不可寫)
// cp[0] = 'a';      // 直接編譯報錯(const保護)

關鍵差異?
?char *str?

  • 僅表示指向字符的指針,不承諾指向的內容是否可改
  • 若指向字符串常量(如""),嘗試修改會導致?未定義行為?(通常是段錯誤)

const char *str?

  • 明確告知編譯器指向的內容不可修改
  • 任何修改嘗試會觸發?編譯時錯誤?,提前暴露問題

?3. 使用場景建議?
?用 char * 當?:

  • 需要兼容舊代碼(歷史遺留API)
  • 明確知道后續會指向可修改內存(如malloc分配的堆內存)
    ?

用 const char * 當?:

  • 指向字符串常量(如""或字面量)
  • 作為函數參數防止意外修改(如strlen的原型)

?4. 為什么推薦const版本??

?1、安全性?:避免意外修改只讀數據(如p[0] = 'x’的隱蔽錯誤)
?2、可讀性?:明確表達設計意圖(“我只讀不寫”)
?3、編譯器優化?:const可能幫助編譯器生成更優代碼

?5. 特殊注意?

  • 以下寫法是?等效?的(均指向只讀空字符串):
const char *s1 = "";
char const *s2 = "";  // const位置不同,但含義相同
  • 但若寫成char * const s3 = “”,則表示?指針本身不可改?(而非指向內容)。

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

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

相關文章

小程序入門: tab bar 實現多頁面快速切換效果

在小程序開發中&#xff0c;tab bar 是實現多頁面快速切換的關鍵組件&#xff0c;能極大提升用戶體驗。上一篇我們完成了基礎配置&#xff0c;今天深入探索&#xff0c;打造更豐富實用的 tab bar 效果。 實現目標 這次要在小程序底部創建包含 “首頁”“消息”“聯系我們” 三…

Python 數據分析:numpy,抽提,多維切片索引

目錄 1 示例代碼2 歡迎糾錯3 免費爬蟲------以下關于 Markdown 編輯器新的改變功能快捷鍵合理的創建標題&#xff0c;有助于目錄的生成如何改變文本的樣式插入鏈接與圖片如何插入一段漂亮的代碼片生成一個適合你的列表創建一個表格設定內容居中、居左、居右SmartyPants 創建一個…

【向上教育】結構化面試概述.pdf

目 錄 第一章 面試須知—面試形式 .......................................................................................................... 1 一、結構化面試 .................................................................................................…

STM32F407控制單個張大頭閉環步進電機講解與梯形加減速(HAL庫)

文章目錄 硬件連接CubeMX配置**使用TIM5定時器CH3,即PA2作為脈沖控制&#xff0c;PE5控制方向&#xff08;TIM5_CH4是為控制雙電機做準備的可以先不配置&#xff09;** 設置占空比為50%,以下為AI講解重要&#xff01;&#xff01;&#xff01;定時器更新中斷脈沖觸發原理詳解PW…

MongoDB入門學習(含JAVA客戶端)

0.序章 致命的面試問題&#xff1a;為什么使用MongoDB&#xff1f; 大型的分布式的文檔型數據庫&#xff0c;也是NoSQL數據庫&#xff08;例如 redis&#xff09; MongoDB適合數據量大而價值又低的這種數據&#xff08;播放進度、評論、彈幕&#xff0c;實時數據的CRUD&…

RedisCache與StringRedisTemplate的深度對比

1. 基本概念 RedisCache ??定位??&#xff1a;自定義封裝的Redis緩存工具類??特點??&#xff1a;通常針對業務場景進行了高層抽象??典型功能??&#xff1a; 帶過期時間的緩存操作自定義序列化方式業務鍵前綴管理簡化常用操作API StringRedisTemplate ??定位…

HOOPS Visualize技術詳解(二):3D圖形系統HOOPS/3DGS的段結構與屬性機制

在工業級三維可視化領域中&#xff0c;HOOPS Visualize憑借其高性能和模塊化設計被廣泛應用于CAD、CAM、仿真、BIM等工程軟件中。其中&#xff0c;HOOPS 3D Graphics System&#xff08;簡稱HOOPS/3DGS&#xff09;是HOOPS Visualize的核心組件&#xff0c;承擔著圖形場景管理、…

隨機化在臨床試驗中的應用與挑戰

一、隨機化的核心目的 1.1 控制混雜偏倚 1.1.1 平衡預后因素 確保已知/未知預后因素在組間分布均衡,避免基線不平衡影響結果。 1.1.2 避免選擇偏倚 防止研究者或患者主觀選擇分組,保障組間差異歸因于干預。 1.2 保障統計推斷有效性 1.2.1 滿足獨立性假設 滿足統計檢驗…

在C++中#pragma“可選預處理指令的作用“。

文章目錄 1. 標準定位&#xff1a;2. 語法形式&#xff1a;3. 常見用途舉例4. 為什么用 #pragma&#xff1f;5. 宏里用 __pragma / _Pragma6. 常見誤區 在 C/C 里&#xff0c;#pragma 本質上是“可選預處理器指令”&#xff0c;用來告訴編譯器在編譯某段代碼時啟用或關閉某些特…

windows系統中docker數據遷移出系統盤

1、關閉docker 2、移動docker數據 找到docker數據目錄&#xff0c;一般在C:\Users\61050\AppData\Local\Docker文件&#xff0c;將整個docker目錄復制到其他盤&#xff08;例如 D:\Docker&#xff09;&#xff0c;為保證不出錯&#xff0c;可以先提前復制一份。 3、創建符號鏈…

win11電腦突然休眠問題排查

WinR, 輸入eventvwr.msc打開事件查看器。找到出現問題的時間點那條數據。會顯示原因。首先還是要先排查原因。再去猜測。我因為猜測就直接去了科技市場掃灰加硅來了一個遍。另外還買了散熱風扇和金屬支架。雖然不知道有沒有必要。但是別人是很原因。到頭來早上還是發現自動休眠…

安卓開發 lambda表達式

第一步&#xff1a;初學者代碼 (沒有 Lambda 的“舊”方法) 假設我們有一個簡單的需求&#xff1a;執行一個耗時的計算&#xff08;比如網絡請求&#xff09;&#xff0c;并在計算完成后&#xff0c;通過一個“回調”來通知我們結果。 1. 定義一個回調接口 這個接口只有一個…

JMeter中變量如何使用?

在性能測試的世界中&#xff0c;Apache JMeter是一把利器&#xff0c;憑借其強大的可擴展性與圖形化操作界面&#xff0c;在工業界和開源社區中廣受青睞。而“變量的使用”作為JMeter中提高測試靈活性、可維護性和復用性的關鍵技術點&#xff0c;卻常常被初學者忽略或誤用。本文…

印度和澳洲的地理因素

研究表明&#xff0c;氣溫每升高1℃&#xff0c;勞動生產率可能下降1.5%至3%&#xff0c;甚至更多。印度大部分地區夏季高溫且濕度較大&#xff0c;有地方60多度&#xff0c;嚴重限制了勞動效率和農業產出。若印度整體地理位置北移約300公里&#xff0c;平均氣溫將降低&#xf…

3D Gaussian Splatting

3D高斯濺射&#xff08;3D Gaussian Splatting &#xff09;是一種基于顯式三維高斯分布的場景表示與渲染方法。與傳統的三維重建技術&#xff08;如多邊形網格、點云或隱式神經輻射場NeRF&#xff09;不同&#xff0c;3DGS將場景表示為大量帶有屬性的3D高斯橢球的集合&#xf…

鴻蒙5:布局組件

注意&#xff1a;博主有個鴻蒙專欄&#xff0c;里面從上到下有關于鴻蒙next的教學文檔&#xff0c;大家感興趣可以學習下 如果大家覺得博主文章寫的好的話&#xff0c;可以點下關注&#xff0c;博主會一直更新鴻蒙next相關知識 專欄地址: https://blog.csdn.net/qq_56760790/…

Flink狀態和容錯-基礎篇

1. 概念 flink的狀態和容錯繞不開3個概念&#xff0c;state backends和checkpoint、savepoint。本文重心即搞清楚這3部分內容。 容錯機制是基于在狀態快照的一種恢復方式。但是狀態和容錯要分開來看。 什么是狀態&#xff0c;為什么需要狀態&#xff1f; 流計算和批計算在數…

【若依學習記錄】RuoYi后臺手冊——分頁實現

目錄 若依系統簡介 前端調用實現 前端調用舉例 后臺邏輯實現 若依系統簡介 RuoYi 是一個基于 Spring Boot、Apache Shiro、MyBatis 和 Thymeleaf 的后臺管理系統&#xff0c;旨在降低技術難度&#xff0c;助力開發者聚焦業務核心&#xff0c;從而節省人力成本、縮短項目周…

從臺式電腦硬件架構看前后端分離開發模式

在軟件開發領域,前后端分離早已成為主流架構設計理念。它將系統的業務邏輯處理與用戶界面展示解耦,提升開發效率與系統可維護性。有趣的是,我們日常生活中常見的臺式電腦硬件架構,竟與這一理念有著異曲同工之妙。今天,就讓我們從臺式電腦的硬件組成出發,深入探討其與前后…

可觀測性的哲學

在現代系統架構中&#xff0c;“可觀測性&#xff08;Observability&#xff09;”已不僅僅是一個工程實踐&#xff0c;是一種關于“理解世界”的哲學姿態, 還是一種幫助架構演變的認知工具。從柏拉圖的“洞穴寓言”出發&#xff0c;我們可以構建起一條從被動接受投影&#xff…