【问题标题】:Why can't you change characters using pointers?为什么不能使用指针更改字符?
【发布时间】:2021-11-05 18:22:08
【问题描述】:

最近我得到了一本 C 编程语言书。 在第 95 页有一个 strcpy 函数的实现。

void strcopy(char *s, char *t) {
    while(*s++ = *t++) 
        ;
}

int main(int argc, char *argv[]) {
    char *hello = "hello";
    char *world = "world";

    strcopy(hello, world);
    return 0;
}

我尝试自己实现它,但是在(成功)编译之后

gcc -o c_lang c_programming_lang_exercises.c

并尝试运行它

./c_lang

我收到以下错误消息:

zsh: bus error

我尝试了不同的实现,但不知何故这对我不起作用。

也许有人知道为什么?

感谢您的帮助:)


编辑: 为了我自己的理解,如果我错了,请纠正我。 在函数中调用“strcopy(hello, world);”我在这里传递指针本身的值,所以我用这样的东西调用函数:strcopy(0x123a4,0x234859b)。现在 C 不认为 this 是变量,因此它的值被复制并传递给函数。 在 strcopy 函数本身中,我无法取消引用它,因为我只是获取指针的值。

我应该做的是传递地址,指针引用,这样我就可以取消引用strcopy函数中的值并访问正确的内存地址。

另一个错误可能是我声明的主函数char *hello = "hello",据我所知,它称为字符串常量,因此不可修改。

所以,如果我的假设是正确的,下面的代码应该可以工作:

void strcopy(char *s, char *t) {
    //code goes here...
}
int main(int stringc, char *argv[]) {
    char hello[] = "hello";
    char world[] = "world";
    strcopy(&hello, &world);
    return 0;
}

它可以工作,但我收到以下编译器警告:

 incompatible pointer types passing 'char (*)[6]' to parameter of type 'char **' [-Wincompatible-pointer-types]
    strcopy(&hello, &world);

【问题讨论】:

  • 请说明您是如何在代码中调用该函数的。
  • 你要传递什么给s?字符串文字?请以文本形式发布Minimal Reproducible Example,这是显示问题的最短完整代码。
  • 另请注意,您发布的代码有一个额外的{
  • 你应该发帖minimal reproducible example如果按预期使用,该功能本身将起作用。
  • 请注意,您的函数不符合该名称的 C 标准库函数。一方面,它应该返回传递的目标指针。

标签: c pointers


【解决方案1】:

C 在类型方面做出了非常糟糕的让步,这与历史原因有关。

main() 中,您将字符串声明为:

char *hello = "hello";

您应该做的是将警告级别waaaay 调高并重新编译。问题是"hello" 是一个字符串literal——它不能被修改。它应该声明为:

const char *hello = "hello";

(打开警告会告诉你这一点。)

因此,您试图将字符复制到只读内存中,这在现代处理器和现代编译器上是不允许的——这会产生访问冲突。 Zsh 替你抱怨。

相反,请确保您对从只读内存复制的本地数组具有写入权限:

char hello[] = "hello";

是的,它创建了一个本地 可变 数组,该数组有六个字符长(五个字符用于单词“hello”加上一个用于空终止符)并从只读内存自动初始化。

这是在 C 中声明的东西经常让初学者感到困惑的微妙症结之一:

  • const char * s = "Hello world!"; — 指向 ROM 的指针
  • char s[] = "Hello world!"; — 从 ROM 初始化的本地可变数组

就是这样!

【讨论】:

    猜你喜欢
    • 2013-01-26
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多