指针与数组
指针
-
指针之间不同类型不能相加
-
指针的类型很重要,决定指针的长度,解析方式
-
指针的类型决定了指针从指针的值前进几个字节
-
指针不能指向数据类型不同的数据
-
const在*左边,可以改变指向,不能修改所修饰变量的值,const在*的右边,不可改变指向,但可以修改值 -
const int * const p指向和数据都不可以改变 -
指针优先级
- *p++,++先执行
- ++p,p先执行,优先级接触生效
-
指针与数组名
int a[10]={1,2,3,4,5,6,7,8,9,10}- a是一个指针,步长为4,&a是一个数组指针,步长为40,*a指向一列,步长为4
int b[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}- b等价于行指针,步长为一行的大小,&b步长就是整个数组,*b步长为一列的一个元素,步长为4
二维数组
-
int a[10],a是int *指针, &a 是int (*)[10]类型,数组指针 -
int(*p)[5] = a+0;//二维数组名本质 -指向一个固定长度的数组的常量指针 -
int a[3][5],a int (*)[5],&a,int (*)[3][5]面指针, *a是int *指针 -
二维数组等同于
*(*(a+i)+j) -
数组优点便于查找, 删除,插入效率低
-
链表,便于插入,删除,不方便查找
-
分块数组,查找效率与数组一样,删除,插入,效率最高
- 分块的数组可以等长,也可以不等长
-
在栈上创建二维数组
- 一维数组:
int *p=(int []){0} - 二维数组:
int (*px)[4]=(int [] [4]){0} - 三维数组:`int (*py)[3][4]=(int [] [3][4])
- 一维数组:
-
堆上分配内存地址连续的二维数组
void main4() { int(*p)[4] = malloc(sizeof(int)* 12);//连续 int num = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("%4d", p[i][j] = num++);// } printf("\n"); } free(p); system("pause"); } -
堆上分配内存地址不连续的二维数组
void main2() { int **pp = calloc(3, 4);//分配指针数组 for (int i = 0; i < 3;i++) { pp[i] = malloc(4 * sizeof(int));//每个指针分配内存 } int num = 0; for (int i = 0; i < 3;i++) { for (int j = 0; j < 4;j++) { printf("%4d",pp[i][j]=num++ );// *( *(pp+i)+j) pp[i][j] //*(pp+i) ==pp[i] pp+i == &pp[i] } printf("\n"); } for (int i = 0; i < 3;i++)//先释放块 { free(pp[i]); } free( pp);//再释放指针数组 system("pause"); }
N级指针
int **********pppppppppp = malloc(4*(sizeof(int *********)))
int*********ppppppppp =malloc(4*(sizeof(int ********))
N级指针,存储N-1级指针的地址
N级指针分配一个数组,存放N-1级指针
数据 0级指针
分块数组
void main()
{
int **pp = malloc(sizeof(int *)* 5);//20个字节,
//*(pp + 0) pp[0]
int num = 0;
for (int i = 0; i < 5;i++)
{
pp[i] = malloc(sizeof(int)*(5+i));
for (int j = 0; j < 5+i;j++)
{
pp[i][j] = num;//赋值
num++;
}
}
for (int i = 0; i < 5;i++)
{
for (int j = 0; j < 5+i; j++)
{
printf("%4d", pp[i][j]);
}
printf("\n");
}
system("pause");
}
二维数组本质
void main2()
{
int b[5];
int a[3][5];
printf("\n%p,%p", a, a + 1);//20个字节
printf("\n%p,%p", *a, *a + 1);//4个字节
//int ** p = a;
int(*p)[5] = a+0;//二维数组名本质 -指向一个固定长度的数组的常量指针
//a = 1;
int *px = *(a+0);//*a 4, *a 就是int *
int (*py)[3][5] =&a; //&a,一个指向固定长宽的二维数组的指针,二维数组指针
system("pause");
//int a[10],a是int *指针, &a 是int (*)[10]类型,数组指针
//int a[3][5],a int (*)[5],&a,int (*)[3][5]面指针, *a是int *指针
}
遍历二维数组
void main1()
{
int a[3][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < 3;i++)
{
for (int j = 0; j < 5;j++)
{
printf("%4d", a[i][j]);
}
printf("\n");
}
for (int *p = &a[0][0]; p < *a + 15; p++)//&a[0][0]
{
printf("%4d,%p\n",*p,p );
}
printf("\n\n");
for (int i = 0; i < 15;i++)
{
printf("%4d,%p\n", a[i / 5][i % 5], &a[i / 5][i % 5]);//游戏
}
// 00 01 02 03 04
// 10 11 12
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%4d %p", a[i][j], &a[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
for (int i = 0; i < 3; i++)
{
printf("\na+%d=%p,%p", i, a + i, &a[i]);//a+i行指针 a + i, &a[i]
}
printf("\n");
printf("\n");
for (int j = 0; j < 5; j++)
{
printf(" %p %p \n", *(a + 0) + j, a[0] + j);// *(a + 0) + j,取地址,改变类型 a[0] + j
printf(" %p %p \n", *(*(a + 0) + j), *(a[0] + j));
}
//a 行指针
//a+i &a[i] 第几行
// *(a+i) a[i] 第i行第0列地址
//*(a+i)+j a[i]+ k 第i行第j列地址
//*(*(a+i)+j) *(a[i]+ k ) 第i行第j列地址
system("pause");
}
指针数组与数组指针
数组指针:指向数组的指针
指针数组:数组中每个元素都是指针
void show(char * str[5])
{
for (int i = 0; i < 5; i++)
{
printf("%s\n", str[i]);
}
}
void show1(char ** str)//指针数组作为参数的时候,数组名的时候会退化为二级指针
{
for (int i = 0; i < 5; i++)
{
printf("%s\n", str[i]);
}
}
void main1()
{
// int *a[10];
//指针的数组的数组名是二级指针
char * str[5] = {"calc","notepad","tasklist","mspaint","pause"};
char **pp = str;
//printf("%p", str);
show1(str);
system("pause");
}
动态数组
静态数组就是编译的时候就确定了大小:int a[10];
动态数组是申请堆上内存:
列必须确定的,行可以动态分配
void main1()
{
//a[N]
int N;
scanf("%d", &N);
int *p;
p = malloc(sizeof(int)*N);
for (int i = 0; i < N; i++)
{
p[i] = i;
printf("\n%d", p[i]);
}
free(p);//释放内存
//free(p);释放内存,只能释放一次,不可以反复释放
system("pause");
}
void main2()
{
// int a[3][10]
int(*p)[10] = malloc(sizeof(int)* 30);
int num=0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 10;j++)
{
printf("%3d", p[i][j] = num++);
}
printf("\n");
}
system("pause");
}
void main3()
{
int *p = malloc(3234567890);
printf("%p", p);
//分配成功返回首地址,
//分配失败返回null
system("pause");
}
void main4()
{
//int *p = malloc(-1);//分配失败为0.-1补码
int *p = malloc(0);
printf("%p", p);//0能分配成功,没有意义
system("pause");
}
void run()
{
void *p = malloc(10);//p占区
//内存泄露,存储地址的指针消亡,就无法释放了
// free(p);
}
void main()
{
int(*p)[3][5] = malloc(sizeof(int)* 30);
int num = 0;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 5;k++)
{
printf("%4d", p[i][j][k] = num++);
}
printf("\n");
}
printf("\n\n");
}
system("pause");
}

浙公网安备 33010602011771号