国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - C語言中const,volatile,restrict的用法總結(jié)

C語言中const,volatile,restrict的用法總結(jié)

2021-01-08 13:33C語言教程網(wǎng) C/C++

以下是對C語言中const,volatile,restrict的用法進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過來參考下

1. const

變量聲明中帶有關(guān)鍵詞const,意味著不能通過賦值,增量或減量來修改該變量的值,這是顯而易見的一點。指針使用const則要稍微復(fù)雜點,因為不得不把讓指針本身成為const和指針指向的值成為const區(qū)別開來、下面的聲明表示pf指向的值必須是不變的

constfloat *pf;而pf則是可變的,它可以指向另外一個const或非const值;相反,下面的聲明說明pf是不能改變的,而pf所指向的值則是可以改變的:

float* const pf;

最后,當(dāng)然可以有既不能改變指針的值也不能改變指針指向的值的值的聲明方式:

constfloat * const pf;

需要注意的是,還有第三種放置const關(guān)鍵字的方法:

float const * pf; //等價于constfloat * pf;

總結(jié)就是:一個位于*左邊任意位置的const使得數(shù)據(jù)成為常量,而一個位于*右邊的const使得指針本身成為const

還要注意的一點是關(guān)于const在全局?jǐn)?shù)據(jù)中的使用:

使用全局變量被認(rèn)為是一個冒險的方法,它使得數(shù)據(jù)在程序的任何部分都可以被錯誤地修改,如果數(shù)據(jù)是const,那么這種擔(dān)心就是多余的了不是嘛?因此對全局?jǐn)?shù)據(jù)使用const是合理的。

然而,在文件之間共享const數(shù)據(jù)要格外小心,有兩個策略可以使用。一個是遵循外部變量的慣用規(guī)則,在一個文件進(jìn)行定義聲明,在其他文件進(jìn)行引用聲明(使用關(guān)鍵字extern)。

/*file1.c------定義一些全局常量*/

const double PI = 3.14159;

/*file2.c-----是用在其他文件中定義的全局變量*/

extern const dounle PI;

另外一個方法是把全局變量放在一個include文件里,這時候需要格外注意的是必須使用靜態(tài)外部存儲類

/*constant.h----定義一些全局常量*/

static const double PI = 3.14159;

/*file1.c-----使用其他文件定義的全局變量*/

#include”constant.h”。

/*file2.c-----使用其他文件定義的全局變量*/

#include”constant.h”

如果不使用關(guān)鍵字static,在文件file1.c和file2.c中包含constant.h將導(dǎo)致每個文件都有同一標(biāo)識符的定義聲明ANSI標(biāo)準(zhǔn)不支持這樣做(有些編譯器確實支持)。通過使用static, 實際上給了每個文件一個獨立的數(shù)據(jù)拷貝,如果文件想使用該數(shù)據(jù)與另外一個文件通話,這樣做就不行了,因為每個文件只能看見他自己的拷貝,然而由于數(shù)據(jù)是不 可變的,這就不是問題了。使用頭文件的好處是不必惦記在一個文件中進(jìn)行定義聲明,在另一個文件中進(jìn)行引用聲明,缺點在于復(fù)制了數(shù)據(jù),如果常量很大的話,這 就是個問題了。

2. volatile

限定詞volatile告訴編譯器,該變量除了可被程序改變意外還可以被其他代理改變。典型的它用于硬件地址和其他并行運(yùn)行的程序共享的數(shù)據(jù)。例如,一個地址中可能保存著當(dāng)前的時鐘信息。不管程序做些什么,該地址會隨時間改變。另一種情況是一個地址用來接收來自其他計算機(jī)的信息;

語法同const:

volatile int a;//a是一個易變的位置

volatile int * pf;//pf指向一個易變的位置

把volatile作為一個關(guān)鍵字的原因是它可以方便編譯器優(yōu)化。

假如有如下代碼:

va= x;

//一些不使用x的代碼

vb= x;

一個聰明的編譯器可能注意到你兩次使用了x,但是沒有改變它的值,它將把x臨時存貯在一個寄存器中,接著,當(dāng)vb主要x是的時候,它從寄存器而非初始的內(nèi)存位置得到x的值來節(jié)省時間。這個過程被稱為緩存。通常緩存是一個好的優(yōu)化方式,但是如果兩個語句中間的其他代理改變了x的值的話就不是這樣了。如果沒有規(guī)定volatile關(guān)鍵字,編譯器將無從得知這種改變是否可能發(fā)生,因此,為了安全起見,編譯器不使用緩存。那是在ANSI以前的情形,現(xiàn)在,如果在聲明中沒有使用volatile關(guān)鍵字,編譯器就可以假定一個值在使用過程中沒有修改,它就可以試著優(yōu)化代碼。總而言之,volatile使得每次讀取數(shù)據(jù)都是直接在內(nèi)存讀取而不是緩存。

你可能會覺得奇怪,const和volatile可以同時使用,但是確實可以。例如硬件時鐘一般不能由程序改變,這使得他成為const,但他被程序以外的代理改變,這使得他成為volatile,所以你可以同時使用它們,順序是不重要的:

const volatile time;

volatile表明某個變量的值可能在外部被改變,優(yōu)化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器里的備份。它可以適用于基礎(chǔ)類 型如:int,char,long......也適用于C的結(jié)構(gòu)和C++的類。當(dāng)對結(jié)構(gòu)或者類對象使用volatile修飾的時候,結(jié)構(gòu)或者類的所有成員 都會被視為volatile.

該關(guān)鍵字在多線程環(huán)境下經(jīng)常使用,因為在編寫多線程的程序時,同一個變量可能被多個線程修改,而程序通過該變量同步各個線程。

簡單示例:

復(fù)制代碼 代碼如下:

DWORD __stdcall threadFunc(LPVOID signal)
{
int* intSignal=reinterdivt_cast(signal);
*intSignal=2;
while(*intSignal!=1)
sleep(1000);
return 0;
}


該線程啟動時將intSignal 置為2,然后循環(huán)等待直到intSignal 為1 時退出。顯然intSignal的值必須在外部被改變,否則該線程不會退出。但是實際運(yùn)行的時候該線程卻不會退出,即使在外部將它的值改為1,看一下對應(yīng)的偽匯編代碼就明白了:

 

mov ax,signal
label:
if(ax!=1)
goto label

對于C編譯器來說,它并不知道這個值會被其他線程修改。自然就把它cache在寄存器里面。C 編譯器是沒有線程概念的,這時候就需要用到volatile。volatile 的本意是指:這個值可能會在當(dāng)前線程外部被改變。也就是說,我們要在threadFunc中的intSignal前面加上volatile關(guān)鍵字,這時 候,編譯器知道該變量的值會在外部改變,因此每次訪問該變量時會重新讀取,所作的循環(huán)變?yōu)槿缦旅鎮(zhèn)未a所示:
label:
mov ax,signal
if(ax!=1)
goto label

注意:一個參數(shù)既可以是const同時是volatile,是volatile因為它可能被意想不到地改變。它是const因為程序不應(yīng)該試圖去修改它。

3.restrict

關(guān)鍵字restrict通過允許編譯器優(yōu)化某幾種代碼增強(qiáng)了計算支持。記住,它只能用于指針,并且表明指針是訪問一個數(shù)據(jù)對象的唯一且初始的方式。為了清楚為何這樣做,我們需要看一些例子:

復(fù)制代碼 代碼如下:


intar[10];

 

int* restrict restar = (int*)malloc(10*sizeof(int));

int* par = ar;


這里,指針restar是訪問malloc分配的內(nèi)存的唯一而且初始的方式,因此聲明為restrict。然而,par指針既不是初始的,也不是訪問數(shù)組ar中數(shù)據(jù)的唯一方式,所以不用restrict限定詞。現(xiàn)在考慮下面這個更加復(fù)雜的例子,其中n是一個int

復(fù)制代碼 代碼如下:


for(n= 0;n < 10;n++)

 

{

par[n]+= 5;

restar[n]+= 5;

ar[n]*= 2;

par[n]+= 3;

restar[n]+= 3;

}


知道了restar是訪問它所指向的數(shù)據(jù)的唯一初始方式,編譯器就可以用具有同樣效果的一條語句來替代包含restar的兩個語句

 

restar[n]+= 8;/*可以替換*/

然而將兩個計算par的語句精簡為一個則會導(dǎo)致錯誤因為在par兩次訪問數(shù)據(jù)之間,ar改變了該數(shù)據(jù)的值。沒有關(guān)鍵字restrict,編譯器將不得不設(shè)想比較糟糕的那一種形式,而使用之后,編譯器可以放心大膽的尋找計算的捷徑。可以將關(guān)鍵字作為指針型函數(shù)參量的限定詞使用,這意味著編譯器可以假定在函數(shù)體內(nèi)沒有其他標(biāo)志符修改指針指向的數(shù)據(jù),因而可以試著優(yōu)化代碼,反之不然。來看一下C99標(biāo)準(zhǔn)下C庫中的兩個函數(shù),他們從一個位置把字節(jié)復(fù)制到另一個位置

void*memcpy(void* restrict s1,const void* restrict s2,size_t n);

void*memmove(void* s1,const void * s2,size_t);

memcpy要求兩個指針的位置不能重疊,但memmove沒有這個要求。把s1,s2聲明為restrict意味著每個指針都是相應(yīng)數(shù)據(jù)的唯一訪問方式,因此他們不能訪問同一數(shù)據(jù)塊。這滿足了不能有重疊的要求。

關(guān)鍵字restrict有兩個讀者:編譯器,它告訴編譯器可以自由地做一些優(yōu)化的假定。另一個讀者是用戶,他告訴用戶僅使用滿足restrict要求的參數(shù)。一般,編譯器沒法檢查你是否遵循了這一限制,如果你蔑視它,也就是讓自己冒險。

延伸 · 閱讀

精彩推薦
  • C/C++學(xué)習(xí)C++編程的必備軟件

    學(xué)習(xí)C++編程的必備軟件

    本文給大家分享的是作者在學(xué)習(xí)使用C++進(jìn)行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當(dāng)程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關(guān)于C語言中文件...

    針眼_6702022-01-24
  • C/C++c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    這篇文章主要介紹了c++ 單線程實現(xiàn)同時監(jiān)聽多個端口的方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    strcpy 和strcnpy函數(shù)是字符串復(fù)制函數(shù)。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數(shù)使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++深入理解goto語句的替代實現(xiàn)方式分析

    深入理解goto語句的替代實現(xiàn)方式分析

    本篇文章是對goto語句的替代實現(xiàn)方式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下...

    C語言教程網(wǎng)7342020-12-03
  • C/C++C語言實現(xiàn)電腦關(guān)機(jī)程序

    C語言實現(xiàn)電腦關(guān)機(jī)程序

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)電腦關(guān)機(jī)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++C/C++經(jīng)典實例之模擬計算器示例代碼

    C/C++經(jīng)典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典實例之模擬計算器的相關(guān)資料,文中通過示...

    jia150610152021-06-07
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下...

    青山的青6062022-01-04
主站蜘蛛池模板: www.91福利 | 欧洲一区二区在线观看 | 懂色av中文字幕一区二区三区 | 日韩理伦片在线观看视频播放 | 九九在线视频 | 亚洲综合色自拍一区 | 国产在线一区二区三区 | 草草视频网站 | 播放毛片 | 久久久中文字幕 | 中文字幕在线观看一区二区三区 | 欧美日韩成人一区二区 | 一区二区三区国产视频 | 国产成人天天爽高清视频 | 欧美精品一区二区三区四区五区 | 91免费黄色片 | 欧美成人免费在线 | 免费一级网站 | 亚洲成人免费 | 国产成人精品久久二区二区91 | 国产亚洲成av人片在线观看桃 | 亚洲精品第一区在线观看 | 亚洲午夜激情 | 欧洲精品久久久 | 天堂资源最新在线 | 免费观看国产视频在线 | 欧美综合一区 | 中文字幕人成乱码在线观看 | 人人干天天干 | 亚洲免费视频在线观看 | 日韩欧美在线综合网 | 午夜成人免费电影 | 在线观看av网站永久 | 久久久久久亚洲一区二区三区蜜臀 | 黄色片视频免费看 | 欧美一区二区三区在线看 | 操操操操操操 | 综合精品 | 欧美日韩在线电影 | 欧美大片免费影院在线观看 | 亚洲欧美激情精品一区二区 |