数组越界问题和指针初入门例子分析

主要内容:数组越界问题和指针初入门例子分析

一、 数组越界问题

例子思考
int main()
{
int i;
int arr[10];
for(i=0;i<=10;i++)
{
arr[i] = 0;
printf("%d\n",i);
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
问题:当运行上述代码时,会出现什么问题?为什么会这样?

为解决以上问题,我们首先得明白当定义一个函数时,函数中各个量的空间分配符合栈(后进先出)的原则,如果一个量被先定义,那么系统便先给它分配存储空间。而在数组中,0号下标地址值永远小于1号下标地址值。因此,对于上述问题,我们可以画出它的内存空间示意图,分析运行代码会出现什么结果。具体图如下所示:

根据上图所示,程序从主函数开始往下执行,当int i;时,系统首先为i分配四个字节的空间,接着int arr[10];时,定义了一个长度为10的数组,因为在数组中,0号下标地址值永远小于1号下标地址值,同时栈的定义就是栈底地址大。便可知到上图(左)(图中两红线之间表示为数组所占空间)便为定义后,i与数组arr在内存中分配图。接着执行:for(i=0;i<=10;i++){arr[i] = 0; printf("%d\n",i);}。当i<10时,数组下标0-9分别对应的元素被赋值为0。i=10时数组满溢,会发生越界情况。在数组越界情况中,数组会默认牵涉其邻近元素,在此例子中即为i,因此当i=10时,系统会将i所对应的值赋为0。

结论
 此段代码运行时会产生死循环。原因是:因为数组越界,当i=10时,系统将i所对应的值赋为0,此时i=0且i<=10系统又会进入新一轮循环。以此类推,系统陷入死循环。

解决办法
 i.编译器:Visual Studio 2012针对于上述问题会产生崩溃现象,具体实现过程如上图(右),VS12会在数组arr与变量i中间进行隔离,避免数组越界影响到i,同时在数组arr与变量i中间申请两个内存空间,分别放在两颗“炸弹”,数组一旦越界,触碰到炸弹,系统中断,提出警告。
 ii.人力控制:牢记数组最大下标值=数组长度-1,代码仔细书写,避免越界问题产生。

二、 指针初入门

概念介绍
 符号& :表示取地址。//eg: &a表示取a 的地址。
 符号* :可以表示乘法、定义一个指针变量、对变量解引用。//eg: 34、intp(定义一个指针变量p)、*p(对p解引用)
 首先我们得知道指针==地址 ,通过以下介绍,我们来理解指针为什么相当于地址。

例子思考
其中&a=1000,&b=2000,&p=3000,观察此代码,分析每一步都做了什么!

int main()
{
int a = 10;
int b = 20;
int *p = &a;
*p = 100;
p = &b;
*p = 200;
int **pp = &p;
*pp = &a;
**pp = 1000;
*pp = &b;
**pp = 2000;

return 0;

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 对上段代码,我们画图理解:

(1)定义一个整形变量a,并将10赋值给它;
 (2)定义一个整形变量b,并将20赋值给它;
 (3)定义一个整形指针变量p保存变量a的地址,此时执行上图中的第(1) 步,p指向a;
 (4)*p = 100;对p解一次引用,此时p指向a,即a=100;
 (5)指针变量p保存变量b的地址,此时执行上图中的第(2) 步,p指向b;
 (6)*p = 200;对p解一次引用,此时p指向b,即b=200;
 (7)定义一个整形二级指针变量pp保存指针变量p的地址;
 (8)对pp解一次引用,也就是执行上图中的第(3) 步,pp指向p,此时p中保存的是a的地址,即p=&a;
 (9)对pp解两次引用,也就是执行上图中的第(3) 步,再执行第(1) 步,pp指向p,此时pp指向a的值, **pp = 1000,也就是将a的值置为1000;
 (10)对pp解一次引用,也就是执行上图中的第(3) 步,pp指向p,此时将b的地址赋值给p,p中保存的是b的地址,即p=&b;
 (11)对pp解两次引用,也就是执行上图中的第(3) 步,再执行第(2) 步,pp指向p,此时pp指向b的值, **pp = 2000,也就是将b的值置为2000;
因此,此代码每一步都做了什么展示如下:

int main()
{
int a = 10;(1)
int b = 20;(2)
int *p = &a;(3)
*p = 100;(4) //a = 100;
p = &b;(5)
*p = 200;(6) //b = 200;
int **pp = &p;(7)
*pp = &a; (8) //p = &a;
**pp = 1000; (9) //a = 1000;
*pp = &b;(10) //p = &b;
**pp = 2000;(11) //b = 2000;

return 0;

}


作者:du_lijun
来源:CSDN
原文:https://blog.csdn.net/du_lijun/article/details/83083317
版权声明:本文为博主原创文章,转载请附上博文链接!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值