通过查看此代码示例:
/* strrchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a sample string";
char * pch;
pch=strrchr(str,'s');
printf ("Last occurence of 's' found at %d \n",pch-str+1);
printf("pch number: %d \n str number: %d", pch, str);
return 0;
}
输出如下:
Last occurence of 's' found at 18
pch number: -8575
str number: -8592
我不明白,pch
和str
有多少号码以及%d
printf()
下的转换似乎是什么。这是内存单元格的数量,其中指向第一个字符的指针位于str
的情况下)?如果是,为什么str
大于pch
?它应该代表指向第一个字符串字符的指针,不应该吗?最后,为什么我们在+1
中需要pch-str+1
?
添加:这不是我的代码(第二个printf()
除外)。我在cplusplus.com上找到了它,正在寻找strrchr()
引用。
答案 0 :(得分:2)
pch和str是指针。它们包含字符串内存中的地址和最后一个字符。 (这就是为什么他们的差异为18)
您没有正确打印它们,所以您没有看到整个地址。做%p而不是%d(告诉编译器这些是指针)
pch - str + 1有效,因为您可以添加和减去地址。它们只是非常大的数字,但是当你减去它们时,你可以获得较小的数字(100001 - 100000 = 1)。编译器知道它们是指针所以'做对了'。为什么printf'做正确的事情'?,因为printf的工作方式是在程序运行时使用%d,编译器不知道发生了什么。实际上这是谎言,大多数现代编译器都知道printf行为,并将查看格式字符串以查看它是否正常。如果您正确设置编译器选项,它将警告您在指针上执行%d
答案 1 :(得分:1)
str
和pch
不会自行存储值;它们指向到内存中的某个位置,因此它们的值实际上是它们指向的内存中的地址。
在计算机科学中,指针是一种编程语言对象,其值指的是(或“指向”)使用其地址存储在计算机内存中其他位置的另一个值。指针引用一个位置在内存中,获取存储在该位置的值称为解除引用指针。作为类比,书籍索引中的页码可以被认为是指向相应页面的指针;取消引用这样的指针将通过翻转到具有给定页码的页面来完成。
结果是绝对自然的:来测试这个,你必须理解2的补码是如何工作的:让我们以维基百科提供的例子为例:
Binary Unsigned 2's complement
011 3 3
010 2 2
001 1 1
000 0 0
111 7 -1
110 6 -2
101 5 -3
100 4 -4
我想告诉你的是,最大的无符号二进制值被映射到2的补码中的最大负值。
要解决此问题,请按以下步骤更改您的程序:
/* strrchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a sample string";
char * pch;
pch=strrchr(str,'s');
printf ("Last occurence of 's' found at %ld \n",pch-str+1);
printf("pch number: %ld \n str number: %ld", pch, str);
return 0;
}
您需要做的唯一更改是将%d
更改为%ld
,因此,程序将打印int
值,而不是long int
值。
当我测试这段代码时,我得到了:
Last occurence of 's' found at 18
pch number: 140735717807905
str number: 140735717807888
然而,打印指针最典型和最正确的方法是使用%p。
/* strrchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a sample string";
char * pch;
pch=strrchr(str,'s');
printf ("Last occurence of 's' found at %p \n",pch-str+1);
printf("pch number: %p \n str number: %p", pch, str);
return 0;
}
打印哪些:
Last occurence of 's' found at 0x12
pch number: 0x7fffdcf2b3f1
str number: 0x7fffdcf2b3e0
回答你的上一个问题:
最后,为什么我们在pch-str + 1中需要+1?
让我们看一个例子:
strings
1-----7
所以让我们假设pch等于7而str等于1. pch - str
结果会产生6,所以我们需要递增该值以显示最后s
的位置
答案 2 :(得分:0)
您的代码会导致未定义的行为。 Traceback (most recent call last):
File "/var/lib/ambari-agent/cache/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py", line 120, in <module>
HdfsClient().execute()
File "/usr/lib/python2.6/site-packages/resource_management/libraries/script/script.py", line 219, in execute
method(env)
File "/var/lib/ambari-agent/cache/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py", line 36, in install
self.configure(env)
File "/var/lib/ambari-agent/cache/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py", line 41, in configure
hdfs()
File "/usr/lib/python2.6/site-packages/ambari_commons/os_family_impl.py", line 89, in thunk
return fn(*args, **kwargs)
File "/var/lib/ambari-agent/cache/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py", line 61, in hdfs
group=params.user_group
File "/usr/lib/python2.6/site-packages/resource_management/core/base.py", line 154, in __init__
self.env.run()
File "/usr/lib/python2.6/site-packages/resource_management/core/environment.py", line 152, in run
self.run_action(resource, action)
File "/usr/lib/python2.6/site-packages/resource_management/core/environment.py", line 118, in run_action
provider_action()
File "/usr/lib/python2.6/site-packages/resource_management/libraries/providers/xml_config.py", line 67, in action_create
encoding = self.resource.encoding
File "/usr/lib/python2.6/site-packages/resource_management/core/base.py", line 154, in __init__
self.env.run()
File "/usr/lib/python2.6/site-packages/resource_management/core/environment.py", line 152, in run
self.run_action(resource, action)
File "/usr/lib/python2.6/site-packages/resource_management/core/environment.py", line 118, in run_action
provider_action()
File "/usr/lib/python2.6/site-packages/resource_management/core/providers/system.py", line 87, in action_create
raise Fail("Applying %s failed, parent directory %s doesn't exist" % (self.resource, dirname))
resource_management.core.exceptions.Fail: Applying File['/usr/hdp/current/hadoop-client/conf/hadoop-policy.xml'] failed, parent directory /usr/hdp/current/hadoop-client/conf doesn't exist
函数不是“魔术”:它不知道你传入的参数类型是什么。你有责任给出正确的格式说明符,然后是printf
函数将知道内存中的内容以及要读取的字节数以获取该格式的值。
如果你做不匹配然后发生任何事情,该函数会读取错误的区域并且你得到的垃圾可能与你传入的值完全无关(或者其他任何事情也可能发生)。
在您的代码中,匹配的格式说明符为printf
的{{1}},"%td"
的{{1}}和pch - str + 1
的{{1}}。虽然我不清楚你希望在第二行打印出什么。
答案 3 :(得分:0)
pch
是字符串中最后一个s
的地址。 str
是字符串开头的地址。 pch-str
是str
和pch
之间的字节数,它是字符串中s
的位置。你添加1
是因为你希望结果是基于1的,就像普通人想的那样,而不是基于0的计算机思维方式(所以如果s
是第一个字符,它会说found at 1
1}},而不是found at 0
)。
正如其他人所说,打印pch
和str
时获得奇怪值的原因是因为您使用了错误的printf
格式运算符。您应该使用%p
来打印指针。
答案 4 :(得分:0)
“这是否就像内存单元格的数字,指向第一个字符的指针(如果是str)?如果是,为什么str大于pch?” - &GT;就像问你为什么你的家庭住址大于你朋友的家庭住址,即使你住在同一条街上。有简单的地址。
pch - str + 1
中的+1可能是因为作者喜欢从1开始计算字符串中的位置。在C中从0开始更加惯用,因此:pch - str
。
使用匹配修饰符/说明符。
char str[] = "This is a sample string";
char * pch;
pch = strrchr(str,'s');
// pointer subtraction results in type `ptrdiff_t`. Use `t`
printf("Last occurrence of 's' found at %td \n", pch - str);
// Use p and add cast to `void *`
printf("pch number: %p \n str number: %p", (void *) pch, (void *) str);