关键字



1register

register:请求编译器尽可能地将变量存在CPU内部寄存器中;

使用注意:

register修饰变量的类型必须是CPU所接受的;

register变量可能不是在内存中存储,所以不能使用&来获取变量的地址

 

2Static

全局静态变量:作用范围局限于它的源文件,即只有本文件内的代码才可以访问它,变量名在其他文件内不可见

局部静态变量:局限于特定函数,但出作用域并不释放,在函数体内的静态变量的值也能够维持

静态函数:作用范围仅限于它的源文件,即只有本文件内才能够调用,函数名在其他文件不可见

存放位置:程序开始时,存放在全局数据区,结束时释放空间,默认初始化值是0,使用时可改变其值;

例:

void  f(int  c)

{  int a=0;

   static  int  b=0;

   a++;

   b++;

   printf("%d: a=%d, b=%d\n", c, a, b);

}

void  main(   )

{  int  i;

   for (i=1; i<=3; i++)

      f( i );

}

1: a=1, b=1

2: a=1, b=2

3: a=1, b=3

 

3const只读变量

const int* a; int const *a;

   是一个指向const int型的指针,a所指向的内存单元不可改写,所以(*a)++是不允许的,但a可以改写,所以a++是允许的。

int* const a;

   a是一个指向int型的const指针,*a是可以改写的,但a不允许改写。

int const * const a;

   a是一个指向const int型的const指针,因此*aa都不允许改写

const给读代码的人传达非常有用的信息。比如一个函数的参数是const char *,你在调用这个函数时就可以放心地传给它char *const char *指针,而不必担心指针所指的内存单元被改写。

尽可能多地使用const限定符,把不该变的都声明成只读,这样可以依靠编译器检查程序中的Bug,防止意外改写数据。

const对编译器优化是一个有用的提示,编译器也许会把const变量优化成常量

3volatile

作用:不会在两个操作之间把volatile变量缓存在寄存器中;不做常量合并与常量传播等优化;对voiatile变量的读写不会被优化掉。

中断服务程序中修改的供其他程序检测的变量,多任务环境下各任务间共享的标志,存储器映射的硬件存储器要加volatile说明。

 

4extern外部变量声明

表明变量或函数的定义在别的文件中,下面用到的这些变量或是函数是外来的,不是本文件定义的,提示编译器遇到此变量或函数时,在其他模块中寻找定义;

如果一个函数只能被本文件中其它函数所调用,称为内部函数(或静态函数)。定义时在函数类型前加static

 

6struct定义结构体

在网络协议、通信控制、嵌入式系统的C/C++编程中,我们经常要传送的不是简单的字节流(char型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。

struct node

{

    char a;

    short b;

    char c;

};

struct  node link;

int count = sizeof(link);

printf(%d\n,count);

结果是多少?Count=4

#include <stdio.h>*

 struct  A

 {

      int iMember;

      char *cMember;

 };

 int main(int argc, char* argv[])

{

     struct A instant1,instant2;

     char c = 'a';

      instant1.iMember = 1;

      instant1.cMember = &c;

      instant2 = instant1;

      printf(instant1.cMember = %c,*(instant1.cMembe));

     *(instant2.cMember) = 'b';

      printf(instant2.cMember = %c,*(instant2.cMembe));

      printf(instant1.cMember = %c,*(instant1.cMembe));

      return 0;

}

① “结构体名”用作结构体类型的标志;

②花括弧内是该结构体中的各个成员,由它们组成一个结构体;在结构体内对各成员都应进行类型声明;

③“成员表列”也称为域表。每个成员也称为结构体中的一个域,成员名命名规则与变量名一样;

④每个成员名前的类型标识符可以为已经定义了的任意类型,当然可以是结构体类型标识符,即结构体成员也可以是另一个结构体变量。

⑤此处只是构造出一个新的类型,并没有定义该类型的变量,因此在内存中并没有开辟任何存储空间;

⑥在程序中可以定义多个结构体类型,不同结构体类型用不同的结构体名来区分。

结构体类型定义描述结构的组织形式,不分配内存;用指针,成员只能是指向本结构体类型的指针变量,不能指向其他结构体。

引用形式:.”是成员运算符,在所有的运算符中优先级最高。

struct student

{  int  num;

    char  name[20];

    float  score;

}stu1, stu2

stu1.num=10001;

stu1.score=95;

stu1.name ="Li Ming";=strcpy(stu1.name, "Li Ming");

不能将一个结构体变量作为一个整体进体输入输出,只能对结构体中的各个成员分别进行输入输出。

printf("%d%s%f", stu1);scanf("%d%s%f", &stu1);

printf("%d%s%f", stu1.num, stu1.name, stu1.score);

scanf("%d", &stu1.num);gets(stu1.name);

 

指向结构体变量指针的定义:

struct  student

{  int  num;

    char name[20];

    float  score;

};

struct  student  stu, *p;

p=&stu;p中存放着结构体变量stu在内存中的首地址

注意:不能用指向结构体变量的指针指向该结构体变量的某个成员。

p=&stu.num;

int  *ip;

ip=&stu.num;

 

访问结构体成员变量的三种方法:

①、stu.numstu.namestu.score

②、(*p).num(*p).name(*p).score

③、p->nump->namep->score

 

 

说明:①、“->”为指向运算符,是优先级最高的运算符;

②、成员运算符“.”的优先级高于指针运算符“*”,因此采用 “(*p).成员名” 形式时,括号不能省略;

③、注意以下几种运算:

p->num  得到p指向的结构体变量中的成员num的值

p->num++   得到p指向的结构体变量中的成员num的值,用完后该值加1

++p->num   使p指向的结构体变量中的成员num的值加1

 

在定义结构体变量的同时,可以进行初始化。

注意:结构体变量的各个初值用花括号{}括起来,大括号内各个成员变量的值之间用逗号分隔,其值必须与成员变量一一对应,且数据类型应与成员变量一致。

 struct  student

        {       int num;

                 char  name[20];

                 char sex;

                 int age;

                 char addr[30];

        }stu1={112,Wang Lin,M,19,  200 Beijing Road};

 

嵌入式系统开发中可以使用如下方式对结构体变量进行初始化:

struct  student

        {       int num;

                 char  name[20];

                 char sex;

                 int age;

                 char addr[30];

        }

Struct student stu1=

                  { .num = 112,

                     .name=Wang Lin,

                     .sex=M,

                     .age=19,  

                     .addr=200 Beijing Road};

该赋值方式在花括号外无效!!!!

 

结构体数组的初始化

struct  结构体类型标识符

{

  类型标识符1 成员名1

  类型标识符2 成员名2

   ……     ……

  类型标识符n 成员名n;

}结构体数组={ {数组元素0的各个初值}

          {数组元素1的各个初值}

        ……}

struct  student

{   int  num;

     char  name[20];

     float  score;

}stu[ ]={{10101,"Li Ming", 88},{10102,"Zhang Jin",92},

                       {10103, "Wang Lin", 98.5}};

数组中各个元素的初值用大括号{}括起来,同一数组元素的各个成员变量的初值用逗号分隔。

struct  student

{   int  num;

     char  name[20];

     float  score;

}stu[ ]=

{

{.num=10101, .name="Li Ming", .score=88},

{.num=10102, .name="Zhang Jin", .score=92},

{.num=10103, .name="Wang Lin", .score=98.5}

};

 

使用结构体存在的问题: 内存空洞  字对齐  半字对齐

struct node

{char ch;

 int num;

}; 变量占8个字节

struct node

{char ch;

  int num;

  char ch1;

}; 变量占12个字节

struct node

{char ch;

  char ch1;

  char ch2

}; 变量占3个字节

int型变量占四个字节 字对齐

后一个变量若能在前一个变量分配的空间中存放下,则后一个变量不再重新分配空间。

struct node

{char ch;

 short num;

 char ch1;

  short b;

}; 变量占10个字节

short型变量占2个字节 半字对齐

减少内存空洞的方法:同类型的成员定义放在一起!

 

7union

当多个基本数据类型或复合数据结构要占用同一片内存时,我们要使用联合体;

当多种类型,多个对象,多个事物只取其一时(我们姑且通俗地称其为n 1”),我们也可以使用联合体来发挥其长处;

有时候需要将几种不同类型的变量存放到同一段内存单元中。

分配空间字对齐!4的整数倍!

union node

{ char ch[7];

  int num;

};      8字节!

可以把一个整型变量、一个字符型变量、一个实型变量放在同一个地址开始的内存单元中。即使几个不同的变量共占同一段内存空间。

所谓“共用体(union)”是指使几个不同的变量共占同一段内存的数据类型。

 

CPU存取数据都是从低地址开始开始存放,一个变量占用的内存空间往往不止一个字节,但是不同类型的CPU存放数据的顺序不同,因而产生了字节序的概念,按存放顺序的不同分为大端字节序和小端字节序两种:

Big_endian 大端字节序: 数据的高字节位存储在低地址对应的存储单元;

Little_endian 小端字节序:数据的低字节位存放在低地址对应的存储单元。

 

8enum

枚举类型声明代表常量的符号名称。

enum的默认值

   enum kids{nippy, slats, skippy, nina ,liz};

enum的指定值

   enum levels {low=100,medium=500,high=2000};

enum的用法

   作为switch的标签

 

9typedef

typedefC语言的关键字,其作用是为一种数据类型定义一个新名字

格式:typedef  数据类型  自定义数据类型

typedef unsigned long uint32

在嵌入式的开发中,由于涉及到移植问题,typedef的功能就更引人注目了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值