我有以下函数用于计算字符串中的空格:
int countSpace(char *str) {
int nSpaces = 0;
while (*(str) != '\0') {
if (*(str) == ' ') {
nSpaces++;
}
str++;
}
return nSpaces;
}
我使用这个函数:
char a[]="Hello ";
printf("%d", countSpace(a));
我的问题是,当我这样做:printf("%s", a);
,在调用countSpace之后,为什么a
没有指向最后?我的意思是,我已经在countSpace函数内增加了指针,但外面似乎仍然指向了最开始。那是为什么?
我知道我在countSpace函数中的* str中所做的更改会影响外部,所以如果我这样做:str[0] = 'p'
,在函数之外,a的值将是{{1 }}。所以,我不明白为什么指针仍然指向一开始,即使在我使其向前移动的函数内部。
答案 0 :(得分:4)
因为C按值传递参数
int countSpace(char *str)
^^
This pointer is a copy of the pointer you pass in.
最初,您的str
变量指向与您指针相同的内容
传递给你的函数,但在countSpace()里面你只是增加了该指针的本地副本。
答案 1 :(得分:1)
C是按值传递,所以当你将指针传递给countSpaces
时,它会复制指针的值(请注意,只是指针不是它是什么的指着)。就像任何其他本地值一样:在函数内部对其进行的任何更改都不会反映在外部。
在函数外部可以看到对函数内部指针所指向的内容的任何更改。
例如:我们取a
的地址,将其存储在指针p
中并将其打印为指针(以查看它所拥有的内存地址):
char * p = a;
printf(" p = %p\n", p); // This will not print the string, but the address where it starts
并将其传递给countSpaces
(这相当于将a
传递给countSpaces
):
countSpaces(p);
现在在里面,打印str
作为指针:
printf(" str: %p\n", str);
你会看到两个值都是相同的,这是有意义的,因为它被复制到countSpaces
。但是,如果您打印p
(countSpaces
之外)的地址和str
(内部)的地址。你会发现它们是不同的:
printf("&str: %p\n", &str);
printf("&p: %p\n", &p);
因此,countSpaces
可以更改str
和p
(和a
)指向的内容,但不能更改指针本身:它们是复制到新变量。
答案 2 :(得分:1)
函数不会更改变量a。
了解内存中变量和值的位置有助于理解指针发生的情况。以及稍后帮助调试。
执行a和str的%p printf,你会看到他们指向的内存地址。
printf("a var %p", &a);
printf("a content %p", a);
printf("str var %p", &str);
printf("str content %p", str);
假设婴儿2字节int和ptrs。
,内存中存在事物的示例# c compiler/linker will put string values in global memory
#Addr #Value
#0020 Hello \0
#0027 %d\0
#0030 . .
堆栈内存。 var a在堆栈mem中(假设在main函数的堆栈中)(实际上编译器可以将vars放入寄存器但产生相同的结果)
#stack-main a is a char ptr.
#&a=0100, value of a=0020
#Addr #Value
#0100 0020
#when countSpaces is just called
#code return addr pushed to stack
#Addr #Value
#0102 0222
#space on stack for return of int
#0104 0000
#value of a put on stack (this is str)
#0106 0020
#local vars of countSpaces
# int nSpaces
#0107 0000
在countSpaces返回堆栈后看起来像:
#&a=0100, value of a=0020
#Addr #Value
#0100 0020
#Addr #Value
#code return addr
#0102 0222
#space on stack for return of int
#0104 0001
#value of a put on stack (this is str)
#0106 0026
#local vars of countSpaces
# int nSpaces
#0107 0001
答案 3 :(得分:0)
str
是传递给函数参数列表的指针的副本。它与int
参数没有区别。
因此,a
保持不变。
答案 4 :(得分:0)
str
是指向字符串的指针,并通过值传递给函数。
当您在函数内部更改str
时,从函数外部传递的原始变量不会更改。
当然,str
是一个指针,它允许您更改它指向的char
。
如果要从函数内部更改 outside str
,则必须将指针传递给str
,换句话说,指向指向字符串的指针(第一个字符)。
代码变为:
int countSpace(char **str) {
int nSpaces = 0;
while (**(str) != '\0') {
if (**(str) == ' ') {
nSpaces++;
}
*str++;
}
return nSpaces;
}
像这样使用这个函数:
char a[]="Hello ";
printf("%d", countSpace(&a));