-
1.static
- 全局静态变量:作用范围局限于它的源文件,即只有本文件内的代码才可以访问它,变量名在其他文件内不可见
- 局部静态变量:局限于特定函数,但出作用域并不释放,在函数体内的静态变量的值也能够维持
- 静态函数:作用范围仅限于它的源文件,即只有本文件内才能够调用,函数名在其他文件不可见
- 存放位置:程序开始时,存放在全局数据区,结束时释放空间,默认初始化值是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 );
}
//a=1,b=1
a=1,b=2
a=1,b=3
2.const
- 修饰只读变量
- const int *a,int const *a:只读不能赋值,*a=5(错误),地址可以变化。*a
- int *const a:a是一个指向int型的const指针,*a是可以改写的,但a不允许改写。定义必须初始化。int *const a=&i
- int const * const a:a是一个指向const int型的const指针,因此*a和a都不允许改写。
- 定义函数尽可能多使用const
3.extern
- 表明变量或函数的定义在别的文件中,下面用到的这些变量或是函数是外来的,不是本文件定义的,提示编译器遇到此变量或函数时,在其他模块中寻找定义;
正确
错误
-
如果一个函数只能被本文件中其它函数所调用,称为内部函数(或静态函数)。定义时在函数类型前加static。
4.struct
- 多种数据组合起来的一个整体,其表现形式是一个结构体。
- 类型不占空间
- 结构体内的成员只作用于当前结构体
- 结构体可以嵌套定义,函数不可以。
- 结构体结束加分号:
- 大小:所有成员大小的和
- 成员也可以是指向本结构体类型的指针变量结构体指针只指向结构体,只能指向本身。
-
成员也可以是一个已定义的结构体类型变量,结构体嵌套
- 调用:结构体变量名.成员名。
- “.”是成员运算符,在所有的运算符中优先级最高
- 数组名不能作为左值
- 不能将一个结构体变量作为一个整体进体输入输出
- 不能用指向结构体变量的指针指向该结构体变量的某个成员。
- 访问结构体成员变量的三种方法:
- stu.num、stu.name、stu.score
- (*p).num、(*p).name、(*p).score
- p->num、p->name、p->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}
};
5.union
- 所谓“共用体(union)”是指使几个不同的变量共占同一段内存的数据类型。
- 当多个基本数据类型或复合数据结构要占用同一片内存时,我们要使用联合体;
- 当多种类型,多个对象,多个事物只取其一时(我们姑且通俗地称其为“n 选1”),我们也可以使用联合体来发挥其长处;
- 可以把一个整型变量、一个字符型变量、一个实型变量放在同一个地址开始的内存单元中。即使几个不同的变量共占同一段内存空间
- 分配空间字对齐!4的整数倍!
union node { char ch[7]; int num; }; 占8字节!
- Big_endian 大端字节序: 数据的高字节位存储在低地址对应的存储单元;
- Little_endian 小端字节序:数据的低字节位存放在低地址对应的存储单元。
#include <stdio.h>
union A
{
int a;
char c;
};
int main(int argc, const char *argv[])
{
union A endian;
endian.a=1;
if(endian.c==1)
{
printf("litter\n");
}
else
{
printf("big");
}
return 0;
}
6.enum
- 第一个枚举常量,没有初始化,默认值为0,后一个为前一个加1;
7.typedef
- typedef是C语言的关键字,其作用是为一种数据类型定义一个新名字
- 格式:typedef 数据类型 自定义数据类型
- typedef unsigned long uint32;
- 在嵌入式的开发中,由于涉及到移植问题,typedef的功能就更引人注目了。
10.位运算
左移:<<
高位丢失,地位补零。
右移:>>
正数:低位丢失,高位补零
负数:低位丢失,高位补一
注意用补码运算
[案例] 从键盘上输入1个正整数给int变量num,按二进制位输出该数。
#include "stdio.h"
main()
{ int num, mask, i;
printf("Input a integer number: ");
scanf("%d",&num);
mask = 1<<31;
/*构造1个最高位为1、其余各位为0的整数(屏蔽字)*/
printf("%d=" , num);
for(i=1; i<=32; i++)
{ putchar(num&mask ? ’1’ : ‘0’);
/*输出最高位的值(1/0)*/
num <<= 1;
/*将次高位移到最高位上*/
if( i%4==0 ) putchar(‘,’);
/*四位一组,用逗号分开*/
}
printf("\bB\n");
}
*没有传递性