图示C语言的基本数据类型内存变换

取地址和指针

double pi = 3.1416;
在这里插入图片描述

取地址

π
在这里插入图片描述

指针

char ch = #(char * ) π
cout << ch << end1
则应该打印出如下内容
在这里插入图片描述

short转double

short s = 45;

在这里插入图片描述

double d = * (double * )&s;

在把short类型赋给double的类型的值的时候会自动补充内存,因为short类型的变量只占两个字节,而double变量要占8个字节,所以,会自动向后补充六个字节大小的空内存来填补上
在这里插入图片描述
在这里插入图片描述

定义的数据结构

定义一个结构
student fraction{
int num;
int denum;
}

在这里插入图片描述
现在声明一个
fraction pi;
pi.num = 22;
pi.denum = 7;
于是内存变成了这样:
在这里插入图片描述
下面将进行一系列的内存变换:

① ((fraction *)&(pi.denum))->num=12;

"&(pi.denum) : 取pi.denum的地址
(fraction *)&(pi.denum) : 取pi.denum的地址,然后把它重新构造一个fraction的结构
((fraction *)&(pi.denum))->num=12 : 取pi.denum的地址,然后把它重新构造一个fraction的结构,然后再对这个新的结构进行赋值操作。
在重新构造一个新的fraction时,这时候把pi.denum进行覆盖,给了((fraction *)&(pi.denum))的num,所以此时会重新拿到一块新的内存来进行填补构成一个新的fraction,也就是下图上面空的一块。
在这里插入图片描述

② ((fraction *)&(pi.denum))->denum=33;

为((fraction *)&(pi.denum))的denum进行赋值
在这里插入图片描述

③ ((fraction *)&(pi.denum))[0].denum;

这里将((fraction *)&(pi.denum))改为了一个数组形式,取第0个,然后取他的denum的值,这样写是没有问题的,但是就是非常的怪异,这句话能取出33这个值。

数组

int array[10];

在这里插入图片描述

array[0] = 44; array[9] = 100; array[45] = 45;

在这里插入图片描述

array[10] = 1;

数组的长度只有10,当给数组array[10]进行赋值时,则会额外取一块内存进行赋值,而不是出错。
在这里插入图片描述

array[25] = 25;

同理,会向后延长内存来进行赋值。
在这里插入图片描述

array[-4] = 77;

我当时看到这里还是挺惊讶的,数组的所引值竟然可以有负数,因为在java中从来没有接触过有负数的索引值,所以看到这个还是有点惊奇。不过原理也和上面一样,按序向前找即可。
在这里插入图片描述

*(array - 4)

这个式子的意思就是,取到array[-4]这个值。

几个恒等于

array ≡ &array[0]        // array就相当于array数组第一个成员的地址
array + k ≡ &array[k]        // array+k,偏移k个单位的地址,也就是array[k]的地址
*array ≡ array[0]        // 这和上面的有些区别,这个的意思是指针直接指向的就是array[0]的值,而不是地址
*(array + k) ≡ array[k]        // 同理,这是指向偏移k个地址的之后的值

类型变换

C语言中一个int类型时占两个字节的,short类型只占一个字节,所以下面就有了类型的变换。

int arr[5];

在这里插入图片描述

arr[3]=128;

因为一个int时两个字节构成,128用2进制表示是 1000 0000,于是array[3]里面实际的存储就是0000 0000 1000 0000,也就是前一个字节是0,后一个字节是128
在这里插入图片描述

((short *)arr)[6]=2;

这个数组被改成了short类型的数组,那么此时int类型的数组名义上便被转换为了short类型的数组,所以这时候((short *)arr)就好比把现在的int类型的数组每个位置切了一刀,形成了一个新的二倍的short类型数组,然后把2装在这个数组里面。

在这里插入图片描述
这个时候arr[3]里面的值就发生了变化,后一个字节也就是后8位依旧是128,但是前八位是2,换成二进制,现在arr[3]里面变成了这样:0000 0010 1000 000,所以现在arr[3]里面的值是128*2+128。

( ( short * ) ( ( ( char * ) ( &arr[1] ) ) + 8 ) ) [3] = 100;

这个式子就比较麻烦了,这个式子需要拆分再看,按顺序。

  1. &arr[1] : 取到arr的索引为1的地址
  2. ( char * ) ( &arr[1] ) : 以此数组为char类型来进行操作。
  3. ( ( ( char * ) ( &arr[1] ) ) + 8 ):向右偏移8个单位
  4. ( ( short * ) ( ( ( char * ) ( &arr[1] ) ) + 8 ) ) :以此数组为short类型来操作。
  5. ( ( short * ) ( ( ( char * ) ( &arr[1] ) ) + 8 ) ) [3] = 100:取第三个,赋值为100.
    总的来说就是进行了如此的操作,如下图。
    在这里插入图片描述

操作自定义结构的数组

定义数据结构

struct Student{
char * name;
char suid[8];
int numUtnits;
};
Student pupils[4];
此时会在内存中开辟4个Student大小的内存提供来使用
在这里插入图片描述

pupils[0].numUnits = 21;
pupils[2].name = strdup(“Adam”);

在这里插入图片描述

pupils[3].name = pupils[0].suid + 6;

这句话的意思就是将 pupils[3]的name 的 地址 在 pupils[0]的suid 的第六位处。
在这里插入图片描述

strcpy(pupils[1].suid, “40415xx”);

这句话的意思不是赋值,其实是复制的意思
在这里插入图片描述

strcpy(pupils[3].name, “123456”);

此时我们设定的 pupils[3] ,那么,但是我们前面把它的地址取得是 pupils[0]的suid+6 ,所以此时设置的就是 pupils[0]的suid+6 处的值,然而这里只有7 8 两个位置显然不够,所以,后面的3456会毫不客气地覆盖 pupils[0]的numUints 的值,就发生了下面这样的情况
在这里插入图片描述

pupils[7].suid[11] = ‘A’ ;

我们定义第7个,显然已经超出了范围,所以就一上面说过的数组来说,它会自动向后延申。然而suid一共有8位,盛不下11个,所以还会向后延,他就占用了numUints的第四位。
在这里插入图片描述

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Geek-Banana

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

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

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

打赏作者

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

抵扣说明:

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

余额充值