指针类型的科普(1)

53 阅读3分钟

众所周知,指针是c语言学习的必经之路,也是布满荆棘的道路.*很多初学者因为种种原因倒在指针上面.今天,我想开一个指针系列的博客.现在估计将会有两到三篇.希望大家多多支持.

首先,我们先来 对指针做一个回顾. 1.我们口头说的指针是指针变量,存放的是地址,这个地址会指向内存唯一的一块区域. 2.指针的大小是4/8个字节,取决与是X86/X64系统(32位/64位) 3.指针是由类型的,不同类型的指针+-跨越的步长不同,另外,不同类型的指针解引用能够访问的区域大小不同 在这里插入图片描述 int是整数类型的指针,+1跳过四个字节,因为int的大小就是四个字节 char是字符类型的指针,+1跳过一个字节,因为char的大小是一个字节

指针类型

字符指针

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	char ch = 'a';
	char* p = &ch;
	printf("未改:%c\n", ch);

	*p = 'A';//p存放的是ch的地址,*p相当与ch
	printf("改后:%c\n", ch);

	return 0;
}

在这里插入图片描述 char*是字符指针,存放的是字符类型的地址,且通过 * 可以对该地址所存放的东西进行修改. 值得注意的是常量字符串"hello"传给p指针的是字符串首元素的地址,也就是 h 的地址.

#include<stdio.h>
int main() {
	char* p = "hello";
	return 0;
}

指针数组

指针数组是数组,用来存放指针.

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	int arr1[5] = { 1,2,3,4,5 };
	int arr2[5] = { 2,3,4,5,6 };
	int arr3[5] = { 3,4,5,6,7 };
	int* arr[] = { arr1,arr2,arr3 };//数组名是数组首元素地址
	int i = 0;
	for (i = 0; i < 3; i++) {
		int j = 0;
		for (j = 0; j < 5; j++) {
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述 数组名是首元素地址,而指针是来存放地址的.上面这个指针数组将原本不在一起的三个一维数组组成二维数组.

数组指针

数组指针是指向数组的指针.存放的是数组的地址

数组指针的写法

在这里插入图片描述 上面第一个是指针数组,p先与[ ]结合形成数组 第二个才是数组指针p2先与 * 结合,形成指针,这个数组指针指向的int类型,存放10个元素的数组. [ ]的优先级高于 * .

数组指针的使用

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void Print(int(*p)[5], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			printf("%d ", p[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { { 1,2,3,4,5 } ,{ 2,3,4,5,6 } ,{ 3,4,5,6,7 } };
	Print(arr, 3, 5);
	return 0;
}

我们先来回顾一下,数组名除了在sizeof(数组名)和&数组名情况下,其他都表示首元素的地址. 我们可以把二维数组看作是多个一维数组进行组合.故二维数组的数组名--首元素地址,就是一维数组 { 1,2,3,4,5 } 的地址,得用数组指针来接收

函数指针

从数组指针的定义可以推出,函数指针是存放函数地址的指针 我们先来看一段代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void test() {
	printf("hello\n");
}
int main() {
	printf("%p\n", &test);
	printf("%p\n", test);
	return 0;
}

在这里插入图片描述 我们可以看出,&test和test的效果是一样的.这里跟数组有点类似. 数组名和&数组名得到的地址是一样的.但是又有些不同.区别在于数组名是首元素地址,而&数组名得用数组指针来接受.

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int(*p)[10] = &arr;
	return 0;
}

函数指针的写法 void (p) (int , char) void表示这个函数指针指向的没有返回值的void类型函数,( * p)表明这是个指针,右边的括号是表明是函数,int 和 char 是函数的参数.