数组的栈存储与数据类型的详细讲解(第一期)

目录

1.关于数组的栈存储

1.1 了解局部变量与数组的存储位置

2.数据的类型介绍

2.1 基本的内置类型

2.2 类型的基本归纳


1.关于数组的栈存储

我们先来看一个比较奇怪的代码

#include <stdio.h>
int main()
{
    int i = 0;
    int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
    for (i = 0; i < 12; i++)
    {
        arr[i] = 0;
        printf("hello\n");
    }
    return 0;
}

 这个代码奇怪的地方就在于我们建立了一个元素个数为10的整形数组,但是for循环中我们需要进行循坏12次,来对arr数组进行越界访问。我们来看这个代码的结果就会更奇怪了。

5271fd98a5754493a84100c29619a95c.png

 代码结果为,在打印了12次之后,光标依旧在闪烁(图片看不出来,你们也可以实验试试),代码进入了死循环。


1.1 了解局部变量与数组的存储位置

为什么上一个代码会进入死循环呢,我们需要来了解他们各种的存储位置来寻找答案。

有一定基础的小伙伴们应该知道,局部变量与数组都存储在栈区,局部变量i与数组的存储位置应该如下图所示:                                                  

                    23bad87a3a364393836f1ca61a17cc90.png

我们可以把栈区的存储形式看成一块一块的砖头堆砌,栈区的使用习惯是:先使用高地址,再使用低地址,先进后出的规则。这个图片可以我们看到先分配变量i存储在高地址处,因为数组是跟着下标的增长,地址从低变高的,所以先分配高地址的数组元素。

我们根据这个图片再来分析一下那个代码,先初始化i变量和整形数组,进行for循环   

                              ef84005efd204337a65efb446a60cbf0.png   

 当第一次循环时执行(arr[i] = 0)语句使arr[0]等于0,直到进入第12次的循环是,越界访问到了i变量的存储位置,是i变量重新赋值为0,然后继续进行i=0的for循环,最后代码成了死循环。

 这里最奇怪的地方就是i局部变量的位置,就与arr数组相差2个单位的距离,我们可以通过实验来查询他们的地址。

                                             9b06c5cdfd4f411084199aa8b5c59e8b.png

 这里我们可以看到i局部变量的地址为:13630428

因为数组名代表首元素地址所以arr数组的地址为:13630380

我们可以得到他们二个地址相差48位,因为数组中有10个元素,每个元素是整形占4位,所以48-40=8位,每越界访问一次越过4个字节,即会访问到局部变量i的地址。

我相信通过上面的分析实验,对上面的代码为什么会陷入死循环已经了解了。


需要补充说明的是,这个情况只是在vs编译器里面,不同的编译器有不同的定义,比如:

ed74c0e852ac471a9f4d79ad36b46ced.png9dd0dae992f74df68b0cbdbd94a2f9e9.png


2.数据的类型介绍

 这里我们可以通过这个图片来清楚的了解一下基本数据的分类情况。

a0baf7cdcb9e4645b290fdc188b1d28b.png

2.1 基本的内置类型

我们将这些统称为内置类型

char    //字符数据类型

short   //短整型

int       //整形

long    //长整形

float    //单精度浮点型

double   //双精度浮点型

 注意:在c语言中是没有字符串类型的!

2.2 类型的基本归纳

下面我们对这些各种各样的数据类型进行一个分类:

整形类型:

char  

    unsigned  char

    signed  char

short

   unsigned  short 

   signed   short

long

   unsigned  long

   signed    long

(当然还有long long整型)

 这里大家可能会好奇为什么char字符类型也是在整形类型里面,因为char类型是使用的ASCLL码表,比如'a'代表97,char类型的本质是整形。为了方便理解可以想成,本质上都是面粉,只是有的面粉做成了饺子皮,有的面粉做成了面条等同他们本质上都是整形,只是有的是char类型,有点是short类型。

关于unsigned与signed的区别就在于,第一个是无符号类型,第二个是有符号类型,无符号类型就是没有正负号之说,能代表的就是一个数据本身的大小,更进一步的分析会在下一期分析他们在内存中的区别。

关于short短整型与long长整型的区别简单来说,

类型          长度           

short         2个字节

long          4个字节(在64位编译器中占8个字节)      


浮点数类型:

float

double

 这里我们浅谈一下float与double的区别:

1.所占的字节数不同

单精度类型所占的字节数为4个字节

双精度类型所占的字节数为8个字节

2.能精确的有效位不同

单精度类型所精确的有效位为8个有效位

双精度类型所精确的有效位为16个有效位

3.在程序中的处理速度不同

一般来说,CPU处理单精度类型的处理速度大于双精度类型的处理数据

4.补充说明:

当没有说明的情况下,默认的小数数据类型为double类型。比如:

#include <stdio.h>
int main()
{
	float  a = 1.2;
	return 0;
}

a49b9cedffc8404ebff1de98f2bb7e16.png

 当在vs2019里面输入这段代码时,编译器运行时会说,初始化,从double到float截断。这句话的意思就是double类型有16位的有效位当强行转化为8位有效位的化会截断8位有效位。


在下一期会详细的来深入了解整形数据在内存中的存储形式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

C-Sakura

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

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

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

打赏作者

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

抵扣说明:

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

余额充值