一、关键字
对于初学者,学习C语言第一步就是学习32个关键字
关键字 | 含义 |
---|---|
auto | 声明自动变量,缺省时编译器一般默认为auto |
int | 声明整型变量 |
double | 声明双精度变量 |
long | 声明长整型 |
char | 声明字符型 |
float | 声明浮点型变量 |
short | 声明短整型变量 |
signed | 声明有符号类型变量 |
unsigned | 声明无符号类型变量 |
struct | 声明结构体变量 |
union | 声明联合数据类型 |
enum | 声明枚举类型 |
static | 声明静态变量 |
switch | 声明开关语句 |
case | 开关语句分支 |
default | 开关语句中的“其他”分支 |
break | 跳出当前循环 |
register | 生命寄存器变量 |
const | 声明只读变量 |
volatile | 说明变量在程序执行中可被隐含的改变 |
typedef | 用以给数据类型取别名 |
extern | 声明变量是在其他文件正声明 |
return | 子程序返回语句 |
void | 声明函数无返回值或无参数,声明空类型指针 |
continue | 结束当前循环,开始下一轮循环 |
do | 循环语句的循环体 |
while | 循环语句的循环条件 |
if | 条件语句 |
else | 条件语句否定分支 |
for | 一种循环语句 |
goto | 无条件跳转语句 |
sizeof | 计算对象所占内存空间大小 |
二、变量和零值比较
1.bool类型
bool bTestFlag = FALSE;
if(bTestFlag); if(!bTestFlag);
2.float类型
float fTestVal = 0.0;
if((fTestVal >= -EPSINON) && (fTestVal <= EPSINON));
3.指针类型
int *p = NULL;
if(p == NULL); if(p != NULL);
三、大小端
若开发的项目不与其他平台上通信则无需关注,但若是与其他平台数据交互,则必须考虑到大小端
的问题。
1.定义
大端模式:字数据的高字节存储在低地址,而数据的低字节存储在高地址
小端模式:字数据的高字节存储在高地址,而数据的低字节存储在低地址
注:内存中数据是以字节为单位进行存储的,当多字节数据与其他平台交互时,则需考虑大小端问题。
2.示例
请写一个C函数,若处理器是Big_endiande,则返回0;若处理器是Little_endiande,则返回1
int checkSystem()
{
unoin check
{
int i;
char ch;
}c;
c.i = 1;
return (c.ch == 1);
}
四、数组指针与指针数组
1.数组指针
1.1 定义
int(*p)[10];
通俗来讲,就是一个指针,该指针指向一个数组。
注意: p指针每偏移一位就是偏移一个包含10个int类型元素的数组,例如(p+1)= p + 4*10 ,要想访问其中的一个元素就必须强制转化成(int *)型,即 (int *)p+1,此时指针就是指向这个数组的第二个元素。默认*p+1,也是指向第二个元素。
1.2 示例
int a[10] = {0};
int(*p)[10] = a;
printf("p addr is : %p, p+1 addr is : %p\r\n", p, (p+1));
printf("p addr is : %p, (int *)p+1 addr is : %p\r\n", p, ((int *)p + 1));
printf("p addr is : %p, *p+1 addr is : %p\r\n", p, *p + 1);
打印结果:
p addr is : 00EFF970, p+1 addr is : 00EFF998
p addr is : 00EFF970, (int *)p+1 addr is : 00EFF974
p addr is : 00EFF970, *p+1 addr is : 00EFF974
2.指针数组
2.1 定义
int* p[10];
通俗来讲,就是一个数组,保存的变量类型为(int *)类型。
2.2 示例
int a = 10, b = 20, c = 30;
int* p[3] = {&a, &b, &c};
printf("sizeof(p) = %d \r\n", sizeof(p));
printf("a addr is %p, b addr is %p, c addr is %p \r\n", &a, &b, &c);
printf("*p addr is %p, *(p+1) addr is %p, *(p+2) addr is %p \r\n", *p, *(p + 1), *(p + 2));
printf("**p = %d, **(p+1) = %d, **(p+2) = %d \r\n", **p, **(p+1), **(p+2));
printf("p[0] addr is %p, p[1] addr is %p, p[2] addr is %p \r\n", p[0], p[1], p[2]);
printf("*p[0] = %d, *p[1] = %d, *p[2] = %d \r\n", *p[0], *p[1], *p[2]);
打印结果如下:
sizeof(p) = 12
a addr is 00B6FD50, b addr is 00B6FD44, c addr is 00B6FD38
*p addr is 00B6FD50, *(p+1) addr is 00B6FD44, *(p+2) addr is 00B6FD38
**p = 10, **(p+1) = 20, **(p+2) = 30
p[0] addr is 00B6FD50, p[1] addr is 00B6FD44, p[2] addr is 00B6FD38
*p[0] = 10, *p[1] = 20, *p[2] = 30
五、空类型指针
void *p1;
int *p2;
p1 = p2;
void *可以无需强制类型转换的赋给其他类型的指针。
因为“空类型”可以包容“有类型”,而“有类型”则不能包容“空类型”。
例如:
void *p1;
int *p2;
p2 = p1;
提示:"'=' :cannot convert from 'void *' to 'int *'"
注:不能对void指针进行算法操作
例如: void *p;
p++;//err
六、typedef函数指针的用法
1.简单的函数指针的应用
形式1:返回类型(*函数名)(参数表)
char (*pFun)(int);
char glFun(int a){ return;}
void main()
{
pFun = glFun;
(*pFun)(2);
}
第一行定义了一个指针变量pFun。首先我们根据前面提到的“形式1”认识到它是一个指向某种函数
的指针,这种函数参数是一个int型,返回值是char类型。只有第一句我们还无法使用这个指针,为
我们还未对它进行赋值。
第二行定义了一个函数glFun()。该函数正好是一个以int为参数返回char的函数。我们要从指针的
层次上理解函数——函数的函数名实际上就是一个指针,函数名指向该函数的代码在内存中的首地
址,然后就是main()函数了,它的第一句您应该看得懂了——它将函数glFun的地址赋值给变量
pFun。main()函数的第二句中“*pFun”显然是取pFun所指向地址的内容,当然也就是取出了函数
glFun()的内容,然后给定参数为2。
2.使用typedef更直观更方便
形式1:typedef 返回类型(*新类型)(参数表)
typedef char (*PTRFUN)(int);
PTRFUN pFun;
char glFun(int a){ return;}
void main()
{
pFun = glFun;
(*pFun)(2);
}
typedef的功能是定义新的类型。第一句就是定义了一种PTRFUN的类型,并定义这种
类型为指向某种函数的指针,这种函数以一个int为参数并返回char类型。后面就可以像
使用int,char一样使用PTRFUN了。
第二行的代码便使用这个新类型定义了变量pFun,此时就可以像使用形式1一样使用这
个变量了。
//*****************************例子***********************************
#include <stdio.h>
#include <assert.h>
typedef int (*FP_CALC)(int,int);//定义一个函数指针类型
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return b ? a/b : -1;
}
//定义一个函数,参数为op,返回一个指针,该指针类型为拥有两个int参数、
//返回类型为int的函数指针。它的作用是根据操作符返回相应函数的地址
FP_CALC calc_func(char op)
{
switch( op )
{
case '+':
return add;
case '-':
return sub;
case '*':
return mul;
case '/':
return div;
default:
return NULL;
}
return NULL;
}
//s_calc_func为函数,它的参数是 op,
//返回值为一个拥有两个int参数、返回类型为int的函数指针
int (*s_calc_func(char op)) (int , int)
{
return calc_func(op);
}
//最终用户直接调用的函数,该函数接收两个int整数,
//和一个算术运算符,返回两数的运算结果
int calc(int a, int b, char op)
{
FP_CALC fp = calc_func(op);
int (*s_fp)(int,int) = s_calc_func(op);//用于测试
assert(fp == s_fp);// 可以断言这两个是相等的
if(fp)
return fp(a,b);
else
return -1;
}
void main()
{
int a = 100, b = 20;
printf("calc(%d, %d, %c) = %d\n", a, b, '+', calc(a, b, '+'));
printf("calc(%d, %d, %c) = %d\n", a, b, '-', calc(a, b, '-'));
printf("calc(%d, %d, %c) = %d\n", a, b, '*', calc(a, b, '*'));
printf("calc(%d, %d, %c) = %d\n", a, b, '/', calc(a, b, '/'));
}