【C语言】c语言基础知识梳理(超全)

C语言基础知识梳理

           

printf("%f\n", 1/0.0);  // 无穷大。我的电脑上为:1.#INF00
printf("%f\n", -1/0.0);  // 无穷小。我的电脑上为:1.#INF00
printf("%f\n", 0.0/0.0);  // 空。我的电脑上为:-1.#IND00
int a;  // a是int类型的变量
double b=1.0;  //b是double类型的变量,赋1.0为初值
char c, d;  // c, d是char类型的变量

2、常用特殊前缀

extern int a;  // 声明一个int类型的变量a,一般用在.h文件中声明项目全局变量
const int b=1;  // 定义一个不可变的变量b,使用const关键字都要赋初值
static int c=1;  // 在函数中使用,只在第一次使用时初始化,相当于作用域在函数内的全局变量
typedef long long int;  // 把long long当作int使用

3、数组与初始化变量
int a=1;  // 给a初始化为1
// 以下为C99加入的特性
int b[10] = {1};  // 第一个元素初始化为1,其他9个元素初始化为0
int c[10] = {0};  // 全部初始化为0,常用初始化手段
int d[10] = {[1]=1, 2, [4]=4};  // 0 1 2 0 4 0 0 0 0 0

4、变量作用域
变量有两种类型:局部变量全局变量,变量作用域即变量可使用的范围。
 
对于局部变量可以简单理解为大括号{}内即为一个作用域,变量在哪个大括号内,作用域就在哪。
 
对于全局变量的作用域就是在当前的.c文件中,在.h文件声明后可以在整个项目内使用。
 
对于同名变量,小作用域的变量会在其作用域中覆盖大作用域的变量。
 
(三)字符串
字符串在c语言中有两种形式char*和char[],这里简单分辨下两者之间的不同。
char* c1="HelloWorld!"中,c1指向代码段中的常量,只读不写,且常量相同,指向的地址也相同。
char c2[]="HelloWorld!"中,c2指向堆栈段中的数据,可读可写,相当于把代码端的数据拷贝了出来。

(四) 自定类型——结构体
结构体可以看作是一种个基础类型复合的类型。
// 声明如下:
struct DATE{
	int year, month, day;
};

// 几种定义方式如下:
struct DATE date1;  // 不赋初值
struct DATE date2={2020, 4, 5};  // 根据结构体中的顺序赋初值,这里是年月日
struct DATE date3 = {.year=2020, .day=5};  // 给单独变量赋初值
struct DATE *date4 = &date3;  // 用指针取date3地址(指针后面会单独说)

// 几种赋值方式如下:
date3 = (struct DATE){.year=1999};  // 将数据强制转换成struct DATE类型赋值
date3 = date2;  // 自动赋值
date3.year=2010;  // 对变量中单一元素赋值
date4->year=2010;  // 对指针所指变量中的单一元素赋值

// 常用声明
typedef struct DATE2{
	int year, month, day;
} D;
D date5;  // 这样就可以不用写struct DATE2这么一长串,取而代之用D来表示

扩展:union
union作为关键字与struct类似,但是struct中每个成员都是单独的内存,而union只占最大成员变量的大小,通常用与二进制与十进制的转换。
union DATE{
    int year;
    int month;
    int day;
};  /* 一个union DATE只有一个int大小 */

扩展:enum枚举,枚举类似#define,但是有体系些(c语言的枚举不好用)
// 声明枚举, 默认下标RED:0, YELLOW:1, GREEN:2
enum COLOR1 {RED1, YELLOW1, GREEN1};
// 自定下标
enum COLOR2 {RED2=1, YELLOW2, GREEN2=5};


二、表达式

这里给出运算符优先级

优先级    运算符    名称或含义    使用形式    结合方向    说明
1    []    数组下标    数组名[整型表达式]    左到右    
()    圆括号    (表达式)/函数名(形参表)    
.    成员选择(对象)    对象.成员名    
->    成员选择(指针)    对象指针->成员    
2    -    负号运算符    -算术类型表达式    右到左    单目运算符
(type)    强制类型转换    (纯量数据类型)纯量表达式    
++    自增运算符    ++纯量类型可修改左值表达式    单目运算符
--    自减运算符    --纯量类型可修改左值表达式    单目运算符
*    取值运算符    *指针类型表达式    单目运算符
&    取地址运算符    &表达式    单目运算符
!    逻辑非运算符    !纯量类型表达式    单目运算符
~    按位取反运算符    ~整型表达式    单目运算符
sizeof    长度运算符    sizeof 表达式 / sizeof(类型)    
3    /    除    表达式/表达式    左到右    双目运算符
*    乘    表达式*表达式    双目运算符
%    余数(取模)    整型表达式%整型表达式    双目运算符
4    +    加    表达式+表达式    左到右    双目运算符
-    减    表达式-表达式    双目运算符
5    <<    左移    整型表达式<<整型表达式    左到右    双目运算符
>>    右移    整型表达式>>整型表达式    双目运算符
6    >    大于    表达式>表达式    左到右    双目运算符
>=    大于等于    表达式>=表达式    双目运算符
<    小于    表达式<表达式    双目运算符
<=    小于等于    表达式<=表达式    双目运算符
7    ==    等于    表达式==表达式    左到右    双目运算符
!=    不等于    表达式!= 表达式    双目运算符
8    &    按位与    整型表达式&整型表达式    左到右    双目运算符
9    ^    按位异或    整型表达式^整型表达式    左到右    双目运算符
10    |    按位或    整型表达式|整型表达式    左到右    双目运算符
11    &&    逻辑与    表达式&&表达式    左到右    双目运算符
12    ||    逻辑或    表达式||表达式    左到右    双目运算符
13    ?:    条件运算符    表达式1? 表达式2: 表达式3    右到左    三目运算符
14    =    赋值运算符    可修改左值表达式=表达式    右到左    
/=    除后赋值    可修改左值表达式/=表达式    
*=    乘后赋值    可修改左值表达式*=表达式    
%=    取模后赋值    可修改左值表达式%=表达式    
+=    加后赋值    可修改左值表达式+=表达式    
-=    减后赋值    可修改左值表达式-=表达式    
<<=    左移后赋值    可修改左值表达式<<=表达式    
>>=    右移后赋值    可修改左值表达式>>=表达式    
&=    按位与后赋值    可修改左值表达式&=表达式    
^=    按位异或后赋值    可修改左值表达式^=表达式    
|=    按位或后赋值    可修改左值表达式|=表达式    
15    ,    逗号运算符    表达式,表达式,…    左到右    从左向右顺序结合
总结优先度: 特殊运算符(括号、地址类) > 单目运算符 > 算数运算符(乘除>加减) > (移位运算) > 判断运算符(比较>相等) > (位运算) > 逻辑运算符(&&>||) > 三目运算符 > 赋值运算符 > 逗号运算符
针对十进制字面值
<<:左移数据,相当于乘2(右边填0)
>>:右移数据,相当于除2(unsigned左填0,signed左边填原来的最高位(因为负数移位还要是负数))

1、switch语句
switch(ch){  // switch是传入整数并判断整数进行判断
	case 'a':
		...
		break;
	case 'b':
		...
		break;
	default:
		...
}

(3)switch只能传入整数进行判断,上面的例子就是将char类型的ch转换成了ASCII码

进行比较.

(1)while适用于不知道次数的循环

2、do while语句
do{
	语句
}while(条件);

1)do while适用于不知道次数且要先做一遍的循环

三、跳转语句


break;直接跳出当前条件语句或迭代语句,能且只能 跳出 当前 的 一个 语句。

continue;在 条件语句 中表示什么都不做(替代空语句);在 迭代语句 中表示 直接进入下一轮循环,不执行完当前循环 。

goto;跳转到指定位置(该位置必须有声明),例子:

start:  // goto声明
	...  // 语句
	...  // 语句
	...  // 语句
	goto start;  //跳转到start声明位置

!!!注意,goto仅推荐用于跳出多重循环,例如:

for (int i=0; i<n; i++) {
	for (int j=0; j<m; j++) {
		for (int k=0; k<o; k++) {
			if (跳出条件) {
				goto end;
			}
		}
	}
}
end:

四、函数

(二)函数声明

int f(int a){
	return a;
}

那么函数的声明可以写成:
int f(int a);
或者
int f(int);

特殊的对于返回值和参数都是void的函数,声明可以写成:
void f(void);


(三)结构体中的函数(不懂)

如果能在结构体中写函数,那么结构体就更接近一个类了,例子如下:

struct SHOWDATE{
	void (*show)(int year, int month, int day);
};

static void show(int year, int month, int day){
	printf("%d-%d-%d", year, month, day);
}

static SHOWDATE showDate={.show=show};

int main(){
	showDate.show(2020, 1, 1);
	return 0;
}

五、指针

(一)定义

int a=10;
int *p=&a;  // (1)(2)
*p = 12;  // (3)
int * const p1;  // (4)
const int * p2;  // (5)
int const * p3;

(1)*代表这是一个指针类型。具体到例子中就一个int*类型,代表p存放一个指向int类型的地址

(2)&代表取地址。在例子中就是取int类型变量的地址,即变量a的地址

(3)*p代表一个变量,这个变量就是p所指地址里面的变量

(4)int * const p1;不能修改p里的地址

(5)const int * p2;和int const * p3;不能修改p里地址对应的值

(二)结构体与指针

typedef strcut stDATE{
	int year, month, day;
} DATE;

int main(){
	DATE date1={2020, 1, 1};
	DATE* date2=&date1;
	date1.year=2019;
	date2->month=2;
	printf("%d-%d-%d", date1.year, date1.month, date1.day);
	
	return 0;
}

//输出结果date1.month变为2;

(1)结构体变量访问结构体成员使用.,结构体指针变量访问结构体成员使用->。

(三)数组与指针(不懂

int a[10] = {0}  // (1)、(2)

int *p = a;  // (3)

void *q = (void*)p;  // (4)

int *new = (int*)malloc(10*sizeof(int));  // (5)
free(new);

1)int a[10]里面的a实际上是数组第一个变量的地址,所以可以int *p = a;。
(2)*(p+n)与a[n]等价。
(3)int*指针变量加上一个数n,代表指针变量的数值加上n*32(int的bit)得到偏移。
(4)q表示未定的类型(类似char*但不一样)。
(5)使用int*指针变量来创建数组,使用完要free(程序关闭会自动释放,如果程序长时间使用则会造成内存泄露)。

其他:
char c[][]错误;
char c[][10]正确且限制大小;
char *c[]正确,c[n]是一个char*的字符或字符串
char **c正确,一个指向指针的指针

六、文件读取

(一)文本文件

函数定义:

FILE* fopen(const char* restrict path, const char* restrict mode);  // 打开文件。参数:路径,模式
int fclose(FILE* stream);  // 关闭文件
fscanf(FILE*, ...);  // 文件读取(类似scanf,只是加了第一个参数,具体在八)
fprintf(FILE*, ...);  // 文件输出(类似printf,只是加了第一个参数,具体在八)

fopen的mode选项:
r:只读
r+:读写,从文件头开始
w:只写,清空或新建
w+:读写,清空或新建
a:追加,追加或新建
…x:只新建,若存在则不能打开(wx、ax等)

例子:

FILE* p=fopen("file", "r");
if(fp) {
	...
	fclose(fp);
}

二)二进制文件

函数定义(打开文件和关闭文件与文本文件一致):

// ptr:读入字符串存放的变量、size*nmemb:读多少字符、stream:文件句柄
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);

二进制文件读写主要是读写结构体,现在不常用,因为可移植性不好,不如读写文件

七、编译预处理指令与.h文件

(一)编译预处理指令

在c语言中,所有#开头的语句都是编译预处理指令。
c语言编译经过
.c——处理编译预处理指令——》
.i——c编译器编译成汇编文件——》
.s——生成目标代码文件——》
.o——生成可执行文件——》
#.out / .exe
四步得到可执行文件,第一步就是处理编译预处理指令。

1、# include < stdio.h >
# include <stdio.h>就是将stdio.h文件里面的内容复制到代码里面去

2、#define 名称 操作(宏定义)
# define被称为宏定义,格式为# define 名称 操作
例子:

#define PI 3.14159
#define cube(x) (x*x*x)

int main(){
	cube(3);
	return 0;
}

可以用宏定义定义一个变量PI或一个方法cube。

宏定义定义方法看起来很方便,但十分不推荐初学者使用,因为宏定义的方法是没有类型的,而且运算顺序也不好理解(看上面 二、表达式 15个运算等级的表,就知道多复杂了)。

如果确实想用类似宏定义的方式来定义函数,可以使用下面的方法。

3、(补充)inline内联函数
inline char *dbtest(int a)
{
    return (a % 2 > 0 ? "奇" : "偶");
}

(二).h文件


.h文件主要用来声明对应.c文件里面的变量或函数,把.c文件里面的声明放到.h文件就可以了(全局变量需要加上extern前缀)。

导入标准库时推荐使用<>,如# include <stdio.h>
导入自定声明时推荐使用"",如# include "train.h"

(三)一些常用宏

printf("%d", __LINE__);  // 输出当前语句行号
printf("%s", __FILE__);  // 输出当前文件名
printf("%s", __DATE__);  // 输出编译日期
printf("%s", __TIME__);  // 输出编译时间
printf("%d", __STDC__);  // 当要求程序严格遵循ANSIC标准时该标识符被赋值为1
printf("%s", __FUNC__);  // 输出当前函数名

八、常用函数

(一)常用函数

库名    函数定义    解释
默认    size_t sizeof(type_name)    返回byte
string.h    size_t strlen(const char *s)    返回s的字符串长度(不包括最后的\0)
string.h    int strcmp(const char *s1, const char *s2)    比较两个字符串,返回0:相等; 1:s1>s2; -1:s1<s2
string.h    int strncmp(const char *s1, const char *s2, size_t n)    安全版本比较前n个字符的大小,其他同上
string.h    char* strcpy(char *restrict dst, const char *restrict src)    把src的字符串拷贝到dst,restrict表示不重叠
string.h    char* strncpy(char *restrict dst, const char *restrict src, size_t n)    安全版本,拷贝n个字符,其他同上
string.h    char* strcat(char *restrict s1, const char *restrict s2)    把s2拷贝到s1后面,s1要足够大
string.h    char* strncat(char *restrict s1, const char *restrict s2, size_t n)    安全版本,追加n个字符,其他同上
string.h    char* strchr(const char *s, int c)    在s串中找到c第一次出现的位置,返回指针,没有为null
string.h    char* strrchr(const char *s, int c)    在s串中从右边找到c第一次出现的位置,返回指针,没有为nulltring.h
string.h    char* strstr(const char *s1, const char *s2)    在字符串s1中不忽略大小写寻找字符串s2
string.h    char* strcasestr(const char *s1, const char *s2)    在字符串s1中忽略大小写寻找字符串s2
string.h    void *memset(void *s, int c, unsigned long n)    将指针变量s所指向的前n字节的内存单元用一个“整数”c替换
string.h    void *memcpy(void *dest, const void *src, size_t n)    从src的开始位置拷贝n个字节的数据到dest。如果dest存在数据,将会被覆盖。
stdlib.h    system(“pause”)    暂停程序,按任意键继续

(二)scanf和printf

scanf(stdio.h)函数声明:int scanf(const char *format, …)
format格式:%[flag]type

printf(stdio.h)函数声明:int printf(const char *format, …)
format格式:%[flags][width][.prec][hlL]type

flag含义
-跟width一起用,左对齐(%-9d)
+正数强制输出正号(%+9d) 可以%±9d/%-+9d
正常输出
0数字前填充0(%09d) 不可以%-09d(因为负号已经是左对齐了)
width / prec含义
number最小字符数
.number小数点后位数。%9.2f:一共9位,小数点后2位(正数部分7位)
*将number放到后面作为参数使用(%*d, number, int)
.*将.number放到后面作为参数使用(%.*d, .number, int)
hlL含义
hh单个字节(char 1byte)
hshort(2byte)
llong(4byte)
lllong long(8byte)
Llong double(16byte)

type    用于    含义
i / d    int    接受整数值并将它表示为有符号的十进制整数,i是老式写法
u    unsigned int    无符号10进制整数
o    unsigned int    无符号8进制整数(不输出前缀0)
x / X    unsigned int    无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF(不输出前缀0x)
f / F / lf    double    单精度浮点数和双精度浮点数用f(lf 在C99开始加入标准,意思和 f 相同)
e / E    double    科学计数法表示的数,此处"e"的大小写代表在输出时用的“e”的大小写
g / G    double    有效位数,如:%.8g表示单精度浮点数保留8位有效数字。
c    char    字符型。可以把输入的数字按照ASCII码相应转换为对应的字符
s /    char * / wchar_t *    字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符
p    指针(void *)    以16进制形式输出指针
n    读入/写出的个数(int *)    到此字符之前为止,一共输出的字符个数,不输出文本
%    无    不进行转换,输出字符‘%’(百分号)本身
m    无    打印errno值对应的出错内容,(例: printf("%m\n"); )

                        
原文链接:

【C语言】c语言基础知识梳理(超全)_c语言基础知识必背-CSDN博客

  • 27
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C/C++期末复习资料大汇总 一、内容概述 在本次上传中,我们为您精心整理了关于C/C++的期末复习资料。这些资料涵盖了从基础知识到进阶概念,旨在帮助您全面复习C/C++的相关内容。无论是准备期末考试还是为大作业做准备,这份资料都将为您的学习提供有力的支持。 二、资料详解 基础知识篇:针对C/C++的语法、数据类型、运算符等内容进行了详细的梳理,帮助您打好扎实的基础。 进阶概念篇:深入探讨了指针、函数、文件操作等进阶知识点,为您进一步提升编程能力提供指导。 期末复习题及答案:包含各类期末考试的经典题目及详细答案,让您熟悉考试题型,把握考试重点。 期末大作业指南:针对C/C++的期末大作业,提供了从选题到实现的全程指导,帮助您顺利完成作业。 实战案例集锦:收录了一些经典案例,让您在实践中掌握C/C++的应用技巧。 三、适用人群 这份复习资料适用于学习C/C++的各类人群,无论是初学者还是有一定编程基础的学生,都能从中获得收益。 四、使用建议 我们建议您先从基础知识开始复习,逐步深入到进阶概念。在掌握基本知识点后,结合复习题进行巩固练习,最后通过大作业和实战案例进一步提升自己的编程能力。 五、特别提示 为了更好地掌握C/C++的知识点,除了复习资料外,实际操作和练习也是非常关键的。希望这份资料能帮助您取得优异的成绩,也欢迎您在学习过程中提出宝贵的意见和建议。 最后,感谢您选择我们的复习资料,祝您学习顺利!
C/C++期末复习资料大汇总 一、内容概述 在本次上传中,我们为您精心整理了关于C/C++的期末复习资料。这些资料涵盖了从基础知识到进阶概念,旨在帮助您全面复习C/C++的相关内容。无论是准备期末考试还是为大作业做准备,这份资料都将为您的学习提供有力的支持。 二、资料详解 基础知识篇:针对C/C++的语法、数据类型、运算符等内容进行了详细的梳理,帮助您打好扎实的基础。 进阶概念篇:深入探讨了指针、函数、文件操作等进阶知识点,为您进一步提升编程能力提供指导。 期末复习题及答案:包含各类期末考试的经典题目及详细答案,让您熟悉考试题型,把握考试重点。 期末大作业指南:针对C/C++的期末大作业,提供了从选题到实现的全程指导,帮助您顺利完成作业。 实战案例集锦:收录了一些经典案例,让您在实践中掌握C/C++的应用技巧。 三、适用人群 这份复习资料适用于学习C/C++的各类人群,无论是初学者还是有一定编程基础的学生,都能从中获得收益。 四、使用建议 我们建议您先从基础知识开始复习,逐步深入到进阶概念。在掌握基本知识点后,结合复习题进行巩固练习,最后通过大作业和实战案例进一步提升自己的编程能力。 五、特别提示 为了更好地掌握C/C++的知识点,除了复习资料外,实际操作和练习也是非常关键的。希望这份资料能帮助您取得优异的成绩,也欢迎您在学习过程中提出宝贵的意见和建议。 最后,感谢您选择我们的复习资料,祝您学习顺利!
C/C++期末复习资料大汇总 一、内容概述 在本次上传中,我们为您精心整理了关于C/C++的期末复习资料。这些资料涵盖了从基础知识到进阶概念,旨在帮助您全面复习C/C++的相关内容。无论是准备期末考试还是为大作业做准备,这份资料都将为您的学习提供有力的支持。 二、资料详解 基础知识篇:针对C/C++的语法、数据类型、运算符等内容进行了详细的梳理,帮助您打好扎实的基础。 进阶概念篇:深入探讨了指针、函数、文件操作等进阶知识点,为您进一步提升编程能力提供指导。 期末复习题及答案:包含各类期末考试的经典题目及详细答案,让您熟悉考试题型,把握考试重点。 期末大作业指南:针对C/C++的期末大作业,提供了从选题到实现的全程指导,帮助您顺利完成作业。 实战案例集锦:收录了一些经典案例,让您在实践中掌握C/C++的应用技巧。 三、适用人群 这份复习资料适用于学习C/C++的各类人群,无论是初学者还是有一定编程基础的学生,都能从中获得收益。 四、使用建议 我们建议您先从基础知识开始复习,逐步深入到进阶概念。在掌握基本知识点后,结合复习题进行巩固练习,最后通过大作业和实战案例进一步提升自己的编程能力。 五、特别提示 为了更好地掌握C/C++的知识点,除了复习资料外,实际操作和练习也是非常关键的。希望这份资料能帮助您取得优异的成绩,也欢迎您在学习过程中提出宝贵的意见和建议。 最后,感谢您选择我们的复习资料,祝您学习顺利!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值