简体   繁体   English

C程序中的Char变量行为

[英]Char variable behavior in C program

I wrote a sudoku solver program with function which checks if it is leagal to set a value in a specific location: 我编写了一个带有功能的数独解算器程序,该程序检查是否可以在特定位置设置值:

typedef int cell;
typedef char value;
typedef value sudokuGrid[GRID_SIZE]; // GRID_SIZE is 81


int isLegal (sudokuGrid game, cell location,value candidateDigit);

I also wrote a function to test isLegal function giving it a sudoku puzzle and once the solution is calculated checking if all set values are correct: 我还写了一个函数来测试isLegal函数,给它一个数独难题,一旦计算出解决方案,就检查所有设置值是否正确:

static void testIsLegal(){
   int i, solution;
   int mid_result, result;

   sudokuGrid testGrid = {
      '6','4','.','.','.','.','8','1','7',
      '1','7','.','8','6','.','2','.','4',
      '.','.','.','.','.','.','.','9','6',
      '.','8','.','.','9','6','.','.','.',
      '.','6','.','3','.','1','.','2','.',
      '.','.','.','2','5','.','.','6','.',
      '8','2','.','.','.','.','.','.','.',
      '3','.','7','.','1','8','.','4','2',
      '4','5','1','.','.','.','.','8','3'
   };


   printf("Testing isLegal() function ............\n");

   result = TRUE;


   solution = hasSolution(testGrid);
   showGame(testGrid);

   int f = isLegal(testGrid,78,'9');
   printf("isLegal(testGrid,78,9) = %d\n\n",f);


   i = 0;
   result = TRUE;
   value cellValue;
   if (solution){
      while ((result == TRUE) && (i < GRID_SIZE)){
         cellValue = testGrid[i];
         testGrid[i] = EMPTY_VALUE;
         printf("isLegal(testGrid,%d,%c) = %d\n",i,cellValue,isLegal(testGrid,i,cellValue));
         result = result && isLegal(testGrid,i,cellValue);
         testGrid[i] = cellValue;
         i++;
      }
    }
    if (result)
         printf("\t\t\t\t\t [OK]\n");
      else
         printf("\t\t\t\t\t[NOK]\n");
}

The result of executing this function with a wrong result is: 执行此函数的结果是错误的:

6 4 2   5 3 9   8 1 7
1 7 5   8 6 2   2 3 4
9 3 8   1 4 7   5 9 6

2 8 3   7 9 6   1 7 5
5 6 4   3 8 1   3 2 8
7 1 9   2 5 4   4 6 9

8 2 6   4 2 3   6 5 1
3 9 7   6 1 8   7 4 2
4 5 1   9 7 5   9 8 3

There are many mistakes here but I mentioned the both 9-s in the last line (possitions 75 and 78). 这里有很多错误,但我在最后一行(位置75和78)中提到了两个9-s。 Performed a manual check for isLegal(testGrid,78,'9') which returns FALSE, but when I use a loop isLegal(testGrid,i,cellValue) returns TRUE all the time: 对isLegal(testGrid,78,'9')执行了手动检查,该检查返回FALSE,但是当我使用循环时,isLegal(testGrid,i,cellValue)始终返回TRUE:

isLegal(testGrid,78,9) = 0

isLegal(testGrid,0,6) = 1
isLegal(testGrid,1,4) = 1
isLegal(testGrid,2,2) = 1
isLegal(testGrid,3,5) = 1
.....
isLegal(testGrid,78,9) = 1
isLegal(testGrid,79,8) = 1
isLegal(testGrid,80,3) = 1

My question is why when I use char variable in ' ' quotes (isLegal(testGrid,78,'9') from the code) it shows the correct result, but not when I use cellValue variable? 我的问题是为什么当我在''引号(代码中的isLegal(testGrid,78,'9'))中使用char变量时,它显示正确的结果,但是当我使用cellValue变量时却没有? How can this be fixed? 如何解决?

Thank you! 谢谢!

Adding additional information: 添加其他信息:

#define MIN_VALUE '1'
#define MAX_VALUE '9'
#define EMPTY_VALUE '.'
#define NUM_VALUES (MAX_VALUE - MIN_VALUE + 1)
#define GRID_SIZE (NUM_VALUES * NUM_VALUES)
#define MAX_CELL (GRID_SIZE - 1)

#define TRUE    1
#define FALSE   0

#define MINI_SQUARE_SIZE        3
#define SQUARE_SIZE             9

typedef int cell;
typedef char value;
typedef value sudokuGrid[GRID_SIZE];

isLegal function: isLegal函数:

int isLegal (sudokuGrid game, cell location,value candidateDigit){
   assert (location >= 0);
   assert (location <= GRID_SIZE);

   assert (candidateDigit >= MIN_VALUE);
   assert (candidateDigit <= MAX_VALUE);

   return (isLegalLine(game,location,candidateDigit) &&
            isLegalColumn(game,location,candidateDigit) &&
            isLegalSquare(game,location,candidateDigit));
}




static int isLegalLine(sudokuGrid game, cell location,value candidateDigit){
   assert (location >= 0);
   assert (location <= GRID_SIZE);

   assert (candidateDigit >= MIN_VALUE);
   assert (candidateDigit <= MAX_VALUE);


   int result, mid_result;
   int i;
   int lineNumber = location / SQUARE_SIZE;

   result = TRUE;

   for (i = 0; i < GRID_SIZE; i++){
      if (( i / SQUARE_SIZE ) == lineNumber){
         if ( game[i] != candidateDigit ){
            mid_result = TRUE;
         }
         else{
            mid_result = FALSE;
         }
         result = result && mid_result;
      }
   }

   return result;
}

static int isLegalColumn(sudokuGrid game, cell location,value candidateDigit){
   assert (location >= 0);
   assert (location <= GRID_SIZE);

   assert (candidateDigit >= MIN_VALUE);
   assert (candidateDigit <= MAX_VALUE);


   int result, mid_result;
   int i;
   int columnNumber = location % SQUARE_SIZE;

   result = TRUE;

   for (i = 0; i < GRID_SIZE; i++){
      if (( i % SQUARE_SIZE ) == columnNumber){
         if ( game[i] != candidateDigit )
             mid_result = TRUE;
         else
             mid_result = FALSE;
         result = result && mid_result;
      }
   }
   return result;
}

static int isLegalSquare(sudokuGrid game, cell location,value candidateDigit){
   assert (location >= 0);
   assert (location <= GRID_SIZE);

   assert (candidateDigit >= MIN_VALUE);
   assert (candidateDigit <= MAX_VALUE);


   int result, mid_result;
   int i;

   int lineNumber = location / SQUARE_SIZE;
   int columnNumber = location % SQUARE_SIZE;
//   int squareNumber;

   if ( lineNumber < MINI_SQUARE_SIZE){
      lineNumber = 0;
      if (columnNumber < MINI_SQUARE_SIZE){
      //   squareNumber = 1;
         columnNumber = 0;
      }
      else if (columnNumber < 2*MINI_SQUARE_SIZE){
      //   squareNumber = 2;
         columnNumber = MINI_SQUARE_SIZE;
      }
      else{
      //   squareNumber = 3;
         columnNumber = 2*MINI_SQUARE_SIZE;
      }
   }

   else if (lineNumber < 2*MINI_SQUARE_SIZE){
      lineNumber = MINI_SQUARE_SIZE;
      if (columnNumber < MINI_SQUARE_SIZE){
      //   squareNumber = 4;
         columnNumber = 0;
      }
      else if (columnNumber < 2*MINI_SQUARE_SIZE){
      //   squareNumber = 5;
         columnNumber = MINI_SQUARE_SIZE;
      }
      else{
      //   squareNumber = 6;
         columnNumber = 2*MINI_SQUARE_SIZE;
      }
   }

   else{
      lineNumber = 2*MINI_SQUARE_SIZE;
      if (columnNumber < MINI_SQUARE_SIZE){
      //   squareNumber = 7;
         columnNumber = 0;
      }
      else if (columnNumber < 2*MINI_SQUARE_SIZE){
      //   squareNumber = 8;
         columnNumber = MINI_SQUARE_SIZE;
      }
      else{
      //   squareNumber = 9;
         columnNumber = 2*MINI_SQUARE_SIZE;
      }
   }

   result = TRUE;

   int squareStartLocation = columnNumber + ( SQUARE_SIZE * lineNumber);
   int k = 0;
   int squareStartLocationLineEnd;



   while (k < MINI_SQUARE_SIZE){
      squareStartLocationLineEnd = squareStartLocation + MINI_SQUARE_SIZE;
      for (i = squareStartLocation; i < squareStartLocationLineEnd; i++){
         if (game[i] != candidateDigit)
            mid_result = TRUE;
         else
            mid_result = FALSE;
         result = result && mid_result;
      }
      k++;
      squareStartLocation += SQUARE_SIZE;
      result = result && mid_result;
  }



   return result;

}

Think a little bit about what this: 想一想这是什么:

testGrid[i] = EMPTY_VALUE;

will do to isLegal() in the next line: 在下一行将对isLegal()进行操作:

printf("isLegal(testGrid,%d,%c) = %d\n",i,cellValue,isLegal(testGrid,i,cellValue));

Maybe this does something in isLegal() what you don't want 也许这在isLegal()中做了一些您不想要的事情

Parameter candidateDigit will be passed as a char type to isLegal(). 参数候选人候选者作为char类型传递给isLegal()。 It must be the loop context causing the function to always return TRUE, so you will need to: 它必须是导致函数始终返回TRUE的循环上下文,因此您将需要:

  • show us the code for isLegal() 向我们展示isLegal()的代码
  • show us the value of EMPTY_VALUE 向我们显示EMPTY_VALUE的值

Update1: Thanks for the extra info. 更新1:感谢您的额外信息。 I plugged in your filled out "bad" data, set solution to TRUE, and the test stopped at position 14 with a failure (correctly as this position contains '2' and there is another in the same line). 我插入了您填写的“错误”数据,将解决方案设置为TRUE,并且测试在第14位失败并失败了(正确的原因是该位置包含“ 2”,并且同一行中还有另一个)。 So it seems that your code is correct! 因此,看来您的代码是正确的! At least as far as this test goes. 至少就此测试而言。

Test grid: 测试网格:

   sudokuGrid testGrid = {
      '6','4','2','5','3','9','8','1','7',
      '1','7','5','8','6','2','2','3','4',
      '9','3','8','1','4','7','5','9','6',
      '2','8','3','7','9','6','1','7','5',
      '5','6','4','3','8','1','3','2','8',
      '7','1','9','2','5','4','4','6','9',
      '8','2','6','4','2','3','6','5','1',
      '3','9','7','6','1','8','7','4','2',
      '4','5','1','9','7','5','9','8','3'
   };

Test output: 测试输出:

isLegal(testGrid,78,9) = 0

isLegal(testGrid,0,6) = 1
isLegal(testGrid,1,4) = 1
isLegal(testGrid,2,2) = 1
isLegal(testGrid,3,5) = 1
isLegal(testGrid,4,3) = 1
isLegal(testGrid,5,9) = 1
isLegal(testGrid,6,8) = 1
isLegal(testGrid,7,1) = 1
isLegal(testGrid,8,7) = 1
isLegal(testGrid,9,1) = 1
isLegal(testGrid,10,7) = 1
isLegal(testGrid,11,5) = 1
isLegal(testGrid,12,8) = 1
isLegal(testGrid,13,6) = 1
isLegal(testGrid,14,2) = 0
                    [NOK]

NB Only other code changes I made were to move isLegal() below the functions that it calls (to avoid default promotion of return types) and to comment out calls to hasSolution() and showGrid(). 注意:我所做的其他代码更改仅是将isLegal()移到其调用的函数下方(以避免默认提升返回类型),并注释掉对hasSolution()和showGrid()的调用。

If you do char a = 9 , you are making that a have an ASCII value. 如果执行char a = 9 ,则使a具有ASCII值。 For example: char letter = 80; 例如: char letter = 80; is equivalent to char letter = 'P'; 等价于char letter = 'P';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM