为什么在尝试将原始指针值赋予新值时会导致错误?

for*_*ght 0 c pointers

我是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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    输出是:

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    输出是:

    由于信号终止:分段故障(11)

显然,错误是由声明引起的*po2 = foo;

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

Tob*_*oby 6

  1. 您正在使用字符串中不正确的格式说明符printf().这%d是专门针对整数的.对于你应该使用的指针%p.

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

  2. 当你说*po2 = foo;你实际上是分配价值的foo,以无论是指向通过po2,而不是分配地址的foo进入po2 本身.

    首先,在为指针分配地址时,不要使用*,因此第一部分变为po2 =.其次,你想要分配地址foo而不是它所拥有的值,因此你应该使用"address-of"运算符,&这样整条线就变成了po2 = &foo;

    您当前的代码给出一个分段错误的原因是因为,如前所述当前的代码分配的价值foo,到哪里po2是在指点.因为指针尚未正确初始化,它会保留一些NULL无效的不确定地址(通常).因此,当PC试图找到该无效地址时,它试图找到不存在的存储器位置位置(例如,位置0或位置50亿等).它不能这样做,因此导致分段错误.

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

如果您希望将指针po2指向变量,foo则将地址foo放入指针中.po2将保留地址foo并foo仍将保留'D'.它'D'并没有神奇地移动到指向的内存的其他部分po2,而是保持在它所在的位置.如果您要使用指针来更改其指向的值,那么值in 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
Run Code Online (Sandbox Code Playgroud)