国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 系統(tǒng) > iOS > 正文

IOS開發(fā)之路--C語言存儲(chǔ)方式和作用域

2020-02-19 15:58:28
字體:
供稿:網(wǎng)友

概述

基本上每種語言都要討論這個(gè)話題,C語言也不例外,因?yàn)橹挥心阃耆私饷總€(gè)變量或函數(shù)存儲(chǔ)方式、作用范圍和銷毀時(shí)間才可能正確的使用這門語言。今天將著重介紹C語言中變量作用范圍、存儲(chǔ)方式、生命周期、作用域和可訪問性。

變量作用范圍 存儲(chǔ)方式 可訪問性

變量作用范圍

在C語言中變量從作用范圍包括全局變量和局部變量。全局變量在定義之后所有的函數(shù)中均可以使用,只要前面的代碼修改了,那么后面的代碼中再使用就是修改后的值;局部變量的作用范圍一般在一個(gè)函數(shù)內(nèi)部(通常在一對(duì)大括號(hào){}內(nèi)),外面的程序無法訪問它,它卻可以訪問外面的變量。

//// main.c// ScopeAndLifeCycle//// Created by Kenshin Cui on 14-7-12.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include int a=1;void changeValue(){  a=2;  printf("a=%d/n",a);}int main(int argc, const char * argv[]) {  int b=1;  changeValue(); //結(jié)果:a=2  printf("a=%d,b=%d/n",a,b); //結(jié)果:a=2,b=1 ,因?yàn)閏hangeValue修改了這個(gè)全局變量  return 0;}

變量存儲(chǔ)方式

C語言的強(qiáng)大之處在于它能直接操作內(nèi)存(指針),但是要完全熟悉它的操作方式我們必須要弄清它的存儲(chǔ)方式。存儲(chǔ)變量的位置分為:普通內(nèi)存(靜態(tài)存儲(chǔ)區(qū))、運(yùn)行時(shí)堆棧(動(dòng)態(tài)存儲(chǔ)區(qū))、硬件寄存器(動(dòng)態(tài)存儲(chǔ)區(qū)),當(dāng)然這幾種存儲(chǔ)的效率是從低到高的。而根據(jù)存儲(chǔ)位置的不同在C語言中又可以將變量依次分為:靜態(tài)變量、自動(dòng)變量、寄存器變量。

靜態(tài)變量

首先說一下存儲(chǔ)在普通內(nèi)存中的靜態(tài)變量,全局變量和使用static聲明的局部變量都是靜態(tài)變量,在系統(tǒng)運(yùn)行過程中只初始化一次(在下面的例子中雖然變量b是局部變量,在外部無法訪問,但是他的生命周期一直延續(xù)到程序結(jié)束,而變量c則在第一次執(zhí)行完就釋放,第二次執(zhí)行時(shí)重新創(chuàng)建)。

//// 2.1.c// ScopeAndLifeCycle//// Created by Kenshin Cui on 14-7-12.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include int a=1; //全局變量存儲(chǔ)在靜態(tài)內(nèi)存中,只初始化一次void showMessage(){  static int b=1; //靜態(tài)變量存儲(chǔ)在靜態(tài)內(nèi)存中,第二次調(diào)用不會(huì)再進(jìn)行初始化  int c=1;  ++b;  a+=2;  printf("a=%d,b=%d,c=%d/n",a,b,c);}int main(int argc, const char * argv[]) {  showMessage(); //結(jié)果:a=3,b=2,c=1  showMessage(); //結(jié)果:a=5,b=3,c=1  return 0;}

自動(dòng)變量

被關(guān)鍵字auto修飾的局部變量是自動(dòng)變量,但是auto關(guān)鍵字可以省略,因此可以得出結(jié)論:所有沒有被static修飾的局部變量都是自動(dòng)變量。

//// 1.3.c// ScopeAndLifeCycle//// Created by Kenshin Cui on 14-7-12.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include #include int main(int argc, const char * argv[]) {  int a=1;  auto int b=2;  printf("a=%d,b=%d/n",a,b); //結(jié)果:a=1,b=2 ,a和b都是自動(dòng)變量,auto可以省略    //需要注意的是,上面的自動(dòng)變量是存儲(chǔ)在棧中,其實(shí)還可以存儲(chǔ)到堆中  char c[]="hello,world!";  long len=strlen(c)*sizeof(char)+1;//之所以加1是因?yàn)樽址竺婺J(rèn)有一個(gè)/0空操作符不計(jì)算在長度內(nèi)  char *p=NULL;//可以直接寫成:char *p;  p=(char *)malloc(len);//分配指定的字節(jié)存放c中字符串,注意由于malloc默認(rèn)返回“void *”需要轉(zhuǎn)化  memset(p,0,len);//清空指向內(nèi)存中的存儲(chǔ)內(nèi)容,因?yàn)榉峙涞膬?nèi)存是隨機(jī)的,如果不清空可能會(huì)因?yàn)槔鴶?shù)據(jù)產(chǎn)生不必要的麻煩  strcpy(p,c);  printf("p=%s/n",p);//結(jié)果:p=hello,world!  free(p);//釋放分配的空間  p=NULL;//注意讓p指向空,否則p將會(huì)是一個(gè)存儲(chǔ)一個(gè)無用地址的野指針      return 0;}

當(dāng)然存儲(chǔ)自動(dòng)變量的棧和堆其實(shí)是兩個(gè)完全不同的空間(雖然都在運(yùn)行時(shí)有效的空間內(nèi)):棧一般是程序自動(dòng)分配,其存儲(chǔ)結(jié)果類似于數(shù)據(jù)結(jié)構(gòu)中的棧,先進(jìn)后出,程序結(jié)束時(shí)由編譯器自動(dòng)釋放;而堆則是開發(fā)人員手動(dòng)編碼分配,如果不進(jìn)行手動(dòng)釋放就只有等到程序運(yùn)行完操作系統(tǒng)回收,其存儲(chǔ)結(jié)構(gòu)類似于鏈表。在上面的代碼中p變量同樣是一個(gè)自動(dòng)變量,同樣可以使用auto修飾,只是它所指向的內(nèi)容放在堆上(p本身存放在棧上)。

這里說明幾點(diǎn):malloc分配的空間在邏輯上連續(xù),物理上未必連續(xù);p必須手動(dòng)釋放,否則直到程序運(yùn)行結(jié)束它占用的內(nèi)存將一直被占用;釋放p的過程只是把p指向的空間釋放掉,p中存放的地址并未釋放,需要手動(dòng)設(shè)置為NULL,否則這將是一個(gè)無用的野指針;

寄存器變量

默認(rèn)情況下無論是自動(dòng)變量還是靜態(tài)變量它們都在內(nèi)存中,不同之處就是自動(dòng)變量放在一塊運(yùn)行時(shí)分配的特殊內(nèi)存中。但是寄存器變量卻是在硬件寄存器中,從物理上來說它和內(nèi)存處在兩個(gè)完全不同的硬件中。大家都是知道寄存器存儲(chǔ)空間很小,但是它的效率很高,那么合理使用寄存器變量就相當(dāng)重要了。什么是寄存器變量呢?使用register修飾的int或char類型的非靜態(tài)局部變量是寄存器變量。沒錯(cuò),需要三個(gè)條件支撐:register修飾、必須是int或char類型、必須是非靜態(tài)局部變量。

除了存儲(chǔ)位置不同外,寄存器變量完全符合自動(dòng)變量的條件,因此它的生命周期其實(shí)是和自動(dòng)變量完全一樣的,當(dāng)函數(shù)運(yùn)行結(jié)束后它就會(huì)被自動(dòng)釋放。由于寄存器空間珍貴,因此我們需要合理使用寄存器變量,只有訪問度很高的變量我們才考慮使用寄存器變量,如果過多的定義寄存器變量,當(dāng)寄存器空間不夠用時(shí)會(huì)自動(dòng)轉(zhuǎn)化為自動(dòng)變量。

//// 1.3.c// ScopeAndLifeCycle//// Created by Kenshin Cui on 14-7-12.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include int main(int argc, const char * argv[]) {  register int a=1;  printf("a=%d/n",a);  return 0;}

上面我們說到變量的存儲(chǔ)類型,其實(shí)在C語言中還有兩種存儲(chǔ)類型:常量存儲(chǔ)區(qū)和代碼存儲(chǔ)區(qū),分別用于存儲(chǔ)字符串常量、使用const修飾的全局變量以及二進(jìn)制函數(shù)代碼。

可訪問性

在C語言中沒有其他高級(jí)語言public、private等修飾符,來限定變量和函數(shù)的有效范圍,但是卻有兩個(gè)類似的關(guān)鍵字能達(dá)到類似的效果:extern和static。

externextern作用于變量

我們知道在C語言中變量的定義順序是有嚴(yán)格要求的,要使用變量則必須在使用之前定義,extern用于聲明一個(gè)已經(jīng)存在的變量,這樣一來即使在后面定義一個(gè)變量只要前面聲明了,也同樣可以使用。具體的細(xì)節(jié)通過下面的代碼相信大家都可以看明白:

//// 2.1.c// ScopeAndLifeCycle//// Created by Kenshin Cui on 14-7-12.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include //如果在main函數(shù)下面定義了一個(gè)變量a,如果在main上面不進(jìn)行聲明是無法在main中使用a的;//同樣如果只進(jìn)行了extern聲明不進(jìn)行定義一樣會(huì)報(bào)錯(cuò),因?yàn)閑xtern并不負(fù)責(zé)定義變量a而僅僅是聲明一個(gè)已經(jīng)定義過的變量;//當(dāng)然如果說在main上面定義int a;去掉main下面的定義同樣是可以的,相當(dāng)于在上面定義,但如果兩個(gè)地方都定義a的話(main上面的extern去掉),則程序認(rèn)為上面的定義是聲明,只是省略了extern關(guān)鍵字;//第一種情況,在下面定義,不進(jìn)行聲明,報(bào)錯(cuò)int main(int argc, const char * argv[]) {    printf("a=%d/n",a);  return 0;}int a;//第二種情況,在上面定義,正確int a;int main(int argc, const char * argv[]) {    printf("a=%d/n",a);  return 0;}//第三種情況,在下面定義在上面聲明,正確extern int a;int main(int argc, const char * argv[]) {    printf("a=%d/n",a);  return 0;}int a;//第四種情況,只在上面聲明(編譯時(shí)沒有問題,因?yàn)樯厦娴穆暶黩_過了編譯器,但運(yùn)行時(shí)報(bào)錯(cuò),因?yàn)閑xtern只能聲明一個(gè)已經(jīng)定義的變量),錯(cuò)誤extern int a;int main(int argc, const char * argv[]) {    printf("a=%d/n",a);  return 0;}//第五種情況,上下同時(shí)定義(這種方式是正確的,因?yàn)樯厦娴亩x會(huì)被認(rèn)為是省略了extern的聲明),正確int a;int main(int argc, const char * argv[]) {    printf("a=%d/n",a);  return 0;}int a;//其實(shí)下面的情況也是不會(huì)出錯(cuò)的int a;int a;int main(int argc, const char * argv[]) {    printf("a=%d/n",a);  return 0;}int a;int a;//第六種情況,將全局變量聲明為局部變量,但是它的實(shí)質(zhì)還是全局變量,正確int a;int main(int argc, const char * argv[]) {  extern int a;  printf("a=%d/n",a);  return 0;}int a;//第七種情況,在函數(shù)內(nèi)部重新定義一個(gè)變量a,雖然不會(huì)報(bào)錯(cuò),但是兩個(gè)a不是同一個(gè)int a;int main(int argc, const char * argv[]) {  int a;  printf("a=%d/n",a);//注意這里輸出的a其實(shí)是內(nèi)部定義的a,和函數(shù)外定義的a沒有關(guān)系  return 0;}int a;

如果兩個(gè)文件同時(shí)定義一個(gè)全局變量,那實(shí)質(zhì)上他們指的是同一個(gè)變量。從下面的例子可以看出,在main.c中修改了變量a之后message.c中的變量a值也修改了。

需要注意,在上面的代碼中無論在message.h中將a定義前加上extern,還是在main.h中的a定以前加上extern結(jié)果都是一樣的,extern同樣適用。和在單文件中一樣,不能兩個(gè)定義都添加extern,否則就沒有定義了。如果把message.c中a的定義(或聲明)去掉呢,那么它能否訪問main.c中的全局變量a呢,答案是否定的(這和在一個(gè)文件中定義了一個(gè)函數(shù)在另一個(gè)文件不聲明就直接用是類似的)。

extern作用于函數(shù)

extern作用于函數(shù)就不再是簡(jiǎn)單的聲明函數(shù)了,而是將這個(gè)函數(shù)作為外部函數(shù)(當(dāng)然還有內(nèi)部函數(shù),下面會(huì)說到),在其他文件中也可以訪問。但是大家應(yīng)該已經(jīng)注意到,在上面的代碼中message.c中的showMessage前面并沒有添加extern關(guān)鍵字,在main.c中不是照樣訪問嗎?那是因?yàn)檫@個(gè)關(guān)鍵字是可以省略的,默認(rèn)情況下所有的函數(shù)都是外部函數(shù)。

和作用于變量不同,上面main.c和message.c中的extern都可以省略,在這里extern的作用就是定義或聲明一個(gè)外部函數(shù)。從上面可以看到在不同的文件中可以定義同一個(gè)變量,它們被視為同一個(gè)變量,但是需要指出的是外部函數(shù)在一個(gè)程序中是不能重名的,否則會(huì)報(bào)錯(cuò)。

staticstatic作用于變量

其實(shí)在前面的例子中我們已經(jīng)看到static關(guān)鍵字在變量中的使用了,在例子中使用static定了一個(gè)局部變量,而且我們強(qiáng)調(diào)static局部變量在函數(shù)中只被初始化一次。那么如果static作用于全局變量是什么效果呢?如果static作用于全局變量它的作用就是定義一個(gè)只能在當(dāng)前文件訪問的全局變量,相等于私有全局變量。

從上面的輸出結(jié)果可以看出message.c中的變量a和main.c中的變量a并不是同一個(gè)變量,事實(shí)上message.c中的變量a只能在message.c中使用,雖然main.c中的變量a是全局變量但是就近原則,message.c會(huì)使用自己內(nèi)部的變量a。當(dāng)然,上面例子中main.c中的變量a定義成靜態(tài)全局變量結(jié)果也是一樣的,只是這樣如果還有其他源文件就不能使用a變量了。但是main.c中的a不能聲明成extern,因?yàn)閙ain.c不能訪問message.c中的變量a,這樣在main.c中就沒變量a的定義了。

static作用于函數(shù)

static作用于函數(shù)和作用于變量其實(shí)是類似的,如果static作用于函數(shù)則這個(gè)函數(shù)就是內(nèi)部函數(shù),其他文件中的代碼不可以訪問。下面的代碼在運(yùn)行時(shí)會(huì)報(bào)錯(cuò),因?yàn)閙esage.c中的showMessage()函數(shù)是私有的,在main.c中盡管進(jìn)行了聲明,可以在編譯階段通過,但是在鏈接階段會(huì)報(bào)錯(cuò)。

總結(jié)

最后做一下簡(jiǎn)單總結(jié)一下:

extern作用于變量時(shí)用于聲明一個(gè)已經(jīng)定義的變量,但是并不能定義變量;使用extern你可以在其他文件中使用全局變量(當(dāng)然此時(shí)extern可以省略); extern作用于函數(shù)時(shí)與它作用于全局變量有點(diǎn)類似,聲明這個(gè)函數(shù)是外部函數(shù),其他文件可以訪問,但不同的是當(dāng)它作用于函數(shù)時(shí)不僅可以聲明函數(shù)還可以定義函數(shù)(用在函數(shù)定義前面),不管是定義還是聲明都可以省略,C語言默認(rèn)認(rèn)為函數(shù)定義或聲明都是外部函數(shù); static作用于變量時(shí),該變量只會(huì)定義一次,以后在使用時(shí)不會(huì)重新定義,當(dāng)static作用于全局變量時(shí)說明該變量只能在當(dāng)前文件可以訪問,其他文件中不能訪問; static作用于函數(shù)時(shí)與作用于全局變量類似,表示聲明或定義該函數(shù)是內(nèi)部函數(shù)(又叫靜態(tài)函數(shù)),在該函數(shù)所在文件外的其他文件中無法訪問此函數(shù);

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
久热中文字幕| 99中文字幕一区| 日本h视频在线观看| av在线1区2区| 欧美性xxxx交| 国产男女av| 久久精品无码一区二区日韩av | 国产麻豆视频| 国产黄色av免费看| 亚洲天堂二区| 中文字幕在线视频观看| 国产大学生粉嫩无套流白浆| www.超级碰| 国产精品久久久精品a级小说| 在线黄色av| 国产午夜精品久久久久免费视| 在线观看av的网站| 国产精选在线视频拍拍拍| 92久久精品| 激情综合丁香| 在线观看的网站你懂的| 国产野外战在线播放| 亚洲v片在线观看| 国产一起色一起爱| 黄色一级视频网站| 不卡av免费观看| 夜夜操天天干| 在线国产网址| 在线观看av网站永久| 精品女厕厕露p撒尿| 国产丝袜在线| 中文字幕中文字幕在线中高清免费版| 91免费日韩| 国产超碰在线| 中文字幕在线观看播放| 久久精品最新免费国产成人| 四虎国产精品永久| 日韩黄色成人| 白浆爆出在线观看| 热99在线观看| 黄色网页网址在线免费| 在线观看免费高清完整| 亚洲欧美自拍另类| 国产精品偷乱一区二区三区| 欧美激情福利视频在线观看免费| 69精品视频| 中文字幕有码在线视频| 久久久久久五月天久久久久久久久| 精品街拍一区二区| 成网站在线观看人免费| 久热久精久品这里在线观看| 麻豆av在线| 黄色一级视频网站| 国产三级在线播放| 国产一二区在线观看| 成年网在线观看免费观看网址| eeuss影院www在线观看| 日本在线观看| 高潮毛片在线观看| 中文字幕在线视频免费观看| 成在线人视频免费视频| 国产一级二级在线| 国产三级自拍| 樱花草在线观看www| 精品一区二区三区高清免费不卡| 69久久久久| 波多野结衣久久高清免费| 欧美日韩在线资源| 免费网站看黄yyy222| 99热在线免费观看| 亚洲а∨精品天堂在线| 国产秒拍福利视频露脸| 国产porn在线| 久久99精品久久久久久野外| 国产亚av手机在线观看| 永久av在线| 五月婷婷在线视频| www.99色.com| 国产色在线观看| 伊人网在线视频| 国产美女福利在线| 在线成人一区| 18激情网站| 尤物网址在线观看| 日本欧美在线视频免费观看| 中文字幕日本在线| 超碰97国产精品人人cao| 91蜜桃在线视频| 国产免费专区| 女同一区二区免费aⅴ| 91在线看片| 国产一级黄色片免费| 国产黄色免费| 黄色国产网站在线播放| 国产精品久久久高清免费| 久久亚洲资源| 女人色在线免费视频| 亚洲精品视频在线免费| 伊人网在线视频| 在线影视一区| 国产成人精品综合网站| 玖玖在线视频| 中文天堂av| 国产黄视频在线观看| 午夜视频免费在线观看| 丁香视频五月| 中文字幕在线观看播放| 国产一卡2卡3卡4卡网站免费| 开心婷婷激情五月| 亚洲人成影院在线| 亚洲精品自拍区在线观看| 影音av资源站| www.三级.com| 黄色一级视频网站| 国产性一级片| 在线观看av资源网| 中文字幕亚洲精品视频| 懂色一区二区三区| 日本中文字幕高清视频| 中文字幕在线观看播放| 97在线超碰| 99综合精品久久| 四虎www视频| 免费在线播放av| 欧美日韩国产亚洲沙发| 国产在线视精品麻豆| 国产黄色免费| 欧美a免费在线| 国产黄在线看| 黄网在线免费| 精精国产xxxx视频在线中文版| 夜夜操com| 国产乱在线观看视频| 国产极品美女到高潮| 亚洲wwwwww| 国产精品视频一区二区三区麻豆| 精品一区二区91| 国产九色在线| 最新av中文字幕| 亚洲视频精品在线观看| 懂色av一区| eeuss影院www在线观看| 中文字幕欧美日韩在线不卡| 精品美女在线观看视频在线观看 | eeuss影院www在线播放| 午夜不卡视频| 日本一二三区视频免费高清| 国产网红在线观看| 国产小视频免费在线网址| 天天插天天操| 国产黄大片在线观看画质优化| 黄色片大全在线观看| 日本福利在线观看| 亚洲网站一区| 在线视频三级| 国产福利电影在线观看| 国产一二在线观看| 国产中文字幕网| 超碰在线国产| 超碰免费在线播放| 日本高清不卡中文字幕| av三级在线观看| heisi视频网在线观看| av亚洲在线| 一本免费视频| 欧美高清视频| 国产中文在线观看| 中文字幕国产欧美| 国产福利电影在线观看| 精品999视频| eeuss影院www在线观看| 欧美日韩在线中文字幕| 狠狠操视频网站| 国产区视频在线观看| 国产wwww| 人成在线免费视频| 国产精品一品| 96精品视频| 欧美日韩亚洲国内综合网| www.av在线| 五月天婷婷基地| 在线视频婷婷| 五月婷婷视频在线观看| 精品国产二区三区| 久蕉依人在线视频| 国产成在线观看免费视频| a视频在线播放| 最近中文字幕mv免费高清在线| 国产亚洲精品久久久久久移动网络 | 国产视频福利在线| 国产不卡在线| 免费在线高清av| 国产性色视频| 小说区乱图片区| 国产一二三区在线观看| av手机天堂| 国产三区视频在线观看| 超碰在线网站| 天天艹天天操| 中文岛国精品亚洲一区|