简单地检查条件语句中的指针值有什么后果?

时间:2014-03-21 03:52:10

标签: c++ arrays pointers pointer-to-pointer

这是我的代码:

#include <iostream>
using namespace std;
int countX(char*, char);

int main() {
    char msg[] = "there are four a's in this sentence a a";
    //char *ptr = msg; // <----- question 2!
    cout << countX(msg, 'a');
    cin.get();
}

int countX(char* ptr, char x) {
    int c = 0;
    for (; *ptr; ptr++) {
        if (*ptr == x) c++;
    }
    /*
    while(*ptr) {
        if(*ptr==x) c++;
        ptr++;
    }
    */
    return c;
}

我想知道一些关于安全练习和指针的事情:

  1. 我在for循环; *ptr ;中的条件语句是否是安全的做法?如果在阵列中最后一个元素旁边的内存地址中存储了某些东西,它会不会中断?这甚至可能吗?它是如何知道何时终止的?何时*ptr被视为不可接受?
  2. (关于主要注释掉的char *ptr = msg;):我理解一个指针和一个数组是非常相似的,但是,将实际数组传递给countX与传递一个数组是否有区别指针(指向数组的开头?)。
  3. countX中,我提供了两种不同的方法来解决这个简单的问题。一个被认为优于另一个吗?

3 个答案:

答案 0 :(得分:1)

Q 我在for循环中的条件语句; * ptr;,这是安全的做法吗?

A 是的,大部分时间都是。有关详细信息,请参见下文。

Q 如果在阵列中最后一个元素旁边的内存地址中存储了某些内容,那么它(我知道你的意思是)会破坏它吗?

A 是。

那甚至可能吗?

A 是的。您可以轻松地访问一个超过数组最后一个字符的内存,并使其成为空字符以外的其他内容。

如何知道何时终止?

A 当您遇到字符串的终止空字符时,它将终止。如果空字符已被其他内容替换,则行为将无法预测。

什么时候* ptr被认为是不可接受的?

A 如果字符串长度为len,则可以在ptrmsg范围内设置msg+len。如果ptr指向超出该范围的任何内容,则行为未定义。因此,在程序中应该认为它们是不可接受的。

Q (关于注释掉的char * ptr = msg;在主要内容):我理解指针和数组非常相似,但是,将实际数组传递给countX与传递指针(指向数组的开头?)。

A 不。他们是完全相同的。

在countX中,我提供了两种不同的方法来解决这个简单的问题。一个被认为优于另一个吗?

A 不,不是。归结为个人品味。我喜欢使用for循环,而我知道那些喜欢使用while循环的人。

答案 1 :(得分:0)

Q1:我在for循环中的条件语句; * ptr;,这是安全的做法吗?如果在阵列中最后一个元素旁边的内存地址中存储了某些东西,它会不会中断?这甚至可能吗?它是如何知道何时终止的?什么时候* ptr被认为是不可接受的?

Ans:当与c风格的字符串一起使用时,是的,这是一种安全的做法。任何c风格的字符串都必须以&#39; \ 0&#39;结尾,基本上为0.当&#39; \ 0&#39;时,行为未定义。不在这里。所以循环会在字符串的末尾打破。 *如果ptr不是c风格的字符串,它将永远不会终止。例如,一个c风格的&#34;你好&#34;实际上是一个包含&#39; h&#39;&#39;&#39; l&#39;,&#39; l&#39;,&#39; o&#39;的数组, &#39; \ 0&#39 ;.因此,循环存在于&#39; \ 0&#39;永远不会访问它之后的内存。 可以在数组的最后一个元素之后访问内存。例如,

int a[5] = {0,1,2,3,4,5};
int *p = a+5;

p正在访问数组a的最后一个元素之后的元素。

Q2:(关于注释掉的char * ptr = msg;在主要内容):我理解一个指针和一个数组非常相似,但是,传递实际数组之间是否有区别countX与传递指针(指向数组的开头?)。

Ans:数组和指针并不完全相似。它只是一个数组名称只是指向数组的第一个元素的常量指针。考虑我写的前一个例子。其中,a [3],3 [a],*(a + 3)和*(p + 3)都是指相同的元素。由于您是通过值传递的,因此常量指针msg的值将被复制到ptr。所以,不,它没有任何区别。

Q3:在countX中,我提供了两种不同的方法来解决这个简单的问题。一个被认为优于另一个吗?

答案:我不是专家,但我会拒绝。

另外,你可能不需要cin.get()。

答案 2 :(得分:-2)

这是非常糟糕的做法。

您在for条件下执行的操作基本上是if (*ptr),换句话说,ptr指向的内存是否包含非零值?

因此,如果字符串后面的内存位置包含非零值(可能来自使用该空格的另一个变量)或垃圾值,那么您的循环可能会无限,或者给您一个不正确的值。相反,你应该从0运行循环到字符串的长度。