【问题标题】:C function change string using pointerC函数使用指针更改字符串
【发布时间】:2014-10-29 09:34:27
【问题描述】:

我正在尝试创建一个从主函数更改 char 数组的函数,这就是我想要做的:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

void change(char *a);

int main()
{
    char a[] = "hello";
    printf("\na = %s", a);
    change(a);
    printf("%\na = %s", a);
    getch();
}

void change(char *a)
{
    a = "goodbye";
}

【问题讨论】:

  • main 中,a 是一个数组。你所能做的就是修改它的内容。您当然不能将长度为 8 的数组放入其中,因为它只有 6 个空间。
  • 你的问题是什么?
  • 你需要决定是修改数组,还是修改指向数组的指针

标签: c string function


【解决方案1】:

主要问题是您通过这样做发送了 char 指针 a 的副本:

void change(char *a)
{
    a = "goodbye";
}

如果你想改变另一个函数中的值,你应该这样做:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

void change(char **a);

int main()
{
    char *a = "hello";
    printf("\na = %s", a);
    change(&a);
    printf("%\na = %s", a);
    getch();
}

void change(char **a)
{
    *a = "goodbye";
}

【讨论】:

  • 您的“更改”函数与函数原型不匹配。
  • 这似乎行得通。我不清楚为什么 char a[] 必须改为 char*。
【解决方案2】:

这段代码有几个问题,但首先我们需要退后一步,谈谈如何在 C 中处理数组。

除非它是 sizeof 或一元 &amp; 运算符的操作数,或者是用于在声明中初始化另一个数组的字符串字面量,否则“T 的 N 元素数组”类型的表达式将被转换(“decay”)为“pointer to T”类型的表达式,表达式的值将是数组第一个元素的地址。

在声明中

char a[] = "hello";

"hello" 是一个字符串文字,其类型为“char 的 6 元素数组”(5 个字符加上 0 终止符)。因为它被用来在声明中初始化数组a,所以上面的规则不适用;相反,a 的大小设置为与字面量 (6) 的大小相同,并将字符串字面量的内容复制到数组中。

当您从main 呼叫change

change(a);

表达式 a 的类型为“char 的 6 元素数组”。由于它既不是字符串文字,也不是sizeof 或一元&amp; 运算符的操作数,因此该表达式将转换为“指向char”的类型,表达式的值将是第一个地址元素。因此change 函数被声明为

void change(char *a);

在这种情况下,a 只是一个指针。当你写

a = "goodbye";

字符串文字"goodbye" 没有在初始化程序中使用,它不是sizeof 或一元&amp; 运算符的操作数,因此表达式被转换为类型“指向char”的指针,并且表达式的值是第一个字符的地址。所以这里发生的情况是,您将字符串文字"goodbye"地址 复制到a。这将覆盖a 中的值,但此amain 中的array a 不是同一个内存对象,因此对它的任何更改都不会反映在@987654352 中@。

如果您想更新数组的内容,您将需要使用库函数strcpy/strncpy(用于以0 结尾的字符串)或memcpy(用于其他所有内容),或者显式更新每个元素(a[0]='g'; a[1]='o'; a[2]='o'; 等)。

要更新a 的内容,您可以使用

strcpy( a, "goodbye" );

除了...

a 只能容纳 5 个字符和一个 0 终止符; "goodbye" 是 7 个字符加上 0 终止符;它比a 能够存储的字符大两个字符。 C 将很乐意让您执行操作并立即丢弃a 之后的字节,这可能会导致任何数量的问题(像这样的缓冲区溢出是典型的恶意软件利用)。此时您有两个选择:

首先,您可以声明 a 大到足以处理任一字符串:

#define MAX_LEN 10
...
char a[MAX_LEN] = "hello";

其次,可以限制复制到a的字符串大小:

void change( char *a, size_t size )
{
  strncpy( a, "goodbye", size - 1 );
  a[size - 1] = 0;
}

请注意,当您调用change 时,您需要传递a 可以存储为单独参数的元素数量;没有办法从指针告诉它指向的数组有多大:

change( a, sizeof a / sizeof *a ); // although in this case, sizeof a would be
                                   // sufficient.

【讨论】:

    【解决方案3】:

    我更改了功能,现在它可以这样工作了:

    void change(char *a)
    {
        strcpy(a, "goodbye");
    }
    

    【讨论】:

    • 大卫在看着你:)
    • 记住:有效!= 好
    猜你喜欢
    • 2021-02-24
    • 2013-11-10
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2016-10-12
    • 1970-01-01
    相关资源
    最近更新 更多