C++培训_007_指针地址内存_数据结构_文件操控(未完成)

指针与地址

定义的时候 加几个 *  就是几级地址。

使用的时候 加几个 * 或者[]  就是还原成指针所指向的数据。 加 几个& 就是把数据还原成他的地址。

const修饰符

#include"iostream"
using namespace std;

int main()
{
	int *p1;
	const int *p2;
	const int **p3;
	//只要不改变你 const 就是对的赋值方式。
	//p1=p2;// 可以改变const 所以错误。 
	//p2=p1;// 不改变 const 正确; 
	//p3=&p1;// 可以改变const 所以错误。
	//因为 p3=&p1 再定义一个数 const int a=10;
	//*p3=&n; *p1=10;这样就达到了改变 const 的目的。所以 p3 = &p1 不可以。 
	return 0;
}

register修饰符

register 修饰的变量 在寄存器中。寄存器是读取最快的存储地点。如果某个东西在程序中经常使用 加上这句就会快到意想不到。

但是最好不要乱加。有时候加上去之后反而更慢。因为寄存器空间很小,加上一个固定的数,那么其它数据就无法使用该地点,反而阻碍程序的速度。

#include"iostream"
using namespace std;

int main()
{
	register int a=3; 
	return 0;
}

二级地址

#include"iostream"
using namespace std;

int main()
{
	
	int a[3][5];
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<5;j++)
		{
			a[i][j]=i*5+j+1;
			//等价于	*(*(a+i)+j)=i*5+j;
		}
	}
	int *p1[5];//宽度为 1 的五个一级指针。
	int (*p2)[5];//宽度为 5 的一个一级指针。
	p2=a;
	cout<<"****"<<endl; 
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<5;j++)
		{
			cout<<*(*(p2+i)+j)<<endl;
			//等价于	cout<<p2[i][j]<<endl;
			
		}
		
	}
	return 0;
}

函数指针

有时候不同的函数有相同的返回值,有相同的输入变量的个数和类型。可以用一个指针指向该函数。调用指针,加快程序运行,方便使用。声明方式和调用见如下代码。

#include"iostream"
using namespace std;
void f1(int a,int b)
{
	cout<<a<<"  "<<b<<endl;
}
void f2(int a,int b)
{
	cout<<"这是第二个函数了"<<endl; 
}
int main()
{
	void (*p)(int ,int );
	p=f1;
	p(1,2);
	p=f2;
	p(1,3);
	return 0;
}

指针函数

指针函数就是返回返回指针的函数。就像 int 函数 是返回 int 的函数。

#include"iostream"
using namespace std;
//返回比 n 大的位置。 
int *getshuzu(int a[],int lenth,int n)
{
	int geshu=0;
	for(int i=0;i<lenth;i++)
	{
		if(a[i]>n)
		{
			geshu++;
		}
	}
	int *sult=new int[geshu+1];//给这个指针分配 geshu 个 int 型内存空间,让函数结束后 内存不被释放。
	int temp=0;
	for(int i=0;i<lenth;i++)
	{
		if(a[i]>n)
		{
			sult[temp++]=i;
		}
	}
	sult[temp]=-1;//用 -1 标识 结束。因为没有位置是 -1 . 
	return sult;
}
int main()
{
	int a[10]={9,8,3,1,5,1,7,8,7,0};
	int *p=getshuzu(a,10,5);//得到比 5 大的位置的数组。
	cout<<"比 5 大的位置为:"<<endl; 
	for(int i=0;p[i]!=-1;i++)
	{
		cout<<p[i]<<"    ";
	}
	cout<<endl;
	return 0;
}

分配销毁内存与变量的生命期和作用域

存储区域

代码区:存放代码。

静态存储区:存放全局的变量和静态变量。

栈区:存放动态局部变量。

堆区:存放申请内存的变量。

  作用域就是函数或者变量可以发挥作用的区域。一般一个花括号内的东西就在本花括号内有作用。比如你把函数写在主函数外面,那么全局都能调用这个函数。但是你把函数写在主函数里,那么只有主函数可以调用这个函数。同样,你把变量写在外面全局都能使用,你把变量写在某个花括号内,那么只有这个花括号内才能使用这个变量。

添加自定义头文件

在项目文件夹里,新建一个文本文档,后缀改为 .h 在里面写好代码后 可以直接包含进该文件夹里的其他文件。

可以在编译器默认的头文件文件夹里自己写头文件,这样,所有用该编译器的文件都可以直接包含这个头文件。

修改头文件路径,用该编译器的文件可以直接使用该头文件。修改图标也在对应的设置里。

代码示范

主函数里:

#include"iostream"
using namespace std;
#include"abc.h"

int main()
{
	f();
	f();
	f();
	f();
	f();
	cout<<endl;
	return 0;
}

自定义的头文件里

#include"iostream"
using namespace std;
void f()
{
	static int temp2=0;
	int temp1=0;
	temp2++;
	temp1++;
	cout<<"int temp1 = "<<temp1<<"		static temp2 = "<<temp2<<endl;
}

运行之后的结果为:



new malloc calloc realloc 分配内存在程序结束后才释放内存。

内存分配

#include"iostream"
#include"stdlib.h"//C语言的 malloc 和 free 等内存函数 用到的头文件。也可以是 #include"malloc.h"
using namespace std;
int main()
{
	int *a1=new int;
	int *a2=new int[10];
	int *b1=(int *)malloc(sizeof(int));//malloc 分配内存不赋值。
	int *b2=(int *)calloc(10*sizeof(int));//calloc 分配内存把内存全调成 0
	realloc(b2,20*sizeof(int));//将内存大小扩大分配到 20 个 int 。 C语言的函数。
	//如果 C++ 想扩大,可以用 realloc 。也可以新 new 一个内存 再把旧内存里的数据复制过去。再删除旧的内存。
	//过程如下 
	int *a3=new int[3];
	a3[0]=0;a3[1]=1;a3[2]=2;
	int *a33=new int[5];
	a33[0]=a3[0];a33[1]=a3[1];a33[2]=a3[2];
	a33[3]=3;a33[4]=4;
	delete []a3;

	delete a1;//删除一个空间的内存。 
	delete []a2;//删除多个时候,前面加上括号 
	free(b1);
	free(b2);
	delete []a33;
	cout<<endl;
	return 0;
}

文件输入输出

fopen  fclose  FILE EOF fgets fgetc frintf fputs

并不实用,不学也罢。都是简单的函数。自己调用试试就知道了。

题目名称
  begin

描述
  编写一个程序,输入一个整数,判断它是否为3位整数,如果是,请输出YES,如果不是,请输出NO。

输入样例1
  1000
输出样例1
  NO

输入样例2
  999
输出样例2
  YES

//要考虑 2147483748*2-100;或者double
//2,147,483,748 × 2 + 100 = 4294967596

#include"iostream"
#include"cstring"
using namespace std;

int main()
{
	freopen("begin.in","r",stdin);
	freopen("begin.out","w",stdout);
	char a[1000000];
	cin.getline(a,1000000);
	int x=strlen(a);
	for(int i=0;a[i]!='\0';i++)
	{
		if(a[i]=='.')
		{
			x=i;
			break;
		}
	}
	if(a[0]=='-')
	{
		cout<<"NO";
	}
	else
	{
		if(x==3)
		{
			cout<<"YES";
		}
		else
		{
			cout<<"NO";
		}
	}
	return 0;
} 

结构体与数据结构

#include"iostream"

using namespace std;
typedef struct stu
{
	char name[20];
	int xuehao;
	double fenshu;
}stu;

// 普通变量 用 点 列出它的成员。 
void P(stu a)
{
	cout<<"姓名"<<a.name<<endl<<"学号:"<<a.xuehao<<endl<<"分数"<<a.fenshu<<endl;
}
// 指针 用 箭头 -> 列出成员 。 
void shuru(stu *a)//为了能够改变 输入的数据。这里用引用。 
{
	cin>>a->name;
	cin>>a->fenshu;
	cin>>a->xuehao;
}
int main()
{
	stu a={"temmo",10,59.9};
	P(a);
	stu b;
	shuru(&b);
	P(b);
	return 0;
}

线性表与链表

线性表是连续存储的,效率高,占用内存少。链表是通过指针链接的内存块,不是连续存储,效率比线性表低一些,还要给指针分配地址,占用内存大一些。

虽然听上去,线性表结构更加优越,但是当数据块太大的时候,不能使用,因为计算机内存没那么大块地方。

实际应用中,为了兼顾二者优点,把线性表和链表组合使用。

一般的线性表

一般的线性表有3部分组成。数据,当前长度,总空间,这三个部分。

//线性表
 
#include"iostream"
#include"cstdlib"
using namespace std;

typedef struct xian
{
	int nowlength;//当前长度 
	int sumlength;//总长度 
	int *data;//数据,可以有很多数据。这里为了方便我写 一个数据。 
}xian;

//创建线性表。长度为 size 。 
xian chuangjian()
{
	xian n;
	n.sumlength=3;
	n.nowlength=0;
	n.data=new int[3];
	return n;
}

//销毁链表。 
void xiaohui(xian *n)
{
	delete [](n->data);
	n->nowlength=0;
	n->sumlength=0;
}

//输出函数
void shuchu(xian n)
{
	cout<<"*******"<<endl;
	for(int i=0;i<n.nowlength;i++)
	{
		cout<<"第 "<<i<<" 个数据为:"<<n.data[i]<<endl; 
	}
	cout<<"*******"<<endl<<endl;
} 
//在第 pos 个位置 插入数据。 
void charu(xian *n,int shuju,int pos)
{
	n->nowlength++; 
	while(n->nowlength>=n->sumlength)
	{
		n->sumlength+=10;//如果满了,就增加一些内存。
		n->data=(int *)realloc(n->data,n->sumlength*sizeof(int));
	}
	n->data[pos]=shuju;
}
int main()
{
	xian head=chuangjian();
	charu(&head,1,0);
	charu(&head,2,1);
	charu(&head,3,2);
	charu(&head,4,3);
	shuchu(head);
	xiaohui(&head);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值