void buggy_substring(char *input, size_t pos, size_t len)
{
input += pos;
input[len] = '\0';
}
int main(int argc, char *argv[])
{
char name[16];
strcpy(name, "Tessier-Lavigne");
buggy_substring(name, 3, 2);
printf("%s\n", name);
return 0;
}
为什么这样打印“ Tessi”而不是“ si”? 这是将size_t与char混合的问题吗?
答案 0 :(得分:2)
仅在功能中更改开始位置。但是,在打印时,您仍然会将字符串的原始开头传递给printf。
尝试将name + 3传递给printf。
int main(int argc, char *argv[])
{
char name[16];
// allocated a buffer of 16 bytes on the stack (called name)
// note that an array of chars and a pointer to a char is NOT the same thing
strcpy(name, "Tessier-Lavigne");
// copies from a const null-terminated string
// now char* name contains
// ['T','e','s','s','i','e','r','-','L','a','v','i','g','n','e','\0']
buggy_substring(name, 3, 2);
// name is passed as an immutable number "by value",
// the value of name is not changed
// however, the contents name points to can be
// now name is
// ['T','e','s','s','\0','e','r','-','L','a','v','i','g','n','e','\0']
printf("%s\n", name);
//output 'T','e','s','s' + new line
return 0;
}
void buggy_substring(char *input, size_t pos, size_t len)
{
//local pointer input
// points to ['T','e','s','s','i','e','r','-','L','a','v','i','g','n','e','\0']
//pos=3
//len=2
input += pos;
// input points to 's' (original name still points to 'T'
input[len] = '\0';
//equivalent code
char * p=input;
p+=len;
*p='\0';
// input+2 points to 'i'
// 'i' is replaced with zero
// the original buffer looks like
//['T','e','s','s','\0','e','r','-','L','a','v','i','g','n','e','\0']
}
免责声明:当然,您应该使用库字符串操作函数来编写更严肃的代码,并且不要尝试重新发明轮子。
答案 1 :(得分:1)
C是一种按值传递的语言。您的子字符串函数中的input += pos
不会更改name
中的main
。
答案 2 :(得分:1)
您需要将指针传递给指针,以便修改 pointer 而不是被引用的对象。
void substring(char **input, size_t pos, size_t len)
{
*input += pos;
(*input)[len] = '\0';
}
如果您将指针传递给数组char (*pa)[]
答案 3 :(得分:0)
由于C是传递值,因此将作为参数提供的值的副本绑定到函数调用中的形式参数上。这意味着在buggy_substring()
中,input
是name
中main()
标识的指针值的副本。 (当然,name
是char
的数组,在函数调用中它会衰减为指向char
的指针。)
由于input
只是name
(指针)的副本,因此对input
(指针)的任何更改都不会影响name
的值在main()
中。但是,input
仍与name
指向内存中的相同位置,因此通过 input
(指针)进行的更改会影响指向的相同内存区域通过name
(指针)。
所有这一切的结果是,当input
的值增加时,它不再指向与name
(指针)相同的存储位置。递增的指针可用于通过input[len] = '\0'
写入内存,但是当buggy_substring()
函数返回时,input
的生存期结束(input
是自动变量),返回main()
时name
保持不变。因此,当调用printf()
时,从头开始打印到新插入的name
所指向的字符串(指针:记住,数组标识符在大多数情况下会衰减到指向其第一个元素的指针)。空终止符。