提问人:mhsquare 提问时间:10/30/2023 最后编辑:chqrliemhsquare 更新时间:11/1/2023 访问量:132
这些类型的声明意味着什么
What do these type of declarations mean
问:
我在 C 中遇到了一些声明,无法理解它们的含义。
这里有什么意义和意思?这些用于函数。*const
*restrict
aio_suspend
const struct aiocb *const aiocb_list[]
const struct timespec *restrict timeout
答:
3赞
Sanskar Omar
10/30/2023
#1
为了清楚起见,让我们分别看一下它们:
const struct aiocb *const aiocb_list[]
:const
应用于 :这表示中的指针指向常量结构对象,允许您使用这些指针以只读方式访问数据。struct aiocb
aiocb_list
aiocb
const
应用于:数组本身是常量;存储在其中的指针无法更改。aiocb_list
const struct timespec *restrict timeout
:const
应用于:指向的数据是常量(只读)。struct timespec
timeout
restrict
应用于 :提示编译器没有别名(没有指向同一内存的其他指针),允许进行某些优化。timeout
注: 对于 applied to ,这不会阻止相同对象的非常量视图存在于程序中的其他位置。对象本身本质上不是恒定的或只读的,而是通过这些指针强制执行只读视图。const
struct aiocb
aiocb_list
评论
1赞
HolyBlackCat
10/30/2023
“其地址无法更改”->“存储在其中的指针无法更改”。无论 .const
1赞
Ben Voigt
10/31/2023
“这些指针指向的数据是常量(只读)”不正确。事实上,它提供了对象的只读视图,但没有什么能阻止同一对象的非常量视图存在于程序的其他地方。这些对象不是常量或只读的。aiocb_list
struct aiocb
1赞
arfneto
10/31/2023
#2
[1]const struct aiocb* const aiocb_list[];
这里
aiocb_list
正在宣布。它是一个数组。- 它是一个常量数组
- 常量是指针
- 数组的每个元素都是指向 的指针,一个
aiocb
struct
- 数组本身也是常数,因为第一个
const
- 由于它没有被初始化,所以它必须是某些东西的一部分,比如参数列表,因为它是声明的
const
因此,它是一个指向const
struct
例
这是一个使用这种结构的程序
输出
function got 4 pointers
Values are
S
O
S
O
法典
#include <stdio.h>
struct aiocb
{
char what;
};
struct aiocb* action(
size_t size, const struct aiocb* const aiocb_list[]);
int main(void)
{
const struct aiocb data[4] = {
[0] = {'a'},
[1] = {'O'},
[2] = {'S'},
[3] = {'d'},
};
const struct aiocb* const list[] = {
&data[2],
&data[1],
&data[2],
&data[1],
&data[0]
};
action(4, list);
return 0;
}
struct aiocb* action(
size_t size, const struct aiocb* const aiocb_list[])
{
printf(
" function got %llu pointers\n Values are\n",
size);
for (size_t i = 0; i < size; i += 1)
printf(" %c\n", aiocb_list[i]->what);
return NULL;
}
第二个例子:使用typedef
这是相同的代码,只是对 .一般来说,它更容易阅读并节省大量打字typedef
struct
struct aiocb
#include <stdio.h>
typedef struct
{
char what;
} Aiocb;
Aiocb* action(size_t, const Aiocb* const[]);
int main(void)
{
const Aiocb data[4] = {
[0] = {'a'}, [1] = {'O'},
[2] = {'S'}, [3] = {'d'},
};
const Aiocb* const list[] = {
&data[2], &data[1], &data[2], &data[1], &data[0]};
action(4, list);
return 0;
}
Aiocb* action(
size_t size, const Aiocb* const aiocb_list[])
{
printf(
" function got %llu pointers\n Values are\n",
size);
for (size_t i = 0; i < size; i += 1)
printf(" %c\n", aiocb_list[i]->what);
return NULL;
}
请注意,这些赋值main
list[0] = NULL; // error: array elements are const
const Aiocb* other[5] = {0};
// error: list can not point to other places
list = other;
不会编译,因为所有数组元素都是并且也是const
list
const
[2]const struct timespec *restrict timeout;
此处被声明为指向 .并且是恒定的。timeout
timespec
struct
restrict
是程序员的承诺,即在其生命周期内,如此声明的指针将是唯一访问其目标的指针。对目标的访问仅限于此指针。
此保证为编译器提供了优化代码的机会。
一个很好的例子是 cppreference:
int foo(int *a, int *b)
{
*a = 5;
*b = 6;
return *a + *b;
}
int rfoo(int *restrict a, int *restrict b)
{
*a = 5;
*b = 6;
return *a + *b;
}
以及可能生成的代码
; generated code on 64bit Intel platform:
foo:
movl $5, (%rdi) ; store 5 in *a
movl $6, (%rsi) ; store 6 in *b
movl (%rdi), %eax ; read back from *a in case previous store modified it
addl $6, %eax ; add 6 to the value read from *a
ret
rfoo:
movl $11, %eax ; the result is 11, a compile-time constant
movl $5, (%rdi) ; store 5 in *a
movl $6, (%rsi) ; store 6 in *b
ret
我们看到,编译器知道除了 和 之外没有人指向函数内部的目标,可以返回并跳过之前的返回。a
b
11
add
在某些情况下,可以大大节省执行时间和代码大小,因为编译器可以在大型循环中重新排序或跳过操作。restrict
评论
0赞
Ben Voigt
10/31/2023
“这是一个数组”不,不是。此处适用参数类型调整;它实际上是一个指针。
0赞
arfneto
10/31/2023
这是全部。最后的手段意味着什么。没有它们,编译器会说:它是一个指针。编译器说。无论如何,数组会衰减为指针。但它是一个数组,在示例中声明:C
[]
(parameter) const Aiocb* const aiocb_list
(parameter) const Aiocb* const aiocb_list[]
main
const Aiocb* const list[]
0赞
arfneto
10/31/2023
@BenVoigt我不明白这一点。它是在 main 中声明的。它是一个数组。是的。它作为参数进入函数,在 .作为程序中的数组参数,你可以说它是一个指针。那又怎样?这是如何使用数组的示例,在 中声明,如问题中所示。它只是假的,甚至不是真的。请按原样查看。C
C
C
main
struct
aiocb
0赞
Fe2O3
11/1/2023
"当数组名称传递给函数时,传递的是初始元素的位置。在被调用的函数中,这个参数是一个局部变量,因此数组名称参数是一个指针,即一个包含地址的变量。谁错了?丹尼斯·里奇(Dennis Ritchie)还是阿夫内托(arfneto)?
评论
aiocb_list
aiocb
timeout
timespec
restrict
特别是,在没有任何上下文的情况下,意义不大 - 请发布完整的功能。由于是特定指针(通常是参数)与其他指针和/或文件范围变量之间的关系。restrict
aiocb_list[]
不是数组,而是指针,由于参数类型调整。