簡體   English   中英

int *ptr= 5 怎么做; 與 int *ptr= 變量地址不同?

[英]How does the int *ptr= 5; is different than that of int *ptr= address of variable?

雖然它非常基本並且可能看起來很傻,但我試圖了解int *ptr = 450xc8750;之間有什么區別0xc8750; (一些數字) vs. int *ptr= &a; (變量地址)

我已經知道的是:

  • 指針用於存儲變量的地址並修改指向變量的內容(但我想知道它將如何實現)
  • 在后一種情況下,我可以將*ptr分配給不同的合法地址。
  • 但是,在第一種情況下它是非法的!。

如果地址/數字都是整數,為什么后者是非法的? 它們在內存中存儲時的處理方式有何不同?

我有兩段代碼/程序基本上可以突出顯示相同的內容:

情況1:

#include <stdio.h>

int main()
{    
    int *ptr = 0xc42; // is this stored in read only memory?!! which later leads to seg faults in further assignments?!
    *ptr = 45; //illegal leads seg fault.
    return 0;
}

案例2:

int main()
{
    int a=10, b=20;
    int *ptr = &a;  // is here get any special treatment and object will be created for *ptr!!!
    *ptr = &b; //legal
    printf(" *ptr = %d \n", *ptr);
    *ptr = 20; //legal !!
    printf(" *ptr = %d \n", *ptr);
    *ptr = 50; //legal
    printf(" *ptr = %d \n", *ptr);
    return 0;
}

正如我們所看到的*ptr = 20*ptr = 50是合法的! (沒有分段錯誤)。

為什么int *ptr = 0xc989或 5 的賦值與 int *ptr = &variable

讓我們從基礎開始:指針是包含指向給定類型數據的地址的變量。 如果我們聲明

datatype* foo;

foo (當前未初始化)將包含類型為datatype的變量的地址,並推遲

*foo = ...;

我們正在訪問該地址並將其值存儲在那里。


在這兩種情況下,我們都有* foo ,但它們不一樣!

  • 在第一種情況下,星號指的是datatype 變量類型為datatype * 變量名是foo foo包含一個地址。
  • 在第二種情況下,我們取消引用地址,以便訪問它。 星號指的是為了執行指針解除引用的變量。

所以,當你寫

int *ptr = 0xc42; // is this stored in read only memory?!!
                  // which later leads to seg faults in further assignments?!
*ptr = 45; //illegal leads seg fault.
  • int *ptr = 0xc42; 您對編譯器說您正在聲明一個名為ptr的變量,類型為int *且其第一個值為0xC42 注意:正如用戶Lundin正確說明的那樣,此分配需要進一步強制轉換才能成為有效的 C)
  • *ptr = 45; 您正在訪問ptr指向的地址並分配值45 合法嗎? 嗯,如果你之前分配了一個有效的地址(一般來說,如果你用&運算符將另一個變量的地址分配給一個指針,例如int *ptr = &a; )。 但是如果你給它分配一個隨機整數......它可能會導致分段錯誤。

從邏輯上講,如果您確定位置0xc989保留了您需要的內容,則int *ptr = 0xc989完全有效(關於您的思維概念,正如 Roberto Caboni 所說)。

從技術上講,正如 Lundin 所說,您需要根據 C 標准進行轉換。

首先int *ptr = 0xc42; 不是有效的 C 並且不會在配置為嚴格標准 C 的編譯器上干凈地編譯。使用 gcc、clang 和 icc 這意味着使用-std=c11 -pedantic-errors編譯。 有關詳細信息,請參閱“來自整數的指針/來自沒有強制轉換的指針的整數”問題

int *ptr = (int*)0xc42; 是有效的 C 但可疑。 澄清一下,這在指針變量本身中存儲了一個地址,它不存儲值。 所以如果你知道內存地址0xc42有一個int大小的項,比如內存映射的硬件寄存器,那么你可以直接點do。 但是這樣做時,只有使用volatile才有意義: volatile int *ptr = (volatile int*)0xc42; . 像這樣的代碼在嵌入式系統和其他與硬件相關的編程中最有意義。

至於為什么你的第二個例子工作正常,那里的地址是由鏈接器而不是程序員分配的,所以它們將指向有效的分配數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM