这是我的代码:
#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;
}
我想知道一些关于安全练习和指针的事情:
; *ptr ;
中的条件语句是否是安全的做法?如果在阵列中最后一个元素旁边的内存地址中存储了某些东西,它会不会中断?这甚至可能吗?它是如何知道何时终止的?何时*ptr
被视为不可接受?char *ptr = msg;
):我理解一个指针和一个数组是非常相似的,但是,将实际数组传递给countX
与传递一个数组是否有区别指针(指向数组的开头?)。 countX
中,我提供了两种不同的方法来解决这个简单的问题。一个被认为优于另一个吗?答案 0 :(得分:1)
Q 我在for循环中的条件语句; * ptr;,这是安全的做法吗?
A 是的,大部分时间都是。有关详细信息,请参见下文。
Q 如果在阵列中最后一个元素旁边的内存地址中存储了某些内容,那么它(我知道你的意思是)会破坏它吗?
A 是。
问那甚至可能吗?
A 是的。您可以轻松地访问一个超过数组最后一个字符的内存,并使其成为空字符以外的其他内容。
问如何知道何时终止?
A 当您遇到字符串的终止空字符时,它将终止。如果空字符已被其他内容替换,则行为将无法预测。
问什么时候* ptr被认为是不可接受的?
A 如果字符串长度为len
,则可以在ptr
和msg
范围内设置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运行循环到字符串的长度。