提问人:sun_dance 提问时间:9/14/2023 最后编辑:Jonathan Lefflersun_dance 更新时间:9/14/2023 访问量:82
C 错误:将 typedef 用于 int 数组的指针类型不兼容问题
C error: incompatible pointer types issue using typedef for int array
问:
我正在尝试实现一个简单的函数,该函数将一个数组的值分配给另一个数组,但是我不断收到错误
program.c:90:14: error: incompatible pointer types passing 'longint_t' (aka 'int [3]') to parameter of type 'longint_t *' (aka 'int (*)[3]'); take the address with & [-Werror,-Wincompatible-pointer-types]
我最初的想法是,它应该接受 2 个longint_t值(通常一个是空的或全是零,但并非总是如此),另一个longint_t值并将第二个数组的所有值分配给第一个数组。
最后,变量 var 的格式应为
[
[0,0,0],
[0,0,0],
.
.
. 26 arrays of [0,0,0]
]
这是我的一点代码:
#include <stdio.h>
#include <stdlib.h>
#define INTSIZE 3 /* max number of digits per integer value */
#define NVARS 26 /* number of different variables */
typedef int longint_t[INTSIZE];
void do_assign(longint_t *var1, longint_t *var2);
void zero_vars(longint_t vars[]);
/* Main program controls all the action
*/
int
main(int argc, char *argv[]) {
longint_t vars[NVARS];
zero_vars(vars);
for (int i=0; i<NVARS; i++){
for (int j=0; j<3;j++){
//printf("%d",vars[i][j]);
}
}
return 0;
}
void
zero_vars(longint_t vars[]) {
int i;
longint_t zero = {0};
for (i=0; i<26; i++) {
do_assign(vars[i], &zero);
}
return;
}
void
do_assign(longint_t *var1, longint_t *var2) {
for (int i=0; i<=3; i++){
*var1[i] = *var2[i];
}
}
答:
0赞
New Leaf
9/14/2023
#1
do_assign(&vars[i], &zero); // this compile successfully in my device.
此函数采用两个指针作为参数。因此,您应该使用 &. 传递地址而不是值。
评论
0赞
sun_dance
9/14/2023
由于某种原因,虽然解决了以前的错误,但它会导致 var= 02282-145021416 0-6371244-6371248 00-142708......等等
0赞
New Leaf
9/14/2023
@sun_dance您应该提供更多详细信息。你期望变量var是什么样子的?
0赞
sun_dance
9/14/2023
我添加了更多信息
3赞
anatolyg
9/14/2023
#2
指向数组的指针是一个小众的 C 主题,由于数组到指针的衰减,它非常令人困惑。
你的函数应该将一个数组分配给另一个数组(但它有问题;见下文)。它接收指向数组的指针。do_assign
您的函数应初始化一个二维数组(数组数组)。它还接收指向数组的指针(由于衰减规则,这是编译器所认为的)。但它赋予了这个指针不同的含义——它是指向数组第一个元素的指针。这个数组有元素,每个元素都是一个整数数组。混乱!zero_vars
NVARS
INTSIZE
在您的实现中,是一个数组。但是,接收指向数组的指针!所以你应该取它的地址:zero_vars
vars[i]
do_assign
do_assign(&vars[i], &zero);
但是,在实现中,应取消引用指针:do_assign
(*var1)[i] = (*var2)[i];
首先取消引用指针,然后为结果编制索引。由于运算符优先级规则,应显式指定这些操作的顺序。
你不需要“指向数组的指针”类型来实现这一切。您可以改用“指针”。这样,您可以避免不必要且令人困惑的间接信息:int
void
do_assign(int *var1, int *var2) {
for (int i=0; i<INTSIZE; i++){
var1[i] = var2[i];
}
}
由于数组衰减规则,以下操作也有效,并且执行完全相同的操作:
void
do_assign(longint_t var1, longint_t var2) {
for (int i=0; i<INTSIZE; i++){
var1[i] = var2[i];
}
}
但我不确定它是否更清楚——数组也是一个很少使用的功能,因为它们可能会带来不确定性和混乱。typedef
评论
0赞
sun_dance
9/14/2023
哦,我明白。一段时间以来,我一直在努力理解 C 语言中的指针。这真的很有帮助,非常感谢!我的问题是,如果我想要一个 500 个 0 的数组而不是三个 0 的数组,这是否也有效,或者这会导致溢出问题?
1赞
anatolyg
9/14/2023
如果所有维度和索引都正确无误,则不会出现溢出。编译器对 500 的执行与对 3 的执行完全相同。我刚刚注意到索引有问题;编辑了它。
评论
do_assign(longint_t *var1
longint_t
longint_t
do_assign(longint_t var1, longint_t var2)
for (int i=0; i<=500; i++)
您可能希望增加到 。INTSIZE
501
for (int i=0; i<=3; i++)
您可能希望增加到 ,因为将访问第 4 个元素。INTSIZE
4
i<=3