C中带指针的For循环
我不明白指针在C中带指针的For循环,c,arrays,string,pointers,for-loop,C,Arrays,String,Pointers,For Loop,我不明白指针在for循环中的作用。*p在以下循环中做什么 我确实理解其余的,但是为什么*p不像p>3或者类似的东西呢? 为什么只有它? 为什么是这样写的?它利用了一个事实,即字符串的终止符(最终由for循环找到)将是一个ASCIINUL,它是一个零,也恰好计算为false,从而终止for循环 值得注意的是0、false、NULL和ASCII-NUL之间的区别和相似性。请参阅此问题:在布尔上下文中,例如for循环的条件,C中的每个表达式的计算结果为true(非零)或false(零) 您希望for循
for
循环中的作用。*p
在以下循环中做什么
我确实理解其余的,但是为什么*p
不像p>3
或者类似的东西呢?为什么只有它?
为什么是这样写的?它利用了一个事实,即字符串的终止符(最终由for循环找到)将是一个ASCII
NUL
,它是一个零,也恰好计算为false,从而终止for循环
值得注意的是0、false、NULL和ASCII-NUL之间的区别和相似性。请参阅此问题:在布尔上下文中,例如
for
循环的条件,C中的每个表达式的计算结果为true(非零)或false(零)
您希望for
循环在到达字符串末尾时终止
在C语言中,每个字符串都以字符
'\0'
结尾,实际上是0
。因此,当for
循环到达字符串末尾时,*p
计算结果为'\0'
,即0
,计算结果为false,终止for
循环。可以这样重写
for (p = str; *p != '\0'; p++)
{
// Code
}
在C语言中,字符串必须始终以空字符结尾,这与“\0”或
0
相同,如果两个之间有任何内容,则for循环将终止语句中的code>为零(false)*p
取消对p的引用并返回char
,p
指向。根据“C将字符串视为字符数组,通常以标记终止”。该标记是(ASCII)值为零的空字符。所以,这个for循环:
for (p = str; *p; p++)
相当于这些
for (p = str; *p != '\0'; p++)
for (p = str; *p != 0; p++)
for (p = str; p[0] != '\0'; p++)
空终止字符的另一个名称是sentinel或根据Donald Knuth的“虚拟值”(计算机编程艺术,第1卷)。以下是str
字符串、每个字符的索引(从开始的偏移量)以及每个索引处的值的图表:
为完整起见,在请求注释后,调试器在str
占用的内存块中看到了以下内容:
0x00007fffffffe6a0:
0x53 0x6f 0x6d 0x65 0x20 0x54 0x65 0x78 0x74 0x00 0x00 0x00 0x00 0x00 0x00 0x00
S o m e T e x t
第一行的十六进制值是该内存块的地址(64位)。这就是p
指向for循环开始处的位置
在第二行,您可以看到字符串中字母的十六进制值。您可以看到一个ASCII表。字符串中的最后一个字符是t
,十六进制值为0x74
。在此之后,您将获得字符串的空字符0x00
。然后您会看到更多的空字符,因为我是在调试模式下构建的,编译器零初始化。通常您会看到垃圾(看似随机的值)
在第三行,我添加了字符串的字符以供参考
我知道你现在正处在C语言指针的学习过程中,但最终你将能够说“I C the point”
如图所示,for
循环以*p
开头,其中p
指向str
。此时,*p
具有S
当连续循环for
时,它最终到达str[9]
,它有'\0'
,意思是NULL
此时,for(p=str;*p;p++)
中的条件语句*p
等于NULL
,因此代码将从for
循环中中断。让我们以干燥但深入的方式分析它吧!
或者就像D.里奇所说的:让我们一起做吧
我将通过参考ISO/IEC:9899(emphasis mine)-C99标准来解释所有必要的方面。 (这篇文章的风格源于唐纳德·克努特(Donald Knuth)的一句话:“科学是我们能够很好地向计算机解释的东西。艺术是我们所做的一切。”) 首先,让我们检查一下-循环的
到底应该做什么!
参考ISO/IEC:9899 6.8.5“迭代声明”
语义学
4迭代语句导致称为循环体的语句反复执行,直到控制表达式比较为0
到目前为止,我想没有什么新鲜事,让我们开始吧:
6.8.5.3报表格式
1声明
for(第1条;表达式-2;表达式-3)语句
行为如下:表达式expression-2是控制表达式,在循环体的每次执行之前对其进行评估
因此,我们现在知道,只要您的*p
的预先评估值不为零,主体(在您的示例中为//code
)将被执行
。。。表达式表达式-3在循环体每次执行后作为无效表达式进行计算。[…]
所以现在我们知道,(我假设挖掘p++
的定义是没有必要的?!)对于每个迭代p
增量,因此*p
可能会有变化
下面这一点是不相关的,但我添加它是因为这使得for
的语义部分完整,而且很清楚,因为这就是原因,为什么for(;;)
是一个inf循环
2(---)第1条和表达式-3均可省略。省略的表达式-2替换为非零常量
好的,这就是for
循环在您的案例中所做的枯燥但信息丰富的部分
现在让我们来讨论指针算法:
6.5.6加法运算符
约束条件
2对于加法,两个操作数都应为算术类型,或者一个操作数应为指向对象的指针,另一个操作数应为整数类型。(递增等于加1。)
因此,在您的例子中,您将向“指向对象的指针”类型添加1(整数)
什么是等价物
0x00007fffffffe6a0:
0x53 0x6f 0x6d 0x65 0x20 0x54 0x65 0x78 0x74 0x00 0x00 0x00 0x00 0x00 0x00 0x00
S o m e T e x t
for (p = str; *p; p++)
p = &str[0];
p = str;
char str[128] = "Some Text";
#include <stdio.h>
int main() {
char str[128] = "We all scream for ice cream!";
char *p = str;
// here we see again the loop exit condition *p == '\0'
while(*p) {
printf("%c", *p);
p++;
}
printf("\n");
}
for( initialization ; Conditional Expression ; expression3)
{
Code here will execute while 2nd Expression(Conditional Expression) is true
true means non-zero value
'\0' is equivelant to 0,so when *p equal '\0' : loop will terminate
}
int var=0;
int *p;
int p=&var;
int array[3]={9,8,7};
printf("%d",array[0]); //prints what is on 1st position,9
printf("%d",array[1]); //prints what is on 2nd position,8
printf("%d",array[2]); //prints what is on 3rd position,7
printf("%d",*(array+0)); //prints what is on 1st position,9
printf("%d",*(array+1)); //prints what is on 2nd position,8
printf("%d",*(array+2)); //prints what is on 3rd position,7
char str[128] = "Some Text";
char *p;
for (p = str; *p; p++)
{
printf("%c",*p);
}
if(expr)
if((expr) != 0)
WHY for (p=str; *p; p++)
IS for (p=str; p[0] != 0; p++)
THINK for (i=0; str[i]; ++i)