上海龙凤419

C说话

C说话中的几个主要观点

时候:2024-06-17 00:40:25 C说话 我要投稿
  • 相干保举

C说话中的几个主要观点

  进修是一个按部就班的进程,须要同窗们不时的进修和尽力。C说话中的几个主要观点就为大师分享这里了,但愿能赞助大师更好的温习所学的常识。

  一、C说话的指针

  1.指针申明

  指针是包罗另外一变量的地点变量。

  (1)int *p

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

  (2)int *p()

  p是一个函数,该函数前往一个指向整数的指针。

  (3)int (*p)()

  p是一个指针,该指针指向一个函数,这个函数前往一个整数。

  (4)int *p[]

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

  (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 ,由于远指针增减运算时,段地点不到场运算。在松散、大和巨情势下编译发生的数据指针是远指针(缺省状况)。

  (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)传址体例

  ①传给被挪用函数的是变量的地点。被挪用函数得界说指针变量为形参。

  ②传给被挪用函数的是数组的地点即数组名。被挪用的函数得界说数组或指针变量为形参。

  ③传给被挪用函数的是函数的地点即函数称号。被挪用函数得界说指向函数的指针变量为形参。

  ④传给被挪用函数的是规划的地点。被挪用函数得界说规划指针为形参。

  3.函数挪用(传值体例)成果的前往

  (1)前往的是数值

  请求被挪用的函数范例与领受前往值的变量范例不异。

  (2)前往的是指针

  请求被挪用的函数是指针函数,其指向的范例与领受的指针变量指向范例不异。

  (3)不前往任何值

  被挪用的函数是void型。

  三、C 说话的信息紧缩法

  1.利用位运算符

  要把 5个数据的值紧缩到一个字(16位)中,假设此中三个(f1、f2、f3)是标记(真或伪)各占一名;第四个是叫type的整数,其取值规模为 1到12,须要 4位的存储器;最初一个叫作index 的整数,其取值规模为从 0到 500,需占 9位。为此界说一个整型变量:unsigned int packed_data,可包罗此 5个值。下图是位域分派。

  type    index

  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_data.type=n;

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

  n=packed_data.type;

  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的值赋给eq.equi,就能够从eq.beq.boot获得PC机有没有体系盘的信息;从eq.beq.copr获得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 表示图

  struct     struct

  WORDREGS    BYTEREGS

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

  │  │       │   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.大情势编译时段的利用环境

  静态数据,堆,仓库的分派与松散情势一样;代码段的分派与中情势一样。数据指针和函数指针都是远指针。静态数据的总量不得跨越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间断号,保留函数名);

 

【C说话中的几个主要观点】相干文章:

C说话中的主要观点有哪些12-11

C说话中指针的观点03-16

C说话中各类范例的指针的观点总结11-24

C说话中volatile的寄义12-03

C 说话中宏的利用12-03

C说话中的链接编写05-26

C说话中的指针是甚么03-17

C说话中strpbr()函数的用法03-19

C说话中的相干变量常识11-25