【问题标题】:How to operate C pointer如何操作C指针
【发布时间】:2014-04-17 09:31:21
【问题描述】:

我不擅长指针。

这是一个指针示例程序

int sample(){
        char* a;
        char* b;
        char* *c;
        a = &*c;
        b = &*c;
        *c = "abcd";
        printf("a = %s\n",a);
        printf("b = %s\n",b);
        printf("c = %s\n",*c);
        return 0;
}

编译时出现警告。

warning: assignment from incompatible pointer type

结果如下。

a = 
b = abcd
c = abcd

有人告诉我为什么a 没有显示任何值,而b 显示与c 相同的值吗?

a 如何显示与c 相同的值?

【问题讨论】:

  • 你用什么编译这个?因为我尝试过,它编译时带有 2 个警告,当我运行它时,它给了我一个分段错误。
  • 为 *c 分配一些空间。将 a = &*c 替换为 a = *c 和类似的 b。从一些可以帮助您想象正在发生的事情的好书中阅读 C 指针的基础知识。

标签: c string pointers char memory-address


【解决方案1】:
char *a;

以上语句将a定义为指向字符的指针,即可以存储字符的地址。

char **c;

上面的语句将c定义为一个指向字符的指针,即可以存储指向字符类型的指针的地址,即char *变量。

a = &*c;
// equivalent to
a = &(*c)
// equivalent to
a = c;

cchar ** 类型,而 achar * 类型 - 一个不同的类型。 这些类型是不兼容的类型,可以解释警告消息 -

warning: assignment from incompatible pointer type

变量c是未初始化的,这意味着它包含垃圾值,即它的值是不确定的。

*c = "abcd";

上述语句的意思是指向字符串文字"abcd"的第一个字符的指针存储在c指向的位置,但c的值是垃圾。 取消引用未初始化的指针是未定义的行为。未定义的行为意味着不可预测的行为。即使它看起来可行,从程序崩溃到您的硬盘被格式化,任何事情都可能发生。因此,对调用未定义行为的代码进行推理是没有意义的。该标准对处理此类情况的实现没有要求,您应该始终避免它们。

阅读这些 -

  1. Common undefined behaviour
  2. Undefined behaviour and sequence points

【讨论】:

    【解决方案2】:

    a 是一个没有值的未初始​​化变量。

    b 是一个没有值的未初始​​化变量。

    c 是一个没有值的未初始​​化变量。

    &* 在 C 语言中有一条特殊规则:如果语法正确,则 &* 不执行任何操作。所以&*cc 相同。 c的类型和a的类型不一样,所以赋值是非法的。对b 的分配也是如此。好的编译器或具有正确设置的编译器拒绝编译而不是给你一个警告。

    *c = "abcd":由于c 是一个未初始化的变量,分配给*c 是未定义的行为。如果幸运的话,您的程序会崩溃。如果您不走运,它可以在您的开发机器上运行,并且在客户使用该软件时崩溃并造成重大损害。

    【讨论】:

      【解决方案3】:

      您的代码具有未定义的行为。您没有为 c 指向的指针保留任何空间,但仍在访问它。

      【讨论】:

        【解决方案4】:

        你将a,它是char的指针,分配给c,它是char的指针。这里有不同级别的指针,你的警告也是如此。取&*c 与C 中的c 相同。

        因此,当您执行该行时,您尝试读取地址为c 的字符串,而不是地址*c(这是“abcd”的实际地址)

        printf("a = %s\n",a);
        

        【讨论】:

          【解决方案5】:

          首先a = &*cb = &*c是非法指针转换,所以你可能想要a = *c。其次,您甚至无法在初始化之前将*c 分配给a。因此,例如,这是合法的:

          *c = "abcd";
          a = *c;
          b = *c;
          

          这也是合法的:

          char **a = c;
          *c = "abcd";
          

          【讨论】:

          • 我知道&*c 是非法的。但我希望ab 指向c 的同一地址并引用c 中的值,以便c 中的值可能在过程中发生变化。所以我不想更改*c = “abcd” 的订单。即使我一开始做memset(&a, 0, sizeof(a)); memset(&b, 0, sizeof(b)); memset(&(*c), 0, sizeof(*c)); 还是灌胃吗?
          • 你不能用固定的a 来代表正在发生变化的东西。 'a' 是一个局部变量,*c 是内存中的一个位置。但是,您可以将a 设为像c 这样的指针,然后它可以引用相同的位置。您不能将别名用于事先不知道的内存位置。
          猜你喜欢
          • 1970-01-01
          • 2011-05-02
          • 2011-04-17
          • 2015-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-05
          相关资源
          最近更新 更多