C++中數組和指針的關系(區別)詳解

C++中數組和指針的關系(區別)詳解

本文轉自:http://c.biancheng.net/view/1472.html

博主在閱讀后將文中幾個知識點提出來放在前面:

  1. 沒有方括號和下標的數組名稱實際上代表數組的起始地址,這意味著數組名稱實際上就是一個指針。
  2. 在數學語句中使用指針時,它不像常規變量那樣工作。
  3. 向指針添加值時并要解引用時,括號非常重要。
  4. array[index] 相當于 *(array + index)。
  5. C++ 不會對數組執行邊界檢查。
  6. 不僅指針符號可以與數組名稱一起使用,而且下標符號也可以與指針一起使用。
  7. 可以使用地址運算符來獲取數組中單個元素的地址。
  8. 數組名稱和指針變量的唯一區別是,不能改變數組名稱指向的地址,即數組名稱可視為一個指針常量。

我們知道,沒有方括號和下標的數組名稱實際上代表數組的起始地址,這意味著數組名稱實際上就是一個指針。下面程序通過顯示與間接運算符一起使用的數組名稱來說明這一點。

// This program shows an array name being dereferenced with the * operator.
#include <iostream>
using namespace std;
int main()
{short numbers[] = {10, 20, 30, 40, 50};cout << "The first element of the array is ";cout << *numbers << endl;return 0;
}

程序輸出結果:

The first element of the array is 10

numbers 在上面程序中的作用類似于指向數組起始地址的指針,所以當 numbers 被解引用時,第一個元素被檢索出來。那么,如何使用間接運算符來檢索數組的全部內容呢?請記住,數組元素是一起存儲在內存中的,如圖 1 所示。
在這里插入圖片描述

既然 numbers 是 numbers[0] 的地址,那么給 numbers 添加值豈不是就可以獲得數組中其他元素的地址了?這樣想當然很有道理,但是,這里有一個知識點非常重要,即:在數學語句中使用指針時,它不像常規變量那樣工作

在 C++ 中,當給一個指針添加一個值的時候,實際上添加的值是把這個值乘以指針引用的數據類型的大小。換句話說,如果給 numbers 加 1,實際上就是給 numbers 加上 1 X sizeof(short);如果給 numbers 加 2,實際上就是給 numbers + 2 X sizeof(short),以此類推。在 PC 上,這意味著以下說法是真實的,因為 short(短整數)通常使用 2 個字節:

  • *(numbers +1)是指地址 numbers + 1X2 處的值。
  • *(numbers + 2)是指地址 numbers + 2X2 處的值。
  • *(numbers + 3)是指地址numbers + 3X2 處的值。

以此類推。

這種自動轉換意味著數組中的元素可以通過使用其下標或通過將下標添加到指向數組的指針來檢索。既然表達式 *numbers 與 *(numbers + 0) 相同,它可以檢索數組中的第一個元素,那么*(numbers + 1) 就可以檢索第二個元素。同樣,*(numbers+2) 即可檢索第三個元素,以此類推。圖 2 顯示了下標表示法和指針表示法的等價性。

在這里插入圖片描述

注意,向指針添加值時,括號非常重要。* 運算符優先于 + 運算符,所以表達式 *numbers + 1 不等于 *(numbers + 1)。表達式 *numbers + 1 的意思是將數組的第一個元素的內容加 1, 而 *(numbers + 1) 則是先給 numbers 加 1,然后對其進行解引用。

下面的程序使用指針符號顯示了被訪問數組的整個內容:

//This program processes an array using pointer notation.
#include <iostream>
using namespace std;
int main()
{const int SIZE = 5; // Size of the arrayint numbers[SIZE]; // Array of integers// Get values to store in the array// Use pointer notation instead of subscriptscout << "Enter " << SIZE << " numbers: ";for (int count = 0; count < SIZE; count++)cin >> *(numbers + count);// Display the values in the array// Use pointer notation instead of subscriptscout << "Here are the numbers you entered:\n";for (int count = 0; count < SIZE; count++)cout << * (numbers + count) << " ";cout << endl;return 0;
}

程序輸出結果:

Enter 5 numbers: 5 10 15 20 25
Here are the numbers you entered:
5 10 15 20 25

在使用數組時,請記住一個規則,即**array[index] 相當于 *(array + index) **。

另外,請注意C++ 不會對數組執行邊界檢查。當使用指針遍歷一個數組時,有可能會給指針一個越出數組邊界的地址。

要理解數組名稱和指針之間的密切關系,請看下面的程序。它定義了一個 double 數組和一個 double 指針,該指針分配了數組的起始地址。隨后,不僅指針符號可以與數組名稱一起使用,而且下標符號也可以與指針一起使用

// This program uses subscript notation with a pointer
// variable and pointer notation with an array name.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{const int NUM_COINS = 5;double coins[NUM_COINS] = {0.05, 0.1, 0.25, 0.5, 1.0};double *doublePtr; // Pointer to a double// Assign the address of the coins array to doublePtrdoublePtr = coins;// Display the contents of the coins array// Use subscripts with the pointer!cout << setprecision (2);cout << "Here are the values in the coins array:\n";for (int count = 0; count < NUM_COINS; count++)cout << doublePtr [count] << " ";// Display the contents of the coins array again, but this time use pointer notation with the array name!cout << "\nAnd here they are again:\n";for (int count = 0; count < NUM_COINS; count++)cout << *(coins + count) << " ";cout << endl;return 0;
}

程序輸出結果:

Here are the values in the coins array:
0.05 0.1 0.25 0.5 1
And here they are again:
0.05 0.1 0.25 0.5 1

注意,當一個數組的地址分配給一個指針時,就不需要地址運算符了。由于數組的名稱已經是一個地址,所以使用 & 運算符是不正確的。但是,可以使用地址運算符來獲取數組中單個元素的地址

例如,&numbers[1] 得到 numbers[1] 的地址。在程序下面程序中就使用了該技巧。

// This program uses the address of each element in the array.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{const int NUM_COINS = 5;double coins[NUM_COINS] = {0.05, 0.1, 0.25, 0.5, 1.0};double *doublePtr; // Pointer to a double//Use the pointer to display the values in the arraycout << setprecision (2);cout << "Here are the values in the coins array:\n";for (int count = 0; count < NUM_COINS; count++){doublePtr = &coins[count];cout << *doublePtr << " ";}cout << endl;return 0;
}

程序輸出結果:

Here are the values in the coins array:
0.05 0.1 0.25 0.5 1

數組名稱和指針變量的唯一區別是,不能改變數組名稱指向的地址。例如,假定存在以下定義:

double readings[20], totals[20];
double *dptr;

那么以下語句是合法的:

dptr = readings; // 使 dptr 指向 readings
dptr = totals; // 使 dptr 指向 totals

但是以下語句則是非法的:

readings = totals; // 非法!不能改變 readings
totals = dptr; // 非法!不能改變 totals

數組名稱是指針常量。不能讓它們指向除了它們所代表的數組之外的任何東西

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532829.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532829.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532829.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安裝php獨立環境,0507-php獨立環境的安裝與配置 Web程序 - 貪吃蛇學院-專業IT技術平臺...

1.在一個純英文目錄下新建三個文件夾2.安裝apache(選擇好版本)過程中該填的按格式填好&#xff0c;其余的只更改安裝目錄即可如果報錯1901是安裝版本的問題。檢查&#xff1a;安裝完成后localhost打開為It works!添加到電腦屬性環境變量&#xff1a;3.將php文件解壓文檔放到AMP…

linux中PATH變量-詳細介紹

轉自&#xff1a;https://blog.csdn.net/haozhepeng/article/details/100584451 轉載者勘誤 原文最后提到的 echo 命令對于環境變量的修改無影響。這是肯定的&#xff0c;echo 命令相當于只是一個打印的函數&#xff08;比如 Python 中的 print&#xff09;。這里要修改環境變…

php assert eval,代碼執行函數之一句話木馬

前言大家好&#xff0c;我是阿里斯&#xff0c;一名IT行業小白。非常抱歉&#xff0c;昨天的內容出現瑕疵比較多&#xff0c;今天重新整理后再次發出&#xff0c;修改并添加了細節&#xff0c;另增加了常見的命令執行函數如果哪里不足&#xff0c;還請各位表哥指出。eval和asse…

顯卡、顯卡驅動、CUDA、CUDA Toolkit、cuDNN 梳理

顯卡、顯卡驅動、CUDA、CUDA Toolkit、cuDNN 梳理 轉自&#xff1a;https://www.cnblogs.com/marsggbo/p/11838823.html#nvccnvidia-smi GPU型號含義 顯卡&#xff1a; 簡單理解這個就是我們前面說的GPU&#xff0c;尤其指NVIDIA公司生產的GPU系列&#xff0c;因為后面介紹的…

php中msubstr,PHP學習:thinkphp中字符截取函數msubstr()用法分析

《PHP學習&#xff1a;thinkphp中字符截取函數msubstr()用法分析》要點&#xff1a;本文介紹了PHP學習&#xff1a;thinkphp中字符截取函數msubstr()用法分析&#xff0c;希望對您有用。如果有疑問&#xff0c;可以聯系我們。本文實例講述了thinkphp中字符截取函數msubstr()用法…

VS Code的Error: Running the contributed command: ‘_workbench.downloadResource‘ failed解決

VS Code的Error: Running the contributed command: _workbench.downloadResource failed解決 轉自&#xff1a;https://blog.csdn.net/ibless/article/details/118610776 1 問題描述 此前&#xff0c;本人參考網上教程在VS Code中配置了“Remote SSH”插件&#xff08;比如這…

Oracle閃回報錯,oracle 閃回區滿了,ORA-19815

oracle 閃回區滿了&#xff0c;查看日志報錯&#xff1a;ORA-19815&#xff0c;命令行輸入&#xff1a;sqlplus / as sysdbastartup mount //如果你的數據庫出現了無法連接的情況時&#xff0c;可以加上這句select file_type, percent_space_used as used,percent_space_rec…

[2021-ICCV] MUSIQ Multi-scale Image Quality Transformer 論文簡析

[2021-ICCV] MUSIQ: Multi-scale Image Quality Transformer 論文簡析 論文&#xff1a;https://arxiv.org/abs/2108.05997 代碼&#xff1a;https://github.com/google-research/google-research/tree/master/musiq 概述 當前SOTA的IQA&#xff08;圖像質量評估&#xff0…

安裝oracle不動了,windows2008安裝ORACLE到2%不動的問題 | 信春哥,系統穩,閉眼上線不回滾!...

最近又有網友遇到在windows2008服務器上安裝ORACLE軟件時到2%就卡住不動的問題&#xff0c;下面是該網友的描述&#xff1a;oralce 11g r2 windows server 2008 R2安裝到最后一步復制數據文件時卡到2% 不走了內存一直飆升求解決這個問題前段時間也有人遇到過&#xff0c;但是他…

手把手教你入門Git --- Git使用指南(Linux)

手把手教你入門Git — Git使用指南&#xff08;Linux&#xff09; 系統&#xff1a;ubuntu 18.04 LTS 本文所有git命令操作實驗具有連續性&#xff0c;git小白完全可以從頭到尾跟著本文所有給出的命令走一遍&#xff0c;就會對git有一個初步的了解&#xff0c;應當能做到會用并…

linux修改主機名后oracle em控制臺起不來,更改計算機名后導致Oracle dbconsole無法啟動問題解決方法...

今天不知道哪根筋搭歪了&#xff0c;看著Oracle EM控制臺的主機名WIN-LOSGI0TCOG0亂七八糟的很不爽&#xff0c;就把它給改了。然后Oracle EM就上不去了&#xff0c;Oracledbconsole服務起不來&#xff0c;我嘗試把所有“WIN-LOSGI0TCOG0”替換成“ggsjy”&#xff0c;找了好多…

Shell腳本多行換行報錯:- unrecognized arguments- \

shell error: unrecognized arguments: \ 在使用linux長命令時&#xff0c;我們通常會用一個shell腳本加\分行的形式來更清晰展示參數。 這時有一個注意事項&#xff1a;在\后必須緊跟回車&#xff0c; 否則會導致后面的參數無法傳入。因為這時程序會將后面的參數算作一條新命…

shell腳本長命令帶換行 注釋方法

shell腳本長命令帶換行 注釋方法 命令行傳參 在訓練深度學習網絡時&#xff0c;我們每次實驗通常會有許多超參數需要設置&#xff0c;如batch size, epoch, gpu id, arch甚至還有一些具體的模型結構等。這事我們通常使用python模塊argparse&#xff0c;在命令行進行傳參。 比…

php對中英文字符串進行截取,利用php怎么對中英文混合的字符串進行截取

利用php怎么對中英文混合的字符串進行截取發布時間&#xff1a;2021-01-04 15:31:24來源&#xff1a;億速云閱讀&#xff1a;103作者&#xff1a;Leah利用php怎么對中英文混合的字符串進行截取&#xff1f;很多新手對此不是很清楚&#xff0c;為了幫助大家解決這個難題&#xf…

Linux查找命令find、loacte、whereis、which、type梳理

Linux查找命令find、loacte、whereis、which、type梳理 Linux操作系統中有5種常用的查找命令&#xff1a;find&#xff0c;locate&#xff0c;whereis&#xff0c;which&#xff0c;type&#xff0c;他們分別用于查找不同的東西&#xff0c;本文將就他們各自的功能進行一下梳理…

php數據關系圖,如何利用navicat查看數據表的ER關系圖

文章背景&#xff1a;(相關推薦&#xff1a;navicat)由于工作需要&#xff0c;現在要分析一個數據庫&#xff0c;然后查看各個表之間的關系&#xff0c;所以需要查看表與表之間的關系圖&#xff0c;專業術語叫做ER關系圖。默認情況下&#xff0c;Navicat顯示的界面是這樣的&…

Linux軟鏈接的使用

Linux軟鏈接的使用 轉自&#xff1a;https://www.cnblogs.com/sueyyyy/p/10985443.html&#xff0c;本博文僅對原博排版稍微優化。 更為細致的硬鏈接、軟鏈接的介紹可參考&#xff1a;Linux中的硬鏈接和軟鏈接 另外&#xff0c;提供筆者對軟連接的一個最簡單的理解&#xff…

oracle死鎖優化,Oracle性能優化之LockContention(轉)

1、概念DML事務使用row-level locks,查詢不會鎖定數據。鎖有兩種模式&#xff1a;exlusive、share。鎖的類型&#xff1a;? DML or data locks:– Table-level locks(TM)– Row-level locks(TX)? DDL or dictionary locks一個transaction至少獲得兩個鎖&#xff1a;一個共享的…

Linux中g++與gcc的區別

轉自&#xff1a;https://blog.csdn.net/bit_clearoff/article/details/53965514 Windows中我們常用vs來編譯編寫好的C和C代碼&#xff1b;vs把編輯器&#xff0c;編譯器和調試器等工具都集成在這一款工具中&#xff0c;在Linux下我們能用什么工具來編譯所編寫好的代碼呢&#…

linux系統可以用迅雷嗎,在Linux系統下使用wine運行迅雷5的方法

在Linux系統下使用wine運行迅雷5的方法一、下載ies4linux去 http://www.tatanka.com.br/ies4linux/page/Installation 下載ies4linux的文件包(目前版本為2.99)&#xff0c;然后解壓縮。注意&#xff1a;這個網站被大陸和諧了&#xff0c;需要跳墻。至于怎么跳&#xff0c;諸位就…