1. 程式人生 > >【C語言天天練(十九)】restrict關鍵詞

【C語言天天練(十九)】restrict關鍵詞

引言:在核心的系統呼叫函式裡,常常遇到函式的引數使用restrict限定詞限定的情況,以下就對該關鍵詞做個總結。

1、restrict關鍵詞是C99特性才加入的,因此在編譯使用含有該限定詞的程式時,一定要在後邊加入-std=c99的標誌,使得gcc能夠支援c99標準。

2、restrict既然是個限定詞。那麼它限定什麼變數呢?它僅僅能限定指標變數。經過它限定的資料物件,表明指標時訪問該資料物件的唯一且初始的方式。注意:這裡的唯一表明瞭,由它限定的指標所指向的資料塊。僅僅能由該指標訪問,不能由除它之外的不論什麼方式訪問。初始指的是它必須在初始化的時候宣告,不能再以後宣告。後面給出樣例解釋。

3、restrict事實上能夠看成僅僅有兩個讀者。一個是編譯器,它告訴編譯器能夠自由地做一些有關優化的假定。

還有一個讀者是使用者,它告訴使用者僅適用滿足restrict要求的引數。比方,下列兩個函式宣告:

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

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

上面兩個函式都是從位置s2把n個位元組拷貝到位置s1。

函式memcpy()要求兩個位置之間不重疊。但memmove()沒有這個要求。

把s1和s2宣告為restrict意味著每一個指標都是對應資料的唯一訪問方式,因此他們不能訪問同一資料塊。這滿足了不能有重疊的要求。

程式演示樣例restrict.c:

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char **argv)
{
	int n;
	int ar[5];
	int	*restrict restar = (int *)malloc(5 * sizeof(int));/*將該指標宣告為了restrict。使得這塊記憶體的資料僅僅能由restar訪問,不能由以下的par指標訪問*/
	int *par = ar;

	for(n = 0; n < 5; n++){
		par[n] += 5;
		restar[n] += 5;
		ar[n] *= 2;
		par[n] += 3;
		restar[n] += 3;	
		printf("ar[%d] = %d\n", n, restar[n]);
		printf("ar[%d] = %d\n", n, ar[n]);
	}

	return -1;
}
編譯:gcc restrict.c -std=c99

執行編譯結果:./a.out

ar[0] = 8
ar[0] = 4851221
ar[1] = 8
ar[1] = 4849653
ar[2] = 8
ar[2] = 269027981
ar[3] = 8
ar[3] = 2147391485
ar[4] = 8
ar[4] = 2614935

從結果能夠看出,通過par指標以及ar所訪問的restar指標所指向的資料並沒有起不論什麼作用。

能夠改變所指向記憶體資料的僅僅是restar[n] += 5;與 resatr[n] += 3;這兩條語句。事實上編譯器會對這兩條語句做優化,將它們合併成一條語句:restar[n] += 8;