C++學習筆記基礎篇15——地址和指標
之前每次看C++都是在這部分內容中學的迷迷糊糊,今天突然覺的好像有點懂了。
1、什麼是地址?
我們在程式中定義的任何變數實際上都是存在記憶體中的,對吧?那麼既然是存在的東西就應該有裝他的地方。舉個例子,小明家,肯定有小明家的地址,張三家也應該有張三家的地址。再來說一個,比如說誰家都有電視機,對吧,那麼我問你電視機在哪裡?你肯定會說在客廳的牆上掛著,不管在哪,電視機肯定在他的位置擺放著呢,換句話說電視機也有他自己的地址。所以變數的地址也是一個意思,就是這個變數真正存在哪,在哪裡!這就是變數的地址。
下面我們用程式碼舉個例子,例如定義一個字元: char ch = ‘a’; 我們用vs的監視視窗來看下字元 ch
的地址是多少呢?他在記憶體中又是如何來展現的呢?具體看視訊教程演示! 那麼在使用 cout << ch; 進行輸出的時候,cout 也會去從
ch 的地址開始讀取一個字元,之後列印輸出出來。好了,通過上面的講解大家應該大概瞭解了什麼是變數的地址。
2、什麼是指標?
變數的地址一般都是比較難記的,例如:0x007f2eab 之類的,那麼能不能用專門的一個東西,或者說一種特殊型別的變數來儲存這個地址呢?
答案當然是可以的,這個特殊型別的變數就是指標。那麼接下來就教大家如何定義指標: 例如: char* p;
//定義什麼型別的指標,就在型別的後面加上一個*,代表是指標型別變數的意思。
這樣就定義了一個指向char型別變數的指標,但是他沒有指向任何變數的地址。接下來我們給他賦值一下: p = &ch;
這樣我們就將指標p指向了字元ch的地址。備註:為什麼指標變數的命名一般總帶著一個字母p,因為指標的英文單詞是pointer,所以簡寫就是p
那麼我們換一下: int a = 5; int* pa = &a;
這裡面我們就將一個int型別的指標pa指向了int型別變數a的地址。&符號是取地址符號,&a 就是取變數a的地址。 這麼這樣解釋一下:
變數a的值或者說a的內容是5,變數a的地址是 &a 指標pa他也是一個變數,只不過是一個指標型別的變數,所以指標變數pa的值或者說內容就是
&a,指標變數pa的地址是 &pa
也就是說指標變數也是變數,他也有內容和地址。之前給大家講解的其他型別變數的值或者說內容都是反應自身的。但是指標變數裡面的值或者內容是反應其他變數的。
3、變數與指標:
在C/C++語言中可以通過取地址符號&得到變數的地址,例如:
int a = 5;
int* pa = &a;
那麼,通過變數的地址,能否得到變數自身呢?答案是可以的!
int a = 5;
int* pa = &a;
pa = 6;
即:在指標變數的前面加上一個就能得到指標指向的變數自身。
所以對一個變數的修改,既可以通過該變數自身(直接修改),也可以通過指標/地址來實現修改(間接修改)。
4、指標變數的定義及初始化:
①、指標變數的定義格式如下:基型別 * 指標變數名; ②、符號* 既可以靠近基型別,也可以靠近指標變數名,例如: int* p; 和 int
*p; 都是正確的。 ③、指標變數可以在定義的時候就初始化,也可以先定義後初始化,也可以在以後的任意一個時間去指向某個變數的地址:
int a = 5;
int *pa;
pa = &a;
int *pb = &a;④、基型別就是該指標變數指向的變數的型別。例如: int* pa;
這個指標變數的定義,就是定義了一個指向int型別的指標變數pa;你就不能把一個float型別的變數地址賦給他。例如:
int* pa;
float a = 2.6;
pa = &a;
這種寫法是錯誤的。 ⑤、指標變數可以指向同一型別的變數,例如:
int a = 5, b= 6;
int *p = &a;
p = &b;
即:指標變數p既可以指向變數a的地址,也可以指向變數b的地址。
5、&和*的例項
定義一個函式實現兩個引數的值
void swap(int a, int b)
{
int t = a;
a = b;
b = t;
}
上面這個函式是沒法實現功能的,我的理解為void為無返回值的,需要定義成int 型,return 對應的值,但是仍然有問題。
int swap( int a, int b)
{
int t = a;
a = b;
b = t;
return a;
}
函式的返回引數只能有一個,所以這裡要實現功能的話,最方便的是使用指標來定義。
void swap(int* pa, int* pb)
{
int t = *pa;
*pa = *pb;
*pb = t;
}
這裡和前面的區別就是一個用的是變數一個是指標變數,在前一個程式中無法正常轉換a,b值的原因是在函式中用了形參,是新申請的地址中把a,b的值放進去,但是沒有把轉換的結果return到原來的地址中。而後面這個使用指標變數他沒有采用新的地址,是直接對原始地址中的a,b進行操作,所以不需要返回,已經修改了a,b的值。
6、小作業:
實現一個函式,作用是獲取一個陣列中的最大值和最小值,函式宣告如下:
#include <iostream>
using namespace std;
#include <string> //C++語法
void get_min_max(int *src, int* max_v, int* min_v,int length)
{
//函式程式碼寫在這個下面
int i;
cout << "length = " << length << endl;
for (i = 0; i <= length; i++)
{
if (src[i] > *max_v)
{
*max_v = src[i];
}
else if (src[i] < *min_v)
{
*min_v = src[i];
}
}
}
int main()
{
int max_v=0;
int min_v=100;
int length;
int src[] = { 1, 2, 3, 4, 5, 32, 14, 3 };
length = sizeof(src)/sizeof(src[0]);
cout << "length = " << length << endl;
get_min_max(src, &max_v, &min_v,length);
cout << "max_v = " << max_v << endl;
cout << "min_v = " << min_v << endl;
system("pause");
return 0;
}
可以看到執行結果的min_v的計算結果不正確。
出現一個負的那麼大的值,可以猜到是陣列越界。檢查了幾遍,想到
for (i = 0; i <= length-1; i++)
這裡length-1才能對,因為陣列是從0,開始的,到length-1就結束了,-858993460這個值即為0xcccccccc的十進位制表示。
修正之後仍然有問題,最小值的計算結果為3。下面這個程式才是對的,要分別使用if不能直接if ,else
#include <iostream>
using namespace std;
#include <string> //C++語法
void get_min_max(int *src, int* max_v, int* min_v,int length)
{
//函式程式碼寫在這個下面
int i;
cout << "length = " << length << endl;
for (i = 0; i <= length-1; i++)
{
if (src[i] > *max_v)
{
*max_v = src[i];
}
if (src[i] < *min_v)
{
*min_v = src[i];
}
}
}
int main()
{
int max_v=0;
int min_v=100;
int length;
int src[] = { 1, 2, 3, 4, 5, 32, 14, 3 };
length = sizeof(src)/sizeof(src[0]);
get_min_max(src, &max_v, &min_v,length);
cout << "max_v = " << max_v << endl;
cout << "min_v = " << min_v << endl;
system("pause");
return 0;
}
相關文章
- MySQL學習筆記【基礎篇】MySql筆記
- 指標學習筆記指標筆記
- vue學習筆記【基礎篇一】Vue筆記
- iOS指標學習筆記iOS指標筆記
- html學習筆記(1)——基礎標籤HTML筆記
- C指標原理(15)-C指標基礎指標
- C++基礎知識學習筆記(1)C++筆記
- C++基礎知識學習筆記(3)C++筆記
- PHP學習筆記(1)–基礎知識篇PHP筆記
- 黑馬筆記--C++基礎篇--隨筆筆記C++
- 【C#學習筆記】指標使用C#筆記指標
- C++筆記(11) 智慧指標C++筆記指標
- CSS 基礎學習筆記CSS筆記
- node基礎學習筆記筆記
- Web基礎學習筆記Web筆記
- Redis基礎學習筆記Redis筆記
- Shell 學習筆記 基礎筆記
- Oracle基礎學習筆記Oracle筆記
- Java基礎學習筆記Java筆記
- 12c in memory option學習筆記一_基礎篇筆記
- 深度學習word2vec筆記之基礎篇深度學習筆記
- 安卓初學基礎學習筆記安卓筆記
- DI、IOC基礎學習筆記筆記
- JavaScript學習筆記——基礎部分JavaScript筆記
- 彙編基礎學習筆記筆記
- 基礎知識學習筆記筆記
- Python基礎學習筆記Python筆記
- 影象拼接基礎學習筆記筆記
- 類的基礎學習筆記筆記
- JavaWeb基礎-學習筆記02JavaWeb筆記
- Java基礎-學習筆記05Java筆記
- Java基礎-學習筆記06Java筆記
- Java基礎-學習筆記07Java筆記
- Java基礎-學習筆記04Java筆記
- Java基礎-學習筆記17Java筆記
- Redis基礎知識(學習筆記15--持久化 (1))Redis筆記持久化
- 菜鳥學習筆記:Java基礎篇1(基礎語法、物件導向)筆記Java物件
- Linux基礎學習-Docker學習筆記LinuxDocker筆記