准备工作之指针与数组[基于郝斌课程]

数据结构概述
定义:我们如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(比如查找某个元素,删除某个元素,对所有元素进行排序)而执行的相应操作,这个相应的操作也叫算法。

数据结构 = 个体 + 个体的关系
算法 = 对存储数据的操作

算法
解题的方法和步骤

衡量算法的标准
1、时间复杂度
大概程序要执行的次数,而非执行的时间
2、空间复杂度
算法执行过程中大概所占用的最大内存
3、难易程度
4、健壮性

数据结构的地位
数据结构是软件中最核心的课程
程序 = 数据的存储 + 数据的操作 + 可以被计算机执行的语言

指针
指针的重要性
指针是C语言的灵魂
定义:
地址:内存单元的编号,从0开始的非负整数
指针:指针就是地址,地址就是指针
指针变量:是存放内存单元地址的变量
指针的本质是一个操作受限的非负整数
分类:
基本类型的指针
指针和数组的关系


/*
@file      main.c
@brief     数据结构预备知识之指针学习
@author    EricsT (EricsT@163.com)
@version   v1.0.0
@date      2025-09-17
@history   2025-09-17 EricsT - 新建文件
*/




#include <stdio.h>

//int main(void)
//{
//	int* p;
//	int i = 10;
//	int j;
//
//	/*该程序错误
//	由于p保存一个变量地址
//	但是其在定义时未进行初始化
//	故无法知晓它保存的是哪一个变量的地址
//	*p是变量地址的值,故也无法知晓,所以此处编译错误*/
//	j = *p;
//	printf("%d\n", j);
//
//	return 0;
//}

//int main(void)
//{
//	/*
//	* p是一个变量的名字,
//	* int*表示该p变量只能存放int型变量的地址
//  * 不能存放实数
//	*/
//	int* p;
//	int i = 10;
//
//	char ch = 'A';
//
//	/*
//	* 该程序错误,
//	* ch是一个char型变量
//	* 但是p是一个int*型指针,只能存放int型变量的地址,无法存放其他类型变量的地址
//	* 故此处编译错误
//	*/
//	p = &ch;
//
//	return 0;
//}

//int main(void)
//{
//	/*
//	* p是一个变量的名字,
//	* int*表示该p变量只能存放int型变量的地址
//	* 不能存放实数
//	*/
//	int* p;
//
//	/*
//	* 该程序错误
//	* 10是一个实数,不是一个地址
//	* 故此处编译错误
//	*/
//	p = 10;
//
//	return 0;
//}

//int main(void)
//{
//	/*
//	* p是一个变量的名字,
//	* int*表示该p变量只能存放int型变量的地址
//	* 不能存放实数
//	*/
//	int* p;
//	int i = 10;
//
//	*p = i;//此处错误,p未进行初始化,属于野指针
//
//	printf("i = %d,*p = %d", i, *p);
//
//
//	return 0;
//}

int main(void)
{
	/*
	* p是一个变量的名字,
	* int*表示该p变量只能存放int型变量的地址
	* 不能存放实数
	*/
	int* p;
	int i = 10;
	int j;

	/*
	i的值改变,p的值不会变
	p的值改变,i的值不会变
	*p就是i,i的值变了,则*p的值也会发生改变
	*/
	p = &i;
	j = *p;//等价于 j = i

	printf("i = %d, j = %d, *p = %d", i, j, *p);


	return 0;
}

/*
@file      main.c
@brief     数据结构预备知识之指针与函数学习
@author    EricsT (EricsT@163.com)
@version   v1.0.0
@date      2025-09-17
@history   2025-09-17 EricsT - 新建文件
*/

#include <stdio.h>

//void f(int i)
//{
//	i = 100;
//}
//
//int main(void)
//{
//	int i = 9;
//	f(i);
//	printf("i = %d\n", i);//此时i = 9
//
//	return 0;
//}

void f(int* ptr)//ptr接收地址
{
	*ptr = 100;//f(i)时,*ptr就相当于i
}

int main(void)
{
	int i = 9;
	f(&i);
	printf("i = %d\n", i);//此时i = 100

	return 0;
}

/*
@file      main.c
@brief     数据结构预备知识之指针与数组学习
@author    EricsT (EricsT@163.com)
@version   v1.0.0
@date      2025-09-17
@history   2025-09-17 EricsT - 新建文件
*/



#include <stdio.h>

int main(void)
{
	int a[5] = { 1, 2, 3, 9, 5 };//a存放的是该数组首元素即a[0]

	//3[a]、a[3]、*(a + 3)、*(3 + a)是等价的
	printf("3[a] = %d\n", 3[a]);
	printf("a[3] = %d\n", a[3]);
	printf("*(a + 3) = %d\n", *(a + 3));
	printf("*(3 + a) = %d\n", *(3 + a));

	//数组内元素的地址是连续的
	printf("P_a = %p\n", a);
	printf("P_(a + 1) = %p\n", a + 1);
	printf("P_(a + 2) = %p\n", a + 2);
	printf("p_(a + 3) = %p\n", a + 3);

	return 0;
}

/*
@file      main.c
@brief     数据结构预备知识之指针与数组与函数学习
@author    EricsT (EricsT@163.com)
@version   v1.0.0
@date      2025-09-17
@history   2025-09-17 EricsT - 新建文件
*/

#include <stdio.h>

void Show_Array(int* ptr, int iNum)
{
	ptr[0] = -1;

	for (int i = 0; i < iNum; ++i)
		printf("%d\n", *(ptr + i));
}


int main(void)
{
	int a[5] = { 1, 2, 3, 5, 4 };

	Show_Array(a, 5);

	printf("\n\n\n");

	printf("%d", a[0]);
	return 0;
}

因为在32位系统中,地址总线的宽度为32位,在64位系统中,地址总线的宽度为64位,所以无论指针指向的变量占多少字节,在32位系统里面指针都只占4个字节,在64位系统里面指针都只占8个字节。


/*
@file      main.c
@brief     数据结构预备知识之指针学习
@author    EricsT (EricsT@163.com)
@version   v1.0.0
@date      2025-09-08
@history   2025-09-08 EricsT - 新建文件
*/

#include <stdio.h>

int main(void)
{
	double* p;
	double x = 66.6;//x占8个字节,一个字节8位,一个字节一个地址

	p = &x;//p里面存放的是一个地址,存放的是首地址或者是末地址


	double arr[3] = { 1.1, 2.2, 3.3 };

	double* q;
	q = &arr[0];

	double* q1;
	q1 = &arr[1];

	//q和q1相差8
	printf("q = %p\n", q);
	printf("q1 = %p\n", q1);

	return 0;
}

想通过无返回值的函数,对变量进行值的改变,需要进行传址操作


/*
@file      main.c
@brief     数据结构预备知识之指针学习
@author    EricsT (EricsT@163.com)
@version   v1.0.0
@date      2025-09-08
@history   2025-09-08 EricsT - 新建文件
*/

#include <stdio.h>

void f(int * q)
{
	q = (int*)1;
}

void f1(int** q)
{
	q = (int**)1;
}

void f2(int** q)
{
	*q = (int*)1;
}

int main(void)
{
	int i = 9;
	int* p = &i;//int *p; p = &i;

	printf("%p\n", p);

	f(p);//此时p的值不变,因为是传值操作

	printf("%p\n", p);

	f1(&p);//虽然是传址操作,但是值依旧不变,因为未对地址进行解引用,也就是函数只是改变了局部变量的值

	printf("%p\n", p);

	f2(&p);//传址操作,且对地址进行了改变,所以p的值会改变

	printf("%p\n", p);


	return 0;
}

 

posted @ 2025-09-07 22:43  EricsT  阅读(24)  评论(0)    收藏  举报