0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言里變量的生命周期

DS小龍哥-嵌入式技術(shù) ? 來源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2023-07-11 09:12 ? 次閱讀

在 C 語言中,變量的生命周期指的是該變量存在的時間段,理解變量的內(nèi)存釋放時機,設(shè)計程序才能少出問題。

在程序執(zhí)行期間,變量會經(jīng)歷以下三個階段:

(1)定義階段(定義變量):在定義變量時,編譯器會為該變量分配內(nèi)存空間。此時變量的值是不確定的。

(2)使用階段(賦值、讀取變量):在程序執(zhí)行過程中,可以對變量進行賦值或讀取操作。此時變量的值是確定的,并且會隨著程序執(zhí)行的進度而變化。

(3)銷毀階段(變量被銷毀):在變量的作用域結(jié)束時,該變量就會被銷毀。在這個過程中,編譯器會自動釋放該變量所占用的內(nèi)存空間。

根據(jù)變量的定義位置和作用域,C 語言中的變量可以分為以下兩種類型:

(1)局部變量:定義在函數(shù)內(nèi)部或代碼塊內(nèi)部的變量稱為局部變量。局部變量只能在其定義所在的函數(shù)或代碼塊內(nèi)部使用,并且在函數(shù)或代碼塊結(jié)束時被銷毀。局部變量的生命周期受限于其所處的函數(shù)或代碼塊的生命周期。

(2)全局變量:定義在函數(shù)外部或文件頂部的變量稱為全局變量。全局變量可以在整個程序中使用,其生命周期從程序開始到程序結(jié)束。全局變量在程序運行期間一直存在,并且在程序結(jié)束時才被銷毀。

除了上述兩種變量類型之外,C 語言還提供了另外一種特殊的變量類型——靜態(tài)變量。靜態(tài)變量定義在函數(shù)內(nèi)部或代碼塊內(nèi)部,但其生命周期與局部變量不同。靜態(tài)變量在函數(shù)或代碼塊結(jié)束時不會被銷毀,而是繼續(xù)存在于內(nèi)存中,并保留其上一次賦值的值,直到下一次被修改。

在 C 語言中,變量的生命周期是由其作用域和定義位置決定的。正確地管理變量的生命周期對于程序的正確性和性能都至關(guān)重要,程序員需要深入了解變量的生命周期,遵循正確的使用規(guī)則,確保程序的正確性和健壯性。

以下是使用代碼進行舉例說明變量的生命周期:

(1)定義階段

在定義變量時,編譯器會為該變量分配內(nèi)存空間。

例如,在函數(shù)內(nèi)部定義一個整型變量 a,其定義語句如下:

void foo() {
     int a;  // 定義變量
 }

此時變量 a 就被分配了內(nèi)存空間,但其值是不確定的。

(2)使用階段

在程序執(zhí)行過程中,可以對變量進行賦值或讀取操作。

例如,在上述定義變量的基礎(chǔ)上,給變量 a 賦值并讀取其值的代碼如下:

void foo() {
     int a;  // 定義變量
 ?
     a = 10;  // 給變量賦值
     printf("a = %d
", a);  // 打印變量的值
 }

此時變量 a 的值已經(jīng)確定為 10,并被輸出到控制臺。

(3)銷毀階段

在變量的作用域結(jié)束時,該變量就會被銷毀。在這個過程中,編譯器會自動釋放該變量所占用的內(nèi)存空間。例如,在上述定義變量和使用變量的代碼基礎(chǔ)上,添加一個條件語句使得變量 a 在條件成立之后被銷毀,示例代碼如下:

void foo() {
     int a;  // 定義變量
 ?
     a = 10;  // 給變量賦值
     printf("a = %d
", a);  // 打印變量的值
 ?
     if (a > 5) {
         int b = 20;  // 定義變量
         printf("b = %d
", b);  // 打印變量的值
     }
 ?
     printf("a = %d
", a);  // 打印變量的值,此時變量依然存在
 }

在上述代碼中,當(dāng)條件 a > 5 成立時,程序會在條件中定義并使用一個新的整型變量 b,但該變量在條件結(jié)束后就被釋放了。而變量 a 的生命周期則受限于函數(shù) foo() 的作用域,即在函數(shù)結(jié)束時被銷毀。

(4)子函數(shù)返回地址(指針)

如果子函數(shù)返回指針變量,需要注意指針變量的生命周期問題,以避免指針失效和內(nèi)存泄漏等問題。

假設(shè)有一個子函數(shù) get_string(),該函數(shù)返回一個動態(tài)分配的字符串指針。函數(shù)定義及示例代碼如下:

char* get_string() {
     char* str = (char*) malloc(10 * sizeof(char));
     str[0] = 'H';
     str[1] = 'e';
     str[2] = 'l';
     str[3] = 'l';
     str[4] = 'o';
     str[5] = '';
     return str;
 }
 ?
 int main() {
     char* s = get_string();
     printf("%s
", s);  // 輸出 "Hello"
 ?
     // 此處應(yīng)該手動釋放內(nèi)存
     free(s);
 ?
     return 0;
 }

在上述代碼中,函數(shù) get_string() 動態(tài)分配了一個長度為 10 的字符數(shù)組 str,并返回了該數(shù)組的首地址,該指針是在堆(heap)上分配的。由于是動態(tài)分配的內(nèi)存空間,因此需要手動釋放。在 main() 函數(shù)中對指針進行操作后,也需要手動釋放該指針所指向的內(nèi)存空間,以避免內(nèi)存泄漏。

以下是一個錯誤的示例,用于和前面正確示例進行對比,幫助理解返回指針的生命周期問題:

char* get_string() {
     char str[] = "Hello";
     return str;
 }
 ?
 int main() {
     char* s = get_string();
     printf("%s
", s);  // 輸出 "Hello"
 ?
     return 0;
 }

在這個示例中,函數(shù) get_string() 返回了一個局部數(shù)組 str 的首地址。由于 str 是在函數(shù)內(nèi)部定義的局部變量,其生命周期僅限于函數(shù)調(diào)用過程中。當(dāng)函數(shù) get_string() 執(zhí)行完畢后,str 的生命周期已經(jīng)結(jié)束,其內(nèi)存空間已被回收,此時返回的指針變量 s 已經(jīng)成為了野指針,指向了無效的內(nèi)存空間,進而會導(dǎo)致未定義的行為。

盡管該函數(shù)定義的返回類型是 char*,但是由于返回了一個局部變量的指針,會導(dǎo)致指針失效、訪問非法內(nèi)存等問題,從而產(chǎn)生程序崩潰等錯誤行為。

總結(jié):如果一個子函數(shù)需要返回指針變量,需要確保返回的指針指向的內(nèi)存空間在使用期間有效,否則會導(dǎo)致嚴重的問題。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    2942

    瀏覽量

    73726
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7581

    瀏覽量

    135540
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3541

    瀏覽量

    93462
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4256

    瀏覽量

    62223
  • 指針變量
    +關(guān)注

    關(guān)注

    0

    文章

    17

    瀏覽量

    7221
收藏 人收藏

    評論

    相關(guān)推薦

    基于Rust語言中的生命周期

    Animal的代碼示例。 生命周期 生命周期是Rust語言中的一個概念,用于決內(nèi)存安全問題。我們在Rust中定義一個變量時,需要確定這個變量
    的頭像 發(fā)表于 09-19 17:03 ?829次閱讀

    AutoScaling 生命周期掛鉤功能

    摘要: AutoScaling 伸縮組實例管理功能全面升級,新上線生命周期掛鉤(LifecycleHook)功能,方便用戶更加靈活地管理伸縮組內(nèi)實例。使用生命周期掛鉤可以在伸縮組發(fā)生伸縮活動時將伸縮
    發(fā)表于 06-27 17:13

    請問C6720的生命周期還有多長?

    您好!因成本限制,有個產(chǎn)品想使用TMS320C6720BRFP200,但是不知道這個芯片的生命周期還有多長?謝謝!
    發(fā)表于 08-01 06:37

    HarmonyOS應(yīng)用開發(fā)-PageAbility生命周期

    pageAbility的生命周期如下圖所示:在代碼中通過調(diào)用下列方法實現(xiàn)生命周期操作:onShow() :Ability由后臺不可見狀態(tài)切換到前臺可見狀態(tài)調(diào)用onShow方法,此時用戶在屏幕可以看到
    發(fā)表于 10-17 11:11

    在S32G2 RM中有“生命周期”,生命周期的完整含義是什么?

    在S32G2 RM中,有“生命周期”。生命周期的完整含義是什么,我們應(yīng)該如何使用它?
    發(fā)表于 04-23 10:37

    一文讀懂Android Activity生命周期

    正常情況下Activity的生命周期: Activity的生命周期大概可以歸為三部分 整個的生命周期:onCreate()可以設(shè)置所有的“全局”狀態(tài), onDestory()可以釋放所有的資源 可見
    發(fā)表于 05-30 01:03 ?1545次閱讀

    基于延長WSN生命周期的LEACH算法的改進

    基于延長WSN生命周期的LEACH算法的改進(開關(guān)電源技術(shù)與設(shè)計pdf百度云)-基于延長WSN生命周期的LEACH算法的改進? ? ? ? ? ? ? ? ? ??
    發(fā)表于 09-15 11:17 ?14次下載
    基于延長WSN<b class='flag-5'>生命周期</b>的LEACH算法的改進

    存儲類&作用域&生命周期&鏈接屬性

    、鏈接屬性前言本篇文章將會為大家介紹一些變量相關(guān)的存儲屬性、作用域、生命周期以及鏈接屬性的一些知識,有助于大家更好地理解程序,分析程序。一、存儲類&作用域&生命周期&鏈接屬性的概念解析1、存儲類(1)存儲
    發(fā)表于 12-09 15:51 ?5次下載
    存儲類&作用域&<b class='flag-5'>生命周期</b>&鏈接屬性

    Synopsys 啟動硅生命周期管理計劃

    Synopsis 的數(shù)據(jù)分析驅(qū)動的硅生命周期管理計劃解決了 IC 生命周期中的質(zhì)量、可靠性和安全挑戰(zhàn)。
    發(fā)表于 08-18 15:37 ?790次閱讀
    Synopsys 啟動硅<b class='flag-5'>生命周期</b>管理計劃

    Vue入門Vue的生命周期

    .生命周期 4.1生命周期是什么 Vue的生命周期, 就是Vue實例從創(chuàng)建到銷毀的過程.
    的頭像 發(fā)表于 02-06 16:16 ?806次閱讀
    Vue入門Vue的<b class='flag-5'>生命周期</b>

    編譯器的標準生命周期

    編譯器的標準生命周期
    發(fā)表于 03-14 19:06 ?0次下載
    編譯器的標準<b class='flag-5'>生命周期</b>

    編譯器的標準生命周期

    編譯器的標準生命周期
    發(fā)表于 07-05 19:32 ?0次下載
    編譯器的標準<b class='flag-5'>生命周期</b>

    數(shù)據(jù)包的生命周期

    電子發(fā)燒友網(wǎng)站提供《數(shù)據(jù)包的生命周期.pdf》資料免費下載
    發(fā)表于 10-13 14:44 ?0次下載

    鴻蒙開發(fā):【PageAbility的生命周期

    PageAbility生命周期是PageAbility被調(diào)度到INACTIVE、ACTIVE、BACKGROUND等各個狀態(tài)的統(tǒng)稱。PageAbility生命周期流轉(zhuǎn)及狀態(tài)說明見如下圖1、表1所示。
    的頭像 發(fā)表于 06-17 10:05 ?624次閱讀
    鴻蒙開發(fā):【PageAbility的<b class='flag-5'>生命周期</b>】

    鴻蒙開發(fā)組件:DataAbility的生命周期

    應(yīng)用開發(fā)者可以根據(jù)業(yè)務(wù)場景實現(xiàn)data.js/data.ets中的生命周期相關(guān)接口。DataAbility生命周期接口說明見下表。
    的頭像 發(fā)表于 06-20 09:39 ?329次閱讀