我尝试从Codewars进行此问题设置,并通过编译器运行我的代码。这表明存在细分错误,但我不知道我要去哪里。问题集如下:
下图给出了如何将给定的“ true”矩形切成正方形的概念(“ true”矩形意味着两个维度是不同的)。
您可以将此图形转换为算法吗?
系统将为您提供二维-正整数长度(名为lng的参数) 正整数宽度(名为wdth的参数)。 您将返回一个数组。
我的代码如下:
typedef struct Data Data;
struct Data {
int *array;
int sz;
};
Data* sqInRect(int lng, int wdth) {
Data* ptr = (Data*) malloc(sizeof(Data));
// if square length == square width
if(lng == wdth){
ptr->array = NULL;
ptr->sz = 0;
return 1;
}
//initialise variables
int rmdLength,rmdWidth,rmdSmallSquares,rmdLengthTimes,rmdWidthTimes,SIZE,temp=0;
//assign length to temporary rmd variable
rmdLength = lng;
//calc how many squares of side *wdth* inside rect
while((lng-wdth)>wdth){
rmdLength -= wdth;
rmdLengthTimes++;
}
rmdLength -= wdth;
rmdLengthTimes++;
//assign width to temporary rmdWidth variable
rmdWidth = wdth;
//calc how many squares of side *rmdWidth* inside rect (remaining area)
while(rmdWidth>rmdLength){
rmdWidth -= rmdLength;
rmdWidthTimes++;
}
rmdWidth -= rmdLength;
rmdWidthTimes++;
//calculate final number of remaining squares
rmdSmallSquares = rmdLength/rmdWidth;
//calculate SIZE
SIZE = rmdLengthTimes + rmdWidthTimes + rmdSmallSquares;
//declaration of array
int arr[SIZE];
//for loop to put square values in array
temp = rmdLengthTimes + rmdWidthTimes;
for(int i=0;i<rmdLengthTimes;i++){
arr[i] = wdth;
}
for(int j=rmdLengthTimes;j<temp;j++){
arr[j] = rmdLength;
}
for(int k=temp;k<SIZE;k++){
arr[k]= rmdWidth;
}
//get Data* ptr to store array AND size of that array
ptr->array = arr;
ptr->sz = SIZE;
return ptr;
}
如果有人可以跟我澄清我出了错的地方,我将不胜感激。我一直在这个问题上停留太久了。谢谢。
答案 0 :(得分:2)
您正在访问arr
数组的边界。
arr[i] = wdth;
因为尚未在变量下面初始化;
int rmdLength,rmdWidth,rmdSmallSquares,rmdLengthTimes,rmdWidthTimes,SIZE,temp=0;
并将它们用作数组的index
会导致未定义的行为。
SIZE = rmdLengthTimes + rmdWidthTimes + rmdSmallSquares;
for(int k=temp;k<SIZE;k++){
arr[k]= rmdWidth;
}
初始化如下。
int rmdLength=0,rmdWidth=0,rmdSmallSquares=0,rmdLengthTimes=0,rmdWidthTimes=0,SIZE=0,temp=0;
答案 1 :(得分:2)
您在下面的行中有很多未初始化的变量:
int rmdLength,rmdWidth,rmdSmallSquares,rmdLengthTimes,rmdWidthTimes,SIZE,temp=0;
注意:上一行不会将所有变量初始化为0
。只会将temp
初始化为0
。
要将所有变量初始化为0
,必须先声明它们,然后像这样初始化它们:
int rmdLength, rmdWidth, rmdSmallSquares, rmdLengthTimes, rmdWidthTimes, SIZE, temp;
rmdLength = rmdWidth = rmdSmallSquares = rmdLengthTimes = rmdWidthTimes = SIZE = temp = 0;
使用未初始化的变量会导致未定义的行为:
从online cpp reference on Uninitialized variables:
未初始化变量中的值可以是任何值–不可预测,并且每次运行程序时都可能不同。 读取未初始化变量的值是不确定的行为 –这始终是一个坏主意。必须先使用一个值对其进行初始化,然后才能使用它。
此外,在以下代码中,您还使用未初始化的变量rmdLengthTimes
作为检查以遍历数组的检查:
for(int i=0;i<rmdLengthTimes;i++){
arr[i] = wdth;
}
这将导致访问超出范围的内存地址,这也是未定义的行为:
来自wiki:
某些编程语言(最著名的是C和C ++)的行为在某些情况下是不确定的。在这些语言的标准中,某些操作的语义被描述为未定义。这些情况通常代表代码中明确的错误,例如,例如在数组边界之外索引数组。
因此在使用所有变量之前对其进行适当的初始化将解决您的问题。