指標初階

許木101發表於2023-02-16

1. 指標

 

地址,空間

大部分數字計算機將記憶體,分割為一個個空間,每一個空間大小為一個位元組

每一個位元組,都對應著一個編號進行管理,這些編號也稱為地址

指標初階

什麼是指標,指標變數

C語言通常稱為低階語言,這裡的低階是指C語言與計算機底層有緊密的聯絡,可以透過指標來訪問記憶體空間

所以,指標可以理解為地址

既然指標就是地址,那麼指標變數就是儲存地址的變數

口語中的指標,實際上是指標變數

 

指標的申明

int * pa

* 表示pa是一個指標,

int, 表示指標的型別為整形, 儲存的是一個整形變數的地址,也叫做指向整形的指標

指標初階

 

 

取地址& ,間接引用* 運算子

直接看一個例子

#include <stdio.h>
int main()
{
	int a = 1;
	int* pa = &a;
	*pa = 2;
	printf("%d", a);
}

指標初階

 

執行流程

1,int a = 1

開闢4個位元組的空間,然後將1存進去

指標初階

指標初階

2,int* pa = &a

&, 取地址運算子

&a表示取出整形變數a的起始地址,存入整形指標pa的儲存空間中

指標初階

指標初階

 

3, *pa = 2

* ,間接定址運算子,透過地址訪問對應的空間

pa 儲存的是a的地址, *pa 實際上訪問的是a的空間,然後將存入2

指標初階

指標初階

 

2. 指標型別

指標的大小

#include <stdio.h>
int main()
{
	printf("%d\n", sizeof(char*));
	printf("%d\n", sizeof(int*));
	printf("%d\n", sizeof(double*));
    
}

指標初階

指標是儲存地址的變數,地址的大小由機器地址線決定

所以指標的大小都是一樣的,和型別無關

那麼,指標型別的意義是什麼 ?

 

型別的意義

1. 型別決定,*定址的許可權

觀察下面兩個例子

#include <stdio.h>
int main()
{	
	int a = 0x11223344;
	int* pa = &a;
	*pa = 0;
}

指標初階

#include <stdio.h>
int main()
{	
	int a = 0x11223344;
	char* pa = (char*)&a;
	*pa = 0;
}

指標初階

當pa的型別為整形時,*定址可以一次性訪問4個位元組

pa型別為字元時, 只能訪問一個位元組

 

2. 型別決定,指標的步長

#include <stdio.h>
int main()
{	
	int a = 0x11223344;
	int* pa = &a;
	char* pb = (char*)&a;
	printf("%p\n", pa);
	printf("int*: %p\n", pa + 1);
	printf("char*: %p\n", pb + 1);

}

指標初階

pa, 整形指標, +1跳過了4個位元組

pb, 字元指標, +1跳過了1個位元組

型別決定指標進行運算時,具體跳過多少個位元組

 

3. 指標運算

指標 + 整數

#include <stdio.h>
int main()
{
	int a = 0;
	int* pa = &a;
	char* pb = (char*)&a;
	printf("%p\n", pa);
	printf("%p\n", pa+1);
	printf("%p\n", pb);
	printf("%p\n", pb + 1);
}

指標初階

從中可以發現,指標+整數,是向高地址移動的,指標的步長由指標的型別決定

 指標初階

 

指標 - 整數

#include <stdio.h>
int main()
{
	int a = 0;
	int* pa = &a;
	char* pb = (char*)&a;
	printf("%p\n", pa);
	printf("%p\n", pa - 1);
	printf("%p\n", pb);
	printf("%p\n", pb - 1);
}

 指標初階

指標-整數時,指標向低地址移動,移動的步長由型別決定

 

指標 - 指標

#include <stdio.h>
int main()
{
	int arr[10] = {0,1,2,3,4,5,6,7,8,9};
	printf("%d\n", &arr[9] - &arr[0]);
}

指標初階

指標 - 指標,得到的是兩個指標之間的元素個數

 

分析

指標初階

 指標初階

注意: 

C語言規定,指標 - 指標時,必須要確保兩個指標指向同一記憶體塊

同時,保證兩個指標型別相同

 

指標 - 指標的應用

// 求字串長度
#include <stdio.h>
 
int len1(char* str)
{
	int count = 0;
	char* ps = str;
	while (*str != '\0')
	{
		str++;
	}
	return str - ps; // 指標 - 指標
}
int main()
{
	char arr[] = "abcdef";
	int res = len1(arr);
	printf("%d\n", res);
	return 0;
}

指標初階 

指標初階

 

指標的關係運算

可以用關係運算子,對兩個指標進行比較

比較的結構,取決於兩個指標在同一記憶體塊中的地址

#include <stdio.h>
int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	printf("%d\n", &arr[9] <= &arr[0]);
	printf("%d\n", &arr[9] >= &arr[0]);
}

 指標初階

陣列元素9的地址大於或等於元素0 的地址,為1(真)

所以,兩個指標之間進行比較,實際上比較的是地址

 

4. 二級指標

什麼是二級指標

指標是一個儲存地址的變數,既然是一個變數,那麼就可以用&取地址運算子,取出一個變數的地址

所以,二級指標就是儲存一個一級指標地址的變數,也叫做指向指標的指標

#include <stdio.h>
int main()
{
	int a = 0;
	int* pa = &a;	// 一級指標
	int* *ppa = &pa;	// 二級指標
}

 

 指標初階

 指標初階

二級指標的宣告與賦值

int* *ppa;

ppa前面的*, 表示pppa是一個指標變數,用來儲存地址

int*, 表示變數ppa儲存的是一個一級整形指標的地址

 

int* *ppa = &pa;

 二級指標和一級指標一樣,可以用 =賦值運算子,進行賦值

 

二級指標的使用

#include <stdio.h>
int main()
{
	int a = 0;
	int* pa = &a;	// 一級指標
	int** ppa = &pa;	// 二級指標
	**ppa = 1;
	printf("%d\n", a);
}

 指標初階

 * *ppa = 1

*ppa,表示訪問ppa的空間, ppa存放的是pa的地址, 所以可以這麼理解 **ppa = *(pa)

*pa, 訪問的是a的空間,並存入1

 

相關文章