数组和指针的那些事

数组是一个由若干同类型变量组成的集合。

 

数组由连续的存储单元组成,最低地址对应第一个元素,最高地址对应最后一个元素。

数组有一维数组和多维数组。

在学习数组的时候了解指针很有必要,使用指针变量比使用下标效率更高!

 

一维数组

数组名问题:

int a[10];

我们把a称为数组,a是一些同类型值得集合,a[0]表示a数组的第1个元素,a[1]表示第二个元素,a[i]表示第i个元素,下标和数组名一起,表示数组中某个特定的值,它们的类型是int型。

数组名a单独使用时,数组名此时代表的是数组第1个元素的地址(一个指针常量)。它的类型取决于数组元素的类型,比如a就是“指向int的常量指针”。

指针常量的值不能被修改!

数组名不作为首元素地址的两种情况:

数组名作为sizeof操作符或单目操作符&的操作数时。sizeof返回整个数组的长度。取一个数组名的地址是取一个指向该数组的指针。

 

int  a[10];

int  b[10];

int  *c;

 

c=&a[0];c=a;

这两条赋值语句的结果是一样的,因为数组名表示的是首元素a[0]的地址!经过赋值后的c所指向的是a数组的第1个元素。

b=a;非法!复制数组元素必须对数组的每一个元素依次进行复制,考虑用循环。

a=c;非法!记住a是指针常量,指针常量的值不能被修改!

下标问题:

a[0]表示数组的第1个元素;

a 表示第一个元素的地址;

*a 呢?

*”间接访问操作符,对指针进行间接访问操作可以获得这个指针指向的结果值,所以* a的意思就是获得 a指向的元素的值,即就是第一个元素的值a[0]

*a+2)其实是a所指向的第1个元素后移2int长度的位置指向的元素的值。

 

int  arr[10];

int  *p=arr+2;

它表示指针p指向了arr+2,其实arr+2表示指向数组第1个元素后移2int长度的位置,arr[2]。所以表达式结果是,指针p指向arr[2]

有时候我们对优先级掌握的不清楚,也会造成判断结果出错。

比如:

*p+6表示的是arr[2]+6

p+6表示p指向元素arr[2]后移6int长度位置的元素(&arr[8])。

*(p+6)表示的是p先后移6个整数长度的位置,指向arr[8],在对arr[8]进行间接访问,得到arr[8]的值。

 

多维数组

多维数组是在一维数组上的推广延伸。

int  a[3];

int  b[3][3];

int  c[3][3][3];

………

多维数组在存储顺序上和一维数组类似,数组元素的存储顺序是是线性的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


在数组名问题上,多维数组和一维数组也是类似的,不过“第1个元素”的含义不同。

一维数组中,第一个元素是第一个值。

多维数组中,第一个元素其实是“第一个数组”,在二维数组里按照咱平时理解就是第一行元素。

 

 

 

 

 

指针

了解了数组,让咱了解指针,啥是指针呢?

指针就是一个地址的名字!

指针就是一个地址的名字!

指针就是一个地址的名字!

 重要的话说三遍~~~

在计算机里,指针是用来存放地址的变量

 

周末我邀请小明来我家玩,我给了小明地址(马栏山马兰坡),保证小明能顺利找到我家。(对没错,马栏山马兰坡就是指针~~~

 

同样的如果我们要在计算机中找到某个内存单元,我们要找到该内存单元的地址。这个地址的名字称为“指针”。

这样一说,你就了解了为啥要有指针这种存在了,是为了方便啊,没有“马栏山马兰坡”这地名的出现,小明永远找不到我家!

既然已经知道指针的存在是为了找位置,那么问题来了,在计算机中,怎么编址???

对于32位的计算机,假设有32根地址线,假设每根地址线在寻址的是产生一个电信号,那32根地址线产生的地址就是:

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001

00000000 00000000 00000000 00000010

00000000 00000000 00000000 00000011

…….

11111111 11111111 11111111 11111111

总共有232地址,每个地址标志一个字节。

 

32位计算机地址用3201组成二进制序列,所以地址用4个字节存储,所以1个指针的大小是4个字节。

 

指针有类型吗?

Yes!

 

 

在上边说数组名的时候,a是数组第1个元素的地址,是一个“指向int类型的指针变量”,如果数组是char型,那么a就是“指向char类型的指针变量”,其实指针的类型是由它指向变量的类型确定的!

 

char*类型的指针是为了存放char类型变量的地址,int*类型的指针是为了存放int类型变量的地址

 

 

数组有一维数组,二维数组,多维数组,指针呢?

 

 其实指针还有一级指针,二级指针,多级指针。嗯,对,所谓二级指针就是指向一级指针的指针。

 

int  a=0;

int *p=&a;

int **pp=&p;

 

a的地址存放在p中,p的地址存放在pp中。

 

指针运算

指针+整数

结果还是指针。

 

如果对char类型指针+1,就是后移1char类型长度位置,结果指向下一个字符。如果对int类型指针+1,就是后移1int类型长度位置,结果指向下一个整型值。

 

char占据1个字节的内存空间,int占据4字节的内存空间,指针+1时会自动根据类型进行调整。

 

 

表达式

指针p

*p的大小

增加到指针的值

P+1

char

1

1

short

2

2

P+1

int

4

4

double

8

8

P+2

char

1

2

short

2

4

int

4

8

double

8

6

 

指针可以减指针吗?

 

Yes,但是,前提是,它俩都指向同一个数组当中的元素,p1-p2结果是-4.

 

 

 


 嗯,看完有没有一丢丢明白了?

 

指针数组 

啥是指针数组?它到底是指针?还是数组?

嗯,它是“数组”。

指针数组,顾名思义,它是存放指针的数组。

int   *p[10];//包含10个指针元素的数组。

那么

int   *p[10];

这个表达式是?
数组指针 

啥是数组指针呢,它是数组?还是指针?

嗯,它是“指针”。

数组指针,顾名思义,它是指向数组的指针。

int  a[10][3];

int  (*p)[3]=a;

这里,a是一个数组名,是一个指针。

P是一个指针变量,它指向包含3int元素的一维数组。

*(p+1)是数组a的“首元素地址”(二维数组首元素可以理解为第一行元素地址)。

*p+1+1表示a[1][1]的地址。
函数指针 

函数指针是指向函数的指针。

学习数组时,数组名是一个常量指针,指向数组首元素。

其实函数名也是一个常量指针,指向函数的第一条指令。

程序编译时,编译器要为每个函数分配地址,这个地址用一个指针来保存。此时,这个 指针 就是函数指针。

int  *p(int x,int y);
函数指针数组 

函数指针 数组,就是存放 函数指针 的数组。

int(*p_fun[])(int, int)
函数指针数组的指针 

函数指针数组的指针,就是指向一个数组元素都是函数指针的数组的指针。

Void**p[10](const char *)

 

 

 血槽已空。。。。。。

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值