Pointer-2

P.s. 此直行為廢話,正文請往右

  • 今天的課不太好懂(我也覺得好難)
  • 會有多一點思考的時間,和旁邊的好夥伴確認一下程式的意思
  • 如果等一下懷疑自己的眼睛看到什麼不要緊張,再看一次會發現怎麼還是那麼詭異😂

大家加油~

深吸一口氣我們就開始囉~

Pointer-1 Review

在經歷段考摧殘後,小小複習一下~

#include <iostream>
using namespace std;
int main(){
  int a=10;
  int *pointer;
  pointer=&a;
  cout<<pointer<<'\n'; //0x6ffe14
  cout<<*pointer; //10
}
  • 把 int *看作一個型態,可以儲存int型態變數的地址
  • &是取址符號,例如:&a (變數的a的地址)
  • * 是取值符號,例如:*pointer (指標pointer的值)

Pointer Array

Array

1 2 3 4 5

arr[0]

arr[1]

arr[2]

arr[3]

arr[4]

int arr[5]={1,2,3,4,5};

Pointer Array

#include <iostream>
using namespace std;
int main()
{
    int a[5]={1,2,3,4,5};
    cout<<&a<<'\n'; //0x7ffd4b1fff70
    cout<<&a[0]<<'\n'; //0x7ffd4b1fff70
    return 0;
}

陣列指標的地址就是第零格的地址!

Pointer Array

#include <iostream>
using namespace std;
int main(){
    int arr[5]={1,2,3,4,5};
    for(int i=0;i<5;i++){
      cout<<&arr[i]<<' ';//下一張投影片
    }
    for(int i=0;i<5;i++){
      cout<<*arr+i<<' ';//1 2 3 4 5
    }
    return 0;
}

Pointer Array

1 2 3 4 5

arr[0]

arr[1]

arr[2]

arr[3]

arr[4]

0x6ffe00

0x6ffe04

0x6ffe08

0x6ffe0c

0x6ffe10

欸?是連續的!為什麼差4呢?

1個bit是0或1;1個byte是8個bit

sizeof

如果我們想知道某個東西占幾個byte,我們可以用sizeof()

#include <iostream>
using namespace std;
int main()
{
    int arr[100];
    cout<<sizeof(int)<<'\n'; //4
    cout<<sizeof(double)<<'\n';//8
    cout<<sizeof(char)<<'\n';//1
    cout<<sizeof(int *)<<'\n';//8
    cout<<sizeof(double *)<<'\n';//8
    cout<<sizeof(char *)<<'\n';//8
    cout<<sizeof(arr)<<'\n';//400
    return 0;
}

其實,計算陣列的大小還有下面這個方法

#include <iostream>
using namespace std;
int main(){
    int b[]={1,3,5,7,9,11,13,15,17,19,21};
    int length=*(&b+1)-b;
    cout<<length;
    return 0;
}

為什麼行得通?

因為+1的單位是&b

&b的單位是int (*) [11]

陣列的名字也是一個指標!?
#include <iostream>
using namespace std;
int main(){
  int a[5]={1,2,3,4,5};
  cout<<a; //0x7ffd9ddb2f20
  cout<<*a;//1
  return 0;
}

等一下!其實從前面的例子就可以看出這一點了!?

sort

#include <algorithm>
#include <iostream>
using namespace std;
int main(){
    int a[5]={10,4,7,2,9};
    sort(a,a+5);
    for(int i=0;i<5;i++)
        cout<<a[i]<<" "; //2 4 7 9 10
    return 0;
}

a

a

a+1

a+2

a+3

a+4

a+5

sort(a,a+5)

[first, last):包含first,但是不包含last

-->包含a、不包含a+5

Pointer Function

Pass by value

#include<iostream>
using namespace std;
void f(int A, int B) {
	int temp = A;
	A = B;
	B = temp;
    cout << A << " " << B <<'\n';  //2 1
}
int main(){
	int a = 1, b = 2;
	f(a, b);
	cout << a << " " << b;  //1 2
	return 0;
}

因為傳到函式裡的東西是副本,所以沒有改到原本的值

Pass by pointer

#include<iostream>
using namespace std;

void f(int *A, int *B) {  //A, B是指標型態的參數
    int temp = *A;  //取A記憶體位址的值,也就是a的值
    *A = *B;  //把A記憶體位址的值(a),改成B記憶體位址的值(b)
    *B = temp;  //把B記憶體位址的值(b),改成temp
    cout << *A << " " << *B <<'\n';  //2 1
}

int main(){
    int a = 1, b = 2;
    f(&a, &b);  //傳入a, b的記憶體位址
    cout << a << " " << b;  //2 1
    return 0;
}

Pass by reference

#include<iostream>
using namespace std;

void f(int &A, int &B) {
	int temp = A;
	A = B;
	B = temp;
	cout << A << " " << B <<'\n';//2 1
}

int main(){
	int a = 1, b = 2;
	f(a, b);
	cout << a << " " << b;//2 1
	return 0;
}

是不是覺得reference 這個詞有點耳熟阿?

在上次的課程中有提到reference就像是取小名的概念

備課冷知識

條列幾個查資料發現的酷東西
  • 指標開頭是0x.......,那個0是令解析器可以辨認數,x代表16進位(O代表8進位)
  • 大概介紹16進位:規則和10進位、2進位差不多,特別的點是10到15的表示方法,10 : A , 11 : B , 12 : C , 13 : D , 14 : E, 15 : F。舉幾個例子,16是10、28是1C。
  • 二維陣列的指標,可以用指標的指標(**),然後c++可以用new得到動態的記憶體。不過小小聲地說…感覺還是vector好用?
Made with Slides.com