c语言必会知识点,c语言笔记-知识点汇总
c语言必会知识点,c语言笔记-知识点汇总%f实型, float 大小为4字节%c字符型, char 大小为1字节short 大小为2字节 int 大小为4字节 long 大小为4字节
1,除法运算符“/" 运算的变量均为整数时,结果也为整数:2/6结果为0,向0取整,整形和实型运算时会自动转换,打印时结果要用高 精度符号。
2,有符号数据,最高位决定正负,0为正,1为负。
3,输入输出函数中32位环境下(1字节=8位):
%d 整形数据,
short 大小为2字节
int 大小为4字节
long 大小为4字节
%c字符型, char 大小为1字节
%f实型, float 大小为4字节
%lf双精度实型 doule 大小为8字节
4 占位符分类
%d 整型
%hd short
%ld ----->long
%lld ---->long long
%o ---->八进制
%x ---->十六进制
%u ----->打印无符号数
%f ---->float
%lf ----->double
%e ---->指数形式
%g ----->比较智能,会选择较短的方式去打印数据
%c ---->char
%s ---->字符串
%p -----> 地址
%Md ----> M为域宽(默认是右对齐) ---》M为一个常数
%-Md ----->M为域宽(左对齐) ---》M为一个常数
5 取余运算必须是整型,可以用来十进制数的按位分离
6,位运算符,“&”“|” “~”“<<”“>>”
按位与“&”十进制数转换为二进制,每一位进行判断,有0则0,全1为1
0000 0101 & 0000 1011 结果为0000 0001
按位或“|”十进制数转换为二进制,每一位进行判断,有1则1,全0为0
0000 0101 | 0000 1011 结果为0000 1111
按位异或“^”十进制数转换为二进制,每一位进行判断,相同为0,不同为1
0000 0101 ^0000 1011 结果为1111 0001
按位取反“~”十进制数转换为二进制,每一位进行判断,是0为1,是1为0
~0000 0101结果为 1111 1010
按位左移“<<”每位左移动,低位补零,每移一位,十进制数扩大二倍
按位右移">>"每位右移动,高位补零,每移一位,十进制数减小二倍
7,随机数函数rand和srand
rand()/32767随机产生0,1两个数;rand返回值在0-32767之间
srand((unsigned)time(NULL))初始化随机数种子,seed值相同,rand会产生相同的随机数,
time(NULL)取系统时间的函数
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i=0 j=0 tmp=0; time_t times=0; int num[10]={0}; times=time(NULL); srand(times); for(i=0;i<10;i ) { num[i]=rand()0; } for(i=0;i<10;i ) { printf("num[%d]=%d " i num[i]); } printf("\n"); return 0; }
8, \t \r \n都是转义字符,空格就是单纯的空格,输入时可以输入空格
\t 的意思是 :水平制表符。将当前位置移到下一个tab位置。
\r 的意思是: 回车。将当前位置移到本行的开头。
\n 的意思是:回车换行。将当前位置移到下一行的开头。
\f的意思是:换页。将当前位置移到下一页的开头。
9,位操作
如果需要某个变量的某一位变为0,其它位不改变,a = a & ~ (1<
a xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1xxx
1 0000 0000 0000 0000 0000 0000 0000 0001
<<3 0000 0000 0000 0000 0000 0000 0000 1000
~ 1111 1111 1111 1111 1111 1111 1111 0111
& xxxx xxxx xxxx xxxx xxxx xxxx xxxx 0xxx
如果需要某个变量的某一位变为1,其它位不改变,a = a | (1<
a xxxx xxxx xxxx xxxx xxxx xxxx xxxx 0xxx
1 0000 0000 0000 0000 0000 0000 0000 0001
<<3 0000 0000 0000 0000 0000 0000 0000 1000
| xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1xxx
如果要对某两位写入某值,其他位不变,需要先清零,再或一个具体值(n);
a= a & ~(3<
a= a | (n<
01:n=1 10:n=2 11:n=3
xxxx xxxx xxxx 10xx xxxx xxxx xxxx xxxx
3 0000 0000 0000 0000 0000 0000 0000 0011
<<18 0000 0000 0000 1100 0000 0000 0000 0000
~ 1111 1111 1111 0011 1111 1111 1111 1111
& xxxx xxxx xxxx 00xx xxxx xxxx xxxx xxxx
2 0000 0000 0000 0000 0000 0000 0000 0010
<<16 0000 0000 0000 1000 0000 0000 0000 0000
| xxxx xxxx xxxx 10xx xxxx xxxx xxxx xxxx
10,三目运算
表达式1 ?表达式2 :表达式3
a
a小于b是否正确,是max等于b 不是max=a
11,if else 和 switch case
满足就执行,不满足不做任何操作时用“if”
有两种情况,满足执行一种情况,不满足执行另一种情况用“ if else”
多种情况,执行一种“if else if”" switch case"(switch case语句不能根据表达式的范围做出选择,case后只能是常量)
12,for 和while循环
知道循环次数时使用for循环,不知道循环次数时,使用while循环。
例:输入一个数打印出这个数是几位数;
int counnt=0; int a;//输入的数 while(1) { while( a!= 0) { a=a/10; count } printf("%d" count); count=0 }
14,循环结构while,do-while,for语句中
break用法:只打断直接包含break的循环语句,执行break后,循环语句里后边的语句不再执行。
continue用法:打断本次循环,跳转到循环开始处,继续下一次循环,当次循环后边的语句不再执行,下次循环继续执行。
goto用法:直接跳转到标签名所在位置,执行程序,相较于break可以直接跳转到多层循环之外
return 用法:1,返回一个值,2,程序结束
15,函数的格式
int main(void)//函数头 格式 返回值类型 函数名 (形参列表) 返回值类型可以省略,省略时默认为int类型 { return 0;//函数体 具体执行的代码,如果有返回值用return 返回。 }
16,函数中的局部变量,只能在函数中使用
17,子函数的结果需要在其父函数中做运算,需要有返回值。
18,主函数中的数据需要在子函数中做运算,需要有形参列表。
19,getch()函数:输入字符的函数,输入的字符不显示,不需要按回车键,包含在头文件conio.h中
char a;
a=getch();
20,函数分类 类型 调用格式
void mm(void);无参数无返回值函数 mm();
void mm (int a);有参数无返回值函数 mm(实参);
int mm(void);有返回值,无参数函数 int a=mm();
int mm(int a);有返回值,有参数函数 int a=mm(实参);
21,地址传递:
地址传递就是将实参数据地址给了形参,可以通过地址进入实参的空间改变实参的值
22,修饰变量的关键字
const:
格式:const int a=10;const修饰的变量存在flash中,变量的值不允许改变。
使用:当存放大量数据并且不需要修改时候用const修饰,比如图片信息
extern:
格式:extern int a=10;extern修饰的变量可以跨文件使用。
static :
修饰函数:static void delay_ms(u32ms); 此函数只能在当前的.c文件使用
修饰变量: static int a=0 ;此变量被放在静态区,函数结束时,变量不会释放。下次循环到这个语句时,检测到static就不会再给a赋值0;
23,地址的理解:
系统内存的储存空间,以字节为单位一个一个编号;地址的编号就是字节在内存中的编号。
24,变量值和变量地址的理解:
short a = 10;
变量名是a,变量的类型是short,变量的值是10,变量的地址是“&a”;
系统分配一个2byte的空间,空间名字叫做变量a,空间地址是这个空间的起始字节的编号。
在空间里写入一个值10,
地址值:分配空间后空间的起始字节编号(编号是系统规定的),
变量值:分配空间后,往空间里写入的值。
访问空间的方式:
通过变量名访问:a=10;
通过地址值访问:&a;
25,指针的理解:
int *p
变量名:p
变量名的类型: int *
描述:这是一个可以存地址数据得变量---指针变量
26,指针运用:定义一个变量a,定义一个指针变量b,a的值等于10,将a的地址值赋给指针b;
int a;
int *b;
int a=10;
b = &a;
27,指针变量的类型
int *p 指针变量 存储整型变量;
short *p 指针变量 存储short类型变量;
char *p 指针变量 存储char类型变量;
28,p= &a
指针变量p储存了变量a的地址,也可以描述为指针p指向了a
29,值传递:
父函数中的实参的数据拷贝到子函数中的形参,不能改变实参的值
地址传递:
父函数中的实参的地址传入到子函数中的形参,子函数可以通过地址编号改变实参的值
30,如何确定值传递和地址传递
只是需要在父函数中的变量值,并不需要改变变量的本体,使用值传递
需要使用父函数中的变量,并需要修改变量本体,使用地址传递。
地址传递时需注意,形参的参数是指针变量,函数定义中拿到的数据要用取内容符“*”,函数调用要传实参地址。
31,取地址符“&”,取内容符“*”
int a=10 ; int *p ; int b
p = &a
b = *p
解释:变量a,取a变量的地址赋值给指针变量p,取指针变量p内的内容10,赋值给变量b,变量b等于10.
32,指针变量空间大小,指针是用来存地址编号的,地址编号固定为32位,四字节,所以指针变量的大小为4字节。
33.指针的位移跟指向对象的数据类型有关系,
int *p:指针跳动一步,地址编号就偏移4,该指针变量所存储的地址编号 加4
char *p:指针跳动一步,地址编号就偏移1,该指针变量所存储的地址编号 加1
short *p:指针跳动一步,地址编号就偏移2,该指针变量所存储的地址编号 加2
34,指针的加法
b = *p ;这条语句表达的是将指针p里的变量赋值给b之后,指针p在加1
c =*p 1;这条语句表达的是,将指针p内的值加1后赋值给c
d =*(p );这条语句表达的是,指针p加一,即指针位移一位,然后将位移的地址内的值赋值给d
35,指针的减法,
指针可以减去一个整数,表示向低地址位位移。
指针和指针做减法,表示两个指针地址之间差几步,
36,函数指针:使用时应严格按照函数的类型进行声明,有无返回 值,和函数的参数,都要保持一致。
void (*pf)(char a,int b):
将pf声明为指向函数的指针,它所指向的函数带有一个char类型, 一个int类型的参数,且返回值是void
pf =fun;
明确指针指向函数fun;
(*pf)(m,n);
通过指针调用函数
37,函数指针使用时,需要先将指针指向所调用的函数,然后再用取内容符来调用函数本身, 函数的参数使用和直接调用该函数时,用法一样。
38,指针函数(返回值时地址的函数即可称为指针函数)
void *pf (char a,int b);
判断指针函数,还是函数指针只需要看是否带有括号即可。
39,数组名就是数组首元素的地址
40,整型数组,冒泡排序
有n个数的排序 需要进行n-1次比较,
每次比较的次数=数据个数-对应的次数。
for(i=1;i<n;i ); 比较次数 { for(j=0;j<n-i;j );每次比较的次数,j要用来代表下标,所以从零开始。 { if(a[j]<a[j 1])从大到小排序 { temp = a[j]; a[j] =a[j 1]; a[j 1]=temp;交换两个相邻数据的位置 } } }
41,字符串一定存储在字符数组中,一定有一个结束字符“\0” 例:“sd6”包含“s”“d”“6”“\0”四个字符
42,字符串形式:char name “LOL”;输入字符串 : scanf(“%s”,数组名);
43,字符串输入函数
gets()和scanf(“%s”)
当输入的内容有空格时,使用gets()
fgets(str sizeof(str) stdin)
函数使用时会自动吸收一个换行符,在用strlen函数计算长度时会导致数据比输入数据多1;
44,字符串输出函数
put()和printf(“”)
put自带结束换行
45,计算字符串长度函数
strlen(数组名)包含于头文件string.h中,用来计算字符串长度的函数,有返回值
sizeof关键字,用来计算占用空间字节大小。
56,字符串复制函数;
strcopy(str1 str2),包含于头文件striing.h中: 将字符串str2复制给字符串str1
57,字符串拼接函数
strcat(str1,str2)将字符串str2拼接到字符串str1后
58,字符串比较函数
strcmp(str1 str2) 比较的是字符串元素的ASCII码表的值
返回值为int 类型,用来表示s1>s2(>0) 或者 s1=s2(=0)或者 s1
59,对于一个数组 int a[5] a和&a的差别
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int a[5] = {1 2 3 4 5};
int *ptr = (int *)(&a 1);
printf("%d\n" *&a);//取地址a得到的是数组的地址,即首元素的地址,
// 和a表示的地址值一致,但表达的跨度不一样。&a表示的大小为a数组的大小
printf("%d\n" a);//a表达的为数组元素a[0]的地址,a 1代表在数组内加一得到结果为a[1]的地址
printf("%d\n" *(&a 1));///&a 1,表示在数组a大小的空间外加1
printf("%d\n" *ptr);
printf("%d %d\n" *(a 1) *(ptr-1));
return 0;
}
60 scanf函数里遇到*p 和*(p )时,运行结果一致,都是先*p取出 地址里的值,然后p再加1。
61 指针在使用字符串赋值时,会先创建一个空间存放字符串,然后将字符串的首地址传给指针,下列指针a和b所对应的地址都是hello字符串的首地址。
char *a = "hello"; char *b = "hello";
62 scanf函数放到循环内时,会吸收回车符,导致输入数据变少,提前结束循环,在取字符时会出现这种情况。
#include<stdio.h>
int main()
{
int i=0 j=0;
char a[3][3]={0};
char (*p)[3]=a;
for(i=0;i<3;i )
for(j=0;j<3;j )
scanf("%c" (*(p i) j));
printf("%d\n" j);
for(i=0;i<3;i )
for(j=0;j<3;j )
printf("%c" *(*(p i) j));
return 0;
}
63 二维数组中行可以省,列不能省。
64,’\101‘是以八进制存储的ASCII码表中的字符。
65 在数据溢出时系统是如何处理的:
signed char有符号空间范围-128~127
输入-129
-129的原码存储空间不够需要借位为16位
1000 0000 1000 0001负数存储时需要存补码,即原码取反 1(取反时符号位不变)
1111 1111 0111 1110 1
1111 1111 0111 1111 反码,
存储在一个8位有符号的空间时实际存储内容为
0111 1111
在读取时,最高位为0,判断为正数,直接输出
0111 1111 =127
同理输入-130
1000 0000 1000 0010
1111 1111 0111 1101 1
1111 1111 0111 1110
实际存储内容为
0111 1110 = 126
输入128
1000 0000原码,读取时判断高位为1,为负数需要-1,在取反,借位-1
1111 1111 反码 取反
1000 0000 =-0 =-128 -0在char类型中定义为-128
66 char *p=null 定义一个指针,没有空间,只有当它指向一个具体的地址时它的空间才是该地址的空间。
67 ASCII码中数字0~9的范围在48~57,A~Z的范围在65~90 a~z的范围在97~122.
68 与运算当第一个表达式为假时,不再执行后边的表达式
或运算当第一个表达式为真时,不再执行后边的表达式
69,函数的传参
函数定义时的形式参数只是作为声明,不占据空间,只有在调用函数时传入实参才会开辟空间,
值传递的特点是单向传递,即主调函数调用时给形参分配存储单元,把实参的值传递给形参,在调用结束后,形参的存储单元被释放,而形参值的任何变化都不会影响到实参的值,实参的存储单元仍保留并维持数值不变,
地址传递指的是将实参的地址传递给形参,在函数中通过操作实参的地址达到操作实参的目的
地址传递的特点是形参并不存在存储空间,编译系统不为形参数组分配内存。数组名或指针就是一组连续空间的首地址。因此在数组名或指针作函数参数时所进行的传送只是地址传送,形参在取得该首地址之后,与实参共同拥有一段内存空间,形参的变化也就是实参的变化。
70,变量的作用域:
变量的分类:
全局变量:定义在所有函数外部的变量
局部变量:定义在任意函数内部的变量
全局变量和局部变量能否重名:
可以重名,在局部内,局部变量有效
作用域:指的是变量有效的范围
全局变量:作用域是整个模块
局部变量:作用域是被定义的函数内部
生命周期:指的是变量存活的时间
变量的一般在定义之后开始有效,直到函数结束或者程序结束
全局变量:从定义到程序结束
局部变量:从定义到函数结束
71,副本机制:
所谓副本机制,是指copy(拷贝)的思想,不论是传值调用还是传址调用,编译器都要为每个参数制作临时副本,或称拷贝,函数体中对参数的修改都是对副本的修改。
72,递归函数:
函数调用函数自身的操作叫递归
递归(英语:Recursion),又译为递回,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。递归一词还较常用于描述以自相似方法重复事物的过程
1、在函数的内部调用函数本身
2、需要指定结束条件
3、需要起始条件
73,预处理(必须大写,XXX代表名称)
#ifndef __XXX_H_
#define __XXX_H_
#endif
#include <stdio.h>
#include <stdlib.h>
#include "fun.h"
//extern int sum(int num);
int main()
{
printf("%d\n" sum(100));
return 0;
}
int sum(int num)
{
if(num==1)
return 1;
else {
return sum(num-1) num;
}
}
预定义
#ifndef _FUN_H_
#define _FUN_H_
int sum(int num);
#endif
74 在使用scanf()函数时遇到%c的情况下要在前面使用空格来吸收输入时的空格。
75,手动在栈区开辟空间使用malloc函数,该函数会返回一个空指针,可以强制转换为其它类型的指针。
可以使用free来释放一个空间实现链表的删除。
malloc free- allocate and free dynamic memory
#include <stdlib.h>
void *malloc(size_t size);
size_t size:指定开辟空间的大小
The malloc() function allocates size
bytes and returns a pointer to the allo‐
cated memory. The memory is not ini‐
tialized. If size is 0 then malloc()
returns either NULL
void *:被称为空指针类型,可以理解为万能指针,可以转换为任何数据类型,
通过强制转换
用来接收malloc开辟空间返回的首地址
void free(void *ptr);
75,scanf函数和printf函数都有返回值,返回值为int类型,代表输入与输出的字符个数。
76,指针右左法则
int* (*p[5])(int int );
int (*func)(int *p int (*f)(int*));
C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。
右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
int (*(*func)[5])(int *p);
func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。
77,文件操作各种函数
fopen函数打开一个文件并返回一个文件指针;
格式:FILE *fopen(const char *path const char *mode);
参数:“地址”,“打开方式”
fclose文件关闭函数
格式:fclose(文件指针)
参数:需要关闭的文件
perror:打印一个系统错误信息
格式: void perror(const char *s);
const char *s:用来做提示
fgetc():从文件获取单个字符,并返回该字符对应的ASCII码对应的十进制数;
int fgetc(FILE *stream);
fputc();向任意文件流输出单个字符;返回带字符转换为int类型的值或者EOF文件结束标志
格式:
int fputc(int c FILE *stream)
feof:判断文件指针是否到末尾,是的话返回非0;不是返回0;
格式:
int feof(FILE *stream);
fgets();字符串读取
格式:
char *fgets(char *s int size FILE *stream);
参数:
char *s:需要一个数组存储获取到的字符串;
int size;保存字符串的空间大小;
fputs():字符串输入
int fputs(const char *s FILE *stream);
参数: