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 是不行的