头文件
组成单位:全局变量,函数、结构体、枚举
.sln 文件:Visual Studio的解决方案文件,包含了解决方案中所有项目的引用,一个解决方案可以包含多个不同类型的项目(C#、C++)
.cpp 文件:C++的源代码文件,但在实际开发中C++与C经常混合使用
.vcxproj (Visual C++ Project File)文件:项目的XML格式文件,描述了项目的构建规则、源文件列表、编译器和链接器设置
.vcxproj.filters 文件:组织项目中的文件,将其进行分组和过滤
.vcxproj.user 文件:存储了与特定用户相关的项目设置
程序在编译过程中自动生成的一个文件夹,用于存放与调试相关的信息和文件
.log文件:日志信息文件
.obj文件:目标文件,是源程序编译后的产物,包含了程序中各种符号的信息
.pdb文件:程序数据库文件,用来记录调试信息(变量名、函数名、源代码行号)
packages文件夹:主要用于存储和管理不同的软件包或模块
格式化输出不同类型的数据
字符:%c
字符串(字符数组):%s
整型、布尔型:%d(true输出1,false输出0)
printf(" % .2lf", a):结果保留两位小数
执行一些特殊的动作:换行、制表……
\n:换行
\a:警鸣
\t:水平制表符,插空格用的
&符号是取地址运算符,它可以得到变量的内存地址
需按照指定字符串内容输入内容再按回车
scanf("%d,%d,%d,%d", &a,&b,&c,&d):输入的内容是"值,值,值,值"
scanf("x=%dy=%d",&x,&y):输入的内容是"x=值y=值"
a是数组首元素地址,无需&
scanf里只能塞转换符和转义符,提示语句什么的都是不能有的
无符号int的表示范围为0到4294967295(2^32-1)
有符号int的表示范围为0到-2147483648到2147483647(-2^31到2^31-1)
int a = 1234;
printf("%2d\n", a);
在%d、%f、%lf中面加上n就代表输出的数值的长度至少需要达到n字符,不够就用空格填充
char f;
f = getchar();
putchar(f);
getchar和putchar的功能类似于printf和scanf
0-9对应的ASCII码是48-57
A-Z对应的ASCII码是65-90
a-z对应的ASCII码是97-122
需引用stdbool.h头文件
float
double
指针*
数组[]
结构体struct
枚举enum,空void
函数
对二进制码进行无符号取反操作
左移运算符
>>:右移运算符,优先级与左移运算符相等
逐一比较两个数的每位二进制,都是1时输出1,否则输出0
逐一比较两个数的每位二进制,相同输出0,不同输出1
逐一比较两个数的每位二进制,全0才输出0,有一个1就输出1
一级运算符:( )、[ ]、->、.(结构成员)
二级运算符:!、~、++、--、-(取负)、类型转换、*(指针运算符)、&(取址)、sizeof
三级运算符:*、/、%
四级运算符:+、-
五级运算符:<<、>>
六级运算符:<、<=、>、>=
七级运算符:==、!=
八级运算符:&(按位与)
九级运算符:^(按位异或)
十级运算符:|(按位或)
十一级运算符:&&(逻辑与)
十二级运算符:||(逻辑或)
十三级运算符:? :(条件运算符)
十四级运算符:=、+=、-=、*=、/=、%=、>>=、<<=、&=、^=
十五级运算符:.(逗号)
使用C语言的数组需要当心下标越界、内存管理等安全问题
在C语言中,数组名默认为数组第一个元素的地址(它代表地址但它不是指针)
声明数组时必须指定元素的个数
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
二维数组可以看成数组的数组,数组名a既是首元素地址又是首数组的首元素地址
int (*p)[3] = &a[1]和int (*p)[3] = a+1是等价的,它们都是第二个数组的首元素地址
字符列表初始化:char str1[] = {'A','t','t','a','c','k','\0'};
末尾的\0不强求,它代表着字符串的结束
如果在声明字符数组的同时对其初始化,那么可以省略掉数组长度的定义,系统会根据初始值自动确定字符数组长度
字符串字面量初始化:char str2[] = "Attack";
系统会自动在其末尾加上\0,故str2和str1的内存大小相等
char a[7] = "ac\0ac\0":字符数组会以遇到的第一个空字符标准\0为字符结尾,\0后面的字符都不会再显示
虽然\0不被算在字符数组中,但它却实实在在占用了1字节的内存空间
strlen只会计算首字符到第一个\0的字符数(\0不算其中)
转义字符(会被编译)与空字符也占内存空间(1字符)
C语言的逻辑对错常用int值来表示,非0值被视为true,0将被视为fasle
switch的括号里可以传入:整数、字符、枚举
使用方法同C#
while:同C#
do…while:同C#
for:同C#
break:同C#
continue:同C#
想要调用函数,那么函数必须定义在调用它的地方之前,因为C语言是逐条执行的
数组方法中的a是一个5行5列的二维数组
此方法可以完成0到24的累加
在main()使用的的数组方法()必须定义在main()之前
当然,也可以在被调函数所在的函数中进行函数声明
函数的声明语法为:返回类型 函数名(形参类型列表)
想让一个数组作为函数的形参可以使用int a[]或int *a
虽然函数不能作为形参,但是函数指针却可以
此功能类似C#的委托,不过比它更灵活但也不安全
结构需要定义在main函数前才能使用
结构体的成员不能直接初始化,没有默认值
它能放:变量、数组、结构体、共用体、指针
枚举顾名思义,就是列出变量所有的可能值,如果一个变量的可能值是有限的,那么它就特别适合被做成枚举
与C#的枚举不同,C语言的枚举成员是不能被直接赋值的
枚举也需要定义在main函数前才能使用
只能赋给color对应枚举结构范围内的成员
red,green,blue的值默认为0、1、2,可以显示赋予自定义值
共用体虽然在设计上看起来很像结构,但从内存角度上来讲,共用体是一种比结构体还轻量级的复合数据类型
共用体的成员所占用的空间是同一块,也就是说共用体不可能一次性初始化所有成员,后来的成员会覆盖掉先前的成员
共用体变量的内存大小等于其最大成员所占用的内存大小
共用体指针指向的既是整个共用体变量在内存中的起始地址又是共用体变量里的第一个成员的内存位置
typedef是一个用于定义数据类型别名的关键字
不管是自己定义的数据类型还是内置的数据类型(int、float),都能用typedef定义别名
注:*只需在类型名和指针名的中间即可,*与两者之间有几个空格无所谓
int a = (*p)++:将p指向的数据赋给a随后加一
int a = *p++:将p指向的数据赋给a随后将p后移
因为数组名是数组首元素的地址,所以不用取址符来进行指针赋值
这里的p++不是地址+1,而是增加它所指向的数据类型所占用的字节数
p必须是一个指向整数数组的指针而不能是简单的int *p
*(p+1)并不是a[1][0]的值而是a[1][0]的地址,*(*(p+1))才是a[1][0]的值
注:*(p)+1是a[0][1]的地址,而*(p+1)是a[1][0]的值,因为C语言的数组是以行优先存储的,注意区分
返回类型 (*指针名)(形参类型列表)
int (*ptr)(int,int):在所有指针声明中,它可以说是最特别的
调用函数指针:(*指针名)(实参列表)
结构体指针指向的既是整个结构体变量在内存中的起始地址又是结构体变量里的第一个成员的内存位置
(*ptr).age和ptr->number的功能是一样的,都是为了取出所指变量的成员值
int (*ptr)[5]:这是一个指向整数数组的指针
int *ptr[5]:这是一个指针数组,包含5个元素,每个元素都一个指向整数的指针
计算机的文件在磁盘中都存有与之关联的元数据(文件名、大小、创建时间),C为了简化抽象这些信息,为其创建了一个结构体FILE
使用fopen方法即可让程序与该结构体建立连接并返回一个指向FILE结构体的指针,这个指针封装了文件操作相关信息,通过修改这个结构体中的内容就能以做到对文件的读写
r:读取文件数据
w:写入文件数据,如果文件不存在则会自行创建文件
a:在文件末尾写入文件数据,如果文件不存在则会自行创建文件
r+:读取和写入文件数据
w+:读取和写入文件数据,如果文件不存在则会自行创建文件
a+:读取和写入文件数据,如果文件不存在则会自行创建文件
功能和文本文件的模式一样,就是在后面加上个b:rb、wb、ab、rb+、wb+、ab+
fopen打开失败会返回NULL,也就是0
EOF:这是个宏标识符,其值一般为-1,用于表示文件尾
fgetc(file):从file指向的文件中读取一个字符
fputc(ch,file):在file指向的文件中写入字符ch
在"w"模式下fputc写入的内容会覆盖文件的原有内容
在"a"模式下fputc写入的内容会被追加在文件的末尾
#include:将一个头文件的内容加载进程序
宏可以是标识符、关键字、数值、运算符,它们会在编译时将程序中所有与它们有关的记录都替换掉
宏标识符并不会占用内存空间,但是没有数据类型,在实际操纵时相比于全局变量更容易出错
不要在定义宏标识符时添加额外的符号。像什么"="
M(2+3)会被替换为2*(2+3),故a=10
F(2+3)会被替换为2*2+3,故b=7
使用#undef可以收回对宏的定义
它的功能是在编译之前根据某些条件来选择性地包含或排除代码
当编译器遇到#if指令时,他会测试其条件表达式的值,如果为true则执行代码,否则就将其删除
#if常与#elif和#else组合出现,需以#endif结尾
defined会检测其括号内的宏是否被定义
需与#if组合使用
#ifdef与#ifndef其实就是#if defined的简化版本
它们也需以#endif结尾
int a = abs(-2):计算绝对值
double a = floor(-2.321):计算不大于-2.321的最大整数
double a = log(3):求对数(以e为底)
double a = pow(2, 3):求2的3次幂
double a = sqrt(9):开根号
printf("%d",islower(a));
用于判断a是否为小写字母,对则返回非0值,否则返回0,没有ishigher函数
toupper(a)与tolower(a):将a转换为小写字母或大写字母
gets函数并不会检测输入字符串是否已经超出了字符数组长度,是个危险函数
strcat的原理是把b接到a的后面,它并不会检测a是否有足够的空间容纳b,也是个危险函数
strcpy并不会检测a是否有足够的空间用于复制b的字符串,也是危险函数
strncpy(a,b,2)):将数组b的前面两个数组成员赋值到数组a中(危险函数)
虽然C语言的数组没有像length这样的属性用来输出数组长度,但它有个用来获取字符数组长度的strlen函数
若a比b长→返回1
若a和b等长→返回0
若a比b短→返回-1
将An integer: 123和A float: 45.669998写入file指向的文件
从file指向的文件中先找到An integer: ,然后把它后面的整数读取出来赋给anInteger
rewind(file);
无论是打开模式a、r还是fputc和fscanf等文件函数,它们都会移动文件指针在文件数据中的位置,导致一些操作失败,所有要用rewind来将文件指针置于文件开头
feof(file):检测文件指针是否位于文件末尾,是则返回非零值,否则返回0
从堆内存中获取指定字节数的连续内存空间然后返回首字节的地址
该函数的默认返回指针类型为void,需用(int*)进行转换
如果嫌麻烦,(sizeof(int) * 10)可以写成为malloc(40),不推荐这种做法
free():用于释放malloc/calloc/realloc函数从堆内存那里获取的内存空间