C语言 C++ 动态内存 堆区

1.C语言 动态内存分配

1.1 malloc( size_t  size)

作用:在堆区申请长度为size的内存空间 ,返回值为这段内存的首地址。

1.1.1  开辟内存,写入整型数组

开辟的堆区空间,当做数组使用,空间是连续的。

free之后的空间,不会立即失效。通常将free后的地址,再次赋值为NULL。

注意:不可以free野指针,程序会崩溃。free的地址必须是Malloc 申请返回的地址.

例:申请长度为10的整型数组。

	int *p1=(int*)malloc(sizeof(int)*10);
	//写入数据 
	for(size_t i=0;i<10;i++){
		p1[i]=i+10;
	}
	for(size_t i=0;i<10;i++){
			printf("数组是%d\n",p1[i]);
		}
free(p1);
p1=NULL;

1.1.2   字符数组 需要自己加终止符

char *p2=(char*)malloc(sizeof(char)*11);
    if(p2==NULL){
		printf("失败!");
		return -1;
	}
    char str[]="ABCDEFGHIJ";
    for(int i=0;i<10;i++){
		p2[i]=str[i];
	}
    p2[10]='\0'; 
 printf("%s",p2);
    free(p2);
    p2=	NULL;

1.2 二维数组使用动态内存

1.2.1  整型数组

int **p3=(int**)malloc(sizeof(int*)*3) ;
   for(int i=0;i<3;i++){
   	    p3[i]=(int *)malloc(sizeof(int)*4);
   }
 
   //同时写两层数据 
     for(int i=0;i<3;i++){
     	 for(int j=0;j<4;j++){
     	 	p3[i][j]=i+j; // 或者: *(*(p+i)+j)=你的赋值
     	 }
     }
      for(int i=0;i<3;i++){
	      for(int j=0;j<4;j++){
	      	 printf("%d   ",p3[i][j]);
	      }
	      printf("\n");
      }
      //释放内层,再外层 
      for(int i=0;i<3;i++){
      	free(p3[i]);
      }
      free(p3);

1.2.2  字符数组 二维

//二维数组 字符数组 
  char tem[][15]={ //别char *tem[ ]这么写变量。会出警告
  	"hello",
  	"lake",
  	"world",
  	"reading",
  	"aspire"
  };
 
  char **p4=(char**)malloc(sizeof(char *)*5);
  for(int i=0;i<5;i++){
     	p4[i]=(char *)malloc(sizeof(char)*10);
     	  strcpy(p4[i],tem[i]);  
		 //别char *tem[ ]这么写变量。会出警告
		 //原因: tem[i]是const char*  p4[i]是char*
		 //strcpy(p4[i],"coffee");  这么写也行	
     }

     for(int i=0;i<5;i++){
     	printf("%s\n",p4[i]);
     }
     for(int i=0;i<5;i++){
     	free(p4[i]);
     }
     free(p4);

2.C++ 书写习惯 指针  待补充。。。

2.1. C++ 字符数组与指针

首先引入C++头文件

#include <iostream>  
#include <string>   
#include<stdio.h>
#include<string.h>
using namespace std;
	

字符数组


int main (){

	char message[] {"hello world"};
	cout<<message<<endl;
	char *p {nullptr};
	p=message;
	cout<<p<<endl;
	message[1]='D';
	cout<<message<<endl;
	
    //message[23]='W';   //这样不出错,因为原来没写长度。 


//devC++ 警告  还是别这么写 了 
  //	char *mess {"blue sky"};
//	cout<<mess<<endl;
//	cout<<*mess<<endl;
//	cout<<*(mess+1)<<endl;
	
//这两行无效 
//	*mess='D';
//	cout<<mess<<endl;

//这样不警告
const char *p2 {"WRT"};
string petname {"Dami"};
 

	

	const char *p3[] {
		"Here a fox",
		"How are you?"
	};
	cout<<p3[0]<<endl;



//遍历
const char *students[] {
	"Daniel Tang",
	"Tom Kruse",
	"Wang wu",
	"Zhang san"
} ;
cout<<*students<<endl;
cout<<students[2]<<endl;
cout<<"--------------------------"<<endl;

for (const char *stu:students){
	cout<<stu<<endl;
}

cout<<"--------------------"<<endl;
cout<<"--上面的学生名单,进行修改-----"<<endl;
//*students[0]='W';  编译器报错
const char *new_stu {"Fellip Dom"};
students[0]=new_stu; 
cout<<"-----修改后遍历--------"<<endl;
for (const char *stu:students){
	cout<<stu<<endl;
}


//自己尝试新编代码 不用这个烦人的const
//编译器警告   
//  	char *mystus []{
//		"Sha Dolly",
//		"Lily Trumple",
//		"Mellisa Tom"
//	} ;
//	

2.2. C++ 整数数组与指针

2.2.1. 概念辨析:常量指针 const int *  和 指针常量  int* const ,双const

//常量指针,指针指向可以修改 但是指向的值是常量不能修改
	int num1=300;
	const int*p4 {&num1} ; 
//*p4=1000*/     错误语法 

	int num2=500;
	p4=&num2;


//指针指向固定了,但是直接改值
	int* const p5 =&num1;
	cout<<*p5<<endl; 
	*p5=600;
    cout<<*p5<<endl;
//p5=&num2;
//cout<<*p5<<endl;
cout<<"num1   "<<num1<<endl;

还有const int  *const 


//既不能改变指向,也不嫩通过指针改变值
//留下疑问:这种指针的作用是用来指向那些 const int num5=90的变量的么 
int num3=89;
const int* const p6=&num3;	
cout<<*p6<<endl;

 2.2.2. 指针在数组上的3个应用:交换两个数组,计算指针距离,比较指针大小

2.2.2.1 对于数组来讲,数组名可以当做指针使用

int score [] {60,61,62,63,64,65};
int *arrp {score};
cout<<score[0]<<endl;
cout<<*score<<endl;
cout<<arrp[0]<<endl;
cout<<*arrp<<endl;
cout<<arrp<<endl;
cout<<score<<endl;
cout<<&score[0]<<endl;

2.2.2.2 应用:轻松交换两个数组,不用写太多代码

//应用:交换swap两个数组   在arr1和arr2长度相同条件下
int arr1[] {1,2,3,4,5};
int arr2[] {7,8,9,10,11};

int *parr1 {arr1};
int *parr2 {arr2};
int *temp {nullptr};
temp=parr1;
parr1=parr2;
parr2=temp;

for(int i=0;i<5;i++){
	cout<<parr1[i]<<endl; //arr1还是没变!! 
}
//下一行是错误做法 
//int *temp; temp=arr1; arr1=arr2;arr2=temp; 
 
 cout<<"---------Poiner Algorithm-----------------"<<endl;
 cout<<"---------count-----------------"<<endl;		
    int nums[] {10,11,12,13,14,15};
    *(nums+2)=34;
    for(int i=0;i<6;i++){
		cout<<*(nums+i)<<endl;
	}

2.2.2.3 计算两个数在数组中的距离

ptrdiff_t是一个有符号整数,表示两个指针(地址)相减得到的差。有正负。不能随便找俩地址相减!!!必须是数组里的两个地址。

cout<<"---------Distance-----------------"<<endl;


//	 int *p1 {&nums[1]};
//	      int *p2 {&nums[3]};	
     int *pointA {nums+1};
     int *pointB {nums+3};

     
     ptrdiff_t diff1=&nums[4]-&nums[1];
     ptrdiff_t diff2=pointB-pointA;
     
     cout<<"diff1=   "<<diff1<<endl;
     cout<<"diff2=   "<<diff2<<endl;
     cout<<sizeof(diff1)<<endl;//4  就是一个signed int 

 2.2.2.4 数组中的两个指针,可以用比较运算符来比较大小

cout<<"---------Compare Pointer-----------------"<<endl;
  cout<<boolalpha<<endl;
  cout<<(pointA>pointB)<<endl;
  cout<<(pointA<pointB)<<endl;  //true

2.2.3 数组存储在堆区上 动态内存


  cout<<"--堆区,动态分配内存 和数组 -----"<<endl;
  double *arr4{ new double [10]};
  int *arr5 {new(nothrow) int [5]{}};//一个长度为5的数组,每个值都是0 
  int *arr6 {new(nothrow) int [5]{21,22,30,4,5}};//长度写6也行 为0留位置 

   //一定先检查是否空指针!不然程序崩溃
   if(arr6!=nullptr){
   	  for(size_t i=0;i<5;i++){
		 	cout<<"arr6输出打印"<<*(arr6+i)<<endl;
		 }
   } 
   
    delete[]arr4;
    delete[]arr5;
    delete[]arr6;
    
    cout<<"-------注意事项---"<<endl;
	//dongta动态分配的数组跟 栈区的array不同
	//不能用size()hansh函数,也不能用基于范围的for循环 
	//for val:vals 是不行的 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值