C语言~指针进阶(1)

一维数组指针:

数组名:可以代表首地址,那么咱们就可以用指针指向数组。

虽然数组名可以代表一个元素首地址,但是它是个常量,不能自增或者自减!但是可以创建一个指针指向数组,然后++。

int arr[10];
arr++; //	error E0137	表达式必须是可修改的左值	
       //   error C2105	“++”需要左值


printf("%p \n", arr); //1  004FF810,代表第一个元素地址
printf("%p \n", &arr);//2 004FF810,代表整个数组      1,2的值一样但是意义完全不同
printf("%p \n", arr + 1);  //3 004FF814  跳过一个元素
printf("%p \n", &arr + 1);//4  004FF9A0  跳过了一个数组 


int arr[6] = {0,1,2,3,4,5};
//p是个指针变量,可以任意操作   &arr[0]==arr
int* p = &arr[0];
p++;
printf("%d", *(p++));//输出结果:1
//&arr的类型是:int (*)[6]指向整个一维数组的类型
int a = &arr;//error:C2440	“初始化” : 无法从“int(*)[6]”转换为“int”
int(*pp)[6] = &arr;  //正确的做法

二维数组指针:

//定义一个二维数组
	int map[5][2] = { 1,2,3,4,5,6,7,8,9,10 };
	//定义指针指向二维数组
	//int a = ↦ //error:	C2440	“初始化” : 无法从“int(*)[5][2]”转换为“int”
	int(*p)[2] = ↦//(*p)为了让p先于*结合,成为一个指针,[2]是二维数组列数
	

p+1得到的是map[1]地址,因为map[1]里包含map[1][0],map[1][1]  所以不能直接*(p+1)来获取数值,

只能**(p+1)来获取

//p+1==map[1]        map[1][0]==**(p+1)
printf("\n%d", *(p + 1));//输出结果:4585576  /*警告	C6273	传递了一个非整数作为_Param_(2),而对“printf”的调用需要一个整数,实际类型: “int[2]” : 如果当前传递的是一个指针值,则应使用 % p */
printf("\n%d", **(p + 1));//输出结果:3    等价于(*(p+1))[0]

printf("\n%d", map[1][1]);//4
printf("\n%d", (*(map + 1))[1]);//4   map+1==&map[1]   *(p+1)==map[1]第一个元素首地址   (*(p+1))[1]==(*(map+1))[1]
printf("\n%d", (**(map + 1))+1);//4

内存四区:

1.栈区:放在栈区的变量,生命周期结束自动释放内存     例如:int age=3;

2.堆区:需要手动申请,需要手动释放,如果忘记释放就会导致内存泄漏

3.全局区:静态变量   全局变量  常量(不是const定义的)

4.代码区:代码,二进制代码

int num = 0;//栈区
	const double p = 3.14;//栈区
	static aa = 0;//全局区
	char arr[] = "hello";//栈区
	"hello";//全局区(常量区)
	printf("%p    %p", arr, "helllo");//输出结果:007FFB9C    00F67BCC

动态内存分配:

malloc:

//动态内存分配,在堆区
	int* pa = (int*)malloc(sizeof(int));
	//防御性编程
	if(pa == NULL)
	{
		return -1;//如果申请失败返回-1
	}
	//使用
	*pa = 18;
	printf("%d", *pa);//输出结果:18

	//不要改变pa指向,如果改变了,释放就会出错,内存会泄露,后果很严重
	 (*pa)++;
	 printf("\n%d", *pa);//输出结果:19
	
	 //如果实在改变了要在释放内存前恢复原样再释放
	 (*pa)--;
	//释放内存
	free(pa);
	pa = NULL;//释放后再置空,后面再使用这个内存就会报错
	
	危险:使用了释放了的内存
	//*pa = 6666;
	//printf("\n%d", *pa);

realloc:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BABY_NUM 61
int main()
{
	//定义一个数组存储所有同学年龄
	//int ages[61];//虽然这样也可以,但是不够灵活,要是同学少于61则浪费内存,多余61数组又不够大
	int* ages = (int*)malloc(sizeof(int)* BABY_NUM);
	if (!ages)
	{
		return -1;
	}
	for (int i = 0; i < BABY_NUM; i++)
	{
		*(ages + i) = 19;
		printf("%d\n", ages[i]);
	}
	printf("\n");
	//怎么调整大小?realloc传进去的内存已经释放掉了,返回的是新的内存地址
	int* Newages = (int*)realloc(ages, sizeof(int) * 59);
	if (!Newages)
	{
		Newages = ages;
		//free(ages);
		return -2;
	}
	for (int j = 0; j < 59; j++)
	{
		
		printf("%d", Newages[j]);
	}
	free(Newages);


	return 0;
}

calloc:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
	int capacity = 10;//容量
	int* pa = (int*)malloc(sizeof(int) * capacity);//malloc不会自动初始化
	memset(pa, 0, sizeof(int) * capacity);//清空数组内存
	for (int i = 0; i < capacity; i++)
	{
		printf("%d", pa[i]);//如果不用memset输出结果:-842150451-842150451...垃圾值
	}
	printf("\n");
	int* pa2 = (int*)calloc(capacity, sizeof(int));//calloc自动初始化为0
	for (int i = 0; i < capacity; i++)
	{
		printf("%d ", pa2[i]);//输出结果:0 0 0 0 0 0 0 0 0 0
	}

	//别忘了释放置空
	free(pa);
	pa = NULL;
	free(pa2);
	pa2 = NULL;

	
	return 0;
}

指针数组:

//指针数组
	//数组里的元素都是int型指针
	int* arr[5] = { NULL };
	for (int i = 0; i < 5; i++)
	{
		arr[i] = (int*)calloc(5, sizeof(int));
		for (int j = 0; j < 5; j++)
		{
			arr[i][j] = j;
		}
	}
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			printf("%d  ", **(arr+1)+j);
		}
		printf("\n");
	}
	for (int i = 0; i < 5; i++)
	{
		free(arr[i]);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Luckys-Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值