如何在函数中创建指针更改C中的指针

时间:2013-02-12 01:35:49

标签: c pointers

嘿,伙计们,

我一直在阅读关于指针和指针的一些事情,并开始变得好奇。我唯一不理解的是指针在函数中的行为,因此代码如下:

#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

4 个答案:

答案 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没有传递引用,虽然它有指针,它们是引用类型。传递指针仍然是按值传递,并且仍然形成具有相同指针值的副本。因此,您的作业是复制,而不是原件。