今天在刷《剑指offer》时,遇到了几个比较有意思的点,题目是面试题20,我写的代码如下:
class Solution { public: bool isNumeric(char* str) { if(str == nullptr) return false; bool flag = isSignedDigit(str); if(*str == '.') { str++; flag = isDIgit(str) || flag; } if(*str == 'e' || *str == 'E') { str++; flag = flag && isSignedDigit(str); } return flag && *str == '\0'; } bool isSignedDigit(char*&str) { if(*str == '+' || *str == '-') str++; return isDIgit(str); } bool isDIgit(char*&str) { int flag = 0; while(*str != '\0' && *str <= '9' && *str >= '0') { str++; flag++; } return (flag > 0)?true:false; } };
这段代码,有两个点需要注意:
1.在函数isDIdit和函数isSignedDigit中,它们的形参实际上是指针的引用,即本质是个引用,不过这个引用是指针变量的引用。原书代码中采用的是二级指针,我嫌麻烦使用了指针的引用。此处有几点需要注意:
(1)一开始我是把这两个函数的形参直接设置的为指针变量,但我发现这样做的话str++这个操作并没有执行,即真正的str指针并没有移动。细想了下,虽然实参是一个指针变量,但由于形参也是一个指针变量,所以和其他类型的变量一样,实参实际上是str这个指针变量的一个复制值,函数中进行的str++操作只是这个复制变量的操作,而真正的str并没有执行str++操作。(这里与swap函数不一样,swap函数形参虽然也是指针变量,但该函数的操作是改变指针所指变量的值,假设该变量为a,即使对于指针的复制体,它里面存的值和原指针是一样的,都是变量a的地址,所以不管对这两个变量哪一个进行改变,实际上a的值都变。 但在本题中改变的是指针变量本身,而不是它指向的变量的值)。
(2)此处用指针的引用和二级指针都可以,但要注意的一点是:引用变量本身不能为空。
2.在flag = isDIgit(str) || flag;这个操作中,||的运算我是先使用的isDigit(str),然后为flag。因为在c++中,在进行A||B的判断时,如果A是ture的话,就不会对B进行判断了,就直接返回true。如果改为flag = flag || isDIgit(str);当flag为true时就不会执行sDIgit(str)了,相当于无法继续遍历str了。这点需要注意一下。