我有一个像这样的字符串:
char* hello = "Hello, world!";
我必须循环遍历此字符串中的每个字符.我试过这些,但他们要么给我编译错误,要么访问违规,或者只是永远不要离开循环:
for( char* p = hello; p!=0; p++ ) printf("%x\n", p); for( char* p = &hello; p!=0; p++ ) printf("%x\n", p); for( char* p = *hello; p!=0; p++ ) printf("%x\n", p); for( char* p = hello; *p!=0; *p++ ) printf("%x\n", *p);
我真的不明白指针在C中是如何工作的,我只是随机地放置星号直到它起作用,在这种情况下它不会.
我没有strlen
像其他问题一样使用.
p
是一个指针char
.因此,取消引用它会*p
产生一个char
.
添加1可p
将其移动到您正在遍历的任何字符串中的下一个字符.添加1以*p
向字符添加一个p
指向.
让我们仔细检查每一次尝试,看看它有什么问题.
char* hello = "Hello, world!";
公共部分:hello
是一个指针char
,它指向一个常量字符串,编译器将嵌入到目标文件中的某个位置.请注意,不应更改此类字符串; 这样做通常会出错.
如果你想要一个可以改变的字符串,那就char hello[] = "Hello, world!";
有效; 这会创建一个缓冲区作为可以自由操作的局部变量.
for( char* p = hello; p!=0; p++ ) printf("%x\n", p);
在这里,你正确地指出p
了第一个字符hello
.但是,然后通过比较p
零来查找字符串的结尾.p
是一个指针,0作为指针意味着一个NULL指针.
for( char* p = &hello; p!=0; p++ ) printf("%x\n", p);
在这里,您指向p
地址hello
,表示进程存储指针所在的任何位置hello
.取消引用这将给你hello
,而不是它指向的.
for( char* p = *hello; p!=0; p++ ) printf("%x\n", p);
在这里,你取消引用hello
,给出char
一个值为H
.分配给p
它的是类型不匹配,语义也不正确.
for( char* p = hello; *p!=0; *p++ ) printf("%x\n", *p);
在这里,最后,您正确地将哪些p
点与零进行比较.
但是,你也增加
*p
而不是p
,这是不正确的,并且(如上所述)也会导致像这样的常量字符串的问题.*p++
也将增加p
,返回p
增量前指向的内容,因为它没有被使用,所以没有实际意义.
另一件事:你想打印指针的值p
,还是char
它指向的?前三个正确打印指针.最后一个%x
用来打印char
.不确定会做什么,但这不正确.
既然你用过%x
,我假设你想用十六进制打印字符本身?那将是printf("%x\n", *p);
最后一个.但是,我建议%02x
使用零填充来获得恒定的宽度.
假设您要打印字符,这是一个正确的版本:
for( char* p = hello; *p!=0; p++ ) printf("%x\n", *p);
或者,既然0
是假的,我们可以简单地说,并且可以说:
for( char* p = hello; *p; p++ ) printf("%x\n", *p);