c学习笔记(5)-数组以及指针

本文详细介绍了C语言中的数组结构,包括数组的声明、赋值、数组名字的分析。接着讨论了指针与数组的关系,如何通过指针操作数组。还深入讲解了二维数组的使用和初始化,并探讨了二维数组的指针操作,强调了行指针与面指针遍历的区别。
摘要由CSDN通过智能技术生成

1.数组结构

        首先介绍一下什么是数组,当面对一系列有规律的,同类型的,长度固定并且还是排列的,就可以使用数组记录

        数组声明定义:    类型  数组名 [长度]

        成员变量就可以使用   数组名[下标]-------注意数组的第一位是从0开始,假如有三位数,那么就是0,1,2

        并且在使用过程中一定不能越界,比如你有四位,你非得弄到五位数,内存不够,就会提醒你,错误如下

                                                

对数组的赋值

第一种可以进行一个一个赋值,当然在定义数组之后,也可以使用一次直接赋值

bl[0] = 22;
bl[1] = 32; 
bl[2] = 25;
bl[3] = 27; 
bl[4] = 19;

//定义一个五位数组
int bl[5]={22,32,25,27,19}
//可以对后面未标出的数值,默认为0
int bl[5]={0,1}//后面未标出的位数默认为0
//
        C语言数组的长度必须是固定的,在定义时就需要写明确。因为运行时,计算机会为数组创建一片连续存
储空间。

2.对数组名字分析

        再定义一个数组之后,会得到数组名,对于这个数组名,就可以理解是这个数组的首位地址

      也同样是表示为第一个元素的地址

        因此在使用的时候,我们可以用首地址+偏移地址得到我们想要的数据

as+0,as+1--表示对地址进行便宜操作,得到下位元素的操作,这个值与&as[0]的值一样,因此,就完全可以认为

                                as+0=&as[0],   as+1=&as[1]

因为其地址值表示一样,所以对于他们空间的取值,也同样是一样,输出结果完全一样,可以替换

                                        *(as+0)=as[0

                                        *(as+1)=as[1]

3,指针与数组

        通过定义一个指针指向数组的首位地址,这样就可以通过改变指针,来对数组进行操作

int as[]={10,20,30,40,50};
	int *p;
	int i=0;
	p = as;    //as直接表明的就是地址,所以不需要在进行取地址操作
	//指针+1与数组名+1的区别
	p++;        //指针是变量,可以对其进行改变
	as++;       //数组名是一个固定的数,不能进行更该
	
	//数组名+[下标] 与 *(指针+移动) 与 指针+[下标] 的应用效果*/
	printf("%d %d %d %d", as[2], *(as + 2), *(p + 2), p[2]);------输出的的都是30
	// 利用指针变量实现数组的便利操作
	for (i = 0; i < 5; i++)
	{
		printf("%d %d", *(p + i), p[i]);----验证了俩种方法都是一样的,都可以进行输出
	}
	for (i = 0; i < 5; i++)
	{
		printf("%d ",*p++ );//*跟++是同一级别,因此,运算的时候,从右往左进行
	}

4.二维数组

二位数组的类型:int 数组名[][]

二维数组的成员使用:

    arr[0][0] = 1; arr[0][1] = 1; arr[0][2] = 1;
    arr[1][0] = 0; arr[1][1] = 1; arr[1][2] = 0;
    arr[2][0] = 0; arr[2][1] = 1; arr[2][2] = 0;

对内部成员进行遍历:

int h, l;
		for (h = 0; h < sizeof(arr) / sizeof(arr[0]); h++)//arr表示整个二维数组,arr[0]表示第一行的空间大小,相除得到的是数组的行数
		{
			for (l = 0; l < sizeof(arr[0]) / sizeof(arr[0][0]); l++)//第一行的空间大小除以每个元素的空间得到的是列数
			{
				printf("%d ", arr[h][l]);
			}
			printf("\n");
		}

对二维数组进行初始化:

        int arr1[2][3] = { 1,2,3,4,5,6 };
        int arr2[2][3] = { { 1,2,3 } ,{4,5,6 } };        

        如果有不完全初始化的内容,那就其他位置进行补0操作

        int arr3[2][3] = { 1,2,3,4 };
        int arr4[2][3] = { { 1  } ,{4,5  } };

               尤其注意一下,初始成员的个数时候,行数可以由系统自动算出,但是列行不能省略

5.二维数组的指针

       int  arr[3][4]={1,2}

        首先我们先定义一个指针,int *p;让这个指针p指向二维数组的初始地址,p=&arr[0][0]

对于p的这个指针,因为是按位指的,所以是每次移位是一字节

int arr[3][4]={1,2};
	
	int* p;
	p = &arr[0][0];
	
	int i = 0;
	for (i = 0; i < 12; i++)
	{
		/*printf("%d", *p++);*/
		printf("%d",*(p+i));
		/*printf("%d\n", p[i]);*/
	 }

        所以对这个三部分来说意义是一样的,都是对二维数组进行遍历打印

int arr1[5] = {1,2,3,4,5 };
	int arr2[3][4] = { 1,2,3,4,5,6,7,8,9 };
	printf("%d %d %d\n", arr1, arr1 + 1, arr1 + 2);//一维数组每进行地址加一,都是加一个字节的变量
	printf("%d %d %d\n", arr2, arr2 + 1, arr2 + 2);//二位数组进行加,变化类型的也就是离数组名最近的维度,会变化一行的变量,所以是变化4*4
	printf("%d %d %d\n", *(arr1),* (arr1 + 1), *(arr1 + 2));
	printf("%d %d %d\n", *(arr2+0), *(arr2+ 1)+1, *(arr2 + 2)+2);// *(arr2+0)这个是相当于取第0行的空间,因为这个是空间,所以表达出的是这个空间的首地址
	printf("%d %d \n", *(arr2 + 0), arr2);

************一定不要弄混&arr的意思,这个是表明,对这个arr数组整体整体进行取地址,所以&arr+1不是指arr的地址加一,而是地址横跨这个arr数组的内存大小,arr+1则是指跨行**********

int(*pline)[4]---------定义一个指针,是含有四个字节空间的

int*pline[4]--------里面含有四个指针地址-----int*pline[4]={&a,&b,&c,&d}

-----------------------------------------------------------------------------------------------------------------------

int arr2[3][4] = { 1,2,3,4,5,6,7,8,9 };
	int* p;
	int(*pline)[4];//定义行指针
	p = &arr2[0][0];
	pline = arr2 + 0;//*(arr2+0)
		printf("%d %d\n", p, pline);
		printf("%d %d\n", p+1, pline+1);
		for (int j = 0; j < 3; j++)
		{
			printf("%d %d %d %d\n", (*pline)[0], (*pline)[1], (*pline)[2], (*pline)[3]);
			printf("%d\n", *pline++);
		}
 (*pline)[0]-----表示取pline指向的空间,并且取第0个数,跨度是一行的地址

 -------------------------------------------------------------------------------------

行指针遍历

int ge[3][5] = { {1,2},{10,20,30},{111,222} };
		int(*p_ge_line)[5];//定义行指针
		int h, l;
		p_ge_line = &ge;//地址指向数组的首地址
		for (h = 0; h < 3; h++)
		{
			printf("%d\n",p_ge_line);//输出当前行指针所指向的行首地址 
			for (l = 0; l < 5; l++)
			{
				printf("%d %d\n", (*p_ge_line)[l], ge[h][l]);//对二维数组中的值,进行读取
			}
			p_ge_line++;//行指针指向下一行
		}

 --------------------------------------------------------------------------------------------------------------------------

面指针遍历

int ge[3][5] = { {1,2},{10,20,30},{111,222} };
			int(*p_ge)[3][5];//设置一个面指针
			p_ge = &ge;//指向二维数组的首地址
			int h, l;
			for (h = 0; h < 3; h++)
			{
				for (l = 0; l < 5; l++)
				{
					printf("%d", (*p_ge)[h][l]);//找到面指针指向的空间,进行取空间,然后再找行列对应得值
					printf("%d", *(*(*p_ge+h)+l));另一种写法,取二维空间,找到第几行,在取行空间,在找对应的列,再取列空间,就是对应得数值
					printf("%d", ge[h][l]);//最常用的写法
					printf("%d\n", *(*(ge+h)+l));//另一种写法
				}
			}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值