C语言基础
C语言的构成
-
源程序由函数构成---基本组成单位
-
程序有且只有一个主函数
-
函数体 { } 标识起来的部分
-
每个语句必须以分号结束,预处理命令和函数头以及"}"之后不能加分号
-
注释
-
- 块注释/**/,不能嵌套,可以在任何地方
- 行注释//
-
预处理命令(#include ,#define)以“#”开头的语句
-
-
头文件 .h
-
-
#include <头文件>
-
标准库函数
stdio.h
:本身没有输入输出语句,调用标准函数库的输入输出函数来实现的。 -
getchar putchar gets puts scanf printf -
数学函数
math.h
-
fabs(double x);//浮点数去绝对值 sqrt(4);//平方根double
pow(double x,double y);//幂函数,x为底的y次
sin(x);cos();//x为弧度,返回-1~1
pi=acos(-1.0);
1度=pi/180;//1角度
1(rad)=180/pi;//1弧度- **字符串函数 `string.h`** - ```c strcpy(字符数组1,字符数组2);//2赋值到1,函数返回1的值(用2替换1 strcat(字符数组1,字符数组2);//2接到1 char str1[15]="aaa"; char str2[15]="bbb"; strcat(str1, str2);//aaabbb strcpy(str2, "ABCDEF");//ABCDEF strlen(字符数组);//字符串长度,遇到'\0'或0就返回长度 char a[5] = { '1', '3', '3', 0 , '3' };//strlen(a)返回3 char a[5] = { '1', '3','\0', '3' , '3' };//strlen(a)返回2 strcmp(字符数组1,字符数组2);//字符串大小,相同返回0 printf("%d", strcmp("12", "12"));//0 printf("%d", strcmp("1234", "12"));//1 printf("%d", strcmp("1", "12"));//-1 //'\0'的ACSII码值为0! -
-
stdlib.h
-
abs();//整数绝对值 rand()//随机函数 0~32767 产生1-100以内的随机整数:int num = rand() % 100+1;
-
-
可引用自定义的头文件
/* 我的第一个 C 程序 */ //注释 #include <stdio.h> // 预处理命令 int main()//主函数 { printf("Hello, World! \n"); return 0; //终止main()函数 }
C语言的程序文件的后缀是 .c ;
经过编译后,生成目标文件文件的后缀是 .obj ;
经过链接后,生成可执行文件的后缀是 .exe 。
C语言程序的三种基本结构是顺序,选择,循环。
C 程序的工作过程是编辑、编译、链接、运行。
静态语义错误(编译时报错):10/0,%运算类型不正确,b+a(a为数组
动态语义错误(运行时错误):a/0,死循环,数组下标越界,指针异常,实参传递问题
标识符
是用来标识变量、函数,或任何其他用户自定义项目的名称。
-
关键字
auto、short、int、long、float、double、char、typedef、const、static、void、if、else、switch、case、for、do、while、goto、break、sizeof
等
-
预定义标识符
print
scanf
-
用户定义标识符
- 与关键字相同会产生编译错误。
- 与预定义标识符相同,系统并不报错,只是该预定义标识符将失去原定含义。
-
只能由字母,数字,下划线组成。不能以数字开头。
-
区分大小写
常量
程序运行中不改变的量
整型常量,实型常量,字符常量,字符串常量,符号常量
整型常量:
- 十进制 0~9
- 八进制 以0开头 0~7
- 十六进制 0X或0x开头 0~F
实型常量:
- 小数 十进制
- 指数 e前必须有数字,e后必须为整数
字符常量:''
-
ASCII字符集
-
区分大小写
-
转义字符:以 \ 开头
\n
:换行- **
\\
:反斜线字符 ** \ddd
:1~3位八进制数代表一个ASCII字符 \101 A\xhh
:1~2位十六进制数代表一个ASCII字符 \x65 A
字符串常量:""
符号常量:由预处理命令 #define 定义的常量
/*常量的定义*/ //使用 #define 预处理器。//符号常量不占用内存 #define identifier value //使用 const 关键字。 const type variable = value;//常变量占内存,值固定 //------------------------------------------- 078 /* 非法的:8 不是八进制的数字 */ 032UU /* 非法的:不能重复后缀 */ .e55 /* 非法的:缺少整数或分数 */ 510E /* 非法的:不完整的指数 */ 210f /* 非法的:没有小数或指数 */ 5e3 0.e34 /*合法的*/ 0.123 .123 123. 0.0 /*合法的*/
变量
使用前先定义
/*以下都是正确的*/ int a = 10, b = 12, temp; int i, j, m, n; int i = 0; double d = 0.0;
整型常量,实型常量,字符常量
整型常量:int short long
无符号
字符常量:只能存放一个字符,存储对应ASCII,算术运算是对ASCII码进行运算。
说 明 | 字符型 | 短整型 | 整型 | 长整型 | 单精度浮点型 | 双精度浮点型 | 无类型 |
---|---|---|---|---|---|---|---|
数据类型 | char | short | int | long | float | double | void |
长度字节 | 1 | 2 | 4 | 4 | 4 | 8 | |
有效数字 | 7位 | 15~16位 |
类型自动转换
自动:低精度向高精度 char<short<int<unsigned<long<float<double
-
int i = 4+1.8;//5 舍去小数部分
强转:(类型名)(表达式)
局部变量
- 函数定义
- auto(默认):函数中的局部变量,动态地分配存储空间,数据存储在动态存储区中,在调用该函数时,系统会给它们分配存储空间,在函数调用结束后自动释放这些存储空间。
- register:为了提高效率,C语言允许将局部变量的值放在CPU的寄存器中,这种变量叫“寄存器变量”,只有局部自动变量和形参可以作为寄存器变量。
- extern:外部变量(全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始到本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件末尾。
- static:静态局部变量,属于静态存储类别,在静态存储区内分配存储单元,在程序整个运行期间都不释放。
- 语句定义
全局变量
//若不赋值 int a;//a随机 static int a;//a为0 int a[10];//内容随机 int a[10]={};//多了个大括号,全为0
运算符
初等运算符>单目运算符>算术运算符>关系运算符逻>辑运算符>条件运算符>赋值运算符>逗号运算符
-
初等运算符 () [] ->//结构体成员运算符
-
单目运算符 ++ --
-
- 运算对象可以是
int
型变量,char
型变量,float
型变量。
- 运算对象可以是
-
算术运算符 + - * / %
-
- 求余左右两边必为整型 注意:
1%2
结果1 ;7%8
结果为7。 - 所有实数都以双精度运算
- 除法两边都为整形,预算结果也为整型即舍去小数部分
1/2
结果为0
- 求余左右两边必为整型 注意:
-
关系运算符 == != <= >= < >
-
逻辑运算符 && || !
-
条件运算符 ? :
-
赋值运算符 = += -= *= /= %=
-
逗号运算符 ,
-
- 逗号表达式
(,)
- 从左到右逐个计算;
- 逗号表达式
-
逗号表达式作为一个整体,它的值为最后一个表达式的值;
- 优先级别在所有运算符中最低。
-
位运算符 & | ^ >> << ~
-
- 按位与(&):若两个相应的二进制位都为1,则该位的结果为1,否则为0。
- 按位或(| ):若两个相应的二进制位中有一个为1,则该位的结果为1,否则为0。
- 按位异或(^):若两个二进制位相同,则结果为0,不同则为1。
- 按位求反(~):按位取反,即0变1,1变0。
- 左移(<<):将一个数的二进制位全部左移若千位。
- 右移(>>):将一个数的二进制位全部右移若干位。
- 按位取反只需要一个操作数
- 右移运算时,高位在某些情况不是补0
-
字节运算符
sizeof
-
-
返回一个对象或者类型所占的内存字节数
-
int i = 5; sizeof i; printf("%d\n", sizeof i);//4 printf("%d\n", sizeof(i);//4 sizeof(int);//ok sizeof int;//error -
数组的
sizeof
-
int site[10] = {1,3,5,4,4};//40 int site[] = {1,3,5,4,4};//20 char site[10] = {'R', 'U', 'N', 'O', 'O', 'B'};//10 char site[] = {'R', 'U', 'N', 'O', 'O', 'B'};//6
-
-
指针运算符
-
&
&a;
变量的实际地址*
*a;
将指向一个变量
输入输出
单个字符输入输出
putchar()//输出 getchar()//输入 char c = getchar(); printf("c: %c\n", c);
数据格式输入输出
print()//格式化输出 printf("%d\n", NULL);//0 printf("%5d", n);//给定了数字宽度默认是右对齐 printf("%-5d", n);//左对齐 printf("%f\n", NULL);//0.000000 小数精度四舍五入 左对齐前导零无效 printf("%5.2f", n);//一共五位,小数占两位,小数部分四舍五入
scanf()//格式化输入 //输入数据的格式要和控制字符串的格式保持一致。 //函数输入整数或实数时,输入数据之间可以使用空格、tab、回车符 scanf("%d %d", &a, &b);//中间要空格,空格个数不受限制 scanf("%d, %d, %d", &a, &b, &c);//56,45,78↙ scanf("%d is bigger than %d", &a, &b);//25 is bigger than 11↙ //能规定宽度,不能规定精度 scanf("%.5f",&a);//error /*字符输入*/ //字符输入时不使用空格、tab键、回车等作为分隔符 scanf("%c",&a); /*字符串输入*/ //输入是字符串所以Scanf函数不识别空格、回车符、制表符 char str[10]; scanf("%s",str);
% //格式字符:可在“%”与格式字符之间插入“宽度说明”、左对齐符号“-”、前导零符号“0”等 d //用于输出十进制数。 o //以八进制数形式输出整数。 x //以十六进制数形式输出整数。 u //用于输出无符号型数据,即输出无符号的十进制数。 c //用于输出一个字符。 s //用于输出一个字符串。 f //用于输出实数(包括单精度型、双精度型),以小数形式输出,使整数部分全部输出。 e //以指数形式输出实数。 g //用于输出实数。
/* 字符串处理函数 */ gets(字符数组)//可以接收带空格的字符串 puts(字符数组) char str[30]; gets(str);
表达式
-
自左向右
-
表达式非0为真,0为假
-
表达式输出值真时为1,假时为0
-
!>算术运算符>关系运算符>&&>||>赋值运算符
-
表达式语句 以分号为结尾
-
空语句
;
-
复合语句:块代码
{}
中定义的变量只能在块代码中使用,可以调用块之外的变量,并更改其值 -
-
int a = 3, b; b = a + 3; { int c = 2; a *= c + 1; printf("%d\n", c); } printf("%d\n", a);//9
-
选择
if(表达式)语句 else ; //上面最近的else if(a=1)//ok的 a=1 if(a)
switch(表达式){//表达式不能为浮点类型,long类型,字符串类型 case 常量表达式: 语句; default: ;//可以不要 } //没有使用break终止switch语句的执行,执行完case 后将继续执行后面的
?: //表达式1?表达式2:表达式3 //表达式1非0,则输出表达式2;表达式1为0,则输出表达式3
循环
注意没有{}时第一个语句分号即结束!!!
for (表达式1;表达式2;表达式3) { printf(); }; //没有表达式2的判断就会无限循环 //for (;;)//无限循环 //for (n;;)//无限循环 //for (;;n++)//无限循环 //for循环可以使用while循环来替换的
while(){ //先判断再执行 };
do{}while(); //先执行一次再判断
continue; //结束本次循环,即跳过循环体中con-tinue语句下面尚未执行的语句,转而去重新判定循环条件是否成立,从而确定下一次循环是否继续执行。 break; //只能出现在循环体内及switch语句内,不能用于其他语句。 //当break语句出现在循环体的switch语句体内时,其作用只是跳出该switch语句体。当break出现在循环体中,但并不在switch语句体内时,则在执行break后,跳出本层循环,当然也不再进行条件判断。
数组
//一维数组定义 int n[2]; //数组初始化赋值是指在数组定义时给数组元素赋予初值。数组初始化是在编译阶段进行的。这样将减少运行间,提高效率。 int n[2]={1,2};//ok int k[n];//no //不能用变量说明数组大小 int n[5]="0123";//no char n[5]="0123";//ok double balance[5] = {3.4, 7.0, 50.0};//部分赋值,其余0.0补齐 double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};//数组大小为5 balance[4] = 50.0;//数组中某的元素的赋值 char site[10] = {'R', 'U', 'N', 'O', 'O', 'B'};//sizeof为10,strlen为6,提示无终止'\0' char site[6] = {'R', 'U', 'N', 'O', 'O', 'B'};//sizeof为6,strlen情况下长度未知 char site[] = {'R', 'U', 'N', 'O', 'O', 'B'};//sizeof为6,strlen情况下长度未知 char site[] = {'R', 'U', 'N', 'O', 'O', 'B','\0'};//sizeof为长度7,strlen为6 char site[] = "RUNOOB";//sizeof为长度7,strlen为6 //字符数组:空字符'\0' %c //将字符逐个输入/输出 %s //将整个字符串一次输入/输出 //二维数组定义 //行可以不指定,列一定要指定,指定了个数必须达到 int a[3][4] = { {0, 1, 2, 3} , /* 初始化索引号为 0 的行 */ {4, 5, 6, 7} , /* 初始化索引号为 1 的行 */ {8, 9, 10, 11} /* 初始化索引号为 2 的行 */ }; int a[][3]={{1,2,3},4,5,6,7};//ok int a[2][2]={{1},2,3}//ok int a[2][]={{1,2},{3,4}}//no,列一定要指定 int a[2][3]={{1,2,3},{4,5,6}};//no,少了
//数组查找 //快速排序,冒泡排序,选择排序 n(n-1)/2 //顺序查找:无序表,不管哪种存储类型;有序表,链式存储结构 n //二分法查找:有序表,顺序存储结构 log2n int a[10] = { 13,24,35,46,57,68,79,99,127,44 }; int i,low=0, mid=0, hight=9,key=99; //int high = sizeof(a)/sizeof(a[0]) - 1;//初始数组长度-1 for (i = 0; i < 10/2; i++) { mid = (low + hight) / 2; if (key>a[mid]) { low = mid + 1; } else if (key < a[mid]) { hight = mid - 1; } else { printf("找到%d",mid); break; } }
函数
- 标准函数:库函数
- 用户自定义函数
- 函数嵌套调用:不允许嵌套定义函数,但可以嵌套调用函数。
- 函数递归调用:函数可以直接或间接的自己调用自己;函数名或指向函数的指针变量作为实参
- 数组元素作为函数实参;数组名作为函数实参,数组名是整个数组的的首地址
- 声明,形参不分配空间,调用时分配
- 形参-->实参,单向值传递
//若被调用函数在主调函数之前定义,可以省略函数原型声明。以下是返例。 //函数声明:参数类型是必须的 int max(int, int);//ok //函数定义 int max(int num1, int num2){};//ok return_type function_name( parameter list ) { body of the function } //函数值类型不写默认为int //return表达式值类型与函数值类型不一致则以函数值类型为准。返回一个值。不限于基本数据类型或指针,也可以是结构体类型等,但不能是数组 main(){ max(a,2);//调用函数 } //空函数,没有执行语句 int fun(){}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现