【问题标题】:why does it cause error when trying to give the original pointer value a new value?为什么在尝试为原始指针值赋予新值时会导致错误?
【发布时间】:2017-02-23 11:41:54
【问题描述】:

我是 C 语言的新手,我正在尝试使用如下指针。

  1. po1 定义为指向地址的指针。 PC 为其分配 1 个字节的内存。 po2 是一样的。我想得到po2指向的内存地址,却只得到一个意想不到的0,显然不是地址。

    #include <stdio.h>
    int main(int argc, char *argv[]) {
        char *po2, *po1;
        printf("---%d---\n", po2); 
        return 0;
    }
    

    输出是:

    demo11.c:5:23:警告:格式指定类型'int',但参数的类型为>'char *' [-Wformat] printf("-****--%d-****--\n", po2); ~~ ^ ~~ %s 生成 1 个警告。 -****--0-****--

  2. 然后我试图将foo 的值赋予po2 指向的内存,但它给出了错误。

    #include <stdio.h>
    int main(int argc, char *argv[]) {
        char *po2, *po1;
        char foo = 'D';
        *po2 = foo;
        printf("%c---------------\n", *po2); 
        return 0;
    }
    

    输出是:

    因信号终止:SEGMENTATION FAULT (11)

很明显,错误是由*po2 = foo语句引起的;

任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 使用%p打印指针地址值
  • @ttdado because both pointer po1 and po2 are NULL 需要注意的是,这只是第一次警告的暗示,并不是标准的保证。 printf("---%d---\n", po2); 也应该是 printf("---%p---\n", po2);
  • *po2 = foo -> po2 = &amp;foo
  • 把这个*po2 = foo;改成那个:po2 = &amp;foo;
  • 如果您使用 C 编程,您需要对指针有很好的理解。我建议你去搜索和学习。大多数人喜欢用方框和箭头来画画——我知道我喜欢。所以尝试搜索“C 指针”的图像,并阅读相关文章。时间上的投入将为您省去很多痛苦。

标签: c pointers


【解决方案1】:
  1. 您在printf() 的字符串中使用了不正确的格式说明符。 %d 专门用于整数。对于指针,您应该使用%p

    查看您收到的警告,您可以从以下位确定这一点:format specifies type 'int' but the argument has type 'char *',这基本上意味着格式说明符(%d)表示int 类型变量,但您提供了char * 类型。

  2. 当您说*po2 = foo; 时,您实际上是将foo 分配给po2指向 的任何东西,而不是分配 foo 的地址 转换为po2 本身

    首先,给指针分配地址时,不要使用*,所以第一部分变成po2 =。其次,你要分配foo的地址而不是它所持有的值,因此你应该使用“address-of”运算符,即&amp;,这样整行就变成po2 = &amp;foo;

    您当前代码给出分段错误的原因是,如前所述,您当前的代码将foo 的值分配给po2指向的任何位置。因为指针还没有被正确初始化,所以它保存了一些无效的不确定地址(通常是NULL)。因此,当 PC 试图找到这个无效地址时,它试图找到一个不存在的内存位置(例如位置 0 或位置 50 亿等)。它不能这样做,因此会导致分段错误。

您似乎误解了指针的工作原理。当您使用char *po2; 时,这会创建一个保存地址的变量。这与创建任何其他类型的变量一样,除了用于保存地址的内存之外,没有分配其他内存。因为像这样定义的指针没有被初始化,它将包含一个不确定的地址值。在某些情况下(但不是全部)该值将是NULL0,这就是为什么您的printf 在发出警告后输出0

如果您想让指针po2 指向变量foo,那么您将foo 的地址放入指针中。 po2 将持有foo 的地址,foo 仍将持有'D''D' 并没有神奇地移动到po2 指向的内存的其他部分,它保持在它所在的位置。如果您要使用指针来更改它所指向的值,那么foo 中的值将是更改后的值。

例如:

char *po2;   // A pointer variable that will hold an address of a char
char foo = 'D'; // A variable that will hold a char
po2 = foo;   // po2 contains a new copy of 'D', this is not what you wanted
po2 = &foo;  // po2 contains address of foo, this is right
*po2 = 'C';  // foo will now contain 'C'
*po2 = foo;  // same as using foo = foo
po2 = 'C';   // po2 contains 'C', this is not what you wanted

【讨论】:

  • 非常感谢您的详细解释。我使用%d而不是%p的原因是我认为地址必须是整数(可能比double大)而应该使用%p的原因应该是C语言原理。
  • 啊...再次感谢您推荐的文章,它们一定会让我更深入的了解。
  • @puming 您应该根据数据类型而不是大小来选择说明符。在 C 中,有大小相同但类型不同的东西,因此通常会以不同的方式打印:)
【解决方案2】:

问题就在这里:

*po2 = foo;

您需要为指针 po2 分配地址,而不是值。在这种情况下,您分配了变量 foo 的指针 po2 值。如果您想分配地址,请执行以下操作:

po2 = &foo;

【讨论】:

  • 投反对票,因为*po2 = &amp;foo; 和“在这种情况下,您分配了变量 foo 的指针 po2 值。”不正确。
猜你喜欢
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多