c语言中的字符串指针 #包括 int main() { char*s[]={“知识”、“是”、“力量”}; 字符**p; p=s; printf(“%s”,++*p); printf(“%s”,*p++); printf(“%s”,++*p); 返回0; }
输出: 致谢致谢c语言中的字符串指针 #包括 int main() { char*s[]={“知识”、“是”、“力量”}; 字符**p; p=s; printf(“%s”,++*p); printf(“%s”,*p++); printf(“%s”,++*p); 返回0; },c,pointers,C,Pointers,输出: 致谢致谢 请特别解释第二个printf()语句的输出。我认为由于++和*具有相同的优先级,因此在*p++p中应首先递增,然后使用*(一元运算符从右到左的关联性).第一个一递增*p并显示字符串(在KnowlEdge中将其设置为n)。第二个显示字符串*p,然后递增p(将其移动到“is”)。第三个增量*p然后显示字符串(从“is”中的s开始)。增量后缀运算符(p++)计算得出的值是p。增量前缀运算符(++p)计算得出的值为p+1 在第二个printf中,*p++的计算结果与*p的计算结果相同,
请特别解释第二个
printf()
语句的输出。我认为由于++
和*
具有相同的优先级,因此在*p++
p
中应首先递增,然后使用*
(一元运算符从右到左的关联性).第一个一递增*p并显示字符串(在KnowlEdge中将其设置为n)。第二个显示字符串*p,然后递增p(将其移动到“is”)。第三个增量*p然后显示字符串(从“is”中的s开始)。增量后缀运算符(p++
)计算得出的值是p
。增量前缀运算符(++p
)计算得出的值为p+1
在第二个printf中,*p++
的计算结果与*p
的计算结果相同,但其副作用是根据以下条件递增p:
“*”与前缀“++”具有相同的优先级,但必须从左向右赋值
printf(“%s”,++*p)
因此,首先计算*p
,然后计算+(*p)
,得到第一个字符串中的第二个字符
“*”的优先级小于后缀“++”
printf(“%s”,*p++)
所以第一个p
是递增的,但它是一个后期递增。操作返回的值是原始值。通过这种方式,*
在原始指针上运行,该指针指向第一个字符串上的第二个字符
请注意,这次,++
在p
上运行,而不是在*p
上运行
由于“2”,p
指向第二个字符串。当您执行++*p
时,您现在指向第二个字符串(“s”)的第二个字符。再次使用预增量时,传递给printf
的值已更改
printf(“%s”,++*p)
如果您稍作更改并打印指针值,我可能会更清楚(忽略警告):
当面对复杂的运算符序列时,通常很容易将其重写为一系列简单语句。您的块变成:
printf("%s [%p]\n", ++*p, p );
printf("%s [%p]\n ", *p++, p );
printf("%s [%p]\n ", ++*p, p );
nowledge [0x7fff6f5519e0]
nowledge [0x7fff6f5519e8]
s [0x7fff6f5519e8]
供参考:如果不明显,此代码将更改
s[0]
和s[1]
。如果这个数组被传递给你,那将是一个令人讨厌的副作用;你会让那些指针基本上不可用。这就是我讨厌将解引用和增量结合起来的部分原因——做错事很容易这真的是家庭作业吗?他们没有更好的东西供你学习吗?或者这是一个糟糕的例子,以至于你学会了不做这样的事情?答案很好,但这些打印不是因为你不能保证函数参数的求值顺序吗?@JoeFish-是的,你是对的。这些表达式有副作用,这就是为什么我说忽略编译器警告。在生产代码中,我们不能依赖这样的表达式。谢谢你的邀请!
printf("%s [%p]\n", ++*p, p );
printf("%s [%p]\n ", *p++, p );
printf("%s [%p]\n ", ++*p, p );
nowledge [0x7fff6f5519e0]
nowledge [0x7fff6f5519e8]
s [0x7fff6f5519e8]
p[0]++; //skips over the 'k' in knowledge
printf("%s", *p);
printf("%s", *p);
p++; //moves to the next word
p[0]++; //skips over the 'i' in is
printf("%s", *p);