我正在尝试编写一个函数,该函数以下列格式从用户获取输入: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;
}
谢谢!
答案 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.0f
或if (col1[i] == 0.0f && col2[i] == 0.0f)
编辑:正如评论中指出的那样,您必须更改函数原型以及if ( (*(col1+i)) == 0.0f && (*(col2+i)) == 0.0f)
条件才能工作。而不是传递数组if
的指针,传递数组float *col[i]
本身。当评估if条件时,将发生数组到指针的转换,从而使代码按预期工作。