C语言报错:applyChange函数重定义类型不兼容问题求助
解决
incompatible types for redefinition of 'applyChange'错误 这个问题的根源其实是C语言的隐式函数声明机制在搞鬼——你看不到显式的重复定义,但编译器已经自动生成了一个和你最终定义不匹配的函数声明。
问题原因
当编译器编译hillClimb函数时,遇到applyChange(valuesCopy,valueChangeCode);这行调用代码,但此时它还没看到你后面写的applyChange函数定义。按照C语言的旧兼容规则,编译器会自动生成一个隐式声明:int applyChange();——这个隐式声明的函数返回int类型,参数列表是不确定的。
等编译器继续往下编译到你写的void applyChange(int values[3][3][3], int changeCode[9])定义时,发现这个函数的签名(返回类型是void,参数是明确的数组类型)和之前隐式声明的int applyChange()完全不匹配,就会抛出"incompatible types for redefinition"错误——它认为你在重新定义一个已经存在的、类型不兼容的函数。
两种解决方案
方案1:提前声明applyChange函数
在hillClimb函数的定义之前,加上applyChange的函数声明,告诉编译器这个函数的正确签名:
// 提前声明applyChange函数,明确返回类型和参数 void applyChange(int values[3][3][3], int changeCode[9]); void hillClimb(int values[3][3][3],int pastData[20]){ int bestVal = evaluateValues(values,pastData); int bestCode[9] = {0,0,0,0,0,0,0,0,0}; int valueChangeCode[9] = {0,0,0,0,0,0,0,0,0}; int valuesCopy[3][3][3]; //copyValues(valuesCopy,values); while (incrementBaseThree(valueChangeCode,9)){ copyValues(valuesCopy,values); applyChange(valuesCopy,valueChangeCode); int evaluation = evaluateValues(valuesCopy,pastData); if (evaluation > bestVal) { bestVal = evaluation; copyChangeCode(bestCode,valueChangeCode); } } applyChange(values,bestCode); } void applyChange(int values[3][3][3], int changeCode[9]){ for (int a = 0; a < 9; a++){ changeCode[a] --; } for (int i = 0; i < 3; i++){ for (int k = 0; k < 3; k++){ values[i][k][ (0+k) % 3 ] += changeCode[ (3*i) + 0]; values[i][k][ (1+k) % 3 ] += changeCode[ (3*i) + 1]; values[i][k][ (2+k) % 3 ] += changeCode[ (3*i) + 2]; } } for (int a = 0; a < 9; a++){//避免破坏上层栈帧的changeCode changeCode[a] ++; } }
方案2:把applyChange的定义移到hillClimb之前
让编译器在编译hillClimb之前就看到applyChange的完整定义,这样就不会触发隐式声明了:
void applyChange(int values[3][3][3], int changeCode[9]){ for (int a = 0; a < 9; a++){ changeCode[a] --; } for (int i = 0; i < 3; i++){ for (int k = 0; k < 3; k++){ values[i][k][ (0+k) % 3 ] += changeCode[ (3*i) + 0]; values[i][k][ (1+k) % 3 ] += changeCode[ (3*i) + 1]; values[i][k][ (2+k) % 3 ] += changeCode[ (3*i) + 2]; } } for (int a = 0; a < 9; a++){//避免破坏上层栈帧的changeCode changeCode[a] ++; } } void hillClimb(int values[3][3][3],int pastData[20]){ int bestVal = evaluateValues(values,pastData); int bestCode[9] = {0,0,0,0,0,0,0,0,0}; int valueChangeCode[9] = {0,0,0,0,0,0,0,0,0}; int valuesCopy[3][3][3]; //copyValues(valuesCopy,values); while (incrementBaseThree(valueChangeCode,9)){ copyValues(valuesCopy,values); applyChange(valuesCopy,valueChangeCode); int evaluation = evaluateValues(valuesCopy,pastData); if (evaluation > bestVal) { bestVal = evaluation; copyChangeCode(bestCode,valueChangeCode); } } applyChange(values,bestCode); }
额外提醒
在C99及以后的标准中,隐式函数声明其实已经被废弃了,但很多编译器为了兼容旧代码还是会支持,这就容易导致这类隐蔽的错误。建议养成先声明后使用的习惯,或者把函数按调用顺序排列,避免踩这种坑。
内容的提问来源于stack exchange,提问作者hexidian
相关产品推荐
相关产品推荐

