Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 直接用变量设置指针意味着什么?_C++_C_Pointers_Data Structures - Fatal编程技术网

C++ 直接用变量设置指针意味着什么?

C++ 直接用变量设置指针意味着什么?,c++,c,pointers,data-structures,C++,C,Pointers,Data Structures,PS,我知道什么是指针以及如何使用指针,但有一点我很困惑。我已尝试搜索stackoverflow关于此问题的内容: int *ptr = 20 //why illegal or seg fault or crash? printf("%i", *ptr) // Seg Fault printf("%i", ptr) // Output -> 20 printf("%p", &ptr) // Returns a valid address. 并发现,通过直接给指针赋值而不使用

PS,我知道什么是指针以及如何使用指针,但有一点我很困惑。我已尝试搜索stackoverflow关于此问题的内容:

int *ptr = 20 //why illegal or seg fault or crash?
printf("%i", *ptr) // Seg Fault
printf("%i", ptr) // Output -> 20
printf("%p", &ptr) // Returns a valid address.   
并发现,通过直接给指针赋值而不使用malloc或null初始化,意味着我们要对编译器说,嘿,CPU,在内存中留出一个空间,在给定的确切地址处存储一个整数作为值,在本例中为20。基本上就是说,让编译器在ram中为一个INT,地址为20。通过这样做,我们正在接触系统内存或非法空间

但我不明白的是

  • 如何将整数20直接引用为内存

  • 当我们对float或char执行相同操作时会发生什么?例如,浮点*ptr=20.25

  • 我曾尝试通过一个网站直接将c代码转换为汇编代码,例如一个合法和非法的指针示例,在该示例中,我看到调用了相同的寄存器,执行了相同的MOV操作,并且没有设置明确的“在给定地址生成空间”指令

  • 最后,当我们通过char声明字符串时会发生什么 *ptr=“你好”
  • 我已经尝试了所有可能的方法来理解这一点,但是没有。你们能给我指一下正确的方向吗?谢谢

    如何将整数20直接引用为内存

    使用我的C++编译器,它不编译:我得到这个错误代替:< /P>

    temp.cpp:22:14: error: cannot initialize a variable of type 'int *' with an
        rvalue of type 'int'
          int * x = 20;
    
    它确实编译为C,尽管有以下警告:

    temp.c:12:11: warning: incompatible integer to pointer conversion initializing
        'int *' with an expression of type 'int' [-Wint-conversion]
      int * x = 20;
    
    但是,这在C和C++下都可以编译:

       int * x = (int *) 20;
    
    。。。它之所以编译,是因为20是一个格式良好的内存地址(它指定了一个内存位置,距离进程内存空间的起始位置20字节)

    注意,在大多数操作系统上,它不是一个可用的内存地址;大多数操作系统将地址空间的前几页标记为“不可读/不可写”,这样当有人试图取消对空指针的引用时(否则会导致进程在距内存空间起始点很小的偏移量处读取或写入内存),它们会使进程崩溃

    当我们对float或char执行相同操作时会发生什么?例如浮动 *ptr=20.25

    这些类型不会编译,因为浮点(或字符)值作为内存地址没有意义。在大多数环境中,内存地址是从内存空间顶部开始的整数偏移量,因此,如果您想将一个指定为常量(顺便说一句,您通常不想这样做,除非您在非常低的级别上工作,例如,在嵌入式控制器中直接寻址DMA硬件),它需要是整数常量

    并且没有设置明确的“在给定地址留出空间”指令

    这是意料之中的——将指针设置为值不会隐式地为任何内容留出空间,它只会将指针设置为指向指定常量的内存地址

    最后,当我们通过char声明字符串时会发生什么 *ptr=“你好”

    在这种情况下,编译器会识别您已声明了一个字符串常量,并将该字符串作为只读数组添加到进程的内存空间中。完成后,它可以将指针设置为指向该数组的开头。请注意,此行为特定于字符串常量,不会延续到其他数据类型,如int或float

    还要注意,触发该常量相加的是字符串常量的声明,而不是指向该常量的指针的设置。例如,如果您有以下代码:

    const char * s1 = "Hello";
    const char * s2 = "Hello";
    printf("s1=%p s2=%p\n", s1, s2);
    
    。。。您将看到如下输出:

    s1=0x104608f4e s2=0x104608f4e
    
    。。。请注意,两个指针都指向相同的内存位置;由于这两个字符串相同且为只读,因此编译器可以通过只分配字符串数据的单个实例来节省内存

    相反,如果您这样做:

    const char * x = (const char *) 20;
    
    。。。您会遇到与您在
    int*
    示例中看到的完全相同的问题。

    关于C++:

    这个程序格式不好。编译器不需要成功编译此程序,他们需要通知您该问题。没有从整数文本到指针的隐式转换(除了文本零)

  • 如何将整数20直接引用为内存
  • 它一般不能被引用。只有分配了地址处的内存,指针才能被有意义地使用。此外,某些用法(如读取指向对象的值)要求对象在其生存期内存在于指向的地址。否则,程序的行为是未定义的

  • 当我们对float或char执行相同操作时会发生什么
  • 与指向int的指针基本相同。除非在指向的地址处有兼容类型的对象,否则通过指针间接访问对象时,行为是未定义的。char稍有不同,它与所有类型的对象都兼容。但即使是char也不能用于读取未分配的内存

  • 。。。未设置明确的“在给定地址留出空间”指令
  • <>你没有告诉C++分配任何内存,那么为什么在给定地址上会有“空间”?

  • 最后,当我们通过char*ptr=“Hello”声明字符串时,会发生什么
  • 由于常量字符数组不会隐式转换为指向非常量字符的指针,因此程序的格式将不正确。除非标准是C++11之前的版本,在这种情况下,由于存在这种转换,程序的格式良好。您将收到一个弃用警告

    这是非法的,因为C和C++标准是这样说的。p> 通过直接给指针赋值,而不使用malloc或null进行初始化,这意味着我们要对编译器说,嘿,CPU,在内存中留出一个空间,在给定为value的确切地址处存储一个整数,在本例中为20

    一点也不像
    int *ptr = 20 //why illegal or seg fault or crash?
    
       int *ptr = 20 //why illegal or seg fault or crash?
    
           int *ptr = (int*)20;