您现在的位置是:首页 >技术杂谈 >【04】数据结构与算法基础-类C语言有关操作补充 | 数组的静态、动态定义 | C、C++中内存分配 | C++中的参数传递方式-指针、数组、引用网站首页技术杂谈
【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;
}
运行结果:
引用数据类型作为形参的三点说明:
- 传递引用给函数与传递指针 的效果是一样的,形参变化实参也变化。
- 引用类型作形参,在内存中并没有产生实参的副本,它直接对实参操作而一般变量作参数,形参与实参就占用不同的存储单元,所以形参变量的值是实参变量的副本。因此,当参数传递的数据量较大时,用引用比用一般变量传递参数的时间和空间效率都好;
- 指针参数虽然也能达到与使用引用的效果,但在被调函数中需要重复使用“*指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较差,另一方面,在主调函数的调用点处,必须用变量的地址作为实参。