C语言中的存储

下面这段文字是我的一部分讲义,也是我教程的一部分,很基础,但很与众不同,感兴趣的同学好好阅读,有不明白或不清楚的地方可以回复,有可能下周在直播课堂里讲述,请大家关注。

 

第二章  程序中的存储       

   第一章讲了计算机的基本工作原理,二进制和如何将资料进行数字化,下面我们就要开始真正进入编程的领域,如何使用内存中的空间,如何在内存中有条理的进行大批量数据的存储与读取。
1. 数据空间
我们用来存数据的空间称为数据空间,和数据空间相对应的是地址空间(指针),我们在运算过程中需要存储大量的数据,(在小球游戏中棋盘上哪些有球,什么颜色,哪些没球,我们都要存储起来,根据这些数据我们才能进行削球,移动球,)最常用的是数字的存储和字符的存储。为了存储数据我们通常需要开辟空间或者说申请空间,首先我们学习开空间的方法即变量声明语句:        
1).开空间
int    a;   开辟一个int类型的空间,a就是这个空间的名字.
char   c;   开辟一个char类型的空间 c
这个语句非常简单,分两部分,前一部分指出要开空间的类型,在32位计算机里 int类型4个字节,char类型1个字节,后一部分是为这个空间起的名字,这个名字是要你来起的哦,又称为标识符,起名字好理解一些,在写程序的时候要起很多名字,起名字也有点学问,尽量用英文单词,一看能知道含义,尽量不使用拼音,和字母加序号,不能以数字开头,只能以字母和下划线(_)开头,中间部位可以出现数字,字母和下划线(_)。在现在的教材里这个语句叫变量声明.
除了int,char还有一些其他类型,常用的有如下:
类型    长度       存储内容
char     1          0-255
int      4          有符号整数
long     4          有符号整数
unsigned  4         无符号整数
short     2         有符号整数
float     4   有符号小数 
double   8     有符号整数
注意:c语言要求每一句话结束要加上“;”。
2).空间赋值
请看代码
int a;
char b;
a=258;
b=’b’;
等号表示把等号右边的数值存储到等号左边的空间里,如果等号左边不是已经开好的空间那肯定是错的。
注意:
1.258需要占用两个字节存储102,上一章的内容,低位在前,所以02在前,1在后。前边不用的位要补0.
2.单引号表示该字母或数字对应的ASC码数值,每对单引号里只能有一个字符;

我们通常还会把一个空间里的内容存储到另一个空间里。
如: b=a ;    把a的内容存到b的里面。
但是当两个空间类型不一样时,就出现了一些问题:
如:char   m=30;
int    b=258;
b=m;
b的空间比m的大,把m的内容放进b绰绰有余,不会有任何问题,多余的空间一定要清零或1,(为什么1),必须保证放进去的值和取出的相等
但是   m=b;会怎样呢?b的空间大于m的空间,无法放下,对于这种情况计算机默认的处理是把b的最低位字节放入,但是编译器会要求我们写出显示转换如下:
m=(char)b;这样编译器就知道这是我们故意要做的,而不是不小心写错了。
根据上述原因,凡是大空间的值放入小空间都需要显示转换,反之就不需要了。
2. 数组
当我们需要开多个相同类型的空间时,可以有一个简便的的方法就是数组。
如 int  a[10];        表示开了10个int类型的空间
这10个空间分别是a[0],a[1]….a[9],使用起来和单独开的空间完全一样。把这10个空间的值都存成0;代码如下:
a[0]=0;
a[1]=0;
a[2]=0;
a[3]=0;
a[4]=0;
a[5]=0;
a[6]=0;
a[7]=0;
a[8]=0;
a[9]=0;
还有一个简便写法:
int a[]={0,0,0,0,0,0,0,0,0,0};这一句连int a[10]都包括了,但是先写int a[10],再写a[]={0,0,0,0,0,0,0,0,0,0}就是错误的.
通常开数组空间一定要指明个数,但是在开空间的时候,直接有赋值语句,赋值语句可以表明个数,这时候就不用指明个数了.

需要说明的是数组开的空间肯定是连续的,除此之外都不能保证连续.
说到数组,就要提到字符串,看代码:
char str[]=”this”;
用双引号括起来的内容我们称为字符串,这个字符串存储在数组str中,共占有5个字节,除了’t’,’h’,’i’,’s’外,还多加了一个字符’/0’,作为结束字符,注意不是’0’,
char str1[]={‘t’,’h’,’i’,’s’};
而str1也是个数组,它只占用4个字节,结尾没有结束字符,就不能当做字符串数组来访问。
我们通常访问字符串数组的时候,只需要首地址就行了,不需要长度,也不需要结束地址,当访问到字符’/0’的时候,就认为字符串结束了。
2 地址空间(又称指针空间)
2.1 地址空间(指针)的含义和使用
与上面讲述的空间不一样,有一种空间不是用来存储数据而是用来存储地址,我们称为指针空间.为什么指针理解不好,主要是因为只强调了指针能够指向一个空间,忽略了指针本身也是一个空间,只不过只能存储地址,来看一下使用方法:
int a;    开一个int类型的普通空间a
int *m;  开一个存储a的地址的空间m
m=&a;  把空间a的地址存入到地址空间m中;  &符号表示取空间的地址,可以用在任何空间的前面.如&m,表示m空间的地址
m中存储了a的地址就可以使用m来访问空间a
*m=26;  *表示指针指向的空间, 必须用在指针空间的前面,在这里相当于通过m给空间a里存储了一个数字26. *不能用在数据空间的前面.如果一个指针空间没有赋值(也称为初始化),是不可以用*操作符的.
2.2地址空间(指针)的类型
我们注意到,在开辟地址空间的时候,也先说明了类型,但与普通空间的类型的意义是完全不同,普通空间的类型主要规定了空间的大小,而对于地址空间来讲大小都是一样,对于任何类型的空间来说,他们的地址的长度都是一样的, 指针空间的类型主要有两个用途:
一 是在使用*符号的时候,决定访问空间的大小:
int a;       
int *m
m=&a;
*m=26;
这时候, m是int类型的指针,m指向空间a的第一个字节,当用*m访问时,无论读取还是修改,都访问4个字节的空间
二 是指针进行运算的时候:
指针可以进行运算,但只能进行加法和减法,表示相对向后偏移或向前偏移,两个指针空间的内容不可以相加,相加没有实际意义,但可以相减,相减的含义是两个指针空间相差多少.
int a[10];
int *m;
m=&a[0];
m=m+1; 也可写成 m++;
这里m+1并不是表示m里的值加1,而是加上1*(int的空间大小),这里的int就是指针m的类型,这样m=m+1后,m里面存的就是a[1]的地址,而不会是a[0]里的第二个字节.我们在对数组进行访问时通常可以用指针的运算来来访问不同的元素.
以上两点说明了指针类型的用途,也解释了指针运算的含义,如果有一种指针没有指明类型,那么就不可以运算,也不可以用*操作符,有吗?有,void *,表示没有类型的指针.
2.3指针类型的转换.
所谓指针类型的转换就是把a类型的指针放入b类型的指针空间里,按道理,所有的指针空间的大小都一样,不存在大小不匹配的问题,但由于指针类型的特殊用途,编译器为防止我们出现错误,要求我们在不同类型指针空间赋值时要强制转换.
如:
char *m;
int *n;
m=(char *)n;
n=(int *)m;

2.4指针与数组,多重指针
这个是大家容易搞混的东西。先看代码:
int a[10];  //开了10个int空间,用a[0]到a[9]分别对应10个空间。
但是如果把a单拿出来可不可以呢,我们刚才没讲,学了指针就可以讲了,如果只写a,不带后面的‘[ ]’,是有可义的,它表示a[0]的地址,即&a[0]. 如果开个指针空间 int *p; 可以写p=&a[0];也可以写p=a;两种的写法的意思是完全相同的。

指针也是一种空间,当你需要同时开多个时,一样可以用数组,称作指针数组,代码如下:
char *p[10];//一下开了开了10个char类型的指针空间,用p[0]到p[9]分别对应10个指针空间。
这时候单独写p,不带后面的‘[ ]’,含义跟上面讲的一样即&p[0], 如果想把&p[0],存起来,就需要开一个二重的指针,看代码
char **m;        m=&p[0]         或       m=p;当用一个*时,*m和p[0]的含义相同,仍旧是一个指针,当**m时,它才代表一个char空间,我们称之为多重指针。说穿了,就是指针的指针。


 3.结构体空间
结构体空间其实没有什么特殊的,只是开结构体的空间的类型比较特殊。先来看一段代码。
struct unit
{
 int x;
    int y;
    char haveBall;
    char ballColor;
} ;
这段代码定义了一个结构体,其中struct是关键字,先解释一下关键字,关键字是C语言中有固定含义的英文单词,我们写程序的时候不能使用关键字来起名字,我们上面提到的数据类型也是关键字。
struct 的含义就是要定义一个新的结构体。后面unit是我们自己起的名字,然后是一对大括号,括号里面是开空间的代码,说明新的类型是由什么样的空间组成,并没有真的开空间,最后用“;”结束。一个新的结构体,就是一种新的类型,上面的代码只是定义了新的类型,我们用新的类型去开的空间,就是结构体空间。代码如下;
unit  a;
新开出来的空间分别由int,int,char,char4个空间来组成。我们在使用这个空间的时候,不可能像以前那样直接”a=…;”我们分别进行赋值,代码如下:
a.x=1;
a.y=1;
a.haveBall=1;
a.ballColor=2;
结构体空间也可以开指针,用法同上。
unit *pa;
pa=&a;
一样可以用pa访问空间a里的内容:
(*pa).x=2;
但是有一个简单的写法
pa->x=2;//和上面一句话的含义完全相同。

 

评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值