007-数组,指针

007-数组,指针

数组:

什么是数组?数组有什么用?

​ 数组即是同类型变量的集合;
​ 作用就是一次性定义多个同类型的变量;

如何定义数组:

格式:
​ 数组的成员类型 数组名[数组的成员个数]

​ 数组的成员类型也被称为数组的基本类型;
​ 数组的成员个数决定了系统为数组分配的空间的多少;
​ 系统会为数组的每一个成员分配一个对应的存储空间;
​ 系统会为数组分配一个连续的存储空间,顺序存放数组的成员变量;

数组的成员类型有哪些:
​ 基本数据类型:
​ char,short,int,long,float,double
​ 特殊数据类型:
​ 结构体、指针、数组…

数组成员的名字表现形式:
​ 数组名[下标];
​ 使用下标来标注数组的第几个成员变量;
​ 下标的范围是0~(数组成员个数-1);

数组的类型是什么?
​ 无论任何时候,任何类型数据
​ 从目标变量的定义去看该变量的类型
​ 变量定义:
​ 变量类型 变量名;
​ 查看方式是找到变量名
​ 变量定义时除变量名之外的所有都是变量类型

例子:
​ int a[5];
​ 意思是定义了一个数组,该数组的基本类型为int
​ 成员个数为5
​ 成员名为a[0],a[1],a[2],a[3],a[4]

​ 注意没有成员a[5]
​ a[5]属于越界访问,不建议
​ 首先越界是错误的,但是程序运行系统会不会直接段错误呢?
​ 不一定会

​ 该数组的变量类型是:
​ int [5]

意义:
​ 空间如何分配
​ 系统会为数组分配一块连续的存储空间
​ 会把存储空间分割成一块块对应基本类型的大小空间
​ 并由小到大命名0~(n-1)

在这里插入图片描述

数组的初始化及赋值:
例子:
1.
    int a[5];

	a = 1,2,3,4,5;	//错误的
注意:
数组的根本任然是一个又一个变量
    所以需要指定数组的成员进行单独赋值

    a[0] = 1;	//正确赋值方式
	a[1] = 2;
	a[2] = 3;
	a[3] = 4;
	a[4] = 5;	//注意不要越界

2.
    利用循环逐个赋值
    int a[5];
	int i;

	for(i=0;i<5;i++)
	{
        a[i] = i+1;
	}
	或者
    for(i=1;i<=5;i++)
    {
        a[i-1] = i;
    }

3.
    特殊复制:初始化
    1.
    int a[5] = {1,2,3,4,5};
	为a[0]~a[4]分别赋值为1,2,3,4,5
    2.
    int a[5] = {1,2};
	a[0]=1,a[1]=2,a[2]~a[4]默认初始化为0
    3.
    int a[5] = {};
	a[0]~a[4]都被默认初始化为0
    4.
    int a[5];
	a = {1,2,3,4,5};	不属于初始化
    错误的

    若相对数组进行整体赋值,必须是定义阶段进行,即是初始化
    若定义阶段未进行整体赋值,则其后不能再进行整体初始化

4.
    1.
    int a[5] = {1,2,3,4,5,6};	写法是错误的
    因为越界了

    2.
    int a[] = {1,2,3,4,5,6};	写法是正确的
    不定长数组

    3.
    int a[];	写法是错误的
    因为不定长数组一定要在定义时进行初始化
    虽然叫不定长数组,但是是通过初始化时的舒适化数值的个数,对数组的长度进行定义

    4.
    int n=5;
	int a[n];	写法是正确的
    变长数组	可根据变量来确定数组的长度
    变长数组指的是每一次数组的定义长度都可能不一样
    并不是说数组定义完成后,还可随意更改数组长度

    问题:
    若数组定义完毕之后,改变n的值为10,数组的大小会变吗?
    不会
    因为系统为a分配空间是因为定义语句的执行
    而改变n的大小不会引起数组的空间再一次分配

    5.
    int n;
	int a[n];
	n=5;		写法是错误的
    原因是想要使用变长数组,那么是数组长度变化的变量n
    必须在数组定义之前的位置确定一个大小,然后才能使用变长数组

    *总结:
    宗旨是任何变量在被定义时,一定要确定大小
    即是确定变量类型,若是数组,则还需额外确定数组成员个数,不能是随机
数组名出现在一些地方时,表示什么意思:
例子:
int a[5];

	数组名					a
    数组首元素			   a[0]
    数组首元素的地址		&a[0]

    sizeof(a);	a表示的就是数组a
    			计算出的结果是数组a的整个大小
    			实际即是计算a的类型大小是多少
   				a的变量类型是int [5]

    a  	        当数组名a单独出现或参与运算时
        		表示数组a的首元素的地址
   				即是a等价于&a[0]
    			a+1表示的是&a[1]

    &a			a表示的是数组a
   				而&a即是表示取得数组a的整个空间的大小

int b[4][5];
	4表示二维数组b的成员变量的个数
   	5表示二维数组的成员变量b[0]~b[3]的成员变量的个数

    二维数组的成员变量是一维数组

    b是二维数组的名字,二维数组的类型是int [4][5]
    sizeof(b) = 4*5*4 = 80字节
    b单独参与一些运算时,表示数组b的首元素b[0]的地址
    即是b等价于&b[0]

    b[0]是二维数组b的首元素,本质是一个一维数组,类型是int [5]
    sizeof(b[0]) = 4*5 = 20字节

思考:
    *(b[0]+1)	获得的是b[0][1]的值
    	b[0]本质是一个一维数组
    	*(&b[0][0]+1)	b[0][0]的地址类型大小4字节
        *(&b[0][1])
    	b[0][1]

    *(*(b+1)+1)		获得的是b[1][1]的值
    	b本质是一个二维数组
    	*(*(&b[0]+1)+1)
    	*(*(&b[1])+1)
    	*(b[1]+1)
    	*(&b[1][0]+1)
    	*(&b[1][1])
    	b[1][1]
练习:
	定义一个数组,数组长度由n确定,n是由终端输入的数字来确定的
	然后通过终端分别为数组的每一个成员变量进行赋值
	最后比较数组中的所有数字,找出最大数和最小数

指针:

什么是指针?
	指针就是寻址的地址
	例如:0xbfebe668
什么是指针变量?
	用来保存地址数据的变量,就是指针变量
	指针变量不属于基本类型
	指针在指向目标变量时,必须保证指针本身的指向类型和目标的变量类型一致
指针的特点:
	特点是具有指向性
	因为它保存的数据就是目标的地址
指针的定义:
格式:
	目标变量的类型	*变量名;

	*表示该变量的类型是指针
	指针的目标变量类型必须与接下来的指向目标的类型一致

	例子:
		int *p;		指向基本数据类型的指针
		char *p;
		float *p;

		指向符合类型数据的指针:
		数组、指针、结构体、函数。。。
            
例子:
	int *p;

	指针的类型:		即是指的指针变量的数据类型
    int *			*表明p是指针变量
    指针所指向的目标量的类型:
		int

    int **q;

	指针的类型:		即是指的指针变量的数据类型
   		int **			最右边的*表明q是指针变量,其它的*表明q所指向变量的类型
    指针所指向的目标量的类型:
		int *
指针的大小是多少:

即是指针变量的存储空间有多大?

	char *p;			4字节
	short *p;			4字节
	int *p;				4字节
	long *p;			4字节
	float *p;			4字节
	double *p;			4字节
	
	指针的本质是保存一个地址,用来进行寻址

指针的指向类型的大小是多少:

	char *p;			1字节
	short *p;			2字节
	int *p;				4字节
	long *p;			4字节
	float *p;			4字节
	double *p;			8字节
指针的加法运算:
	不能用来计算两个指针之间的加法
    因为两个地址加在一起是没有意义的

    指的是指针加上数字,进行的地址上的跳转

    运算规则:
    指针每+1,越过指针所指向的类型的空间大小

    例子:
    char *p1;
	假设p1指向地址0xFFCCDD00
    请问p1+1指向哪个地址?
    	0xFFCCDD00+1*1 = 0xFFCCDD01
    请问p1+10指向哪个地址?
    	0xFFCCDD00+1*10 = 0xFFCCDD0A

    int *p2;
	假设p2指向地址0xFFCCDD00
    请问p2+1指向哪个地址?
    	0xFFCCDD00+4*1 = 0xFFCCDD04
    请问p2+10指向哪个地址?
    	0xFFCCDD00+4*10 = 0xFFCCDD28
指针的减法运算:
只能是两个同类型的指针之间进行相减
结果表示两个指针地址之间的单位差
怎样让指针变量指向目标量:

也即是在为指针变量进行赋值

利用符号& 叫取地址符
意思即是获得目标变量的地址

怎样使用指针访问指针所指向的变量的存储空间:

利用符号* 叫解引用
意思即是直接访问目标地址的存储空间

注意:
	*&在很多时候是可以认为是一对逆操作的
	需要注意的是指针的类型,或者说之地址的类型
	甄别地址类型的简单方式是,考虑类型的大小
问p2+10指向哪个地址?
    	0xFFCCDD00+4*10 = 0xFFCCDD28
指针的减法运算:
只能是两个同类型的指针之间进行相减
结果表示两个指针地址之间的单位差
怎样让指针变量指向目标量:

也即是在为指针变量进行赋值

利用符号& 叫取地址符
意思即是获得目标变量的地址

怎样使用指针访问指针所指向的变量的存储空间:

利用符号* 叫解引用
意思即是直接访问目标地址的存储空间

注意:
	*&在很多时候是可以认为是一对逆操作的
	需要注意的是指针的类型,或者说之地址的类型
	甄别地址类型的简单方式是,考虑类型的大小
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Three笔记

有用的话赏点吧

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

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

打赏作者

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

抵扣说明:

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

余额充值