简介
本次重新学习C,但是区别在于基于LInux上的gcc和make等,最原始的环境。
本系列会默认有一定的C语言能力的,所以会跳过一些我自己认为基础的东西,从而重点去提自己不熟的地方。
一、介绍
main 函数在不同的环境中有不同的传参和接参情况:
程序运行:
C源文件——预处理——编译——链接——可执行文件
编译器gcc
man gcc查看gcc手册
执行程序
执行hello.c文件(方法一:标准版)
预处理:
gcc -E hello.c
宏以#的语句在此状态下被解决
gcc -E hello.c > hello.i
将预处理的结果保存对应后缀名的文件
编译
gcc -S hello.i
此时就将预处理后的文件编译为汇编文件
gcc -c hello.s
生成hello.o的文件,此时就不能直观的看懂文件了
链接
gcc hello.o -o hello
可执行文件
./hello
执行hello.c文件(方法二:简便版)
直接gcc hello.c
gcc hello.c -Wall :打印出所有警告信息
生成a.out文件:此文件就已经执行了之前所有的操作了
最后 ./a.out
执行hello.c文件(方法三:简便版)
gcc hello.c -o Myhello
./Myhello
执行hello.c文件(方法四:用make)
cc:Gcc编译器,直接自动执行
Vim:常用指令:ctrl+p:跳出相关关键字
vim * -p会打开当前目录下所有的文件,gt切换文件编辑
Man 函数名:检索函数操作
基本概念:
算法:解决问题的方法;
程序:用某种语言实现算法
进程:程序开始执行时,出现进程
防止写越界,防止内存泄露,谁打开谁关闭,谁申请谁释放
注意:
1.exit和return 0 的区别?
答:
return
是语言级别的关键字,表示函数返回;而exit()
是系统级别的函数,表示进程退出。2.echo $?什么意思?
答:输出对应的进程信息,
echo $?
的意思是:显示上一条命令的退出状态码3.#if 。。。#endif的意义
答:告诉编译器,只有在满足特定条件时,才编译它们包裹起来的代码。否则,这些代码在编译前就会被预处理阶段直接移除,就像它们从未存在过一样。
4.Float类型:存在失真的情况,因为本身就是不精确的数,所以无法真正的去比较一个数:大数吃小数:小数的精度高会被大数吞——解决方法?
答:本身的比较是不适合的;可以换更高精度的或者用一定的计算公式来比较
二、数据类型、运算符和表达式
- 所占字节数
- 存储区别
- 不同类型的数据间进行转换
- 特殊性: 布尔型
Float类型:存在失真的情况,因为本身就是不精确的数,所以无法真正的去比较一个数:大数吃小数:小数的精度高会被大数吞
Char型是否有符号
不同形式的0值:0、‘0’、“0”、‘\0’
变量和常量:
常量:
整形常量
实型常量:3.14
字符常量:单引号引起来的单个字符和转义字符
字符串常量:双引号引起来的一个或多个字符组成的
标识常量:#define修饰的量,宏会把对应的参数直接替换,注意++/--符号
Gcc -E define.c
变量
存储空间堆:动态内容存储;栈:临时空间,默认;——变量申请,需要通过编译器来决定
存储类型:
Auto:默认,默认值为随机值,自动分配空间,自动回收空间
Static:静态型,自动初始化为0或空值,并值其变量的值具有继承性,只用一块空间;不能跨文件
Register:寄存器类型,只能用来局部变量,大小有限制,只能定义32位;寄存器内部无地址,所以一个寄存器类型的变量无法打印出地址查看或使用。
Extern:说明型,意味着不能改变被说明的变量
运算符和表达式:
特殊用法:
1.取模必须是整数;
2.逻辑运算符:短路原则:
当前面的表达式为0时,在与运算中会直接为0,导致后面的表达式短路,最终打印m=0,n=1;
3.重点——位运算
三、输入&输出专题
1.格式化IO函数:scanf、printf
int printf(const char *restrict format, ...);
Format:“%(修饰符)格式字符”,输出表项
格式字符
%e:科学计数法
修饰符
注意:L和LL:在进行大数据计算时,需要考虑
int scanf(const char *restrict format, ...);——输入值符合,则返回值为1,否则为0
Scanf(”%*c%c“,&ch);——*抑制符,相当吃掉了ch前面的杂项字符
输入输出%s:可能存在溢出的风险
2.字符IO函数:getchar、putchar
int getchar(void);
int putchar(int c);
3.字符串IO函数:gets、puts
这个函数很危险,因为对缓冲区不会对任何检查,一般用char *fgets(char s[restrict .size], int size, FILE *restrict stream)来替换或者getline
int getc(FILE *stream);
int puts(const char *s);
1.getline完全替换gets() ?
答:getline(char **lineptr, size_t *n, FILE *stream);2.%e:科学计数法?
答:当使用
printf
和%e
时,它会将浮点数以科学计数法的形式打印出来。格式:[-]d.ddd...e[+/-]ddd
d:表示一个数字。
.:小数点。
e:指数标记(在有些系统或区域设置下也可能显示为大写的 E)。
[+/-]:指数的符号(正数时通常也会显示
+
号)。ddd:指数部分,通常至少为两位数字,不足时补零
3.Printf 和 fprintf的区别?
答:
printf(...)
是fprintf(stdout, ...)
的简化形式。
fprintf()
是通用函数,可以指定输出到任何文件流。