当前位置:学者斋 >

计算机 >C语言 >

C语言中的重要概念有哪些

C语言中的重要概念有哪些

学习是一个循序渐进的过程,需要同学们不断的学习和努力。下面yjbys考试网小编为大家分享C语言中的几个重要概念,希望能帮助大家更好的复习所学的知识。

C语言中的重要概念有哪些

  一、C语言的指针

1.指针说明

指针是包含另一变量的地址变量。

(1)int *p

p是一个指针,指向一个整形数。

(2)int *p()

p是一个函数,该函数返回一个指向整数的指针。

(3)int (*p)()

p是一个指针,该指针指向一个函数,这个函数返回一个整数。

(4)int *p[]

p是一个数组,该数组的每一个元素是指向整数的指针C语言中的几个重要概念C语言中的几个重要概念。

(5)int (*p)[]

p是一个指针,该指针指向一个数组,这个数组的每一个元素是一个整数。

(6)int *(*p)()

p是一个指针,该指针指向一个函数,这个函数返回一个指向整数的指针。

2.指针的初始化(赋地址)

(1)通过符号&取变量(包括结构变量、数组第一个元素)的地址赋给指针;

(2)把数组名赋给指针;

(3)把函数名赋给指向函数的指针;

(4)动态分配内存

例:struct c{double r,i;};

struct c *p;

p=(struct c *)malloc(sizeof(struct c));

3.指针与数组、函数的关系

(1)对于一维数组 int a[i] 或指针 int *a

a+i 指向 a[i]

(2)对于字符串 char s[i] 或指针 char *s

s+i 指向第 i个字符 s[i]

(3)对于二维数组int a[i][j]

*a+j 指向 a[0][j]

*(a+i) 指向 a[i][0]

*(a+i)+j 指向 a[i][j]

例:对于 a[2][3]={1,2,3,4,5,6,}; 有 *(*(a+1)+1)=5;

(4)对于字符串数组char p[i][j] 或字符型指针数组char *p[i]

*p+j 指向第 0个字符串的第 j个字符

*(p+i) 指向第 i个字符串的第 0个字符

*(p+i)+j 指向第 i个字符串的第 j个字符

例:对于 *p[]={"ABC","DEF"}; 有 *(*(p+1)+1)='E';

例:对于 char p[][3]={"ABC","DEF"}; 有 *(*(p+1)+1)='E';

(5)对于指针数组int *a[i]

a[i] 指向 变量i

即 *a[i]=变量i 或 a[i]=&变量i

(6)对于结构struct XY

{int x;int *y}*p;

p是指向结构XY的指针

(*p).x 或 p->x 是表示 x 的内容

(*p).y 或 p->y 是表示指针 y 的值(地址)

*(*p).y 或 *p->y 是表示 y 所指的内容

&(*p).x 或 &p->x 是表示 x 的地址

(7)指向函数的指针

对于 void func(char *str)

{…}; //定义了一个函数

void (*p)(char*);//定义了一个函数指针

p=func; //让指针指向函数

则(*p)("…"); //用指针p可以调用函数func

(8)指向多个不同函数的指针数组

对于void function_1() {…};

void function_4() {…}; //定义了四个函数

typedef void(*menu_fcn)();//定义了指向函数的指针

menu_fcn command[4]; //定义了指针数组

command[0]=function_1;

command[3]=function_4; //让指针数组指向四个函数

则command[0](); //用指针数组中的一个元素调用一个函数

4.指针的分类

(1)近指针(near):

近指针为16位指针,它只含有地址的偏移量部分。近指针用于不超过64K 字节的单个数据段或代码段。在微、小和中编译模式下产生的数据指针是近指针(缺省状态);在微、小和中编译模式下产生的码指针(指向函数的指针)是近指针(缺省状态)。

(2)远指针(far)

远指针为32位指针,指针的段地址和偏移量都在指针内。可用于任意编译模式。每次使用远指针时都要重装段寄存器。远指针可寻址的目标不能超过64K ,因为远指针增减运算时,段地址不参与运算。在紧凑、大和巨模式下编译产生的数据指针是远指针(缺省状态)C语言中的几个重要概念计算机考试。

(3)巨指针(huge)

巨指针为32位指针,指针的段地址和偏移量都在指针内。可用于任意编译模式。远指针寻址的目标可以超过64K 。巨指针是规则化的指针。

5.指针的转换

(1)远指针转换成巨指针

使用以下函数

void normalize(void far * * p)

{

*p=(void far *)(((long)*p&0xffff000f)+(((long)*p&0x0000fff00<<12));

}

6.指针的使用

(1)将浮点数转换成二进制数

float ff=16.5;

unsigned char *cc;

(float*)cc=&ff;

//此时cc的内容为"00008441"

//即cc第一个字节=0;第二个字节=0;第三个字节=0x84;第四个字节=0x41;

(2)将二进制数转换成浮点数

float ff;

unsigned char *cc;

cc=(unsigned char*)malloc(4);

cc=(unsigned char*)&ff;

*(cc+0)=0;

*(cc+1)=0;

*(cc+2)=0x84;

*(cc+3)=0x41;

//此时ff=16.5

free(cc);

  二、C 语言的函数

1.用户自定义函数格式

类型 函数名(形式参数表)

参数说明

{

……

}

2.函数的调用方式

(1)传值方式

①传给被调用函数的是整型、长整型、浮点型或双精度型变量。被调用的函数得定义相应的变量为形参。

②传给被调用函数的是结构变量。被调用函数得定义结构变量为形参。

③传给被调用函数的是结构变量的成员。被调用函数得定义与该成员同类的变量为形参。

(2)传址方式

①传给被调用函数的是变量的地址C语言中的几个重要概念C语言中的几个重要概念。被调用函数得定义指针变量为形参。

②传给被调用函数的是数组的地址即数组名。被调用的函数得定义数组或指针变量为形参。

③传给被调用函数的是函数的地址即函数名称。被调用函数得定义指向函数的指针变量为形参。

④传给被调用函数的是结构的地址。被调用函数得定义结构指针为形参。

3.函数调用(传值方式)结果的返回

(1)返回的是数值

要求被调用的函数类型与接收返回值的.变量类型相同。

(2)返回的是指针

要求被调用的函数是指针函数,其指向的类型与接收的指针变量指向类型相同。

(3)不返回任何值

被调用的函数是void型

  三、C 语言的信息压缩法

1.使用位运算符

要把 5个数据的值压缩到一个字(16位)中,假定其中三个(f1、f2、f3)是标记(真或伪)各占一位;第四个是叫type的整数,其取值范围为 1到12,需要 4位的存储器;最后一个叫作index 的整数,其取值范围为从 0到 500,需占 9位C语言中的几个重要概念计算机考试。为此定义一个整型变量:unsigned int packed_data,可包含此 5个值。下图是位域分配。

typeindex

f1f2f3┌──┐┌───────┐

┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐

└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘

把 n的 4个低位的值置入packed_data 的type域中,用下面的语句:

packed_data=(packed_data & ~(0xf<<9))|((n&0xf)<<9);

其中位或符号|左边是将type域置 0,右边是取 n的低 4位后左移9 位到type域中。

从packed_data 的type域中提取数值并把它赋予 n的语句是:

n=(packed_data>>9) & 0xf;

2.使用位域结构

(1)定义一个叫做 packed_struct的结构,含有 5个成员

struct packed_struct

{

unsigned int f1:1

unsigned int f2:1;

unsigned int f3:1;

unsigned int type:4;

unsigned int index:9;

};

(注:在结构中还可以放入普通数据类型,如char c;等)

(2)定义一个变量

struct packed_struct packed_data;

(3)把packed_data 的type 域置于n的低位,用语句

packed_=n;

(4)从packed_data 中提取type域(按要求,把它移到低位),并把它赋予 n,用语句

n=packed_;

3.使用联合

(1)一个无符号整型数与一个结构(其中包含许多无符号变量)共用一存储区,当无符号整型数被赋值后,可通过结构变量获得各位的值。

例如,定义一个联合

union {

unsigned equi;

struct {

unsigned boot :1;

unsigned copr :1;

unsigned rsize:2;

unsigned vmode:2;

unsigned dnum :2;

unsigned:1;

unsigned cnum :3;

unsigned gnum :1;

unsigned:1;

unsigned pnum :2;

}beq;

}eq;

当调用BIOS INT 11H中断后,将AX的值赋给,就可以从得到PC机有无系统盘的信息;从得到PC机有无浮点运算部件的信息。......

(2)两个结构共享同一存储区域

例如:union REGS

struct WORDREGS{unsigned int ax,bx,cx,dx,si,di,cflag,flags};

struct BYTEREGS{unsigned char al,ah,bl,bh,cl,ch,dl,dh};

union REGS {struct WORDREGS x;struct BYTEREGS h;}

  四 、位运算

1.数的编码—补码

(1).正数的补码与原码同。

(2).负数的补码为

①第一位(符号位)为 1;

②剩余原码位数逐位取反;

③然后对整个数加 1。

2.位逻辑运算的特殊用途

(1).取一个数中的某些字节

例a & 0x00ff得到a的低字节,a & 0xff00得到a的高字节。

┌─┬───┬────┬────────┐

│数│十进制│十六进制│补码│

├─┼───┼────┼────────┤

│ a││0x2cac│0010110010101100│

│││0x00ff│0000000011111111│

├─┴───┼────┼────────┤

│ 按位与 │ ox00ac │0000000010101100│

│ 运算结果 │││

└─────┴────┴────────┘

(2).将一个数的某些特定位置1

例a | 0x0f使a的低4位改为1。

┌─┬───┬────┬────────┐

│数││十六进制│补码│

├─┼───┼────┼────────┤

│a ││0x0030│0000000000110000│

│││0x000f│0000000000001111│

├─┴───┼────┼────────┤

│按位或││0000000000111111│

│运算结果│││

└─────┴────┴────────┘

(3).将某数特定位置翻转

例a ^ 0x000f使a的低4位翻转(0变1;1变0)。

┌─┬───┬────┬────────┐

│数││十六进制│补码│

├─┼───┼────┼────────┤

│a ││ 0x007a │0000000001111010│

│││ 0x000f │0000000000001111│

├─┴───┼────┼────────┤

│ 按位异或 ││0000000001110101│

│ 运算结果 │││

└─────┴────┴────────┘

(4)将a的右起第2位反向变化(1变0,0变1)

a=a^0x02;//(0x02=00000010),异或的意义是"同值为0"

(5).将两个数(整型数)的值互换

例a=a^b;b=b^a;a=a^b; //三步使得a、b的值互换

3.移位运算的特殊用途

(1).将某数除以2(右移1位)

例a>>2 使得a被4除

①对于 signed a=-8,a>>2

a=-8

┌─┬─┬─┬─┬─┬─┬─┬─┐

│1 │1 │1 │1 │1 │0 │0 │0 │

└─┴─┴─┴─┴─┴─┴─┴─┘

├─┬─┐──>└───┐

┌─┬─┬─┬─┬─┬─┬─┬─┐

│1 │1 │1 │1 │1 │1 │1 │0 │

└─┴─┴─┴─┴─┴─┴─┴─┘

a=-2

②对于unsigned a=248,a>>2

a=248

┌─┬─┬─┬─┬─┬─┬─┬─┐

│1 │1 │1 │1 │1 │0 │0 │0 │

└─┴─┴─┴─┴─┴─┴─┴─┘

└───┐ ──> └───┐

┌─┬─┬─┬─┬─┬─┬─┬─┐

│0 │0 │1 │1 │1 │1 │1 │0 │

└─┴─┴─┴─┴─┴─┴─┴─┘

补0──┴─┘a=62

(2).将某数乘以2(左移1位)

注左移时signed 与unsigned变量的情况一样,均要补0。

(3)将x的右起第n(n>=0)位置0

x&=~(1《n); 若x是long,则x&=~((long)1《n);

(4)将x的右起第n(n>=0)位置1

x|=1《n;

若x是长整形数则 x|=(long)1《n;

  五、C语言访问CPU寄存器的方法

1.使用联合REGS,和函数 int86() / int86x() / intr()

REGS是用来在进行 DOS软中断调用时向各个寄存器传输数据或从各个寄存器取出返回值。

union REGS 示意图

structstruct

WORDREGSBYTEREGS

┌ ┌───────┬──────┐──┬── ┐

│ ││ al │ 1 byte│

│ │ax├──────┤──┴─ 2 bytes

│ ││ ah │ │

│ ├───────┼──────┤───── ┘

│ ││ bl │

│ │bx├──────┤

│ ││ bh │

│ ├───────┼──────┤

│ ││ cl │

│ │cx├──────┤

│ ││ ch │

│ ├───────┼──────┤

│ ││ dl │

│ │dx├──────┤

│ ││ dh │

union regs├───────┼──────┤

│ │││

│ │si││

│ │││

│ ├───────┤│

│ │││

│ │di││

│ │││

│ ├───────┤│

│ │││

│ │cflag ││

│ │││

│ ├───────┤│

│ │││

│ │flags ││

│ │││

└ └───────┴──────┘

│x两个结构变量h│

└──共享同一存储域──┘

2.使用伪变量和函数geninterrupt()

Turbo C 允许使用伪变量直接访问相应的8086寄存器。伪变量的类型有两种。

① unsigned int : _AX、 _BX、 _CX、 _DX、 _CS、 _DS、 _SS、 _ES、 _SP、 _BP、 _DI、 _SI

② unsigned char: _AL、 _AH、 _BL、 _BH、 _CL、 _CH、 _DL、 _DH

  六、C语言使用内存和寄存器的方法

1.段和段寄存器

CS用来存放代码段的段地址;DS用来存放全局变量和静态变量所在段(数据段)的段地址;SS用来存放局部变量,参数所在段(堆栈)的段地址。 此外,还有堆段,是动态分配的内存。

2.微模式编译时段的使用情况

只有一个段,从底往高依此装入代码,静态变量和全局变量,堆。从高往低装入堆栈。

3.小模式编译时段的使用情况

数据、堆栈和近堆共用一个段,代码用一个段,还有一个远堆(用far指针存取)。

4.中模式编译时段的使用情况

中模式有多个代码段,其余与小模式一样。函数指针用far指针。

5.紧凑模式编译时段的使用情况

代码,静态数据,堆栈,堆(只有远堆)各有自己的段。静态数据的总量不得超过64K

6.大模式编译时段的使用情况

静态数据,堆,堆栈的分配与紧凑模式一样;代码段的分配与中模式一样。数据指针和函数指针都是远指针C语言中的几个重要概念计算机考试。静态数据的总量不得超过64K。

7.巨模式编译时段的使用情况

来自不同源文件的代码放在不同的段内,来自不同源文件的静态数据也放在不同的段内,只有堆栈是合在一起的。

8.运行库函数分配的内存:

常规内存区

远堆(数据段之外) 用_fmalloc()分配,得到32位指针

├─────────┤

64│堆(未使用的内存)│用malloc()分配,得到16位的位移地址

KB├─────────┤

数│栈(局部变量)│

据├─────────┤

段│全局和静态变量│

├─────────┤

  七、用C语言写中断服务程序(如果中断服务程序不牵涉到中断链以及 DOS和其本身的重入问题。) ---Turbo C

1.函数类型为interrupt 的中断服务程序定义如下:

#include

void interrupt 函数名(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags);

unsigned int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags;

2.得先保留原中断函数地址

void interrupt (*保留函数名)( );

保留函数名=getvect(0x中断号);

3.在main函数中用自定义的中断服务程序替换原来的程序

setvect(0x中断号,函数名);

4.在main函数中激活自定义的中断服务程序

(1)先设置要用到的寄存器的值(用伪变量),

(2)geninterrupt(0x中断号);

若替换的是计时中断程序,因PC机内的计时器每秒产生18.2次中断,则每秒自动执行18.2次新的中断程序。

5.事后得将原中断函数地址装回向量表中

setvect(0x中断号,保留函数名);

标签: 语言
  • 文章版权属于文章作者所有,转载请注明 https://xuezhezhai.com/jsj/cyuyan/k35moz.html