0

这是我的代码:

#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-loop 中的条件语句,; *ptr ;这是安全的做法吗?如果恰好有一些东西存储在数组中最后一个元素旁边的内存地址中,它会每次中断吗?这甚至可能吗?它如何知道何时终止?什么时候被*ptr认为是不可接受的?
  2. (关于主要注释掉char *ptr = msg;的):我知道指针和数组非常相似,但是,将实际数组传递countX给与传递指针(指向数组的开头?)之间是否有区别。
  3. countX我提供了两种不同的方法来解决这个简单的问题。一个被认为优于另一个?
4

3 回答 3

1

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

A是的,大多数时候。请参阅下面的更多细节。

:如果恰好在数组中最后一个元素旁边的内存地址中存储了某些东西,它是否会每次(我知道你的意思是曾经)中断?

的。

Q这可能吗?

的。您可以轻松地访问数组最后一个字符之后的内存,并将其设置为空字符以外的内容。

Q它如何知道何时终止?

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

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

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

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

A不,它们是相同的。

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

A不,他们不是。这取决于个人口味。我碰巧喜欢使用for循环,而我认识喜欢使用while循环的人。

于 2014-03-21T04:08:43.140 回答
0

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

Ans :当与 c 风格的字符串一起使用时,是的,这是一种安全的做法。任何 c 风格的字符串都必须以 '\0' 结尾,它基本上是 0。当 '\0' 不存在时,行为是未定义的。所以循环会在字符串的末尾中断。如果 *ptr 不是 c 样式的字符串,它将永远不会终止。例如,c 风格的“hello”实际上是一个包含 'h'、'e'、'l'、'l'、'o'、'\0' 的数组。因此,循环存在于 '\0' 处,从不访问它之后的内存。可以在数组的最后一个元素之后访问内存。例如,

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()。

于 2014-03-21T05:33:56.753 回答
-2

这是非常糟糕的做法。

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

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

于 2014-03-21T04:11:40.953 回答