C语言
C 语言是一种通用的、面向过程式的计算机程序设计语言。1972 年,为了移植与开发 UNIX 操作系统,丹尼斯·里奇在贝尔电话实验室设计开发了 C 语言。
C 语言是一种广泛使用的计算机语言,它与 Java 编程语言一样普及,二者在现代软件程序员之间都得到广泛使用。
当前最新的C语言标准为 C11 ,在它之前的C语言标准为 C99
类型运算符与表达式
变量名
变量名的开头必须是字母或下划线,不能是数字
变量名中的字母是区分大小写的
变量名绝对不可以是C语言关键字
变量名中不能有空格
数据类型及长度
类型 | 存储大小 | 值范围 |
---|---|---|
char | 1字节 | -128到127或0到255 |
unsigned char | 1字节 | 0到255 |
signed char | 1字节 | -128到127 |
int | 2或4字节 | -32,768到32,767或-2,147,483,648到2,147,483,647 |
unsigned int | 2或4字节 | 0到65,535或0到4,294,967,295 |
short | 2字节 | -32,768到32,767 |
unsigned short | 2字节 | 0到65,535 |
long | 4字节 | -2,147 ,483,648到2,147,483,647 |
unsigned long | 4字节 | 0到4,294,967,295 |
常量
字符常量 常量表达式 枚举常量
声明
算术运算符
名称 | 运算符号 | 举例 |
---|---|---|
加法运算符 | + | 2+10=12 |
减法运算符 | - | 10-3=7 |
乘法运算符 | * | 2*10=20 |
除法运算符 | / | 30/10=3 |
求余运算符(模运算符) | % | 23%7=2 |
自增运算符 | ++ | int a =1;a++ |
自减运算符 | -- | int a =1;a-- |
关系运算符与逻辑运算符
符号 | 意义 | 举例 | 结果 |
---|---|---|---|
> |
大于 | 10>5 | 1 |
>= |
大于等于 | 10>=10 | 1 |
< |
小于 | 10<5 | 0 |
<= |
小于等于 | 10<=10 | 1 |
== | 等于 | 10==5 | 0 |
!= | 不等于 | 10!=5 | 1 |
符号 | 意义 | 举例 | 结果 |
---|---|---|---|
&& | 逻辑与 | 0&&1 | 0 |
` | ` | 逻辑或 | |
! | 逻辑非 | !0 | 1 |
类型转换
- 自动转换
- 强制转换
函数与程序结构
函数的基本知识
函数的定义形式
返回值类型 函数名(参数声明表){ 声明和语句 }
外部变量
作用域规则
头文件
静态变量
static int a;
寄存器变量
register int x;
register变量将放在机器的寄存器中
程序块结构
初始化
外部变量和静态变量都将被初始化为0
递归
C预处理器
文件包含
#include "文件名" #include <文件名>
宏替换
#define a b
不会替换字符串中的内容
- 带参数的宏
#undef
- 双井号嵌套
条件包含
#ifndef HDR #define HDR #endif
指针
指针与地址
p = &c; // p为指向c的指针
y = *p; // 现在y的值的c的值
指针与函数参数
void swap(int *x,int *y){
int tmp = *x;
*x = *y;
*y = tmp;
}
指针与数组
数组本质也是一个指针
但是指针是一个变量,数组名不是一个变量
地址算术运算
- 相同类型指针之间的赋值运算
- 同整数间的加减法运算
- 指向相同数组的两个指针减法或比较运算
- 将指针赋值为0
字符串与指针
void reverse(char *s,int n){
if (n<0){
return;
}
putchar(*(s+n));
reverse(s,--n);
}
指针数组以及指向指针的指针
char *sa[20];
int main(){
int x;
int *xp = &x;
int **xpp = &xp;
**xpp=15;
printf("%d",x);
}
多维数组
int a[i][j];
指针数组的初始化
指针与多维数组
char *s[]={"123","321","1111"};
命令行参数
int main(int argc,char *s[]){return 0;}
指向函数的指针
int fun(int a) {
return a+6;
}
void fun1(int (*f)(int)) {
printf("%d \n", (*f)(48))
}
int main(int args, char *args[]) {
fun1(&fun);
return 0;
}
复杂声明
结构
基本知识
struct{
int x;
int y;
} point;
struct poinit p;
p.x=1;
结构与函数
结构指针
struct point *pp; (*pp).x=5; y = pp->x;
结构数组
struct poinit ps[20];
结构指针
结构体中的数据对齐问题
自引用结构
struct{
int x;
int y;
struct point *p;
} poinit;
表查找
类型定义
typedef char* String
String s = "123";
联合
union ut{
char a;
int b;
long c;
}u;
u.c=1L;
位字段
输入与输出
标准输入输出
- getchar
- putchar
格式化输出-printf
字符 | 参数类型;输出形式 |
---|---|
d,i | int类型;十进制数 |
o | int类型;无符号八进制数(没有前导0 ) |
x, X | int类型;无符号十六进制数(没有前导0x或0X ), 10~15分别用abcdef或ABCDEF表示 |
u | int类型;无符号十进制数 |
c | int类型;单个字符 |
s | char *类型;顺序打印字符串中的字符,直到遇到'\0'或已打印了由精度指定的字符数为止 |
f | double类型;十进制小数[- ] mdddddd,其中d的个数由精度指定(默认值为6 ) |
e, E | double类型; [-]mdddd e +xx或[ - ]mddddd E土比,其中d的个数由精度指定(默认值为6 ) |
g,G | double类型;如果指数小于-4或大于等于精度,则用各e或8E格式输出,否则用8f格式输出。尾部的0和小数点不打印 |
P | void *类型;指针(取决于具体实现) |
% | 不转换参数;打印一个百分号% |
变长参数表
void pr(int a,...){
va_ list ap;
int i;
va_ start(ap,a);
for(i=0;i<5;i++){
printf( "%d" ,va_ arg(ap,int));
}
va_ end(ap);
}
int main(int argc,char *args[]){
pr(1,2,3,4,5,6);
}
格式化输入-scanf
转换字符指定对输人字段的解释。对应的参数必须是指针,这也是C语言通过值调用语义所要求的
字符 | 输人数据;参数类型 |
---|---|
d | 十进制整数; int*类型 |
i | 整数; int*类型,可以是八进制(以0开头)或十六进制(以0x或0x开头) |
o | 八进制整数(可以以0开头,也可以不以0开头) ; int *类型 |
u | 无符号十进制整数; unsigned int* 类型 |
x | 十六进制整数(可以0x或0X开头,也可以不以0x或0X开头) ; int *类型 |
C | 字符; char *类型, 将接下来的多个输人字符(默认为1个字符)存放到指定位置。该转换规范通常不跳过空白符。如果需要读人下一个非空白符,可以使用%1s |
文件访问
int main(int argc,char *args[]){
FILE *fp;
FILE *fp1;
char c;
fp = fopen(" . /reverse1.c" ,"aw");
fp1 = fopen("./reverse.c","r") ;
while((c=fgetc(fp1)) != EOF){
fputc(c,fp);
}
fputs("test",fp);
fclose(fp);
fclose(fp1);
}
错误处理
- stdout
- stderr
行输入和行输出
- fgets
- fputs
其他函数
UNIX系统接口
文件描述符
内核(kernel)利用文件描述符(file descriptor)来访问文件。 文件描述符是非负整数。 打开现存文件或新建文件时,内核会返回一个文件描述符。 读写文件也需要使用文件描述符来指定待读写的文件。