C語言中的指針專欄

一級指針

指針是什麼
我們可以把宿舍樓裏面的每一個同學看成一個個的變量,存放在一個個宿舍裏,而爲了方便找到每個同學,我們給每個宿舍標號,而指針就是每個宿舍的門牌號,它的值直接指向地址所對應的變量單元。
爲什麼要有指針
很明顯我們找到一個個同學最快的方式就是通過宿舍門牌號,指針就是爲了能找到以它爲地址的內存單元。
總結:指針就是地址,指針變量就是變量,用來存放地址的變量(存放在指針裏的值都會被當成地址來處理)。注意:一個int型變量佔四個字節,每個字節都有一個地址,指針變量存放的是第一個地址。
代碼說明:

#incude <stdio.h>
int main()
{
    int a=10;
    int *p=&a;
    return 0;
}

那麼在這段代碼裏,a的地址就是存放在變量p中的,p就是一個指針變量。
指針的大小
指針的大小在32位平臺上 是4個字節,在64位平臺上是8個字節。
指針的解引用
指針就是它指向的目標

int main()
{
	int n = 0x11223344;
	char *pc = (char *)&n;
	int *pi = &n;
	*pc = 0x55;
	*pi = 0;
	return 0;
}

總結:指針的類型決定對指針解引用的權限。char的指針解引用就只能訪問一個字節,而int的指針能訪問四個字節。

指針±整數
一句話:指針±1是±其所指元素的類型大小。所以多級指針±1都是±4個字節,因爲其所指類型都是指針。
下面來看一段代碼:

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int n = 10;
	char *pc = (char *)&n;
	int *pi = &n;

	printf("%p\n", &n);//1
	printf("%p\n", pc);//2
	printf("%p\n", pc+1);//3
	printf("%p\n", pi);//4
	printf("%p\n", pi+1);//5
	system("pause");
	return 0;
}

這裏一共打印了五個變量,1、2、4不做過多解釋,我們看到3和5都出現了指針+1,不同的是,3裏pc指向的變量類型是char 類型,所以pc+1只+一個字節。而5裏pi指向的變量類型是int 型,所以pi+1就+4個字節。
打印結果如下:
在這裏插入圖片描述
指針±指針
代表兩個指針之間所經歷的的元素個數
舉一個例子:

int my_point(int a[10])
{
       int *p=&a[0];
       int *q=&a[9];
       retunr q-p;
}

很明顯,這裏指針p指向的是下標爲0的第一個元素,q指向下標爲9的第十個元素,所以q-p就是指針q和指針p之間所經歷8的元素個數,爲9.
同樣,指針之間的運算還可以用來求字符串長度:

int my_strlen(char *a)
{
	char *p = a;
	while (*p != '\0')
	{
		p++;
	}
	return p-a;
}

二級指針

前面我們談及的都是一級指針,我們知道指針變量也是變量,是變量就有地址,就可以被存放,二級指針就是用來存放指針的地址。
在這裏插入圖片描述
如上圖所示,a的地址存放在pa中,pa的地址存放在ppa中,ppa就是一個二級指針。
二級指針解引用
*ppa就是訪問pa。

int b=20;
*ppa=&b;//等價於 pa=&b
**ppa=30;
//等價於*pa=30;
//等價於a=30;

指針和數組

指針和數組本身是沒有聯繫的。
數組名的概念
我們先看一段代碼。

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	system("pause");
	return 0;
}

在這裏插入圖片描述
由此可見,數組名和數組首元素的地址是一樣的。數組名錶示的就是數組首元素的地址。
那麼再看下一段代碼:

int arr[20]={1,2,3,4,5,6,7,8,9,0};
int *p=arr;

在這裏p存放的是首元素的地址。那麼我們可以使用指針來訪問一個數組。

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
	int *p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d]=%p   p+%d=%p\n", i, &arr[i], i, p + i);
	}
	system("pause");
	return 0;
}

在這裏插入圖片描述
很明顯,&arr[i]和p+i結果是一樣的。所以p+i其實計算的是數組的arr下標爲i的地址。
那麼我們現在直接通過指針來訪問數組:

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
	int *p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf(" %d", *(p + i));
	}
	system("pause");
	return 0;
}

沒有懸念,打印效果如下:
在這裏插入圖片描述

總結

指針也是一個變量,只不過和其他變量不同的原因是:其他變量放值,指針放地址。所以我們不要害怕指針,就和所有的變量一樣處理就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章