1970年--1989年 经典C
1989年 ANSI89 ISO90标准
C特点
中级语言
比较底层
小型与语言(有限的语言特性,依赖标准函数库)
C语言是一种包容性语言
C语言不是一个强类型的语言(更广阔的自由度,不强制进行详细错误检查)
强类型:安全性较高,严格的安全性检查如C++ C# java...
弱类型:不做类型检查,灵活,安全性低 如:Javascript ,Ruby
高级语言,汇编语言,机器语言
编译型语言:c c++
解释型:Basic
过程:
预处理:预处理执行#开头的命令
编译:
链接:
1·写源程序 2编译:gcc -c xxx.c 1)预处理2)编译 生成目标文件 xxx.o
2·链接:gcc xxx.o -o xxx生成可执行文件
注释 /* */为主 或//
样式:盒型注释,简化盒行注释 翼型注释
变量:内存的一片空间,用类型确定变量大小
声明:类型+变量名
赋值:给float变量的赋值需要在数值后加f
混合赋值是可以的,但不安全
int:4 byte 32bit
标识符
标识符长度;C89声称可以任意长,但编译器只记住前31个
c99 63个
关键字
有特殊含义字符
全用小写
书写规范
空格:rong
缩进:识别程序嵌套
空行:有助于把程序分为逻辑单元
命名规则
驼峰命名:用大小写区分单词
下划线:用下划线区分
变量类型
char;int;double;float
无符号:%u
定义无符号:unsigned int dw;
int ;一般占据4个字节(32位机器中)一般占据2个字节(16位机器中)
有符号整数范围 2147483647~-21473648
unsigned int :0~4294967295
short int long int 默认有符号
%hd :短整型有符号
%hu:短整型无符号
long long int lli;占八个字节
不同情况的int也可这样定义:
unsigned dw1=10;
浮点型:
float(%f);double(%lf);long long double(%lf)
进制转换
10-->2
int x=100;
00000000 00000000 01100100
x=-100
补码:
反码+1
原码 00000000 00000000 01100100
反码 1111111 11111111 11111111 10011011
补码 1111111 11111111 11111111 10011100
转义序列
响铃\a
退格\b
一个tab符\t
回车覆盖\r
%g:flost double 去尾零
%%\n 打印%
打印所占空间大小
sizeof()
sizeof(类型)
sizeof(变量名)
sizeof(表达式)
算术运算符
+ - * / %
#include
2 void mian()
3 {
4 printf("5%3=%d\n",5%3);
5 printf("-5%3=%d\n",-5%3);
6 printf("-5%-3=%d\n",-5%-3);
7 printf("5%-3=%d\n",5%-3);
8
缩进
向后缩进 tab
向前缩进
c中a+b=10,赋值不合法
复合语句
{
}
if 语句
if( 0==X)
{
}
位运算
&:屏蔽掉某一个或某几个二进制位,如通过这个运算使某一个二进制位为0(如底层控制硬件),或知道指定的二进制数是0还是1
|:把某一个二进制位置1,或知道指定的二进制数是0还是1
^:将指定的位反转
~:取反,十进制数直接按位取反等于+1反转符号
<<:左移左移右边空位补0,右移左边空位补符号位,判断左边或右边的二进制位
取地址符
%p:打印地址
a=100;
printf("&a=%p\n",&a);
*:
("%02d"):不够两位数添零补齐
流程控制:
if
switch
:switch(表达式是整数)
case(常量表达式)
default:所以都不满足时执行,与所在位置无关
for(i=0,j=0;i*j<20;i++,j++,printf("%d %\n",i,j));
空语句:
;
错误:
if();执行空语句
输出缓冲区问题,既没输出,也没有输入时,缓冲区内容不显示在显示器上
int i=0;
while(i<10)
{
i++;
if (i==5) continue;
printf("%d",i);
}
printf("\n");
goto :无条件跳转语句
goto next;
next:
printf();
数组:作业:
开发一个程序来维护账户余额;
程序将为用户提供选择菜单,
清空账户余额,存钱,取钱,显示当前余额
sizeof(数组名):或sizeof(数组元素):知道数组所占空间
rand():产生伪随机数
include<time.h>
解决:srand(time(NULL)):交给随机算法一个随机算子
printf("time=%d",time(NULL));
srand(time(NULL));
int x=rand()%4;
有void函数中return;不可有值
return相当于结束函数
函数不能返回数组
参数列表中可以有void
数组可以作为参数
传递数组时:要传两个参数,一个是数组元素,一个是数组长度
函数声明:
隐式声明:返回值均为int
递归函数:一定有退出条件;每进行一次调用,向结果靠近一步
函数参数属于局部变量,而且是自动变量
静态局部变量:static int sa;函数调用结束时,不会释放,不受函数限制,直到程序运行结束
自动局部变量:作用域是函数内部或者更小;如for循环中,生命周期:函数调用期间,函数调用开始分配,调用结束释放
全局变量作用域:整个程序运行期间
任何类型的地址都占4个字节(32位)
int *p;
int x=10;
p=&x;//x的首地址保存在了p中
*运算:用地址找变量&:用变量找地址
函数返回局部变量结果未知
指针运算
加整数,减去整数,指针相减,但不可相加,指针比较
int *p p++:指针向后加四个字节
两个int类型指针相减,得到的是两个指针之间包含的int类型数的个数
数组名是一个指针,但值不可改变
sizeof(数组名):得到的是整个数组长度
*p++=*(p++):是对指针操作
作业:用全局变量实现栈
printf()遇到/0停止打印
cahr [10]="abcdef";也可,但占据了7个长度
char str4[]="abcdef";
printf("%p\n","asdf");打印的是asdf的地址
char* str5="abcdef";只读空间
char str4和char str5的区别:
对str5无法对其元素修改
str5=“abbcdab”;可以,改变指向,指向另一内存空间
段错误;访问了无法访问的内存
打印字符串:
printf("adfa")
printf("%s","asdsafafd");
printf("%10.6s\n",str);输出六个字符,宽度:10;十个空格
puts();输出一串换行的字符串
对字符串,str[];
可以scanf("%s",str);
对char* str3;
scanf("%s",str3);不可;可能破坏数据,可能段错误,可能什么事没有
const
int const* p;常量指针
const int* const pc=2;//pc和pc的地址均不能改变
字符串函数
str[10]="asasd";
strcpy(st1,"asdasdasd")
strncp(str1,"abcdefghijk",9);只能放九个
strlen():字符串长度,不包括"\0"
strcat():字符串连接strcmp(str1.str2);if str1:return 大于1的数字
预处理指令换行;/
#define 标准符 替换列表
p->x++与(*p).x++同一个意思->前须是指针,一般用来访问结构体成员
不要返回局部变量的地址,因为他指向的空间已经释放
sqrt():开方函数,fabs():求绝对值函数
结构体
补齐:
以最长的为标准,成倍数增,超过四已四的倍数为标准
位段:
在结构体中,可以自己定义用多少个二进制位定义一个数
struct date()
{
unsigned int day:5;用五个二进制位表示day
}位段中的成员不能对其取地址
联合
联合中所有的数据共享一片内存,其大小等于所占内存最大的那个变量的内存空间
枚举:增加程序可读性
枚举中每一个变量是整数常量,参与整数运算
enum Season{SPRING,SUMMER ,AUTUMN,WINTER}
相当于 const int SPRING=0;
不赋值时默认按从0开始;赋值按所赋整数
if(type==SPRING)
{
}
用指针操作一片内存空间,空间有无,指向位置在哪
int* p=NULL;//空指针,保存地址为0打印是输出nil
char* fb()
{
char* str="abcde";//在代码区(只读区)存储着abcde,栈区保存abcde的地址
return str;
}//安全,返回字符串字面值是安全的
Int* fa()
{
int x;
return &x;
}//错误
char const *p:指针自己是常量const char *p:指针指向的变量是常量
双指针:
int**保存指针的地址,又叫指针的指针
void* p=NULL
不能进行*号运算,使用时先强制转换为有类型再*
p++:向后走一个字节
用它做函数参数可以传任何类型的地址;
void fa(void* p)
函数指针
void (*pa)()=&fa//pa就是函数指针*pa()//调用fa()函数
void *pf():pf是函数,返回void*
int* (*pfb)(int*,int*)
pfb的类型是int* (*)(int*,int*)
函数名本身就是函数地址&fa=fa
数组指针
int a[10];
int (*p)[10]=&a;//不取地址是第一个元素,取地址是数组指针
动态内存分配
程序执行时分配内存,适用于所有类型,
C99支持变长数组
malloc():分配一片空间,返回空间首地址
calloc():参数两个,会初始化,
realloc():可能会移动内存区域,所以
以上内存分配函数声明在
void fa(int* b)
{free(b);}
int* a=malloc(100*sizeof(int ))
{fa(a);}a就是悬空指针
格式输出
%标志 最小字段宽度 精度 长度修饰 转换说明符
-:左对齐
+:有符号总是以+-号开始
#:以o开头的八进制,以ox开头的十六进制
宽度和精度可以用*号表示,但要用参数传递 .*精度 *宽度
sscanf():从指定的字符串读取
stdin:键盘,标准输入设备
stdout:显示器,标准输出设备,带缓冲区
stderr:显示器,标准错误输出设备,不带缓冲区,直接显示,不能重定向
什么时候清空输入缓冲区
1.程序结束
2,换行
3,等待输入
4.调用函数fflush()
fflush(NULL);清空所有打开的缓冲区
getc(),遇到EOF时读取结束
ungetc(ch,file),把ch字符再次放回
read(),有返回值,通常保存,int r=fread()
移动文件指针:
fseek(wenjian zhizhenxiangnazou xiangduiweizhi)
int main()
{
FILE* fiel=()
putc('1',file)
fseek(file,3,SEEK_SET);//-3,向左走
putc(‘2’,file)
}
头文件:
断言 assert.h 用于调试
float.h stdarg.h:处理可变常参数 ctype.h stdjmp.h stdlib.h:工具 time.h errno.h signal.h :处理进程信号