- scanf 输入特例
int j;
int i;
scanf("%d,%d",&i,&j);//1,2 注意逗号
printf("i=%d\n",i);//i=1
printf("j=%d\n",j);//j=2
/---------------------------------/
int main;//main可以作为变量名
int i;
scanf("%d,%d",&i,&main);//1,2
printf("i=%d\n",i);//i=1
printf("main=%d\n",main);//j=2
浮点数在内存中的表示方式是科学计数法,省略最高位的1.
- 浮点数在内存中的存储方式:符号位(0正,1负)+阶码(指数)+尾数
浮点数
整数部分正常化为二进制,小数部分第一位s=(1/2)*n1+(1/4)*n2+(1/8)*n3…
转换为科学计数法(指数,亦称阶码,用来确定小数点的位置和表示范围;尾数,确定表示精度) - 浮点数的加减运算过程:判断、对阶、正常加减
判断:两个数中是否有0。如果有,则不用计算
对阶:两个数的阶码是否相等。不相等时,小阶换大阶,同时变化尾数(保证原数大小不改变)。
尾数正常加减
引用:C语言中float,double等类型,在内存中的结构
引用:4. 乘除运算及浮点数运算 - sizeof 属于静态运算符,结果在编译时刻确定
int j=1;
printf("sizeof(++j)=%d\n",sizeof(++j));//sizeof(++j)=4
printf("j=%d\n",j);//j=1
- 强制类型转换,产生新的值。不改变原来值的类型和大小
double i=10.1;
int j=(int)i;
printf("i=%f\n",i);//i=10.100000
printf("j=%d\n",j);//j=10
- 数组的集成初始化
int a[]={0,1,2,3,4,2,3};
int b[]={[0]=10,[20]=8};
printf("sizeof(a)/sizeof(a[0])=%d\n",sizeof(a)/sizeof(a[0]));//sizeof(a)/sizeof(a[0])=7
printf("sizeof(b)/sizeof(b[0])=%d\n",sizeof(b)/sizeof(b[0]));//sizeof(b)/sizeof(b[0])=21
/*----------------------------------*/
int a[][4]={0,1,2,3,4,2,3};
int b[][6]={
{1,2},
{3,9,9},
};
printf("sizeof(a)/sizeof(a[0][0])=%d\n",sizeof(a)/sizeof(a[0][0]));//sizeof(a)/sizeof(a[0][0])=8
printf("sizeof(b)/sizeof(b[0][0])=%d\n",sizeof(b)/sizeof(b[0][0]));//sizeof(b)/sizeof(b[0][0])=12
/*----------------------------------*/
int b[][6]={
[2]={1,2},
[4]={3,9,9},
};
printf("sizeof(b)/sizeof(b[0][0])=%d\n",sizeof(b)/sizeof(b[0][0]));//sizeof(b)/sizeof(b[0][0])=30
数组之间的赋值只能通过遍历,因为 int a[10] => int * const a ;
- 字符串初始化
char s1[]={'1','c',0};
char s2[]={'2','c','\0'};
printf("s1=%s\n",s1);//s1=1c
printf("s2=%s\n",s2);//s2=2c
/*---------末尾不能是’0‘---------*/
char s3[]={'1','c','0'};
printf("s3=%s",s3);//s3=1c02c
- 处理字符串使用指针;构造字符串使用数组
char *s1="hello";
等价于
const char *s1="hello";
s1是一个指针存放在栈(stack)中,“hello”存放在代码段(只读区域)。下面是两种常见的错误操作
s1[2]='H';
scanf("%s",s1)
- const int *p = &a 等价于 int const* p =&a
- int *const p = &a
/*--------------------const int *p = &a;--------------------*/
int a=10;
const int *p = &a;
*p=2;//[Error] assignment of read-only location '*p'
int b;
p=&b;
printf("&b=%p\n",&b);//&b=0061FE94
printf("p=%p",p);//p=0061FE94
/*-------------------int const*p = &a;---------------------*/
int a=10;
int const*p =&a;
*p=2;//[Error] assignment of read-only location '*p'
int b;
p=&b;
printf("&b=%p\n",&b);//&b=0061FE94
printf("p=%p",p);//p=0061FE94
/*-------------------int *const p = &a;---------------------*/
int a=10;
int *const p = &a;
*p=2;
printf("a=%d\n",a);//a=2
int b;
p=&b;//[Error] assignment of read-only location '*p'
- 指针的运算
注意:指针之间的减法
int a[10]={1,2,3,4};
int *p=a;
int *q=a+1;
printf("p=%p\n",p);//p=0061FE70
printf("q=%p\n",q);//q=0061FE74
/*------------指针之间的减法---------------*/
printf("q-p=%d\n",q-p);//q-p=1
- *p++ ,先取出 *p的值,然后p++ 。可以用来加速运算
- 函数中申请的动态内存(malloc) 可以作为返回值使用。
尽量在同一个函数中申请和释放动态内存,除非函数本身的作用就是用来申请动态内存的
- 定义字符常量时,const 和 enum 要比 宏 好用。【前两者会有类型检查】
- 结构的集成初始化
Day today={2020,8,20};
Day tomorrow={.year=2021,.month=12};
- 结构之间可以直接赋值
Day today={2020,8,20};
Day tomorrow=today;
- 全局变量初始化值必须在编译时刻已经确定
- printf("%s",func); //打印当前函数
- C语言的注释可以用在宏的后面
- 预定义宏
__LINE__//行号
__FILE__//文件名
__DATE__//日期
__TIME__//当前系统时间
__STDC__//如果编译器遵循ANSI C,其值为1,否则未定义
__func__//当前函数
-带参数的宏使用时,整个值要括号,参数出现的每个地方都要括号
#define MIN(a,b) ((a)>(b)?(b):(a))
宏定义最后不要有 分号
使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
C语言中"#“和”##"的用法
- 全局声明时,在原型前使用关键字 extern。声明不产生代码
int i;//定义
extern int i;声明
全局变量或者函数只想在所在的.c文件中使用时,定义的时候在前面使用关键字 static
- 一种特殊而常用的字符串输入
char s1[10]="";
char s2[10]="";
scanf("%[^,],%[^\n]",s1,s2);//hello,word
printf("s1=%s\ns2=%s",s1,s2);
//s1=hello
//s2=word
- scanf 的返回值是输入数据的个数,printf 的返回值是输出的字节数
int n;
int is,ps;
is=scanf("%d",&n);//12345
ps=printf("%d\n",n);//12345
printf("is=%d\n",is);//is=1
printf("ps=%d",ps);//ps=6 (输出的字符数+结尾的换行)
- 按位&
1、某一位或者几位置0
x&0xFE
2、取一个数中的一段
x&0xFF
- 按位 |
1、某一位或者几位置1
x|0x01
2、把两个数拼起来
0x00FF|0xFF00
- 位段的用法
typedef struct _U0{
int r1:1;
int r2:4;
int r:27;
}U0;
void printBin(int t);
int main()
{
U0 uu;
uu.r1=1;
uu.r2=8;
uu.r=0;
printBin(*(int*)&uu);
return 0;
}