cy语言之指针3

指针是一个变量,它存储的是另一个变量的内存地址,而不是数据本身。通过指针可以间接访问和修改它所指向的变量。

数据类型 *指针变量名;

  • 数据类型:指针所指向的变量的类型(如 intcharfloat 等)。

  • *:表示这是一个指针变量。

  • 指针变量名:符合C语言命名规则的标识符。

int *p; // 定义一个指向 int 类型变量的指针 p

char *q; // 定义一个指向 char 类型变量的指针 q

float *r; // 定义一个指向 float 类型变量的指针 r

关键操作符

  • 取地址运算符 &:获取一个变量的内存地址。

  • 解引用运算符 *:访问指针所指向地址中存储的值。

%p:地址格式说明符(以十六进制打印指针中存储的地址值。)

虽然%d也能打印地址但是会报警,虽然不会报错,如下:

注意事项

  • 指针必须初始化,否则指向未知地址(野指针),可能导致程序崩溃。

  • 不能对未分配有效地址的指针解引用。

  • 指针本身也有地址,可以定义指向指针的指针(二级指针)。

指针数组:

指针数组是指一个数组,其中的每个元素都是一个指针变量。它常用于存储多个地址(例如多个字符串、多个数组的起始地址等)。

数据类型 *数组名数组长度;

  • 数据类型:指针所指向的数据类型。

  • *:表示数组元素是指针。

  • 数组名:标识符。

  • 数组长度:元素个数。

p+i == &arri

*(p + i)) == *(arr+i) == arri

指针p通过加减1,来访问地址的值。

数组的值是通过下标也是索引来进行访问的。

数组就是数组,是一块连续的空间(数组的大熊啊和数组元素的个数和元素类型都有关系。)

指针(变量)就是指针(变量),是一个变量(4/8个字节)

数组名是地址,是首元素的地址

可以使用指针来访问数组

arri == *(arr+i) == *(i+arr) == iarr

\[\] 下标引用符 相当于 加减 1+2 == 2+1 ,所以arri==iarr,但是一般都默认写为arri.

数组传参的本质是传递了数组首元素的地址,所以形参访问的数组和实参的数组是同一个数组的。

形参的数组是不会单独在创建数组空间的,所以形参的数组是可以省略掉数组大小的。

正确写法如下:

cs 复制代码
#include <stdio.h>
void Print(int* p, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{

		printf("%d ", *(p + i));
	}
}

int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	Print(arr,sz);//arr数组名就是数组首元素的地址。
	return 0;
}

冒泡排序

冒泡排序的核⼼思想就是:两两相邻的元素进⾏⽐较。

cs 复制代码
#include<stdio.h>
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)//5个数,进行4次排序
	{
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)//每一次排序确定一个数。
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}
cs 复制代码
//⽅法2 - 优化
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int flag = 1;//假设这⼀趟已经有序了
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0;//发⽣交换就说明,⽆序
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (flag == 1)//这⼀趟没交换就说明已经有序,后续⽆序排序了
			break;
	}
}
int main()
{
	int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

⼆级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪⾥?

&a:变量a的地址 0x100

p:指针p的值(存的就是&a)0x100

*p:就是值 10,因为p指向的是a的地址,*p解引用后就得到了值。

*pp :取pp指向的内容,就是p的值 0x100 pp指向的是p,所以*pp就是解引用得到pp所指向的值,是p,而p是地址,想要得到数值,必须在解引用一次。

pp: 指针pp自己的地址 0x200

**pp:两次解引用,得到a值。,此代码中把%p改为%d,就可得到10。

就相当于你想睡觉,得先进大门,在进卧室门,才能睡觉,而大门是pp,卧室门是p,睡觉是a,那么你在大门第一次解引用,得到的是你卧室门的地址,第二次解引用你才能睡觉;如果你直接在卧室门,那么你只需要解引用一次,就可以睡觉了。

指针数组模拟⼆维数组

cs 复制代码
#include <stdio.h>
int main()
{
int arr1[] = {1,2,3,4,5};
int arr2[] = {2,3,4,5,6};
int arr3[] = {3,4,5,6,7};
//数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中
int* parr[3] = {arr1, arr2, arr3};
int i = 0;
int j = 0;
for(i=0; i<3; i++)
{
for(j=0; j<5; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}

parri是访问parr数组的元素,parri找到的数组元素指向了整型⼀维数组,parri j就是整型⼀维数组中的元素。

上述的代码模拟出⼆维数组的效果,实际上并⾮完全是⼆维数组,因为每⼀⾏并⾮是连续的。

相关推荐
sugar__salt13 小时前
从栈队列数据结构到JS原型面向对象全解
前端·javascript·数据结构
froyoisle16 小时前
CSP-J 历年复赛 T1 及解析(2019~2025)
数据结构·c++·算法·csp-j·csp·算法竞赛·信息学
喜欢打篮球的普通人16 小时前
LLVM 后端流程与关键数据结构:从 IR 到机器码的入门笔记
java·数据结构·笔记
Misnearch17 小时前
1、数组/字符串
java·数据结构·算法
008爬虫实战录17 小时前
【数据结构】 树、二叉树、完全二叉树,先序遍历、中序遍历、后序遍历
数据结构·算法
AllData公司负责人17 小时前
大模型赋能AllData数据中台,系列升级|通过联合智谱大模型与BiSheng开源项目,建设企业大模型应用开发平台,支持知识库向量检索!
大数据·数据结构·数据库·算法·大模型·向量数据库·智谱ai
梦想的颜色19 小时前
MySQL 数据存储结构与查询执行生命周期深度解析
运维·数据结构·数据库·mysql·线程·优化
Ameilide19 小时前
数据结构 算法解释,排序、查找
数据结构
真实的菜20 小时前
Redis 从入门到精通(二):深入数据结构 —— 从 RedisObject 到 SkipList 的源码级拆解
数据结构·redis·skiplist
小欣加油1 天前
leetcode41 缺失的第一个正数
数据结构·c++·算法·leetcode