C编程调用函数...将(浮点*)X传递给函数

时间:2013-06-19 13:06:51

标签: c function prototype

我有以下代码

要调用该函数,代码类似于以下内容:

#define N 2
static float m1[N][N] = {{1.0, -0.02}, {0.0, 1.0}};
static float m2[N][1] = {{1.5f}, {1.5f}};
static float result[N][1];

int main(void)
{
    matrix_multiply((float*) m1, (float*) m2, N, N, 1, (float*) result);
}

void matrix_multiply(float* input_matrix1, float* input_matrix2, int m, int p, int n, float* output_matrix)
{
    // Matrix Multiplication Routine
    // input_matrix1= input matrix (m x p)
    // input_matrix2 = input matrix (p x n)
    // m = number of rows in input_matrix1
    // p = number of columns in input_matrix1 which should equal the number of rows in input_matrix2
    // n = number of columns in input_matrix2
    // output_matrix = output matrix = input_matrix1*input_matrix2 (m x n)
    //.....Code that does matrix multiplication
}

我在调用函数时没有遇到(float*)。有人可以详细描述它。

1 个答案:

答案 0 :(得分:1)

符号(float *)X是演员表。如果矩阵乘法函数在使用之前被声明(或定义),则必须使用强制转换,因为传递给函数的类型不是函数所期望的float *,而是float (*)[2] (这是一个指向数组的指针)。演员们告诉编译器'我们比你更了解这个C',即使这是一个非常有争议的命题。

以下是问题中代码的温和修改版本:

#define N 2
static float m1[N][N] = {{1.0, -0.02}, {0.0, 1.0}};
static float m2[N][1] = {{1.5f}, {1.5f}};
static float result[1][N];

void matrix_multiply(float *input_matrix1, float *input_matrix2, int m, int p, int n, float *output_matrix);

int main(void)
{
    matrix_multiply( m1,  m2, N, N, 1,  result);

    matrix_multiply(&m1[0][0], &m2[0][0], N, N, 1, &result[0][0]);

    matrix_multiply((float*) m1, (float*) m2, N, N, 1, (float*) result);
}

void matrix_multiply(float *input_matrix1, float *input_matrix2, int m, int p, int n, float *output_matrix)
{
    // Matrix Multiplication Routine
    // input_matrix1 = input matrix (m x p)
    // input_matrix2 = input matrix (p x n)
    // m = number of rows in input_matrix1
    // p = number of columns in input_matrix1 and the number of rows in input_matrix2
    // n = number of columns in input_matrix2
    // output_matrix = output matrix = input_matrix1*input_matrix2 (m x n)
    //.....Code that does matrix multiplication
}

在Mac OS X 10.8.4上使用GCC 4.7.1编译时,输出为:

$ gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c matmul89.c
matmul89.c: In function ‘main’:
matmul89.c:10:5: warning: passing argument 1 of ‘matrix_multiply’ from incompatible pointer type [enabled by default]
matmul89.c:6:6: note: expected ‘float *’ but argument is of type ‘float (*)[2]’
matmul89.c:10:5: warning: passing argument 2 of ‘matrix_multiply’ from incompatible pointer type [enabled by default]
matmul89.c:6:6: note: expected ‘float *’ but argument is of type ‘float (*)[1]’
matmul89.c:10:5: warning: passing argument 6 of ‘matrix_multiply’ from incompatible pointer type [enabled by default]
matmul89.c:6:6: note: expected ‘float *’ but argument is of type ‘float (*)[2]’
matmul89.c: In function ‘matrix_multiply’:
matmul89.c:17:29: warning: unused parameter ‘input_matrix1’ [-Wunused-parameter]
matmul89.c:17:51: warning: unused parameter ‘input_matrix2’ [-Wunused-parameter]
matmul89.c:17:70: warning: unused parameter ‘m’ [-Wunused-parameter]
matmul89.c:17:77: warning: unused parameter ‘p’ [-Wunused-parameter]
matmul89.c:17:84: warning: unused parameter ‘n’ [-Wunused-parameter]
matmul89.c:17:94: warning: unused parameter ‘output_matrix’ [-Wunused-parameter]
$

未使用的参数警告是合理的;该函数仍然是一个没有代码的虚拟。第10行是没有演员表的matrix_multiply()的调用。如您所见,GCC诊断出矩阵参数的类型不是float *,而是指针数组。第二个调用是我写它的方式,避免任何需要演员表。第三个调用强迫编译器接受带有强制转换的代码,它实际上可以正常工作,但实际上没有必要进行钝击。

工作C99代码

如果你有C99可用,你可以使用VLA - 可变长度数组 - 整齐地编写代码:

#include <stdio.h>

#define N 2
static float m1[N][N] = {{1.0, -0.02}, {0.0, 1.0}};
static float m2[N][1] = {{1.5f}, {1.5f}};
static float result[1][N];

void matrix_multiply(int m, int p, int n, float matrix1[m][p], float matrix2[p][n], float output[m][n]);
void matrix_print(const char *tag, int m, int n, float matrix[m][n]);

int main(void)
{
    matrix_multiply(N, N, 1, m1, m2, result);
    matrix_print("m1", N, N, m1);
    matrix_print("m2", N, 1, m2);
    matrix_print("m3", 1, N, result);
}

void matrix_multiply(int m, int p, int n, float matrix1[m][p], float matrix2[p][n], float output[m][n])
{
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            output[i][j] = 0.0;

    for (int i = 0; i < m; i++)
        for (int j = 0; j < p; j++)
            for (int k = 0; k < n; k++)
                output[i][k] += matrix1[i][j] * matrix2[j][k];
}

void matrix_print(const char *tag, int m, int n, float matrix[m][n])
{
    printf("%s (%d x %d):\n", tag, m, n);
    for (int i = 0; i < m; i++)
    {
        char *pad = "[";
        for (int j = 0; j < n; j++)
        {
            printf("%s%6.3f", pad, matrix[i][j]);
            pad = ", ";
        }
        printf("%s", " ]\n");
    }
}

编译时没有警告,产生看似合理的输出:

m1 (2 x 2):
[ 1.000, -0.020 ]
[ 0.000,  1.000 ]
m2 (2 x 1):
[ 1.500 ]
[ 1.500 ]
m3 (1 x 2):
[ 1.470,  1.500 ]

使用C89编写代码来模拟地址算法是非常繁琐的 - 远非不可能,而是繁琐。


使用C89代码

#include <stdio.h>

#define N 2
static float m1[N][N] = {{1.0, -0.02}, {0.0, 1.0}};
static float m2[N][1] = {{1.5f}, {1.5f}};
static float result[1][N];

void matrix_multiply(float *matrix1, float *matrix2, int m, int p, int n, float *output);
void matrix_print(const char *tag, int m, int n, float *matrix);

int main(void)
{
    matrix_multiply(&m1[0][0], &m2[0][0], N, N, 1, &result[0][0]);
    matrix_print("m1", N, N, &m1[0][0]);
    matrix_print("m2", N, 1, &m2[0][0]);
    matrix_print("m3", 1, N, &result[0][0]);
    return 0;
}

/*
** Matrix Multiplication Routine
** matrix1 = input matrix (m x p)
** matrix2 = input matrix (p x n)
** m = number of rows in matrix1
** p = number of columns in matrix1 and number of rows in matrix2
** n = number of columns in matrix2
** output = output matrix = matrix1 * matrix2 (m x n)
*/
void matrix_multiply(float *matrix1, float *matrix2, int m, int p, int n, float *output)
{
    int i, j, k;

    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            output[i*n+j] = 0.0;

    for (i = 0; i < m; i++)
        for (j = 0; j < p; j++)
            for (k = 0; k < n; k++)
                output[i*n+k] += matrix1[i*p+j] * matrix2[j*n+k];
}

void matrix_print(const char *tag, int m, int n, float *matrix)
{
    int i, j;

    printf("%s (%d x %d):\n", tag, m, n);
    for (i = 0; i < m; i++)
    {
        char *pad = "[";
        for (j = 0; j < n; j++)
        {
            printf("%s%6.3f", pad, matrix[i*n+j]);
            pad = ", ";
        }
        printf("%s", " ]\n");
    }
}

C89和C99代码的输出相同。