C語言const關鍵字—也許該被替換為readolny

const 是constant 的縮寫,是恒定不變的意思,也翻譯為常量、常數等。很不幸,正是因為這一點,很多人都認為被const 修飾的值是常量。這是不精確的,精確的說應該是只讀的變量,其值在編譯時不能被使用,因為編譯器在編譯時不知道其存儲的內容。或許當初這個關鍵字應該被替換為readonly。那么這個關鍵字有什么用處和意義呢?

const 推出的初始目的,正是為了取代預編譯指令,消除它的缺點,同時繼承它的優點。我們看看它與define 宏的區別。(很多人誤以為define 是關鍵字,在這里我提醒你再回到本章前面看看32 個關鍵字里是否有define)。

一、const 修飾的只讀變量

定義const 只讀變量,具有不可變性。例如:
? ?const intMax=100;
? ?intArray[Max];
這里請在Visual C++6.0 里分別創建.c 文件和.cpp 文件測試一下。你會發現在.c 文件中,編譯器會提示出錯,而在.cpp 文件中則順利運行。為什么呢?我們知道定義一個數組必須指定其元素的個數。這也從側面證實在C 語言中,const 修飾的Max 仍然是變量,只不過是只讀屬性罷了;而在C++里,擴展了const 的含義,這里就不討論了。

注意:const 修飾的只讀變量必須在定義的同時初始化,想想為什么?

留一個問題:case 語句后面是否可以是const 修飾的只讀變量呢?請動手測試一下。

二、節省空間,避免不必要的內存分配,同時提高效率

編譯器通常不為普通const 只讀變量分配存儲空間,而是將它們保存在符號表中,這使得它成為一個編譯期間的值,沒有了存儲與讀內存的操作,使得它的效率也很高。例如:
? ?#define M 3 //宏常量
? ?const int N=5; //此時并未將N 放入內存中
? ?......
? ?int i=N; //此時為N 分配內存,以后不再分配!
? ?int I=M; //預編譯期間進行宏替換,分配內存
? ?int j=N; //沒有內存分配
? ?int J=M; //再進行宏替換,又一次分配內存!
const 定義的只讀變量從匯編的角度來看,只是給出了對應的內存地址,而不是象#define一樣給出的是立即數,所以,const 定義的只讀變量在程序運行過程中只有一份拷貝(因為它是全局的只讀變量,存放在靜態區),而#define 定義的宏常量在內存中有若干個拷貝。

#define 宏是在預編譯階段進行替換,而const 修飾的只讀變量是在編譯的時候確定其值。
#define 宏沒有類型,而const 修飾的只讀變量具有特定的類型。

三、修飾一般變量

一般常量是指簡單類型的只讀變量。這種只讀變量在定義時,修飾符const 可以用在類型說明符前,也可以用在類型說明符后。例如:
? ?int const i=2; 或const int i=2;

四、修飾數組

定義或說明一個只讀數組可采用如下格式:
? ?int const a[5]={1, 2, 3, 4, 5};或
? ?const int a[5]={1, 2, 3, 4, 5};

五、修飾指針

? ?const int *p; // p 可變,p 指向的對象不可變
? ?int const *p; // p 可變,p 指向的對象不可變
? ?int *const p; // p 不可變,p 指向的對象可變
? ?const int *const p; //指針p 和p 指向的對象都不可變
在平時的授課中發現學生很難記住這幾種情況。 這里給出一個記憶和理解的方法:先忽略類型名(編譯器解析的時候也是忽略類型名),我們看const 離哪個近。“近水樓臺先得月”,離誰近就修飾誰。
? ?const int *p; //const 修飾*p,p 是指針,*p 是指針指向的對象,不可變
? ?int const *p; //const修飾*p,p 是指針,*p 是指針指向的對象,不可變
? ?int *const p; //const修飾p,p 不可變,p 指向的對象可變
? ?const int *const p; //前一個const 修飾*p,后一個const 修飾p,指針p 和p 指向的對象都不可變

六、修飾函數的參數

const 修飾符也可以修飾函數的參數,當不希望這個參數值被函數體內意外改變時使用。例如:
? ?void Fun(const int i);
告訴編譯器i 在函數體中的不能改變,從而防止了使用者的一些無意的或錯誤的修改。

七、修飾函數的返回值

const 修飾符也可以修飾函數的返回值,返回值不可被改變。例如:
? ?const int Fun (void);

在另一連接文件中引用const 只讀變量:
? ?extern const int i; //正確的聲明
? ?extern const int j=10; //錯誤!只讀變量的值不能改變。

注意這里是聲明不是定義,關于聲明和定義的區別,請看本章開始處。

講了這么多講完了嗎?遠沒有。在C++里,對const 做了進一步的擴展,還有很多知識未能講完。有興趣的話,不妨查找相關資料研究研究。

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

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

相關文章

dbus服務自啟動方法

Linux 一般發行版上 "/usr/share/dbus-1/services/"目錄就是dbus放service文件的地方。 需要自動啟動的服務器 就在這個目錄放一個 service文件,內容如下: $ cat /usr/share/dbus-1/services/dhcdbd.service [D-BUS Service] Namecom.redhat.…

在Spring Boot中使用 @ConfigurationProperties 注解

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 上一篇博客寫了 如何在Spring Boot application中配置mail . 使用 Value 注解注入屬性. 但 Spring Boot 提供了另一種方式 ,能…

Micronaut教程:如何使用基于JVM的框架構建微服務

\本文要點\\Micronaut是一種基于jvm的現代化全棧框架,用于構建模塊化且易于測試的微服務應用程序。\\tMicronaut提供完全的編譯時、反射無關的依賴注入和AOP。\\t該框架的開發團隊和Grails框架的開發團隊是同一個。\\tMicronaut框架集成了云技術,服務發現…

C語言extern關鍵詞—最會帶帽子的關鍵字

extern,外面的、外來的意思。那它有什么作用呢?舉個例子:假設你在大街上看到一個黑皮膚綠眼睛紅頭發的美女(外星人?)或者帥哥。你的第一反應就是這人不是國產的。extern 就相當于他們的這些區別于中國人的特…

解決Coldfusion連接MySQL數據庫的問題

在連接MySQL時,出現了如下錯誤: Connections to MySQL Community Server are not supported. Please contact MySQL to obtain a MySQL Enterprise or Commercial version. 解決方案: step 1: download the JDBC driver JDBC Driver for MySQ…

范式知識點

Mysql數據庫 ?前關系數據庫有六種范式: 第?范式(1NF)、第?范式(2NF)、第三范式(3NF)、巴斯-科德范式 (BCNF)、第四范式(4NF)和第五范式(5NF&a…

Tensorflow入門----占位符、常量和Session

安裝好TensorFlow之后,開一個python環境,就可以開始運行和使用TensorFlow了。 先給一個實例, #先導入TensorFlowimport tensorflow as tf # Create TensorFlow object called hello_constanthello_constant tf.constant(Hello World!) with …

C語言union關鍵字

union 關鍵字的用法與struct 的用法非常類似。union 維護足夠的空間來置放多個數據成員中的“一種”,而不是為每一個數據成員配置空間,在union 中所有的數據成員共用一個空間,同一時間只能儲存其中一個數據成員,所有的數據成員具有…

js 深拷貝 和 淺拷貝

1、 ...運算符 (淺拷貝) let obj {a:1,b:2}; let obj2 {...obj}; obj.a3 obj //{a: 3, b: 2} obj2 //{a: 1, b: 2}a {a:[{b:1}]}; b a ;b.a[0].b 2; //b {a:[{b:2}]}a // a {a:[{b:2}]} 2、 JSON.parse(JSON.stringify(參數))…

軟考如何備考

軟考上半年 報名時間 3月 考試時間 5月 備考持續時間:一個半月,每天至少兩個小時。 第一輪 基礎知識輪, 15天 在這一輪中如果碰到無法理解的知識點一定不要過于糾結,往后學,一般后面的學著學著之前的內容就…

Python學習第一天-第2節

*本節課內容參見:https://www.cnblogs.com/jin-xin/articles/7459977.html運行第一個Python程序 print(hello world) 將文本文件保存為以.py結尾的文件,如hello_world.py ,在終端中,運行命令:Python hello_world.py&am…

SpringMVC之組合注解@GetMapping

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 Spring4.3中引進了{GetMapping、PostMapping、PutMapping、DeleteMapping、PatchMapping},來幫助簡化…

資源下載地址

1、nginx http://nginx.org/en/download.html 2、nodejs http://nodejs.cn/download/ 3、vscode https://code.visualstudio.com/ 4、canal https://github.com/alibaba/canal/releases/download/canal-1.1.4/canal.deployer-1.1.4.tar.gz 5、jenkins https://jenkins.io/i…

C語言volatile關鍵字—最易變的關鍵字

volatile 是易變的、不穩定的意思。很多人根本就沒見過這個關鍵字,不知道它的存在。也有很多程序員知道它的存在,但從來沒用過它。我對它有種“楊家有女初長成,養在深閨人未識” 的感覺。volatile 關鍵字和const 一樣是一種類型修飾符,用它修…

mysql 備份腳本

#!/bin/bash INNOBACKUPEXFULL"/usr/bin/innobackupex" MYSQL_CMD --socket/ssd/mysql/3346/tmp/mysql.sock --userroot --passwordmysqlpassword --port3346 MYSQL_UP --userroot --passwordmysqlpassword --port3346 #mysqladmin的用戶名和密碼 TMPLOG"/dat…

爆棧的處理方法

爆棧指遞歸中,存儲的信息量大于系統棧的內存。 信息量包括元素編號,每一層中開的變量。 和遞歸的層數正相關。 (雖然noip一般開棧) 1.手寫棧 while(top){ int xsta[top]; for(each son) if(has son){ //blablabla sta[top]son; h…

項目面試題

項目面試題 1.描述最熟悉的或者(最近)的一個項目 ? 目的:檢測技術和項目的熟悉程度工作職責 回答:項目名稱,項目的甲方,背景,實現的目的和意義,該項目主要是為了解決什…

MySQL定時備份(全量備份+增量備份)

MySQL 定時備份 參考 zone7_ 的 實戰-MySQL定時備份系列文章 參考 zmcyu 的 mysql數據庫的完整備份、差異備份、增量備份 更多binlog的學習參考馬丁傳奇的 MySQL的binlog日志,這篇文章寫得認真詳細,如果看的認真的話,肯定能學的很好的。 如果…

java 接口可以多繼承

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 接口是常量值和方法定義的集合。接口是一種特殊的抽象類。 java類是單繼承的。classB Extends classA java接口可以多繼承。Interface…

C語言struct關鍵字詳解—結構體

struct 是個神奇的關鍵字,它將一些相關聯的數據打包成一個整體,方便使用。在網絡協議、通信控制、嵌入式系統、驅動開發等地方,我們經常要傳送的不是簡單的字節流(char 型數組),而是多種數據組合起來的一個…