我一直在阅读关于指针和指针的一些事情,并开始变得好奇。我唯一不理解的是指针在函数中的行为,因此代码如下:
#include <stdio.h>
int pointeeChanger(char* writeLocation) {
writeLocation = "something";
return 0;
}
int main(void)
{
char crypted[] = "nothing";
char* cryptedPointer = crypted;
pointeeChanger(cryptedPointer);
printf("The new value is: %s", cryptedPointer);
return 0;
}
我打算做的是通过给定函数的指针来调整指针“crypted”var。唯一的问题是它不起作用。能否请您解释一下我的思考过程中出了什么问题。我对C很新,所以我的错误可能非常基本。
提前致谢!
问候,
Kipt Scriddy
答案 0 :(得分:4)
C字符串不是学习指针的最佳材料,因为它们是作为char
的指针实现的。我们改用int
:
#include <stdio.h>
void pointeeChanger(int* writeLocation) {
// Using dereference operator "*"
*writeLocation = 42; // something
}
int main(void) {
int crypted = 0; // Nothing
pointeeChanger(&cryptedPointer); // Taking an address with "&"
printf("The new value is: %d", crypted);
return 0;
}
这可以按预期工作。
修改字符串要困难得多,因为您不得不处理内存管理问题。具体而言,您复制到的字符串必须分配足够的空间以适合新字符串。这不适用于“无”和“某事”,因为替换时间长了两个字符。
答案 1 :(得分:3)
简答:writeLocation
是一个局部变量,是cryptedPointer
的副本。修改writeLocation
时,cryptedPointer
未被修改。
如果要修改cryptedPointer
,则必须将指针传递给它,如下所示:
#include <stdio.h>
int pointeeChanger(char** writeLocation) { /* Note: char** */
*writeLocation = "something"; /* Note: *writeLocation */
return 0;
}
int main(void)
{
char crypted[] = "nothing";
char* cryptedPointer = crypted;
pointeeChanger(&cryptedPointer); /* Note: &cryptedPointer */
printf("The new value is: %s", cryptedPointer);
return 0;
}
此代码还存在其他问题。致电pointeeChanger()
后,cryptedPointer
不再指向crypted
数组。我怀疑你确实想要改变那个数组的内容。这段代码无法做到这一点。
要更改crypted[]
的值,您需要使用strcpy()
或(最好)strncpy()
。此外,您需要观察crypted[]
数组的大小 - "something"
超过"nothing"
并且会导致缓冲区溢出,除非crypted[]
变大。
此代码将修改原始crypted[]
数组:
#include <stdio.h>
#include <string.h>
#define MAX_STR_LEN 64
/*
* Only char* required because we are not modifying the
* original pointer passed in - we are modifying what it
* points to.
*/
int pointeeChanger(char* writeLocation)
{
/*
* In C, you need to use a function like strcpy or strncpy to overwrite a
* string with another string. Prefer strncpy because it allows you to
* specify a maximum size to copy, which helps to prevent buffer overruns.
*/
strncpy(writeLocation, "something", MAX_STR_LEN);
/* strncpy doesn't automatically add a \0 */
writeLocation[MAX_STR_LEN] = '\0';
return 0;
}
int main(void)
{
/*
* The +1 is because an extra character is required for the
* null terminator ('\0')
*/
char crypted[MAX_STR_LEN + 1] = "nothing";
pointeeChanger(crypted);
printf("The new value is: %s", crypted);
return 0;
}
答案 2 :(得分:2)
这取决于你实际想做什么:
是否要更改cryptedPointer
指向的内容,或更改cryptedPointer
指向的内容?
第二个可以通过以下方式完成:
strcpy(writeLocation, "something");
请注意,如果something
长于原始字符串的大小,则会溢出缓冲区,这是一件坏事。所以要解决这个问题,你必须要char crypted[10] = "nothing";
,为字符串“某事”腾出空间。
您显然也可以执行以下操作:
writeLocation[2] = 'f';
writeLocation[3] = 'f';
并让printf
打印“noffing”
但是如果你想做第一个变种,那么你需要传递一个指向指针的指针:
int pointeeChanger(char** writeLocation) {
*writeLocation = "something";
return 0;
}
然后致电:
pointeeChanger(&cryptedPointer);
请注意,当这返回时,cruptedPointer
指向一个无法修改的常量字符串,可以修改原始crypted
。
答案 3 :(得分:1)
考虑一下汤姆被萨利雇用来打破黑手党的指关节。
价值传递:如果莎莉告诉汤姆计算他今天上班的指关节的数量,那么莎莉无法知道汤姆在他从路上回来之前想出的那个号码。他们的头脑中都有一个“零”的副本,但汤姆的数字可能会在一天中增加。
注意“复制”一词。当您将值传递给函数时,您将传递该对象的副本。在函数中修改对象时,您将修改副本而不是原始副本。
传递参考:如果Sally告诉Tom计算他在天空中打破的关节数,那么她(以及其他任何感兴趣的人)可以参考天空。通过改变天空,汤姆也将改变莎莉的号码。
编辑:C没有传递引用,虽然它有指针,它们是引用类型。传递指针仍然是按值传递,并且仍然形成具有相同指针值的副本。因此,您的作业是复制,而不是原件。