您现在的位置是:首页 >技术杂谈 >【04】数据结构与算法基础-类C语言有关操作补充 | 数组的静态、动态定义 | C、C++中内存分配 | C++中的参数传递方式-指针、数组、引用网站首页技术杂谈

【04】数据结构与算法基础-类C语言有关操作补充 | 数组的静态、动态定义 | C、C++中内存分配 | C++中的参数传递方式-指针、数组、引用

小浪宝宝 2024-07-16 12:01:02
简介【04】数据结构与算法基础-类C语言有关操作补充 | 数组的静态、动态定义 | C、C++中内存分配 | C++中的参数传递方式-指针、数组、引用

1.元素类型说明

1.1顺序表类型定义

typedef struct{
	ElemType data[];
	int length;
}SqList; //顺序表类型

  其中的ElemType可以是char、float等数据类型,根据具体类型进行修改,也可以通过typedef char ElemType;或者typedef int ElemType;提前定义。如果是一个复杂数据类型变量,那么可以如下定义方式:

typedef struct{
	float p;
	int e;
}Polynomial

typedef struc{
	Polynomial *elem;
	int length;
}SqList;

1.2数组定义

数组静态分配:

typedef struc{
	ElemType data[MaxSize];
	int length;
}SqList;	//顺序表类型

  通过以上方式定义数组,需要的内存大小是固定的,数组名“data”存放的是第一个元素data[0]的地址,也就是首地址或基地址。
数动态分配

typedef struc{
	ElemType *data;
	int length;
}SqList;	//顺序表类型

  通过以上方式定义了一个指针变量,来存放指针的地址,内存大小可以使用内存动态分配函数来分配内存,也就是以下方式:

SqList L;
L.data=(ElemType*)malloc(sizeof(ElemType)*MaxSize);

1.3C语言的内存动态分配

malloc(m)函数,开辟m(m要求为整数)字节长度的地址空间,并返回这段空间的首地址;
sizeof(x)运算,计算变量x的长度;
free(p)函数,释放指针p所指变量的存储空间,即彻底删除一个变量。
需要加载头文件:<stdlib.h>

1.4C++的动态存储分配

1.4.1创建内存

new 类型名T(初值列表) 
  功能:
  	申请用于存放T类型对象的内存空间,并依初值列表赋以初值
  结果值:
  	成功:T类型的指针,指向新分配的内存
  	失败:0(NULL)

【应用举例】:

int *p1=new int;int *p1=new int(10);

  new也是得到空间的地址,需要赋值给指针变量。

1.4.2释放内存

delete 指针P
功能:
	释放指针P所指向的内存。P必须是new操作的返回值

【应用举例】:

delete p1;

1.5C++中的参数传递

  函数调用时传送给形参便的实参必须与形参保持三个一致:类型、个数、顺序。参数传递有两种方式:传值方式(参数为整型、实型、字符串等);传地址(参数为指针变量、引用类型、数组名)。

1.5.1传值方式

  把实参的值传送给函数局部工作区相应的副本中,函数使用这个副本执行必要的功能。函数修改的是副本的值,实参的值不变。

#include<iostream>
using namespace std;
void swap(float m, float n)
{
	float temp;
	temp = m;
	m = n;
	n = temp;
}
void main()
{
	float a, b;
	cin >> a >> b;
	swap(a, b);
	cout << "a=" << a << endl << "b=" << b << endl;
	system("pause");
}

运行结果
在这里插入图片描述
  上段程序首先输入a和b的值,然后调用swap函数,a赋值给m、b赋值给n,在函数中进行m和n值的调换,执行完函数后m和n的值被释放掉,回到调用函数swap的地方继续执行,对a和b的值不产生任何影响,此处是传递的值

1.5.2传地址方式-指针变量

  传地址方式,指针变量作为参数,形参的变化将影响实参。

#include<iostream>
using namespace std;
void swap(float *m, float *n)
{
	float temp;
	temp = *m;	//此处的*是取的m地址中的内容
	*m = *n;
	*n = temp;
}
void main()
{
	float a, b, *p1, *p2;
	cin >> a >> b;
	p1 = &a; p2 = &b;
	swap(p1, p2);
	cout << "a=" << a << endl << "b=" << b << endl;
	system("pause");
}

运行结果
在这里插入图片描述
  形参变化也可以不影响实参。

#include<iostream>
using namespace std;
void swap(float *m, float *n)
{
	float *temp;
	temp = m;	//此处temp被赋值为m的地址,对实际值无影响
	m = n;
	n = temp;
}
void main()
{
	float a, b, *p1, *p2;
	cin >> a >> b;
	p1 = &a; p2 = &b;
	swap(p1, p2);
	cout << "a=" << a << endl << "b=" << b << endl;
	system("pause");
}

运行结果
在这里插入图片描述

1.5.3传地址方式-数组名

  传递的是数组的首地址,对形参数组所做的任何改变都将反应到实参数组中。下面程序中的“b[]”可以用“*b”替代,都是指代数组a的地址。

#include<iostream>
using namespace std;
void sub(char b[])
{
	// 通过指针修改 a 数组的内容
	//伪代码:b[]="world";
	b[0] = 'w';
	b[1] = 'o';
	b[2] = 'r';
	b[3] = 'l';
	b[4] = 'd';
}
int main()
{
	char a[10] = "hello";
	sub(a);
	cout << "a=" << a << endl;
	system("pause");
	return 0;
}

运行结果
在这里插入图片描述
应用举例】:用数组作函数的参数,求10个整数的最大数。

#include<iostream>
using namespace std;
#define N 10
int max(int b[]);
int main()
{
	int a[10];
	int i, m;
	for (i = 0; i < N; i++)
	{
		cin >> a[i];
	}
	m = max(a);
	cout << "the max number is:" << m << endl;
	system("pause");
	return 0;
}
int max(int b[])
{
	int i, n;
	n = b[0];
	for (i = 1; i < N; i++)
	{
		if (n < b[i]) n = b[i];
	}
	return n;
}

运行结果
在这里插入图片描述

1.5.4传地址方式-引用类型

  引用是用来给一个对象提供一格替代的名字。例如下面程序中j将引用i,j是一个引用类型,代表i的一个替代名。i值改变时,j值也将改变,所以会输出“i=7,j=7”。也就是j取了i的地址,j和i共用了同一块内存空间。

#include<iostream>
using namespace std;
int main()
{
	int i = 5;
	int &j = i;
	i = 7;
	cout << "i=" << i << ",j=" << j << endl;
	system("pause");
	return 0;
}

运行结果
在这里插入图片描述
应用举例】:用引用类型交换a和b的值

#include<iostream>
using namespace std;
void swap(float& m, float& n)
{
	float temp;
	temp = m;
	m = n;
	n = temp;
}
int main()
{
	float a, b;
	cin >> a >> b;
	swap(a, b);	
	cout << "a=" << a << ",b=" << b << endl;
	system("pause");
	return 0;
}

运行结果
在这里插入图片描述
引用数据类型作为形参的三点说明

  1. 传递引用给函数与传递指针 的效果是一样的,形参变化实参也变化
  2. 引用类型作形参,在内存中并没有产生实参的副本,它直接对实参操作而一般变量作参数,形参与实参就占用不同的存储单元,所以形参变量的值是实参变量的副本。因此,当参数传递的数据量较大时,用引用比用一般变量传递参数的时间和空间效率都好;
  3. 指针参数虽然也能达到与使用引用的效果,但在被调函数中需要重复使用“*指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较差,另一方面,在主调函数的调用点处,必须用变量的地址作为实参。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。