当前位置: C语言 -- 专题 -- restrict类型限定符

restrict类型限定符(二)

restrict类型限定符的应用

① 用于函数参数

在函数声明或者函数定义中,如果两个形式参数使用restrict类型限定符进行限定,则表示函数不会使用这两个参数来获取相同的对象,即这两个参数指向的对象在内存中没有重叠。

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
/* restrict类型限定符范例2 */

#include <stdio.h>
 
#define LENGTH 10

void func(int number, int * restrict ptrOne, int * restrict ptrTwo)
{
    while(number-- > 0)
        *ptrOne++ = *ptrTwo++;
}

int main(void)
{
    int arr[LENGTH] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    func(LENGTH/2, arr+LENGTH/2, arr);  //合法。
    func(LENGTH/2, arr+1, arr);         //未定义行为。

    /* 其它代码。*/
    
    return 0;
}

func(LENGTH/2, arr+LENGTH/2, arr)中,通过第一个指针可以访问数组的后5个元素,通过第二个指针可以访问数组的前5个元素,两者之间没有重叠,所以是合法的。

func(LENGTH/2, arr+1, arr)中,通过第一个指针可以访问数组第2至第6个元素,通过第二个指针可以访问数组第1至第5个元素,两者之间有多个元素是相同的,所以其行为是未定义的。


如果两个受限指针指向的对象在函数中没有被修改,这两个受限指针可以指向相同的对象。

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
/* restrict类型限定符范例3 */

#include <stdio.h>
 
#define LENGTH 5

void func(int number, int * restrict ptrOne, \
          const int * restrict ptrTwo, const int * restrict ptrThree)
{
    for(int i=0; i<number; ++i)
        ptrOne[i] = ptrTwo[i] + ptrThree[i];
}

int main(void)
{
    const int a[LENGTH] = {1, 2, 3, 4, 5};
    int b[LENGTH];

    func(LENGTH, b, a, a);  //合法。

    /* 其它代码。*/
    
    return 0;
}

func函数中,受限指针ptrTwoptrThree指向的对象没有被修改,所以函数调用时这两个指针可以指向相同的对象。


② 用于结构成员

声明受限指针的块结束执行时,受限指针的生命周期将结束。如果要将受限指针的值传出其声明所在的块,一个解决方法就是将受限指针声明为结构成员,例如:

typedef struct {
    int number;
    double * restrict ptr;
} s;

s func(int number)
{
    s data;
    
    data.number = number;
    data.ptr = calloc(number, sizeof(double));
    
    return data;
}