2012-07-20 95 views
0

我收到以下警告:数组c和指针参数

expected ‘float **’ but argument is of type ‘float (*)[6]’ 

这里是我的代码:

//state and error are output parameters 
void func(float* state[6], float* err[6][6]); 

int main() 
{ 
    float state[6]; 
    float err[6][6]; 

    func(&state, &err); 

    return 0; 
} 

我想状态,犯错是ouptut参数,所以状态应该是一个指针到一个数组,而err应该是一个指向2维数组的指针。

+0

它期待着一个指向指针的指针,但你给它一个指针。你不应该需要参数中的指针,只需要float state []。 – Julio 2012-07-20 15:16:07

+0

状态和错误是输出参数。我想修改它们是什么。 – CodeKingPlusPlus 2012-07-20 15:18:37

回答

2
#include <stdio.h> 

void func(float (*state)[6], float (*err)[6][6]){ 
    printf("%f, %f\n", (*state)[2], (*err)[1][2]);//3.000000, 3.300000 
} 

int main() 
{ 
    float state[6]={1.0f,2.0f,3.0f}; 
    float err[6][6]={{1.0f,2.0f,3.0f},{1.1f,2.2f,3.3f}}; 

    func(&state, &err); 

    return 0; 
} 
+0

我只需要知道如何使它成为(* state)[2]数组的指针。谢谢! – CodeKingPlusPlus 2012-07-23 19:06:34

+0

我的回答很好,能够帮助。 – BLUEPIXY 2012-07-23 23:10:21

5

你的代码更改为:

void func(float state[], float err[][6]); 

int main() 
{ 
    float state[6]; 
    float err[6][6]; 

    func(state, err); 

    return 0; 
} 

要了解为什么,你需要知道float* err[6][6]是指针的6x6的阵列浮动,而不是一个指针浮动的6x6的阵列。

+0

因为C按价值传递了所有东西,现在不会改变和错误吗? – CodeKingPlusPlus 2012-07-20 15:29:12

+1

该数组的地址不会改变,但里面的值将会改变。传递'state'实际上等同于传递数组中第一个元素的地址'&state [0]'。可能有些情况下,你会希望你的函数分配一个新的数组,在这种情况下,你必须使你的参数成为'float **',但是之后没有必要在堆栈上创建一个数组。 – Taum 2012-07-20 15:42:15

+0

为什么匿名倒票,我想知道? – 2012-07-20 21:32:49

1

尽管在一个函数内部,T [] []和T **几乎可以互换使用,当它们作为参数传递的时候有一些注意事项。 '指针指针'模式只使用足够的内存来存储变量本身(通常与处理器的字大小相同),并依赖程序员以某种方式为数据生成正确的偏移量,而使用数组语法,编译器也需要知道结构的步幅,以便它可以正确地处理行。就我个人而言,我不喜欢将数组作为参数传递给它,只是因为这个原因:它使编译时的步长固定下来。在我看来,更好的做法是始终使用行和列辅助参数的T **路线。

2

在大多数情况下,数组类型的表达式将被转换为指针类型的表达式;这意味着当您将数组表达式作为参数传递给函数时,函数将接收的是一个指针。数组表达式是sizeof或一元运算符&的操作数,或者是用于在声明中初始化数组的字符串文字时,此规则的例外情况。

在函数参数声明的上下文中,T a[]T a[N]的处理方式与T *a相同;所有这三个都声明a作为指向T的指针,而不是作为T的数组。

因此,通过您声明

float state[6]; 
float err[6][6]; 

表达state的类型去是“的float 6-元件阵列”,这在大多数情况下将被转换为“指针float”,或float *。类似地,表达式err的类型是“float的6元件阵列的6元件阵列”,其将被转换为“指向6元件阵列float”或float (*)[6]

类型表达&state的是“指针至6个元素的数组的float”,或float (*)[6],以及&err类型是“指针至6个元素的数组的float 6-元件阵列的”,或float (*)[6][6]

因此,如果调用func

func(&state, &err); 

那么原型必须

void func(float (*state)[6], float (*err)[6][6]) 

,你需要明确取消引用stateerr应用任何标前:

(*state)[i] = ...; 
(*err)[i][j] = ...; 

如果电话是

func(state, err); 

那么原型必须

void func (float *state, float (*err)[6]) 

,你会不会需要明确取消引用要么stateerr

state[i] = ...; 
err[i][j] = ...; 

那么,你用哪个呢?就我个人而言,我会选择第二种选择。它有点干净。

0
void func(float* state[6], float* err[6][6]); 


int main() 
{ 
    float state[6]; 
    float err[6][6]; 

    func(&state, &err); 

    return 0; 
} 

以下两个声明的两个是相同的......

char *message = "Hello World!"; 
char message[13] = "Hello World!"; /* "Hello World!" is 12 chars + \0 termination */ 

数组是指针,只是区别对待。 因此,要将这两个声明中的message的地址传递给func1(char *)或func1(char []),则表示您通过地址传递func1(message);

数组只能作为地址传递给第一个值。运行以下程序来证明这一事实。

#include <stdio.h> 
void func(float* array); 

int main() 
{ 
    float state[6]; 
    int i = 0; 
    printf ("Sizeof state: %d\n", sizeof(state)); 
    for (i = 0; i < 6; i ++) { state[i] = i+1; } 
    func(state); 

    return 0; 
} 

void func (float *array) 
{ 
printf ("Sizeof float: %d\n", sizeof(float)); 
printf ("Sizeof array: %d\n", sizeof(array)); 
printf ("Value in array[0] = %f\n", array[0]); 
printf ("Value in *array = %f\n", *array); 
array++; 
printf ("Value in array[-1] = %f\n", array[-1]); 
printf ("Value in array[0] = %f\n", array[0]); 
printf ("Value in *array = %f\n", *array); 
} 

,那么你对func(float* state[6], float* err[6][6]);呼叫声明2级指针,和一个3级指针。类似的功能,但相同的呼叫,可以实现与func(float **state, float ***err);

不用说,而不是你的目标。