C语言第八章——指针(二)

本文详细介绍了C语言中的指针运算,包括数组与指针的关系,指针加减运算的原理,以及指针在遍历数组时的应用。此外,还重点讲解了动态内存分配,通过malloc函数如何根据需求分配内存,并通过示例展示了动态内存分配在处理不确定大小数据时的作用。同时,强调了free函数释放内存的重要性以及注意事项。最后,通过示例演示了如何测试系统的最大内存分配能力。
摘要由CSDN通过智能技术生成

指针运算

注:之前已经说到,把数组赋给指针以后,可以拿数组像指针一样操作,也可以拿指针像数组一样操作

//数组像指针一样操作
char ac[]={0,1,2,3,4,5,6,7,8,9};
int *p=ac;
int *p1=&ac[5];

//指针像数组一样操作
*p->ac[0]
*(p+1)->ac[1]
*(p+n)->ac[n]
//*(p+1)要加括号是因为*是单目运算符,优先级比+高
  1. 对指针加1的时候,不是在地址上加1,而是在地址上加一个sizeof那个指针所指的类型,即移到下一个单元上
  2. 但如果指针不是指向一片连续分配的空间,如数组,则这种运算没有意义(好理解)
  3. int *p=ac;int *p1=&ac[5];int *p=ac;可以不写取地址符,和int *p=&ac[0];是一回事,但是int *p1=&ac[5];必须要写,这个要特别注意的
  4. *(p+1)*p+1不一样,要理解
  5. p1-p是什么?两个指针的相减,最后结果是5,这是两个值相减,再除以sizeof那个类型,即是说中间差了几个数组单元
  6. *p++是什么意思?是取出p所指的那个数据来,完事以后顺便把p移到下一个单元,注意,*的优先级虽然高,但是没有++的优先级高,这常用于数组类的连续空间操作
    以遍历数组为例,其实两种写法本质上是一样的
#include<stdio.h>
int main()
{
	char ac[]={0,1,2,3,4,5,6,7,8,9};

	//遍历数组 方法1
	int i;
	for(i=0;i<sizeof(ac)/sizeof(ac[0]);i++)
	{
		printf("%d\n",ac[i]);
	}
	
	//遍历数组 方法2 
	//这时候应该在数组中多一个不能达到的值,比如-1 
	char ac1[]={0,1,2,3,4,5,6,7,8,9,-1};
	char *p=ac1;
	while(*p!=-1)
	{
		printf("%d\n",*p++);
	 } 
	return 0;
 }

动态内存分配

动态内存分配在什么时候用?
C99以前,确定需要多大的单元的时候

#include<stdio.h>
int main()
{
	int number;
	printf("输入数量:"); 
	scanf("%d",&number);
	int a[number];//就是为了解决这件事情
	//因为C99以前不能在方括号中加数字 
	
	return 0;
 }

如上代码

但注意:malloc是必须掌握的东西

详细介绍怎么用

三部曲:

  1. #include<stdlib.h>这个头文件要加上

  2. a=(int *)malloc(number*sizeof(int));这句话的意思是,先讲你需要多少个number,然后乘以你需要的数据类型的大小,就是 你所需要的内存的大小,malloc(你所申请的内存的大小(字节)) ,但是由于只是给你了这片内存,即这篇内存现在没有明确的类型,是void *,因此要再强制类型转换成int * 这一块因为是连续的空间,就可以当成a是数组,进行操作了
    在这里插入图片描述

  3. free(a)释放的应该是原来的地址
    在这里插入图片描述

样例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int number;
	int *a;
	int i;
	printf("输入数量:"); 
	scanf("%d",&number);
	/*
	int a[number];//就是为了解决这件事情
	//因为C99以前不能在方括号中加数字 
	*/
	a=(int *)malloc(number*sizeof(int));

	for(i=0;i<number;i++)
	{
		scanf("%d",&a[i]);
	}
	for(i=number-1;i>=0;i--)
	{
		printf("%d",a[i])
	}
	//数组和指针 能不能混着用取决于是不是一片
	//连续的空间 
	//上面赋值的语句块和逆序输出的语句块完全是按照数组来做的
	
	free(a);
	
	//如果申请失败就会返回0,或者就是NULL 
	
	return 0;
 }

malloc能给我们分配多大的空间

#include<stdio.h>
#include<stdlib.h>
int main()
{
	void *p;
	int cnt=0;
	while((p=malloc(100*1024*1024))) //每次申请100MB的空间,如果最后输出3300MB,就是只能申请33次100MB,也就是只能给你3300个MB的空间 
	{
		cnt++;
	}
	printf("分配了%d00MB的空间",cnt); 
	
	return 0;
 }

这里需要注意的几点

  1. p为什么是void *,因为malloc()本身就是void *,然后再看你的需要来强制类型转换成你需要的
  2. 三部曲中说的就可以把a当成数组用了,其实还是因为a是个地址,其实应该*a,*(a+1),*(a+2)这样子用,但是为啥可以变成a[0],a[1],a[2],上一节笔记中已经详细的总结清楚了
  3. free()只能还首地址(借啥还啥),因为这一片地址空间是以这个首地址代表的,这就像数组一样,要有一个代表这片空间的名儿,还这个名儿就行
  4. 可以free(NULL)。原因是编程的好习惯是定义一个指针就初始化为NULL,类似变量习惯初始化为0一样,只是因为它是指针变量所以初始化为NULL,然后free了个NULL,意思就是不做事情嘛,具体的理解可以理解成,大家都去还东西,必须要借什么还什么(体现在只能还申请来空间的首地址),但是如果你跟它说,我就是来这和你说一声,我没借(其实就是free(NULL)的意思了)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值