C语言笔记

编译工具(gcc)MinGW
代码文件以.c结尾
开发工具(windows中vs)


头文件:
#include <stdio.h>

#include:将指定文件内容拷贝到此处

<>:表示文件位置在编译器预定义默认的C库文件的位置
"":表示文件位于当前目录,若找不到,再去预定义的位置查找


main函数
程序的唯一入口,有且只有一个
格式1:
int main(void){
return 0;
}

格式2:
int main(int argc,char* argv) {
return 0
}

int:函数返回值,main函数的返回值必须为int
void:参数,void表示没有参数

 

printf函数
向标准输出设备输出信息
占位符:
%s:字符串
%d:整数
%f:小数(小数点后6位有效数字,%.10f:小数点后10位有效数字,%20f:占20个字符宽度,右对齐显示)
%ld:long长整型


编译
gcc 文件 -o 输出文件名

windows:-o指定后文件名后跟后缀exe,未指定为a.exe
linux:-o指定文件名为指定文件名,未指定为a.out


注释
单行注释://
多行注释:/* */


数据类型
char:字符型(1个字符,1个字节,范围(-128~127),和“字符”,所有ASCII字符,128个),char[]:字符数组,字符串
int:整数类型(4个字节,范围-(2的31次方)~2的31次方-1)
long:长整型(8个字节,在32位系统中和int相同,占用4个字节)
long long:长长整型(8个字节,不区分系统位数)
float:单精度浮点类型(4个字节,分开存储尾数和指数,1.75E5:1.75乘以10的五次方(尾数:1.75,指数:5),最大精度为7位有效数字,范围(-3.4*10^38~3.4*10^38))
double:双精度浮点类型(8个字节,最大精度为16位有效数字,范围(-1.7*10^308~1.7*10^308))

 

scanf的使用
scanf("%d",&name):获取键盘输入,将值赋值给name,值为整数类型
注意:如果传入多个值,将会将多余的值存放到缓冲区,为下面的scanf进行赋值
scanf("%d%d",&age1,&age2):同时传入两个参数,分别赋值,空格分隔
scanf("%d,%d",&age1,&age2):同时传入两个参数,分别赋值,必须以逗号分隔
scanf存在返回值,返回的是成功赋值的个数
char类型的赋值不会跳过空格
定义格式化的scanf输入:
int age;
char name[32];
scanf("年龄=%d,姓名=%s",&age,&name); //输入时可以输入“姓名=张三,年龄=24”
printf("name=%s,age=%d\n",name,age);
经典错误:
char a,b;
scanf("%d",&a); //输入256,按4个字节存储,第2个字节保存到b变量中
printf("a=%d,b=%d\n",a,b); //输出为a=0,b=1
输入double类型变量的值,必须使用%lf,否则输入失败
输出double类型变量的值,可以使用%lf或者%f,没有区别
在字符串中的使用
char name[10];
scanf("%s",name); //在接收字符串时,不需要在变量名在加&,原因是name是数组的变量名
缺点:接收字符串时,遇到空格即停止,不能接收到完整的字符串。建议使用gets。


char数据类型的其它输入输出函数
getchar:输入一个字符,不进行赋值可起到暂停程序的效果
char c;
c = getchar();

putchar:输出一个字符
char c = 'a';
putchar(c);

getc:输入一个字符
char c;
c = getc(stdin); //输入一个字符,指定输入设备,stdin表示“标准输入设备”,默认是键盘

putc:输出一个字符
char c = 'b';
putc(c,stdout); //输出一个字符,指定输出设备,stdout表示“标准输出设备”,默认是显示器

gets:接收字符串(次函数容易造成越界,相当于读一行,例如下面定义了10的字符长度,应存放9个字符,若赋值超过此长度,便发生越界,会破坏其它数据)
char name[10];
gets(name);

fgets:接收字符串(读取成功返回字符串,读取失败返回NULL)
char name[8];
fgets(name,sizeof(name),stdin); //接收字符串,最多只接收8-1个字符,从标准输入接收,若在回车符之前的数据不足指定的字符,会停止读取,但回车符也会读取
//sizeof():获取指定变量所占用的字节数



字符串
在C语言中,字符串是以“字符串数组”存储的
字符串结束符:在C语言中,为了便于存储字符串,要求在字符串最后一个字符的后面存储一个0(一个字节),常用“\0”表示
例:zq ---> 'z' 'q' '\0'
字符串的定义:
char name[10];
name[0] = 'Z';
name[1] = 'Q';
name[2] = '\0';
等同于:
char name[10] = "ZQ";
自动判断字符数组的长度,减少浪费内存资源
char name[] = "ZQ";


常用的字符串函数(#include <String.h>)
strlen():计算字符串的长度
char name[] = "zhangsan";
int len;
len = strlen(name);
strcpy():字符串拷贝(不安全,可能导致越界)
char name1[] = "Rock";
char name[32];
strcpy(name2,name1); //将字符串name1拷贝到字符串name2,同时拷贝字符串结束符,打印时遇到结束符停止打印
strncpy():字符串拷贝,指定拷贝字符个数(不拷贝结束符,若拷贝源字符串字符个数达不到指定个数,缺的个数补0)
strcat:字符串连接
char name1[64] = "河北";
char name2[64] = "廊坊";
strcat(name1,name2);
printf("name1:%s",name1); //河北廊坊
printf("name2:%s",name2); //廊坊
strcmp():字符串比较
strcmp(user,"admin"); //判断user是否等于admin,相等返回0,user字符串小于"admin"字符串返回负数,大于返回整数,比较根据字符从前往后依次比较,比较ASCII码值
strncmp():字符串比较(指定比较的位数)
strncmp(user,"admin",strlen("admin")); //仅比较指定位数的字符串字符

数组
定义:int a[8]
赋值:定义时直接赋值:int a[8] = {1,2};({1,2}只能在此种方式使用,不可再下面使用a={1,2})
a[0] = 1;
a[1] = 2;

调用:
printf("第一个元素为:%d",a[0]);


比较运算符:(返回值:真:1(非0即是真),假:0。注:不可比较字符串,比较的是char、int、float、double)
>
<
>=
<=
!=
==


布尔类型(bool)
在C89种,使用0表示假,使用非0值表示真
在C99开始,使用true表示真,false表示假


逻辑运算符
&&:逻辑与,(条件1 && 条件2)当条件1为真时,才去判断条件2
||:逻辑或,(条件1 || 条件2)当条件1为真时,不再判断条件2,当条件1位假时,才对条件2进行判断
!:逻辑非,(!(条件)),当条件中存在变量时,一定要用括号将条件扩起来,错误示例(! age >= 30)(age非0即为真,取反为假,假为0,条件为假)。当条件为真时,为假,当条件为假时,为真


逗号运算符(优先级低,在赋值时要加括号)
(x = (表达式1,表达式2,表达式3)):依次计算,最右面表达式的值为表达式的值


三目运算符
条件 ? 表达式1 : 表达式2
条件为真,值取表达式1
条件为假,值取表达式2


类型转换
隐式类型转换
算术转换(char、int、long、long long、float、double、)
3 + 1.5 => 3.0 + 1.5
赋值转换
int x;
x = 3.14; //按int类型转换
输出转换
printf("%c\n",255+50); //按305的二进制最后一个字节为00110001的十进制49,输出1
printf("%d",3.14); //错误
int类型数据,按照%f格式输出时,将得到错误的输出。
float(或double)类型数据,按照%d个数输出时,将得到错误的输出

强制类型转换
printf("%d",(char)257 + 100); //将257强制转换为char类型


if判断语句的使用(条件判断语句)
形式1:
if(条件判断){
代码块
}
形式2:
if(条件判断){
代码块
}else{
代码块
}
形式3:
if(条件判断){
代码块
}else if(条件判断){
代码块
}else{
代码块
}

while循环语句的使用
while(条件判断){
循环体
}


进程休眠
windows:Sleep(1000); //单位毫秒(<windows.h>)
Linux:sleep(1); //单位秒


for循环语句的使用(在循环次数已知的情况下使用for循环更为方便)
for(int i=1;i<=5;i++){
循环体
}
注:for循环中的三个表达式中的任意一个或多个都可以省略,但分号不可省略


do-while循环语句的使用(不管条件是否成立都会执行一次)
do{
循环体
}while(条件判断)


文件操作(#include <stdio.h>)
fopen:打开文件
FILE *fopen( const char *fname, const char *mode );
参数1:fname表示文件名,可包含路径
参数2:打开方式
返回值:FILE * 文件指针(若打开失败,返回NULL(0))

fclose:关闭文件(写操作可能写到缓冲区中,未写到文件中,只有执行过fclose或fflush才会将文本写到文件中)
fclose(file);

fgetc:从文件中读取一个字符(读完文件后返回EOF也就是-1)

fputc:将一个字符写入文件(写入成功返回写入字符,失败返回EOF)

fgets:从文件中读取一个字符串
fgets:接收字符串(读取成功返回字符串,读取失败返回NULL)
char name[64];
FILE * file1;
file1 = fopen("文件路径","r");
fgets(name,sizeof(name),file1); //接收字符串,最多只接收8-1个字符,从标准输入接收,若在回车符之前的数据不足指定的字符,会停止读取,但回车符也会读取
//sizeof():获取指定变量所占用的字节数

fputs:将一个字符串写入文件

fprintf:往文件中写入格式化数据
fprintf(file,"姓名:%s\t\t年龄:%d\n",name,age); //向file文件流中写入格式化的数据

fflush:刷新缓存
fflush(file):将文件缓冲区的数据立即写入文件
fflush(stdin):清空输入缓冲区(使用案例:scanf("%d",age);中读取的是数字类型遇到换行停止,那么换行符就存在与输入缓冲区中。而接下来使用scanf时,读取的第一个字符是换行符)

fscanf:格式化读取文件中的数据(当读取成功时,返回实际读取的数据个数,失败时,返回EOF)

fwrite:以二进制形式写数据到文件中去
#include <stdio.h>
int fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
参数1:要写入的内容(内容的起始地址,变量名)
参数2:每次写入几个字节(sizeof(char)等同于1)
参数3:写入几次
参数4:写入到哪个文件流中

fread:以二进制形式读取文件中的数据
#include <stdio.h>
int fread( void *buffer, size_t size, size_t num, FILE *stream );
参数1:要读取到哪个变量中
参数2:要读取几个字节
参数3:要读取几次
参数4:从哪个文件流中读取

putw:以二进制形式存储一个整数

getw:以二进制方式读取一个整数(读取成功返回值,读取失败返回-1,文件中读取的是-1返回的也是-1,可以使用feof进行判断读取结束,在使用getw时会将文件结束符也读取为-1,多一个值,尽量使用两者同时判断(value == -1 && feof(文件流)))

feof:判断文件是否结束(未结束返回false,结束返回true)

ferror:判断文件读写是否出错(例如:读权限打开文件,进行写操作)

perror:输出函数的错误信息
FILE * file;
file = open("test.txt","r");
if(!file){
printf("文件打开失败"); //以读权限打开文件
return 1;
}
fputc("A",file);
if(ferror(file)){
perror("fputc"); //输出fputc函数的错误信息,没有错误不输出
clearerr(file); //清除错误标志
}

clearerr:清除文件错误标志(在发生错误后,即使进行正确的操作,也不会清除错误标记,可使用此函数清除错误标志,否则错误标志一直存在)

ftell:获取文件指针的当前位置(返回long类型的长整数,单位是字符个数)

文件定位:
fseek:随机定位
#include <stdio.h>
int fseek( FILE *stream, long offset, int origin );
参数1:文件流
参数2:偏移量,可正可负,>0向文件尾方向偏移,<0向文件头方向偏移
参数3:SEEK_SET 从文件的开始位置定位,此时参数2必须大于0
SEEK_CUR 从文件的当前位置定位
SEEK_END 从文件的结束位置定位,此时参数2必须小于0

switch语句的使用
switch(n){
case '1': //当n为1时
{
... //case代码语句中无法定义变量,如一定要定义变量,需要在前后使用{}括号,且变量仅生效在{}括号内
break;
}
case '2': //当n为2时
...
break;
case '3': //当n为3时
...
break;
default: //当n不为1/2/3时
...
}

使用或的时候可以用以下方式
case 1:
case 3:
case 5:
days = 31 //当值为1/3/5时days赋值31

switch:用于int、char、long、long long类型的变量,和多个特定常量的判断处理(float和double类型不可以)
if:适用于各种逻辑判断

函数:
被调用的函数需要定义在调用者之前,或者在调用者前面声明
声明:返回类型 函数名(参数);

递归函数
斐波那契数列:1,1,2,3,5,8,13,21...(前两个数字为1,从第3个数开始为前两个数字相加的值)
int fib(int n){
int s;
if(n == 1||n == 2){
return 1;
}
s = fib(n - 1) + fib(n - 2);
return s;
}
递归函数缺点:性能很低(能不用则不用)

 

posted @ 2019-01-28 17:57  全心全意_运维  阅读(376)  评论(0编辑  收藏  举报