动态内存分配和位运算Word下载.docx
- 文档编号:20391591
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:12
- 大小:21.54KB
动态内存分配和位运算Word下载.docx
《动态内存分配和位运算Word下载.docx》由会员分享,可在线阅读,更多相关《动态内存分配和位运算Word下载.docx(12页珍藏版)》请在冰豆网上搜索。
main()
{
inti,m;
int*array;
/*array是一个整型指针,也可以
理解为指向一个整型数组的首地址*/
scanf(“%d”,&
m);
array=(int*)malloc(m*sizeof(int));
/*把通用型指针强制转换为整形指针*/
/*标准函数sizeof()用来测试指定数据类型的字节数。
可以测试任意数据类型,包括结构体和共用体。
该函数返回一个整数(这里在DOS下是2,windows是4)。
也可以直接写成array=(int*)malloc(40);
效果等价于array[10],但使用效率不同。
*/
if(array==NULL){
printf("
不能成功分配存储空间。
"
);
exit
(1);
/*退出运行*/
}
for(i=0;
i<
10;
i++)/*给数组赋值*/
array[i]=i+100;
for(i=0;
i++)/*打印数组元素*/
%2d"
array[i]);
}
上例中动态分配了10个整型存储区域,然后进行赋值并打印。
例中
array=(int*)malloc(10*sizeof(int);
if(array==NULL)
常常合并成一条语句。
if((array=(int*)malloc(10*sizeof(int)))==NULL)
语句的执行过程分为以下几步:
1)分配10个整型的连续存储空间,并返回一个指向其起始地址的整型指针
2)把此整型指针地址赋给array
3)检测返回值是否为NULL
2、free函数
由于内存区域总是有限的,不能不限制地分配下去,而且一个程序要尽量节省资源,所以当所分配的内存区域不用时,就要释放它,以便其它的变量或者程序使用。
光用malloc()函数申请内存,而不释放,称作“内存泄漏”,是计算机安全的大敌。
这时我们就要用free函数来释放内存(向操作系统返还)。
其函数原型是:
voidfree(void*p)无返回值,形参为通用型指针(指针类型不限)
作用是释放指针p所指向的内存区(返还操作系统)。
其参数p必须是先前调用malloc函数(动态分配存储区域的函数)时返回的指针。
给free函数传递其它的值很可能造成死机或其它灾难性的后果。
注意:
这里重要的是指针变量的值(即起始地址),而不是用来申请动态内存的指针变量本身。
例:
int*p1,*p2;
p1=malloc(10*sizeof(int));
p2=p1;
……
free(p2)/*或者free(p2)*/
这里:
malloc返回值赋给p1,又把p1的值赋给p2,所以此时p1,p2都可作为free函数的参数。
malloc函数是对存储区域进行分配的。
free函数是释放已经不用的内存区域的。
所以由这两个函数就可以实现对内存区域进行动态分配并进行简单的管理了。
这一对动态内存管理函数,有被称作“堆内存管理”函数或者“堆管理(heap)函数”。
堆是操作系统管理计算机内存的概念,这里就免谈了。
要用动态内存管理函数,就必须在程序中加入头函数:
3、二维数组空间的动态分配
思路:
把每一行当作一个一维数组,分别动态分配内存。
//动态分配二维数组空间
voidmain()
{
intm=4;
//二维数组的行数
intn=5;
//二维数组的列数
inti,j;
//动态分配一个二维数组内存空间
//其类型为int,a指向该数组
int**a;
//指向二维数组的指针为二级指针
a=(int**)malloc(m*sizeof(int*));
/*m个行指针构成一维数组,二级指针a
指向该数组的首地址*/
for(i=0;
m;
i++)/*分配每一行的空间,得到行首指针*/
a[i]=(int*)malloc(n*sizeof(int));
/*以上所作的工作,效果等价于静态内存分配a[4][5],
但动态内存分配的特点是静态数组a[4][5]代替不了的。
*/
i++)
for(j=0;
j<
n;
j++)
a[i][j]=i*j;
printf("
%d"
a[i][j]);
//由此分配的二维数组空间中,行与行之间不一定紧密相邻(连续)。
//但每一行内部的元素肯定是紧密相邻的。
//释放所分配的内存空间
i++)
free(a[i]);
//以行为单位释放数值空间
free(a);
//二级指针a也要释放
}
如果把二维数组的动态内存分配用函数的方式单独写出,就要考虑二级指针变量的双向传递,形参要用三级指针。
上题改写如下:
#include<
stdlib.h>
/*二维数组的动态内存分配函数*/
intdynamic_momory(double***x,intr,intc)
inti;
/*double**x二级指针变量x是指向二维数组的指针
为每行的首元素申请r个地址,这些地址构成一个长度为r的一维数组,
这个数组的首地址存入二级指针变量**x*/
(*x)=(double**)malloc(r*sizeof(double*));
if((*x)==NULL)return0;
/*申请存放每一行c个元素的一维数组空间,得到行首地址,
装入该行的首地址*/
r;
{
*(*x+i)=(double*)malloc(c*sizeof(double));
if((*(*x+i))==NULL)return0;
}
return1;
/*主函数*/
double**a;
/*二级指针二维数组*/
constintn=10,m=5;
/*n行m列*/
/*a双向传递,返回动态分配的二维数组首地址*/
dynamic_momory(&
a,n,m);
for(j=0;
j++)/*随机数赋值*/
a[i][j]=100*rand()/65535.0;
j++)/*二维数组的指针访问*/
printf("
%4.1f"
*(*(a+i)+j));
printf("
\n"
枚举
在实际问题中,有些变量的取值被限定在一个有限的范围内。
例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等。
如果把这些量说明为整型,字符型或其它类型显然是不妥当的。
为此,C语言提供了一种称为“枚举”的类型。
在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。
应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。
枚举类型的定义和枚举变量的说明
一、枚举的定义枚举类型定义的一般形式为:
enum枚举名{枚举值表};
在枚举值表中应罗列出所有可用值。
这些值也称为枚举元素。
例如:
enumweekday{sun,mou,tue,wed,thu,fri,sat};
该枚举名为weekday,枚举值共有7个,即一周中的七天。
凡被说明为weekday类型变量的取值只能是七天中的某一天。
二、枚举变量的说明如同结构和联合一样,枚举变量也可用不同的方式说明,即先定义后说明,同时定义说明或直接说明。
设有变量a,b,c被说明为上述的weekday,可采用下述任一种方式:
方式一:
enumweekday
......
};
enumweekdaya,b,c;
方式二:
}a,b,c;
方式三:
enum
}a,b,c;
枚举类型变量的赋值和使用
枚举类型在使用中有以下规定:
1.枚举值是常量,不是变量。
不能在程序中用赋值语句再对它赋值。
例如对枚举weekday的元素再作以下赋值:
sun=5;
mon=2;
sun=mon;
都是错误的。
2.枚举元素本身由系统定义了一个表示序号的数值,从0开始顺序定义为0,1,2…。
如在weekday中,sun值为0,mon值为1,…,sat值为6。
sun,mon,tue,wed,thu,fri,sat
a=sun;
b=mon;
c=tue;
printf("
%d,%d,%d"
a,b,c);
3.只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。
如:
a=sum;
是正确的。
而:
a=0;
b=1;
c=a+b都是错误的。
如一定要把数值赋予枚举变量,则必须用强制类型转换,如:
a=(enumweekday)2;
其意义是将顺序号为2的枚举元素赋予枚举变量a,相当于:
a=tue;
还应该说明的是枚举元素不是字符常量也不是字符串常量,使用时不要加单、双引号。
enum
not_pass,pass,good,better,best
}everyone[4];
intscore;
=3;
i++){
scanf("
%d"
&
score);
if(score<
60)everyone[i]=not_pass;
elseif(score<
70)everyone[i]=pass;
80)everyone[i]=good;
90)everyone[i]=better;
=100)everyone[i]=best;
/*赋值在0到4之间,但不能赋整数,以防书写混乱*/
i++)printf("
%d\n"
everyone[i]);
/*输出结果为整数,在0到4之间*/
位运算
前面介绍的各种运算都是以字节作为最基本位进行的。
但在很多系统程序中常要求在位(bit)一级进行运算或处理。
C语言提供了位运算的功能,这使得C语言也能像汇编语言一样用来编写系统程序。
一、位运算符C语言提供了六种位运算符:
&
按位与
|按位或
^按位异或
~取反
<
左移
>
右移
1.按位与运算按位与运算符"
是双目运算符。
其功能是参与运算的两数各对应的二进位相与。
只有对应的两个二进位均为1时,结果位才为1,否则为0。
参与运算的数以补码方式出现。
9&
5可写算式如下:
00001001(9的二进制补码)&
00000101(5的二进制补码) 00000001(1的二进制补码)可见9&
5=1。
00001001(9的二进制补码)
00000101(5的二进制补码)
00000001(1的二进制补码)
按位与运算通常用来对某些位清0或保留某些位。
例如把a的高八位清0,保留低八位,可作a&
255运算(255的二进制数为0000000011111111)。
inta=9,b=5,c;
c=a&
b;
a=%d\nb=%d\nc=%d\n"
2.按位或运算按位或运算符“|”是双目运算符。
其功能是参与运算的两数各对应的二进位相或。
只要对应的二个二进位有一个为1时,结果位就为1。
参与运算的两个数均以补码出现。
9|5可写算式如下:
00001001|00000101
00001101(十进制为13)可见9|5=13
|00000101(5的二进制补码)
00001101(1的二进制补码)
c=a|b;
3.按位异或运算按位异或运算符“^”是双目运算符。
其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。
参与运算数仍以补码出现,例如9^5可写成算式如下:
00001001^0000010100001100(十进制为12)
inta=9;
a=a^15;
a=%d\n"
a);
4.求反运算求反运算符~为单目运算符,具有右结合性。
其功能是对参与运算的数的各二进位按位求反。
例如~9的运算为:
~(0000000000001001)结果为:
111111*********0
5.左移运算左移运算符“<
”是双目运算符。
其功能把“<
”左边的运算数的各二进位全部左移若干位,由“<
”右边的数指定移动的位数,
高位丢弃,低位补0。
a<
4指把a的各二进位向左移动4位。
如a=00000011(十进制3),左移4位后为00110000(十进制48)。
6.右移运算右移运算符“>
其功能是把“>
”左边的运算数的各二进位全部右移若干位,“>
”右边的数指定移动的位数。
设a=15,a>
2 表示把00001111右移为00000011(十进制3)。
应该说明的是,对于有符号数,在右移时,符号位将随同移动。
当为正数时,最高位补0,而为负数时,符号位为1,最高位是补0或是补1取决于编译系统的规定。
很多系统规定为补1。
设a=-15,a>
2,结果为-4。
(a=15,a>
2,结果为3。
补码存放,符号移动,高位补1)
-15的原码10001111
(-15的补码)11110001(右移2位)11111100
(减1)11111011(求反,-4的原码)100001000
设a=-15,a<
2,结果为-60。
(a=15,a<
2,结果为60。
左移时符号位不动)
unsigneda,b;
inputanumber:
"
scanf("
a);
b=a>
5;
b=b&
15;
a=%d\tb=%d\n"
a,b);
请再看一例!
chara='
a'
b='
b'
;
intp,c,d;
p=a;
p=(p<
8)|b;
d=p&
0xff;
c=(p&
0xff00)>
8;
a=%d\nb=%d\nc=%d\nd=%d\n"
a,b,c,d);
/*ab9798*/
本章小结
1.枚举是一种基本数据类型。
枚举变量的取值是有限的,枚举元素是常量,不是变量。
2.枚举变量通常由赋值语句赋值,而不由动态输入赋值。
枚举元素虽可由系统或用户定义一个顺序值,但枚举元素和整数并不相同,它们属于不同的类型。
因此,也不能用printf语句来输出元素值(可输出顺序值)。
3.位运算是C语言的一种特殊运算功能,它是以二进制位为单位进行运算的。
位运算符只有逻辑运算和移位运算两类。
位运算符可以与赋值符一起组成复合赋值符。
如&
=,|=,^=,>
=,<
=等。
4.利用位运算可以完成汇编语言的某些功能,如置位,位清零,移位等。
还可进行数据的压缩存储和并行运算。
********************************************************************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 动态 内存 分配 运算