C语言程序10:指针中级篇
Merry Christmas
指针中级
指针中级篇
//1.一级指针动态内存申请
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>//malloc函数报错 ,头文件
/*
size_t: unsigned int
动态内存申请
1.void * malloc(size_t size);
malloc 显著的特点是:申请的内存不会被初始化
2.void * calloc(size_t count,size_t size); //size_t count:申请多少个这样的数据;size_t size : 申请字节数。
calloc会给申请的内存初始化 :
数字类:初始化为0
字符类:\0
3.void * realloc(void *p,size_t size); //重新申请内存
4.free(void *p); //释放内存 ,三种释放方法一样。
*/
void print(unsigned int size)
{
printf("%d\n", size);
}
int main()
{
//堆内存
int *p = (int *)malloc(sizeof(int)); //申请一个变量内存
//编译器是vs2019 申请完成后必须做判NULL处理--->防御性编程:标准写法
if (p == NULL) //NULL表示一个常属性,本身是没有内存的,所以不能重新赋值。
{
printf("申请内存失败!\n");
return;
}
*p = 123;
printf("%d\n", *p);
char *pChar = (char *)malloc(sizeof(char));
*pChar = 'A';
printf("%c\n", *pChar);
//一级指针如何成为数组
int *array = (int *)malloc(sizeof(int)* 10);
//指针变量的类型 int *sizeof(int *)
char cNum = 'A';
for (int i = 0; i < 10; i++)
{
//array[i] = i;
*(array + i) = i;
}
for (int i = 0; i < 10; i++)
{
printf("%d\t", array[i]);
}
printf("\n");
//char *pStr = NULL;
//scanf("%s", pStr);
free(p);
//释放注意点: No.1 释放完后,置空处理
//原因:野指针(没有指向的指针(没有初始化)) 造成内存泄漏
//No.2 同一段内存不能被重复释放
//free(p);
p = NULL;
//程序关闭完,内存会被回收
//内存池-->程序内存管理
free(pChar);
pChar = NULL;
free(array);
array = NULL;
printf("你想要输入几个字符:");//用户眼里只有可见长度
int size = 0;
scanf("%d", &size);
char *str = (char *)malloc(sizeof(char)*(size + 1)); //需要考虑字符串结束标记
fflush(stdin);
gets(str);
puts(str);
for (int i = 0; i < 3; i++)
{
str++;
}
for (int i = 0; i < 3; i++)
{
str--;//从哪里申请的就要从哪里释放!
}
free(str);
str = NULL;
//malloc 显著的特点是:申请的内存不会被初始化
//其他申请内存
//申请10个 数据,每个数据占用的字节数sizeof(int)
int *pCalloc = (int *)calloc(10, sizeof(int));
for (int i = 0; i < 10; i++)
{
printf("%d\t", pCalloc[i]);
}
printf("\n");
free(pCalloc);
pCalloc = NULL;
//释放内存的后指针,可以重新申请内存
pCalloc = (int *)calloc(1, sizeof(int));
printf("%d\n", *pCalloc);
//初始化:第一次赋值-->赋初值
//赋值:=
free(pCalloc);
pCalloc = NULL;
//realloc:再申请 不会初始化, 同时也具备拷贝操作,就是将原来已经赋值的拷贝到再申请的内存中去。
int *pInt = (int *)malloc(sizeof(int)* 2);
pInt[0] = 1;
pInt[1] = 2;
printf("pInt=%d\n", pInt);
pInt = (int *)realloc(pInt, sizeof(int)* 4);//再申请的内存要比原来的内存大。
pInt[2] = 3;
pInt[3] = 4;
for (int i = 0; i < 4; i++)
{
printf("%d\t", *(pInt + i));
}
printf("\n");
printf("%d\n", pInt);
//bad_alloc-->申请内存异常,可以捕获到
//windows内存管理
//1G-2G--->内存读写
//用循环,肯定会失败
//char *pMax = (char *)malloc(sizeof(char)* 1024 * 4*1024);
//if (pMax == NULL)
//{
//printf("申请内存失败!\n");
//system("pause");
//return;
//}
system("pause");
return 0;
}
//2.二级指针与二维数组
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int *)malloc(sizeof(int)* 10);//一级指针
//p--->p[10] 存放多个整数
//二级指针
//pp-->pp[3] 存放的是多个int *: 指针变量(指针类型)
for (int i = 0; i < 3; i++)//相当于再申请内存
{
pp[i] = (int *)malloc(sizeof(int)* 2);相当于列,从0开始
}
//pp--->等效 pp[3][2];
int count = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
pp[i][j] = count++;
printf("%d\t", pp[i][j]);
}
}
//一级指针:p[i]--->*(p+i);
//二级指针: pp[i][j]
/*
令 pp[i] 等于X
对于 pp[i][j] 等效于X[j]
X[j]--->*(X+j);
pp[i]-->*(pp+i)
--> *(*(pp+i)+j)等效pp[i][j]
-->*(pp[i]+j)
*/
printf("\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
//printf("%d\t", *(*(pp + i) + j));
printf("%d\t", *(pp[i] + j));
}
}
printf("\n");
//注意点: 申请内存不满足规律(不连续)
//正常的数组 用指针法表示
int array2D[3][2] = {5,4,3,2,1,0};
//错误代码
//int **pArray = &array2D[0];
//数组指针
//整形数组:存放多个整数的数组
//指针数组: 存放多个指针的数组
//[]优先级高于*
printf("\n");
int (*pArray)[2] = array2D;
//数组指针的类型: 去变量名 ,类型就是 int(*)[2];
//数值指针所指向的类型: int [2] 移动一步就是8个字节
//指针偏移量: p+n :p+sizeof(指针所指向的类型)*n
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
//printf("%d\t", *(*(pp + i) + j));
printf("%d\t", *(pArray[i] + j));
}
}
printf("sizeof(pArray):%d\n", sizeof(pArray));
pArray++;
printf("num:%d\n", *(pArray[0]+1));
//行指针概念:不能够访问到具体元素的值的指针都是行指针
//列指针概念:所有能够访问到具体元素的值的指针都是列指针
//int array1D[3] = { 1, 2, 3 };
//pMove++;
system("pause");
return 0;
}
//3.指针数组与数组指针
#include <stdio.h>
#include <stdlib.h>
/*
如何区别?
数组指针: int (*p)[2]; //如果优先和星号结合,就是数组指针
指针数组: int *p[2]; // 如果优先和方括号结合,就是指针数组
*/
int main()
{
int a = 1;
int b = 2;
int c = 3;
//指针数组 ,以数组为主体,即数组中用到指针。
int *pNum[3] = { &a, &b, &c }; //存放多个一级指针
//pNum[0] pNum[1] pNum[2]; //都是一级指针
//主要用在操作字符串
char *pStr[3] = { "ILove", "ILoveyou", "IMissyouDear" };
for (int i = 0; i < 3; i++)
{
printf("%s\n", pStr[i]);
}
//数组指针
//1.操作二维数组
//2.动态内存产生二维数组
//理解 : 指针的类型:去掉变量名
// 指针所指向的类型: 去掉变量名和*
int(*p)[2] = (int(*)[2])malloc(sizeof(int[2])*2);
int count = 0;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
p[i][j] = count++;
printf("%d\t", p[i][j]);
}
}
printf("\n");
free(p);
p = NULL;
system("pause");
return 0;
}
我知道你在看哟
新浪微博:@秀米XIUMI