主頁 > 企業開發 > 又是指標、&和指標?

又是指標、&和指標?

2022-03-01 01:43:14 企業開發

我只是無法理解指標 - 我應該何時以及如何準確地使用指標。無論我閱讀了多少視頻和文獻,我只是不明白我應該何時以及如何使用它。明明我就是那么濃...

讓我們在這里看看這個例子:

int main()
{
    int* ptr = new int(10);

    std::cout << ptr << std::endl; 
    std::cout << *ptr << std::endl; 
    std::cout << &ptr << std::endl;
}

這將回傳給我們一個像這樣的值:

000001A68ABB5250 
10 
000000455ADCF828

這些輸出是什么意思?第一個和第三個看起來像是記憶體中的地址號,但它們不同,我不明白它們應該做什么?第二個是我分配的值,但為什么我必須用指標符號來獲取它?

讓我們看看這個:

int main()
{
    int ptr = 10;

    std::cout << ptr << std::endl; 
    //std::cout << *ptr << std::endl; //gives "Error(active)    E0075   operand of '*' must be a pointer but has type 'int'"
    std::cout << &ptr << std::endl;
}

分別回傳:

10
000000D9242FF5F4

是什么使上面的代碼與此示例代碼不同?為什么我不必使用指標來獲取值?與號顯示記憶體地址對嗎?

基本上有人可以用最愚蠢、最容易理解的方式向我解釋指標的意義是什么以及為什么我們在 C 中需要它們。

uj5u.com熱心網友回復:

如果我們“繪制”第一個示例,它將是這樣的:

 ------   -----   -------------- 
| &ptr | --> | 指標 | --> | *ptr int(10) |
 ------   -----   -------------- 

ptr指向一個int值(初始化 10 )也是如此10并且&ptr指向變數ptr


在第二個示例中,變數名稱ptr具有誤導性,因為它不是指標。這是一個簡單的int變數。

畫出來會像

 ------   ------------- 
| &ptr | --> | 指標 int(10) |
 ------   ------------- 

uj5u.com熱心網友回復:

當我第一次開始編程時,指標是我剛剛接受它們作業并最終積累了足夠的經驗來學習/理解它們的東西之一。

在我的一堂課上,一位教授說當你想修改一個物件而不是復制它時,最好使用指標。將值傳遞給函式會創建在其中傳遞的物件的副本。

uj5u.com熱心網友回復:

首先要理解的是,符號的含義*取決于&背景關系。

int* ptr,*表示“這是一個指標”。

但除此之外(例如 in cout << *ptr),*意味著“取消參考”一個指標。即,給定一個指向 X 的指標,*回傳 X,無論發生什么。

&(例如 in cout << &ptr)“獲取地址”的東西。給定 X,它給你一個指向 X 的指標。

&*(在第二種意義上)是相反的操作,它們相互抵消。

int* ptr = new int(10);有點類似于int x = 10; int *ptr = &x;這反過來意味著int x = 10; int *ptr; ptr = &x;(不是*ptr = &x,因為*在這里意味著不同的東西,見上文)。

所以,給定int x = 10;,&x是一個“指向 x 的指標”(列印它會給你一個地址)。完成后int *ptr = &x,ptr也是一個“指向 x 的指標”,因此列印它會顯示相同的地址。

*ptr給你x,就像*&x(這意味著*(&x))一樣,因為*&相互抵消。


指標可以指向其他指標。&ptr給你一個“指向”的指標ptr,或“指向 x 的指標”,它的型別為int **. **&ptr因此將回傳 的值x

uj5u.com熱心網友回復:

我不是一個解釋者,但總體概述是:

在你宣告和定義之后int* ptr = new int(10);

當你使用 ptr 時,它是型別的名稱int*,比如 for int x = 5,當你使用 x 時,它是 int 型別的。

ptr是一個指標,所以它是一個存盤在地址中的變數,所以當你列印它時,它將是一個地址。

&ptr將是指標的地址,是的,指標也有地址。基本上,它是 type int**,所以列印時也會是一個地址。

*ptr取消參考指標,因此它將獲得存盤在指標指向的記憶體位置中的值 10。可以把它想象成,每個地址都指向一個存盤值的記憶體位置。

如果它只是 plain int ptr = 10,則不能取消參考它: apply*ptr因為它是 typeint而不是int*.

但是,如果您&ptr向它申請,它將獲得int ptr本質上是 type的地址int*

例如,如果你這樣做:int x = 5; int *ptr = &x;,如果你取消參考ptr,并做:cout << *ptr,它將列印 5。

我第一次也很難用指標。沒關系。我花了一個月左右的時間來解決這個問題。事實上,我仍然有一些讓我感到困惑的事情。哦,好吧,我不太擅長解釋,可能和你讀到的差不多……祝你好運。

uj5u.com熱心網友回復:

簡而言之:

int* ptr = new int(10);

ptr (int)實際上只是您在右側分配的 int 的記憶體地址(一個數字)。

std::cout << ptr << std::endl;

然后列印出新 int 的記憶體地址。這是因為 ptr只是一個恰好是記憶體地址的數字。

std::cout << *ptr << std::endl;

在這里,您告訴 C 使用 ptr 所在的數字訪問記憶體地址。因為 ptr 是 int 的記憶體地址,所以你會得到 int 的值。

std::cout << &ptr << std::endl;

最后,你告訴 C 給你 ptr 的記憶體地址。如果您使用 *&ptr,那么您將得到與您的第一個列印陳述句相同的結果。

至于后半部分,這里的 int 只是一個值,而不是指標。當 C 說你不能使用 * 時,它可以防止你不小心把 int 當作記憶體地址。但是,如果您真的想將 int 視為記憶體地址,

int* x = 10

然后將允許*x編譯。現在因為這是訪問記憶體地址 10 的 int (這不是您的程式的一部分),您的作業系統幾乎肯定會殺死您的程式。

uj5u.com熱心網友回復:

真正有趣的問題是“為什么要使用指標?” 如果你明白了,那么其余的可能會隨之而來。

旁注,C 有許多結構,這些結構使很多“隱藏”,我所描述的仍在幕后進行

有幾種情況下指標很有用

#1 傳遞大事

想象一下你有這個

struct Biggy{
     int Widle[500];
     char Froodle[500];
}

這是一個大物件,復制起來很費錢,你有一個對 Biggy 物件進行操作的函式,比如說它比較 Widle 和 Froodle 陣列。

bool AreTheSame(Biggy b) {....}

c 和 c 的作業方式是引數按值傳遞,這意味著它們從呼叫者復制到被呼叫函式

所以當我這樣做的時候

Biggy b = MakeAndFillBiggy(); // we will come back to this function
bool same = AReTheSame(b);

所有 1000 個位元組都被復制,這很昂貴

但如果我有

 bool AreTheSame(Biggy *b) {....}

那我可以

bool same = AretheTheSame(&b);

現在我只是傳遞一個指標。那是 4 或 8 個位元組而不是 1000。

#2 允許函式修改其引數

正如所指出的

bool same = AreTheSame(b);

將 b 的副本傳遞給函式,這很昂貴,如果函式想要更改 b 它也不能。它只有一個副本。

想象一下,我們有一個函式MakeTheSame(Biggy b);來查看兩個陣列是否相同,如果不是,它會改變它們,很好。但是像這樣它沒有用,因為它改變了副本,而不是原件。

我們又可以做

void MakeTheSame(Biggy *b) {..}
 ...
Biggy b = MakeAndFillBiggy(); // we will come back to this function
bool same = MakeTheSame(&b);

now we are passing a pointer to the callers 'b'

Note that this is useful for any size object.

You have probably seen this

 int num;
 scanf("%d", &num);

we have to pass the pointer to num so that scanf can modify it.

#3 To get and use dynamic memory

YOu have an app that keeps a list of football teams for a tournament.

struct Team{
   string name;
   string town;
   string captain;
}

How big does the array that holds it need to be? YOu dont know in advance how many teams will enter.

YOu could have

 Team teams[100];

But thats a bit wasteful. So instead you use dynamic memory, every time you get a new time you allocate a new Team object on the heap.

Team *team = new Team();

'new' allocates memory dynamically from a pool , it will be big enough for a Team object and it will be initialized. It returns a pointer to this new memory.

Now you can have just the right amount of Team objects.

Lets go back to this

Biggy b = MakeAndFillBiggy(); // we will come back to this function

Now we will do

Biggy *MakeAndFillBiggy(){
    Biggy * b = new Biggy();
    ... fill arrays somehow
    return b;
}

and now we do

Biggy *b = MakeAndFillBiggy();

C goodies

C has a thing called references. These behave like pointers (cheap to pass, allow functions to change their arguments) but syntactically look like non pointers.

Eg

void MakeTheSame(Biggy &b) {..}    

this says that MakeTheSame takes a referenc as an argument. Now we can do

Biggy b;
MakeTheSame(b);

There are some advantages to references over pointers but they do exactly the same thing

C has 'smart pointers'

The problem with our function

Biggy *MakeAndFillBiggy(){
    Biggy * b = new Biggy();
    ... fill arrays somehow
    return b;
}
Biggy *b = MakeAndFillBiggy();

Is that it retunr a pointer to an object on the heap. When we have finished with it we have to realease its memory back to the pool so it can be reused.

so somewhere there has to be

delete b;  

The problem is that in complex code it might be hard to knwo when you have finished with b. Enter 'smart pointers' they detect when you have finished with the memory and release it for you

so you will see

std::shared_ptr<Biggy> MakeAndFillBiggy(){
    std::shared_ptr<Biggy> p = std::make_shared<Biggy>();
    ... fill arrays somehow
    return b;
}
std::shared_ptr<Biggy> b = MakeAndFillBiggy();

or more succintly becuase the compiler is smart

std::shared_ptr<Biggy> MakeAndFillBiggy(){
    auto p = std::make_shared<Biggy>();
    ... fill arrays somehow
    return b;
}
auto b = MakeAndFillBiggy();

under the hood exactly the same thing is happening, theres just some glue added on top to keep track of when this pointer is not longer needed

Inside there was still ptr = new xxx and a *p

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/434179.html

標籤:C 指针 和号

上一篇:c中的qsort型別轉換指標

下一篇:如何使用成員變數初始化結構內部的結構?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more