如何比较传递给函数的数组元素的值

时间:2016-12-01 13:18:00

标签: c arrays function pointers

我正在尝试编写一个函数,该函数以下列格式从用户获取输入:0.3,0.2,1,数据类型为:float,float,int。如果两个浮点数的值均为0.0,则数据条目结束。我初始化了三个数组

float col1Train[1000];
float col2Train[1000];
int col3Train[1000];
主函数中的

(可以合理地假设用户的数据条目少于1k),并调用这样的函数:

nTrainSets = readTrainingData(&col1Train, &col2Train, &col3Train);

现在,我的问题是IF条件(标记如下)使我的程序崩溃,我不知道为什么。我想检查包含的数组元素是否为零..

另外,同一声明的替代表述(至少我认为它是相同的?)是不是在编译引用浮动和*浮动的不匹配 - 为什么这样/我该如何解决?

int readTrainingData(float *col1[], float *col2[], int *col3[])
{
    int i = 0;
    int scanfReturn = scanf("%f,%f,%d", &col1[i], &col2[i], &col3[i]);
    while (scanfReturn == 3) {
        printf ("read: %f, %f, %d", col1[i], col2[i], col3[i]); // Debug statement, execution succeeds
        if (*col1[i] == 0.0f && *col2[i] == 0.0f) {  // Causing the error
        //if (*(col1 + i) == 0.0f && *(col2 + i) == 0.0f) {  // Not even compiling
            col1[i] = NULL;
            col2[i] = NULL;
            col3[i] = NULL;
            break;
        }
        ++i;
        scanfReturn = scanf("%f,%f,%d", &col1[i], &col2[i], &col3[i]);
    }
    return i - 1;    
}

谢谢!

2 个答案:

答案 0 :(得分:1)

float col1Train[1000];
float col2Train[1000];
int col3Train[1000];

考虑在此使用struct

struct train {
    float col1;
    float col2;
    int col3;
};

struct train Train[1000];
  

可以合理地假设用户的数据条目少于1k

永远不要假设任何事情。只需传递函数调用中的元素数量即可。而不是

nTrainSets = readTrainingData(&col1Train, &col2Train, &col3Train);

使用

nTrainSets = readTrainingData(1000, &col1Train, &col2Train, &col3Train);

此外,将数组有效地传递给函数是将指针传递给它的函数的第一个参数。所以,这样称呼:

nTrainSets = readTrainingData(1000, col1Train, col2Train, col3Train);

然后功能原型也需要改变。而不是

int readTrainingData(float *col1[], float *col2[], int *col3[])

要么写

int readTrainingData(size_t size, float col1[], float col2[], int col3[])

int readTrainingData(size_t size, float * col1, float col2, int col3)

两者基本相同。我更喜欢变体float * col1,但有人可以说,float col1[]文档,预期实际数组,而不仅仅是指向单个值的指针。

int scanfReturn = scanf("%lf,%lf,%d", &col1[i], &col2[i], &col3[i]);

由于scanf无论如何都需要指针,只需计算一个指针:

int scanfReturn = scanf("%lf,%lf,%d", col1 + i, col2 + i, col3 + i);

现在,与printf相比,"%f"期望double参数和float由于类型提升规则而被提升为double(以及"%lf"仅在以后被允许用作"%f"的同义词时,scanf - 函数族实际上必须区分这两种数据类型。因此,要扫描double,您可以使用"%lf",但对于float(您在此处使用的内容),您必须限制为"%f",如此:

int scanfReturn = scanf("%f,%f,%d", col1 + i, col2 + i, col3 + i);

然后

    if (*(col1 + i) == 0.0f && *(col2 + i) == 0.0f) {

或(col1 [i] == 0.0f&& col2 [i] == 0.0f){

世界与Cish方式的完美结合:

    if (!col1[i] && !col2[i]) {

        col1[i] = NULL;
        col2[i] = NULL;
        col3[i] = NULL;

在这里,请使用0而不是NULL,因为NULL可能是指针,因此无法分配给非指针变量。

        col1[i] = 0;
        col2[i] = 0;
        col3[i] = 0;

最后得出结论"永远不要假设任何事情" part:在i增量中,测试缓冲区溢出:

    if (++i == size-1) {
        col1[i] = 0;
        col2[i] = 0;
        col3[i] = 0;
        break;
    }

答案 1 :(得分:0)

声明spark-submit是错误的。编译器将上述条件作为指针数组(* col [i])和浮点值(0.0f)之间的比较,而不是需要比较的数组。错误

  

float *和float

之间不匹配
发生

是因为您正在将指向浮点值(float *)的地址与浮点值进行比较,即if (*col1[i] == 0.0f && *col2[i] == 0.0f)

将条件重写为*col[i] == 0.0fif (col1[i] == 0.0f && col2[i] == 0.0f)

编辑:正如评论中指出的那样,您必须更改函数原型以及if ( (*(col1+i)) == 0.0f && (*(col2+i)) == 0.0f)条件才能工作。而不是传递数组if的指针,传递数组float *col[i]本身。当评估if条件时,将发生数组到指针的转换,从而使代码按预期工作。