如果语句被跳过

时间:2015-10-09 05:49:25

标签: c

在这个方法中,我想查看单词搜索中是否出现一个字符串。由于字符串可以出现在任何方向,因此我使用以下方法检查这些方向:

目前我的代码在运行时会出现分段错误。发生这种情况是因为我的方法中的第一个if语句是根据gdb跳过的。

我正在使用的网格如下所示:

a r e o 
o n l y
o d d a

运行时(就在segfault之前)的x,y和str的值是:

x = 0;
y = 0;
str = "add"

现在,strlen(str)的计算结果为3,x - 3的计算结果为-3。

-3 < 0会评估为true并退出我的方法。不幸的是,在运行时跳过方法开头的if语句。有谁知道发生了什么?

此外,如果我将网格的第一行更改为:

,我将添加
q r e o

我得到了正确的结果。

以下是方法:

bool checkNorth (int x, int y, string str) {
  //Deal with trival case and avoid array out of bounds/checking silly things
  if (x-strlen(str) < 0){
    return false;
  }
  //for each character in str 
  for (int i = 0; i < (strlen(str)); i++){
    //If the character above in the grid is the next character in the string
    if (grid[x-i][y].letter == str[i]){
      //keep going
      continue;
    }else{
      //It ain't north
      return false;
    }
  }
  //It's north
  return true;
}

1 个答案:

答案 0 :(得分:8)

由于strlen()返回类型为size_t且未签名的值,因此您计算x - 3计算是在无符号值上完成的,而使用无符号算术0 - 3是一个很大的正值,并且永远不会小于零。事实上,由于比较是针对小于0的无符号数量,但无符号数量永远不会是负数,编译器可以完全优化整个if测试和以下return

您可以通过更改以下内容来解决问题:

if (x-strlen(str) < 0){

为:

if (x < strlen(str)) {

请注意,你的循环效率有点低。你有:

for (int i = 0; i < (strlen(str)); i++){

这会在每次迭代时重新计算strlen(str)。你可以写:

size_t len = strlen(str);

for (size_t i = 0; i < len; i++) {

这保证长度只计算一次,这是足够的,除非你在函数的某个地方修改字符串,或者它调用的函数之一。