C语言基础知识总结
温故知新,心系未来
积跬步,至千里;积小流,成江海。
1、C语言关键字及数据类型
<< ****************** C 语言关键字(44个) *************************
<< 1.数据类型关键字:(16)
<< char,int,float,double,long,register(寄存器),short,signed,sizeof,struct
<< union,unsigned,_Bool,_Complex,_Imaginary,typedef
<< 2.控制语句关键字:(12)
<< break,case,continue,default,do,else,for,goto,if,return,switch,while
<< 3.存储类型关键字:(5)
<< auto,extern,static,_Thread_local,
<< 4.对齐特性关键字:(2)
<< _Alignas,_Alignof
<< 5.内联函数关键字:(2)
<< inline,_Noreturn
<< 6.泛型选择关键字:(1)
<< _Generic
<< 7.编译时检查关键字:(1)
<< _Static_assert
<< 8.其他关键字:(5)
<< const,restrict,_Atomic(并发程序设计),void,volatile(易变性)
1.1、数据类型
<< C 语言数据类型有:"基本类型" "构造类型" "指针类型" "空类型" "其他类型"
<< 1.0 基本类型: 整型 实型 字符型 复数和虚数类型 布尔类型
<< 整型关键字:int; 修饰整型关键字: short, long, signed, unsigned;
<< 实型: float, double, long double;
<< 字符型关键字:char; 修饰字符型关键字: signed, unsigned
<< 复数类型:
<< 虚数类型:
<< 布尔类型:_Bool
<< 2.0 构造类型:字符串,数组,结构体,结构体数组,联合,枚举
2.1.基本数据类型
位(bit):最小的存储单元
字节(byte):常用存储单元,1 byte=8 bit(1字节=8位)
字(word):设计计算机时给定的自然存储单元
C语言提供3个附属关键字修饰基本整数类型(int):short,long和unsigned
,在任何有符号类型的关键字前添加signed,可强调使用有符号类型的意图。
1、short int类型(简写:short) ,占用的存储空间 可能 比 int 少,适用于较小数值的场合,为有符号类型
2、long int类型(简写:long),占用的空间 可能 比 int 大,适用于较大数值的场合,为有符号类型
3、long long int类型(简写:long long) ,占用的存储空间 可能 比 long多,适用于更大的场合,至少占64位,为有符号类型
4、unsigned int(简写:unsigned) ,只用于非负值的场合,与有符号类型表示的范围不同。
5、unsigned long int(简写:unsigned long):
6、unsigned short int(简写:unsigned short):
7、unsigned long long int(简写:unsigned long long):
8、3种复数类型:float_Complex,double_Complex,long double_Complex
9、3种虚数类型:float_Imaginary,double_Imaginary,long double_Imaginary
2.2、常量及其表示方法
整型常量:八进制(020)、十进制(16)、十六进制(0x10或0X10)前缀:16进制前缀为 0x 或 0X,八进制前缀为:0,
浮点型常量:默认的浮点数常量是 double 类型,在浮点数后面加上 f 或 F 后缀可转化成 float 类型;在浮点数后面加上l(小写) 或 L 后缀可转化成long double类型;没有后缀的浮点数常量是 double 类型
可以没有小数或指数部分(2E5、19.28),但是不能同时省略两者;可以没有小数或整数部分(3.E16、.45E-6),但是不能同时省略两者。
十进制(一般计数法、指数计数法或e计数法),书写形式:-1.56E+12、2.87e-3、2E5、19.28、3.E16、.45E-6、.2、100.
十六进制(C99标准新加计数方法,即p计数法),在数字前加上十六进制前缀(0x 或 0X),用 p 或 P 代替指数e或E,2的幂次代替10的幂次;书写形式:0xa.1fP10、0Xa.1fp10,(十六进制 a 代表十进制10,.1f 是1/16加上15/256,p10 是 2^10)
特殊浮点数:NaN
字符常量:单引号括起来的单个字符,如 ‘A’,C语言将字符常量视为 int 类型而非 char 类型
字符串常量:是一个或多个字符的序列,存储在char类型的数组中
标识常量(符号常量):
2.3、转义序列及含义
\a:警报/蜂鸣器
\b:退格
\f:换页
\n:换行
\r:回车
\t:水平制表符
\v:垂直制表符
\:反斜杠
':单引号
":双引号
?:问号
\0oo:八进制值,oo必须是有效的八进制数,即每个o可表示0~7中的一个数
\xhh:十六进制值,hh必须是有效的十六进制数,即每个h可表示0~f中的一个数
3、输入输出函数
3.1、printf()
3.1.1、转换字符说明及其打印的输出结果
%d:有符号十进制整数
%i: 有符号十进制整数(与%d相同)
%u:无符号十进制整数
%f:浮点数、十进制记数法
%e或%E:浮点数、e记数法
%o:无符号八进制整数
%x或%X:无符号十六进制整数,使用十六进制数 0f 或 0F
%a或%A:浮点数、十六进制数和p记数法(C99/C11)
%s:字符串
%c:单个字符
%p:指针
%%:打印一个 % 号
%g或%G:根据值的不同,自动选择 %f 或 %e(%E) 。 %e(%E) 格式用于指数小于-4或者 大于或等于(≥)精度时
3.1.2、转换说明修饰符
printf中的标记:
-:左对齐打印,即从字段的左侧开始打印,如 %-20s
+:在有符号数前显示符号(+ -),如 %+6.2f
空格:有符号数,正值则显示前导空格(不显示+);负值则显示负号(-),如 % 6.2f (其中正负号也占据一个字段宽度)
#:把结果转换成另一种形式,如果是%o格式,则以0开始;如果是%x或%X格式,则以0x或0X开始;对于所用的浮点格式,#保证了即使后面没有任何数字,也打印一个小数点字符。对于%g或%G格式,#防止结果后面的0被删除。如 %#o、%+#10.3e、%#8.0f
0:对于数值格式,用前导0代替空格填充字段宽度。对于整数格式,如果出现 - 标记或指定精度,则忽略该标记
printf中的修饰符(按下面顺序书写)
标记:可以不使用或使用不定项个标记,如 %-10d
数字:最小字段宽度,如果该字段不能容纳待打印的数字或字符串,系统会使用更宽的字段。如 %4d
.数字:表示精度;
对于%e,%E 和 %f ,表示小数点右边的数字的位数
对于 %g 和%G ,表示有效数字的最大位数
对于 %s ,表示待打印字符的最大数量
对于整型转换, 表示待打印数字的最小位数,如有必要,使用前导0来达到这个位数
只使用 . 表示其后跟随一个0,所以%.f 和 %.0f 相同
h:和整型转换一起使用,表示 short int 或 unsigned short int 类型的值,如 %hu,%hx,%6.4hd
hh:和整型转换一起使用,表示 short char 或 unsigned char 类型的值,如 %hhu,%hhx,%6.4hhd
j:和整型转换一起使用,表示 intmax_t 或 uintmax_t 类型的值,如 %jd,%8jx
l:和整型转换一起使用,表示 long int 或 unsigned long int 类型的值,如 %ld,%lu
ll:和整型转换一起使用,表示 long long int 或 unsigned long long int 类型的值,如 %lld,%llu
L:和浮点转换一起使用,表示long double类型的值,如 %Lf,%10.4Le
t:和整型转换一起使用,表示 ptrdiff_t 类型的值,如 %td,%12ti
z:和整型转换一起使用,表示 size_t 类型的值, 如 %zd( 适用于sizeof运算符,strlen() 等返回类型 ),%12zd
3.2、scanf()
3.2.1 转换说明
%u:无符号十进制整数
%d:有符号十进制整数
%i: 有符号十进制整数
%o:有符号八进制整数
%x或%X:有符号十六进制整数
%e或%E,%f或%F,%g或%G,%a或%A:浮点数
%c:单个字符
%s:字符串,从第一个非空白字符开始,到下一个空白字符之前的所有字符都是输入
%p:指针
3.2.2 修饰符(按顺序书写)
* :抑制赋值,如 %*d
数字:最大数字宽度,输入达到最大数字宽度处,或第1次遇到空白字符时停止,如 %10s
hh: 把整数作为 short char 或 unsigned char 类型读取,如 %hhd,%hhu
ll:把整数作为 long long 或 unsigned long long 类型读取,如 %lld,%llu
h或l、L:
%hd 和 %hi 表明把对应的值存储为 short int 类型
%ho 、 %hx 和 %hu 表明把对应的值存储为 unsigned short int 类型
%ld 和 %li 表明把对应的值存储为 long 类型
%lo 、%lx 和 %lu 表明把对应的值存储为 unsigned long 类型
%le、%lf 和 %lg 表明把对应的值存储为 double 类型
在e,f 和 g 前面使用 L 而不是 l(小写),表明把对应的值存储为 long double 类型
如果没有修饰符,d,i,o 和 x 表明对应的值被存储为 int 类型,f 和 g 表明把值存储为 float 类型
j:在整型转换说明后面时,表示使用 intmax_t 或 uintmax_t 类型,如%jd, %ju
z:在整型转换说明后面时,表示使用 sizeof 类型,如%zd, %zo
t:在整型转换说明后面时,表示使用 ptrdiff_t 类型,如%zd, %zo
scanf()函数返回成功读取的项数,如果没有读取任何项,且需要读取一个数字却输入了一个非数值字符串,scanf()返回0。当scanf()检测到文件结尾时,会返回EOF
4、运算符及优先级
4.1、算术运算符
+:加
+:正
-:减
-:负
*:乘
/: 除以,如果两个运算对象都是整数,其结果要被截断。
%: 求余
+ +:(前缀)右边变量的值加一;(后缀)把左边变量的值加1
- - : (前缀)右边变量的值减一;(后缀)把左边变量的值减1
优先级:++,- -(后缀) 》 (前缀)++,- -,+(正),-(负) 》 *,/,% 》 +(加),-(减)
在C语言中,整数除法结果的小数部分被丢弃,这一过程被称为截断(truncation)。
整数除法会截断计算结果的小数部分(丢弃整个小数部分),不会四舍五入
4.2、关系运算符
< : 小于
<= : 小于等于
== : 等于
>= : 大于等于
> : 大于
!=: 不等于
优先级: <,<=,>,>= 》 ==,!=
4.3、赋值运算符
+= :
-= :
*= :
/= :
%= :
&= :
|= :
^= :
>>= :
<<= :
4.4、逻辑运算符
&& : 逻辑与
|| : 逻辑或
! : 逻辑非
&& 和 || 运算符都是序列点,所以这两个运算符的左侧代码会在右侧代码执行前生效,即副作用产生。
优先级: ! 》 && 》** ||
4.5、条件运算符
?: 》》》 expression1 ? expression2 :expression3
expression1为真,则整个表达式的值等于expression2,否则,等于expression3
4.6、逗号运算符
4.7、位运算符
4.1.1、
5、类型转换
1.当类型转换出现在表达式时,无论是unsigned 还是signed的char和short都会自动转换成int,如有必要会被转换成unsigned int(如果short 与int的大小相同,
unsigned short就比int大。这种情况下,unsigned short会被转换成unsigned int。)
3.类型的级别从高到低:long double ,double ,float,unsigned long long,long long,unsigned long ,long,unsigned int,int。例外的情况是:
当long和int的大小相同时,unsigned int 比 long的级别高。
4.赋值表达式语句中,计算的最终结果会转换成被赋值变量的类型,这个过程可能升级或降级
5.当作为函数参数传递时,char和short被转换成int,float被转换成double。
<< 强制类型转换通用形式:
(type)(variable_name)
<< 例如:(int)(n)
5.1 C语言控制语句
<< ****************** while 循环 *************************
<< while循环的通用形式:
while (expression)
statement
<< 其中statement部分可以是分号结尾的简单语句,也可以是花括号的复合语句。
<< 测试条件后面的单独分号是空语句,用于测试程序
<< ****************** for 循环 *************************
<< for循环的形式:
for (initialize; test; update)
statement
<< initialize 在执行for语句之前只执行一次;
<< test表达式为真,执行循环;
<< 接着对update表达式求值,并再检查test
<< ****************** do while 循环 *************************
<< do while 循环的通用形式:
do
statement
while (expression);
<< do while 在执行完循环体后才执行测试条件,所以至少执行循环体一次
<< 在expression为假之前,重复执行statement部分
<< ****************** if 选择分支 *************************
<< if 语句用于选择是否执行一个行为, if else 语句用于在两个行为之间进行选择。
<< if 语句的通用形式:
if (expression)
statement
<< 如果expression为真,执行statement,否则跳过 statement
<< if else 语句的通用形式:
if (expression)
statement1
else
statement2
<< 如果expression为真,执行statement1,为假,执行statement2
<< if else if else 语句
if (expression1)
statement1
else if (expression2)
statement2
else
statement3
<< 如果expression1为真,执行statement1;如果expression2为真,执行statement2;否则,执行statement3
<< ****************** switch 分支语句 *************************
<< switch 语句的一般通用形式:
switch (整型表达式)
{
case 常量1:
语句
case 常量2:
语句
case 常量3:
语句
default :
语句
<< switch 在圆括号中的测试表达式的值应该是一个整数值(包括char类型)。整型,字符型表达式或枚举
<< case 标签必须是整数类型(包括char类型)的常量或整型常量表达式(即,表达式中只含整型常量)。
<< 不能用变量作为 case 的标签。case只起语句标号的作用
<< break 语句可用于循环和 switch 语句中,但是 continue 只能用于循环中。
<< 但是 switch 语句如果在一个循环中, continue 便可作为 switch 语句的一部分,这种情况,
<< 就像在其他循环中一样,continue 会让程序跳出循环的剩余部分。包括 switch 语句的其他部分。
<< ****************** break 语句 *************************
<< 执行到 break 语句时,会终止包含它的循环,并继续执行下一阶段。
<< 对于 for 循环来说,break 和 continue 语句情况不同:
<< 执行完 break 语句后会直接执行循环后面的第一条语句,连更新部分也跳过。
<< ****************** continue 语句 *************************
<< 三种循环语句均可以使用 continue 语句,执行到 continue 时会跳过本次迭代的剩余部分,开始下一轮的迭代。
<< continue 可以用作占位符。相当于其他语言的 pass
<< 对于 while 和 do while 循环,执行 continue 语句后的下一个行为是对循环测试表达式求值。
<< 对于 for 循环,执行 continue 语句后的下一个行为是更新表达式求值(update语句),然后是测试(test)
5.2 函数、数组、指针及结构等的声明
<< ******************** 函数 function *****************************
<< 函数原型或函数声明(function declaration)
<< 函数定义(function definition)
<< 函数调用(function call)
<< 形参:parameter;实参:argument
<< 1、无返回值,无参数,
函数原型:void function_name(void);
函数定义:void function_name(void){}
<< 2、无返回值,有参数:
函数原型:void function_name(int x, char y);
函数原型(省略形参名):void function_name(int,char)
函数定义:void function_name(int m, char n){}
<< ******************** 数组 array *****************************
<< 数组的声明
type_name variable_name[value]
<< 数组的初始化方法:
<< 方法一:声明就初始化
int array[4] = {1,3,6,8};
<< 2、const 关键字声明数组和初始化
const int array[4] = {1,5,7,9};
<< 3、当初始值的项数少于数组的大小时,剩余元素初始化为零
int array[4] = {1,4}; 则 array[2] = array[3]=0
<< 4、省略方括号中的数组的大小,初始值的项数自动匹配数组的大小
int array[] = {1,4,7,8,545};
<< 5、 初始化特定数组元素
传统语法: int array[4] = { 0,0,0,65 };
C99 语法: int array[4] = { [2] = 34 }; 其余数组中的元素会被初始化为0
5.3 结构、嵌套结构及指针
<< ******************** 结构 struct *****************************
<< 1、结构的声明、 结构变量定义
struct book
{
char title[MAXTITL];
char author[MAXAUTL];
float price;
}; 1.1 "结构声明"
struct book
{
char title[MAXTITL];
char author[MAXAUTL];
float price;
} library; 1.2 结构声明 结构变量 librayr 定义
struct
{
char title[MAXTITL];
char author[MAXAUTL];
float price;
} library; 1.3 无结构标记 book 的声明 与定义
注意:如果打算多次使用此结构,就要使用带标记的形式
struct book doyle panshin *ptbook;
定义 struct book 类型的变量 和 指向该类型的指针
<< ******************** 初始化 struct *****************************
<< "使用一对花括号括起来的初始化列表进行初始化,各初始项用逗号分隔"
<< 如果初始化静态存储期的变量(如静态外部链接、静态内部链接或静态无链接),
<< 必须使用常量值,同样适用于结构。
<< "如果初始化一个静态存储期的结构,初始化列表中的值必须是常量表达式。"
<< "如果是自动存储期的结构,初始化列表中的值可以不是常量"
struct book library = {
"The pious Pirate and the Devious Damsel",
"Renee Vivotte",
1.95
};
<< "结构的初始化器" 类似于数组
<< 结构的指定初始化器使用"点运算符和成员名"标识特定的元素
struct book surprise = { .price = 10.99}; 只初始化 price
<< 可以按照任意顺序使用指定初始化器:
struct book gift = {
.price = 25.99,
.author = "James Broadfool",
.title = "Rue for the Toad"
};
<< 对特定成员的最后一次赋值才是它实际获得的值
struct book gift = {
.price = 18.90,
.author = "Philionna Pestle",
0.25
}; price 跟在 author后面 其新值 0.25 取代了 18.90
<< ******************** 声明结构数组 struct *****************************
<< 数组的每个元素都是一个 struct book 类型的结构
struct book library[MAXBKS];
<< "此处 library不是结构名,而是数组名, library[0] 等是结构名"
5.4 存储类别 链接 内存管理
<< 1. C 语言有6个关键字作为存储类别说明符:
auto、 register、 static、 extern、 _Thread_local、 typedef
<< 1.1auto:表明变量时"自动变量存储期",只能用于"块作用域"的变量声明中
<< 默认省略auto,但显式使用auto是为了明确表达要使用与外部变量同名的局部变量名
<< 如果要兼容C++,最好采用默认省略auto
<< 1.2register:表示"寄存器变量",只用于块作用域,保护该变量的地址不被获取
<< 使用关键字 register 声明变量,寄存器变量储存在CPU的寄存器中,
<< 1.3静态变量:变量在内存中原地不动
<< 1.3.1 块作用域的静态变量:块作用域,静态存储期,无链接;只在编译时 被初始化一次,
<< "如果未显式初始化静态变量,它们会被初始化 0 (不能再形参中使用 static)"
<< 1.3.2 外部链接的静态变量(外部变量): 声明在函数外面(无关键字static)
<< "如果未显式初始化外部变量,它会自动初始化为0,也适用于外部定义的数组元素;"
<< "只能使用常量表达式初始化文件作用域变量"
<< "外部变量只能初始化一次,且必须在定义该变量时进行" char permis = 'N'
<< 1.3.3 内部链接的静态变量:用关键字 static 定义文件作用域的变量
<< "作用域和链接"描述标识符的可见性,"存储期"描述了通过这些标识符访问的对象的生存期
<< 2.作用域描述程序中可访问标识符的区域
<< 分为 "块作用域"、 "函数作用域"、 "函数原型作用域"、 "文件作用域"
<< 块作用域:从定义处到块的末尾
<< 函数作用域仅用于 goto 标签("一个标签首次出现在函数的内层块中,作用域也延伸至整个函数")
<< 函数原型作用域: 用于函数原型中的形参名 (从形参定义到函数原型声明结束,所以通常形参名不重要,可省略)
<< 文件作用域: 定义在函数的外面("单文件作用域","多文件作用域")
<< 3.翻译单元:编译器源代码文件和所有的头文件都看成是一个包含信息的单独文件, 叫翻译单元
<< 如果程序由多个源代码文件组成,那么该程序也将由多个翻译单元组成。
<< 每个翻译单元均对应一个源代码文件和它所包含的文件。
<< 4.链接属性:(3种) "外部链接" "内部链接" "无链接"
<< 外部链接: 具有"文件作用域"的 无关键字 static 定义的变量 (也叫"全局作用域")--外部引用 ( extern char a;)
<< 内部链接:具有"文件作用域"的 有关键字 static 定义的变量 static int a=8;(也叫"文件作用域")
<< 无链接: "块作用域,函数作用域,函数原型作用域"的都是 无链接
<< 5.存储期:(4种) "静态存储期" "自动存储期" "线程存储期" "动态分配存储期"
<< 5.1静态存储期:"文件作用域"(内部或外部链接)均具有;块作用域用 static定义的变量 具有静态存储期
<< 5.2线程存储期:关键字 _Thread_local 声明对象,每个线程都获得该变量的私有备份
<< 线程存储期用于并发程序设计,程序执行可被分为多个线程。
<< 具有线程存储期的对象,从被声明时到线程结束一直存在。
<< 5.3自动存储期:自动分配内存和释放内存
<< 6.函数的存储类别: 外部函数(default) 静态函数 内联函数("C99")
<< 静态函数:以关键字 static 声明函数原型,只能用于定义所在的文件
<< static double beta(int, int); 静态函数只能在同一文件调用
<< 外部函数:以关键字 extern 声明函数原型,默认省略 extern
<< (double gama(); 和 extern double game() 等价)
<< 7.动态分配内存
<< 主要工具有: malloc() free() calloc() (在 stdlib.h 中)
<< 7.1 malloc()函数接受一个参数,返回动态分配内存块的首字节地址,如果分配内存失败将返回 NULL
<< double* ptd;
<< ptd = (double*)malloc(30 * sizeof(double)); 指针ptd被声明为指向一个 double 类型
<< 应坚持使用"强制类型转换 (double *)" 注意:C中此处可以不使用 强制类型转换;但是 C++中必须使用
<< 建议使用强制类型转换以便后续转换成C++程序
<< 7.2 创建数组的方法(3种)
<< 1.0 声明数组时,用常量表达式表示数组的维度,用数组名访问数组的元素
<< 2.0 声明变长数组时,用变量表达式表示数组的维度
<< 3.0 声明一个指针,调用malloc(),将其返回值赋给指针,使用指针访问数组的元素,该指针可以是静态的或自动的
<< 7.3 malloc() 与 free() 配套使用,free()的参数是之前 malloc()返回的地址,释放之前 malloc()分配的内存
<< 动态内存存储期从调用 malloc()分配内存到调用free()释放内存为止。
<< 不能用 free()释放通过其他方式分配的内存
<< 7.4 calloc()函数,接受两个无符号整数为参数,参数1: 所需的存储单元数量;参数2:存储单元大小(以字节为单位)
<< newmen = (long *)calloc(100,sizeof(long));
<< 与malloc()不同的是," calloc()函数把块中的所有位都设置为0"
<< free()也可以用于释放 calloc() 分配的内存
<< 7.5 动态内存分配 和 变长数组
<< 变长数组 是自动存储类型, 内存随块的结束自动释放
<< malloc()创建的数组不必局限在一个函数内访问,(可以在被调函数中分配内存,在主调函数中释放内存。)
<< free()和 malloc()两者的指针变量可以不同,但是两个指针必须储存相同的地址。不能释放同一块内存两次。
<< 7.6 存储类别 和 动态内存分配
<< 可以认为程序把它可用的内存分为3部分 :
<< 1.0 供具有外部链接、内部链接和无链接的静态变量使用
<< 2.0 供自动变量使用
<< 3.0 供动态内存分配
<< 总而言之,程序把"静态对象、自动对象和动态分配的对象储存在不同的区域"
<< 静态内存的数量在编译时是固定的,在程序运行期间不会改变
<< 自动变量使用的内存数量在程序执行期间自动增加或减少
<< 动态分配的内存数量只会增加, 除非用 free() 函数进行释放
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
2.读入数据
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。