我以为我真的开始明白指针是如何工作的,然后我遇到了这个练习。我试图重新创建我在“学习C”一书中找到的一大块代码,我完成了它并且它正在工作,我认为一切都很棒:
void PrintWords( char *line ) {
bool inWord = false;
while (*line != kByteZero) {
if (! isspace(*line)) {
if (inWord == false) {
putchar('\n');
inWord = true;
}
putchar(*line);
} else {
inWord = false;
}
*line++;
}
}
这只是一个简单的函数,可以在不同的行上显示数组的单词。当我将它与书中的代码进行比较时,我看到了一个明显的区别。本书代码中的最后一行是'line ++'而不是'* line ++'。
我认为使用'line ++'与我们在这里尝试做的完全相反。我试图增加指针指向的位置,以及操纵存储在该内存地址的文件。 'line ++'对我来说似乎很奇怪,因为我甚至不确定它告诉代码要做什么?从第[i]行移到第[i + 1]行?这看起来很奇怪,因为那时'line'本身似乎只是作为一个指针 - 如果是这样的话,为什么我不能用'line'替换* line的每个实例?
答案 0 :(得分:9)
在这种情况下,*line++
和line++
完全相同。后缀++
的优先级高于*
。您可以用以下代码替换您的代码:
*(line++)
这很容易看出是不必要的。你在这里展示的程序正是你所说的 - 它想要将指针递增到指向下一个字符,这样它就可以测试它并打印它或换行符。您希望line
引用指针,*line
取消引用指针并获取指向的内容。
我刚用你的代码进行了快速测试。我收到来自gcc的警告“使用值计算未使用”*
。
答案 1 :(得分:3)
从第[i]行移动到第[i + 1]行?
是的,这正是line++;
在示例中的含义
请注意,指针只是一个变量,其值用于指示内存中的位置。
所以说你在记忆中有这个:
position | value
0 | H
1 | e
2 | l
3 | l
4 | o
现在说我们有line = 0;
然后*line
将为H
如果我们执行line++;
,line
现在为1,这意味着*line
现在为e
。
如果现在我们执行(*line)++
,那么您实际上正在更改内存中的值,即:
position | value
0 | H
1 | f
2 | l
3 | l
4 | o
答案 2 :(得分:2)
line
是指针。
line
将是一些数字,如0x80b34560。
*line
将类似于'c'
。
所以line
包含一个包含(假设)'c'
的内存位置的地址。
当您希望line
指向下一个位置时,您说line++
,它将是下一个数字(假设为0x80b34561,这是一个包含'd'
的内存位置)。
这里的混淆源于*line++
中运算符的优先级。这相当于*(line++)
,因为++
的优先级高于*
。所以你正在做的是将值存储在指针然后扔掉,这是没用的。
这是一个图表:
+-------------------------------+
| var | address | value |
+-------------------------------+
| line | 80b34560 | 'a' |
| (line+1) | 80b34561 | 'b' |
| line[2] | 80b34562 | ' ' |
| etc... | | |
+-------------------------------+
请注意,我使用了两种不同的符号来访问其中的地址 - line+1
和line[2]
。你的问题“从行[i]移到行[i + 1] ??”是正确的,但重新考虑你的结论。
答案 3 :(得分:2)
line
是一个指针。 line++
将递增指针,即将其移至下一个字符。正如您自己正确说明的那样,它会将指针从line[i]
移动到line[i + 1]
(以line
的原始值传递给PrintWords
函数。)
什么“操纵存储在该内存地址的文件”应该意味着完全超出我的意思。你在谈论什么“文件”?
你的“用'line'替换*行的每一个实例”的含义对我来说也不清楚。当我们想要使用指针line
时,我们使用line
。当我们想要使用指向的*line
字符指针时,我们使用line
。这很简单。
最后,声明*line++
完全等同于line++
。在两种情况下,指针line
都会递增。在前一种情况下,您也会取消引用指针,但由于您忽略了该取消引用的结果,因此它没有任何区别。
答案 4 :(得分:1)
表达式line++
会增加指针,这正是您要做的事情。
表达式*line++
递增指针,并返回新地址处字符的值。但是,你没有做任何有价值的事情。
后缀运算符++
的优先级高于*
运算符。