vlambda博客
学习文章列表

C语言程序10:指针中级篇

C语言程序10:指针中级篇

Merry Christmas

C语言程序10:指针中级篇

指针中级





指针中级篇


//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;

}



我知道你在看

C语言程序10:指针中级篇




新浪微博:@秀米XIUMI