C語言面試題---指針篇(一)

来源:https://www.cnblogs.com/anxiangcx/archive/2017/12/25/8108373.html
-Advertisement-
Play Games

原創2017-12-25創新教育研究中心TeachPlus C語言面試題 指針篇(一) 指針的使用,一直是c語言面試題中必考的部分, 因為指針本身使用的複雜性與普適性,所以考點非常多,而且也可以與其他知識相互結合, 因此我們將會使用五篇專題的篇幅來介紹指針。分析下麵的程式,指出程式中的錯誤: # i ...


原創2017-12-25創新教育研究中心TeachPlus

                                                        C語言面試題---指針篇(一)

指針的使用,一直是c語言面試題中必考的部分,

因為指針本身使用的複雜性與普適性,所以考點非常多,而且也可以與其他知識相互結合,

因此我們將會使用五篇專題的篇幅來介紹指針。分析下麵的程式,指出程式中的錯誤:

# include <stdio.h>
int  main( void)
{
    char a;
    char *str=&a;
    strcpy(str,"hello");
    printf("%s\n",str);
    return 0;
}

本題解析

沒有正確為str分配記憶體空間,將會發生異常。

問題出在將一個字元串複製進一個字元變量指針所指地址。

雖然編譯的時候沒有報錯,但是在運行過程中,因為越界訪問了未被分配的記憶體,而導致段錯誤。

相關知識點

在處理與指針相關的問題時,首先需要搞明白的就是記憶體,因為指針操作的就是記憶體。
第一個,就是記憶體的分區。這也是經常會被考察的一個考點。

寫出記憶體分為幾大區域

對於這個問題,有幾種不不同的說法。

有的說記憶體分為五大分區,有的說分為四大分區,我們先來先看五個分區的說法:

認為記憶體分為五大分區的人,通常會這樣劃分: 

1、BSS段( bss segment )

通常是指用來存放程式中未初始化的全局變量和靜態變量 (這里註意一個問題:一般的

書上都會說全局變量和靜態變量是會自動初始化的,那麼哪來的未初始化的變量呢?變量的

初始化可以分為顯示初始化和隱式初始化,全局變量和靜態變量如果程式員自己不初始化的話的確

也會被初始化,那就是不管什麽類型都初始化為0,這種沒有顯示初始化的就是我們這里所說的未初始化。

既然都是0那麼就沒必要把每個0都存儲起來,從而節省磁碟空間,這是BSS的主要作用)的一塊記憶體區域。

BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態記憶體分配。 

BSS節不不包含任何數據,只是簡單的維護開始和結束的地址,即總大小。

以便記憶體區能在運行時分配並被有效地清零。BSS節在應用程式的二進位映象文件中並不存在,

即不占用磁碟空間而只在運行的時候占用記憶體空間 ,所以如果全局變量和靜態變量未初始化那麼其可執行文件要小很多。

2、數據段(data segment)

通常是指用來存放程式中已經初始化的全局變量和靜態變量的一塊記憶體區域。

數據段屬於靜態記憶體分配,可以分為只讀數據段和讀寫數據段。

字元串常量等,但一般都是放在只讀數據段中。

3、代碼段(code segment/text segment)

通常是指用來存放程式執行代碼的一塊記憶體區域。

這部分區域的大小在程式運行前就已經確定,

並且記憶體區域通常屬於只讀, 某些架構也允許代碼段為可寫,即允許修改程式。

在代碼段中,也有可能包含一些只讀的常數變量,例例如字元串常量等,但一般都是放在只讀數據段中 。

4、堆(heap)

堆是用於存放進程運行中被動態分配的記憶體段,它的大小並不固定,可動態擴張或縮減。

當進程調用malloc等函數分配記憶體時,新分配的記憶體就被動態添加到堆上(堆被擴張); 

當利用free等函數釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減)

5、棧 (stack)

棧又稱堆棧, 是用戶存放程式臨時創建的局部變量,也就是說我們函數括弧“{}” 中定義

的變量(但不不包括static聲明的變量,static意味著在數據段中存放變量)。

除此以外, 在函數被調用時,其參數也會被壓入發起調用的進程棧中,並且待到調用結束後,

函數的返回值也會被存放回棧中。由於棧的先進先出特點,所以 棧特別方便用來保存/恢復調用現場。

從這個意義上講,我們可以把堆棧看成一個寄存、交換臨時數據的記憶體區。

 

而四大分區的說法,則這麼認為:

1、堆區:

由程式員手動申請,手動釋放,若不手動釋放,程式結束後由系統回收,生命周期是整個程式運

行期間。使用malloc或者new進行堆的申請,堆的總大小為機器器的虛擬記憶體的大小。

說明:new操作符本質上是使用了malloc進行記憶體的申請,new和malloc的區別如下:

(1)malloc是C語言中的函數,而new是C++中的操作符。

(2)malloc申請之後返回的類型是void*,而new返回的指針帶有類型。

(3)malloc只負責記憶體的分配而不會調用類的構造函數,而new不僅會分配記憶體,

而且會自動調用類的構造函數。

2、棧區:

由系統進行記憶體的管理理。主要存放函數的參數以及局部變量。

在函數完成執行,系統自行釋放棧區記憶體,不需要用戶管理。

整個程式的棧區的大小可以在編譯器器中由用戶自行設定,

VS中預設的棧區大小為1M,可通過VS手動更改棧的大。

64bits的Linux預設棧大小為10MB,可通過ulimit-s臨時修改。

3、靜態存儲區:

靜態存儲區內的變量在程式編譯階段已經分配好記憶體空間並初始化。這塊記憶體在程式的整個運行

期間都存在,它主要存放靜態變量、全局變量和常量。

註意:
(1)這里不區分初始化和未初始化的數據區,是因為靜態存儲區內的變量若不顯示初始化,

則編譯器會自動以預設的方式進行初始化,

即靜態存儲區內不存在未初始化的變量。

(2)靜態存儲區內的常量分為常變量和字元串常量,一經初始化,不可修改。

靜態存儲內的常變量是全局變量,與局部常變量不不同,

區別在於局部常變量存放於棧,實際可間接通過指針或者

引用進行修改,而全局常變量存放於靜態常量區則不可以間接修改。

(3)字元串常量存儲在靜態存儲區的常量區,字元串常量的名稱即為它本身,屬於常變量。

(4)數據區的具體劃分,有利利於我們對於變量類型的理理解。

不同類型的變數存放的區域不同。後面將以實例代碼說明這四種數據區中具體對應的變量。

4、代碼區:

存放程式體的二進位代碼。比如我們寫的函數,都是在代碼區的。


通過上面的不同說法,我們也可以看出,這兩種說法本身沒有優劣之分,

具體的記憶體劃分也跟編譯器有很大的關係,因此這兩種說法都是可以接受的,

搞明白記憶體的分區之後,指針的使用才能夠更更加的靈活


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 訪問node.js官網(https://nodejs.org/en/download/),下載相應的版本。 下載完,點擊安裝 【預設目錄】 Node.js v8.9.3 to /usr/local/bin/node npm v5.5.1 to /usr/local/bin/npm 安裝完畢 node ...
  • 1、 再開機啟動的時候按鍵盤上的“e”鍵會出現如下界面。再次按”e“鍵進行選擇相應的內核。 2、 選擇相應的內核,再次按“e“。 3、經過第二步,這個畫面可以編輯,在信息的最後加“空格“,然後鍵入”single“(如圖):或者直接輸入數字的”1“並回車確定進入下一步。如下圖: 4、操作完第三步,會出 ...
  • 一、Apache簡介 Apache HTTP Server(簡稱Apache)是Apache軟體基金會的一個開放源代碼的網頁伺服器軟體,可以在大多數電腦操作系統中運行,由於其跨平臺和安全性(儘管不斷有新的漏洞被髮現,但由於其開放源代碼的特點,漏洞總能被很快修補。因此總合來說,其安全性還是相當高的。) ...
  • 轉:http://blog.csdn.net/lichengtongxiazai/article/details/38941913 此文章針對高通msm8953平臺,啟動過程中,bootloader(預設是bootable/bootloader/lk)會根據機器硬體信息選擇合適的devicetree ...
  • mv(選項)(參數) 剪切,或在同目錄下移動重命名1.如果目標文件是文件夾,則源文件直接移動到該文件夾內,名字還是源文件的名字。2.如果目標文件時文件,則源文件移動的同時也會更改名字3.如果源文件為多個,則目標必須是目錄,並且統一移動到目錄下 -b:當目標文件存在時,先進行備份在覆蓋 -f:當目標文 ...
  • 1.gzip壓縮工具 格式:gzip [-d#] filename -d:為解壓縮參數 #:#為數字,表示壓縮等級,1為最差,9為最好,6為預設 壓縮後,原文件會刪除 加入-d參數為解壓縮 主意:gzip只能壓縮文件,不能壓縮目錄 2.bzip2壓縮工具 格式:bzip2 [-dz] filenam ...
  • CleanMyMac 3是Mac系統中一個功能強大的應用程式清理軟體,它能夠優化Mac系統,合理釋放系統資源的開銷。它有一系列的工具,包括系統清理,在Mac上刪除應用程式的卸載程式,不留下任何東西,碎紙機刪除文件沒有痕跡,一套優化調整方案等等。 聽起來不錯?那麼,它也很好看。 CleanMyMac關 ...
  • 使用Linux的文件API,經常看見一個東西,叫做文件描述符. 什麼是文件描述符? (1)文件描述符其實實質是一個數字,這個數字在一個進程中表示一個特定的含義,當我們open打開一個文件時,操作系統在記憶體中構建了一些數據結構來表示這個動態文件,然後返回給應用程式一個數字作為文件描述符,這個數字就和我 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...