C语言基础知识总结
前言:本篇根据《C Primer Plus(第六版)中文版》和自己所学整理的。
一、C语言概述
1.使用工具
devc++或者Visual stdio
2.“hello world"代码
//简单的C语言程序实例
#include<stdio.h>//引用头文件stdio.h
int main()
{
printf("hello world");
return 0;
}
/*main()函数是主函数
C语言程序从main开始,到return结束*/
3.C语言关键字
(c99标准下共32个)
关键字的定义:是C语言中预先定义好的、具有特定含义和用途的单词
3.1 数据类型关键字(12个)
1.short,float,char,int,void(基本键字数据类型关)
2.long,double,unsigned,signed(类型修饰关键字)
3.union(共用体类型),struct(结构体类型),enum,(枚举类型)(构造类型关键字)
3.2 控制语句关键字(12个)
1.while,for,do…while(循环)
2.if,else,switch,case,default(条件判断与分支)
3.break,continue,default,goto(无条件跳转语句)(跳转语句)
3.3 存储类型关键字(5个)
auto,register,extern,static,const(声明常量)
3.4 其他关键字(3个)
typedf,sizeof,volatile
4.C语言标识符
标识符是指用来标识变量、常量、函数数组、结构体等程序元素的名称。
规则:
1.只能由数字、字母、下划线组成;2.不能以数字开头;3.区分大小写;4.不能使用关键字。
规范:
见名知意:命名应当反映标识符的含义,eg:age表示年龄,sum表示总和,避免使用a,b。
二、数据与C
1.常量
1.字面常量:
2.const修饰的常变量,const-常属性
3.#define定义的标识符常量
4.枚举常量
2.变量
全局变量:定义在代码块之外,作用域:整个过程
局部变量:定义在代码块之内,作用域:变量所在的局部范围
局部变量优先于全局变量
3.基本数据类型
整型(%d)、浮点型(%f,%lf)、字符型(%c)、字符串型(%s)
整型:int,4字节
单精度浮点型:float,4字节
双精度浮点型:double,8字节
字符型:由单引号引起来的字符,1字节
字符串型:由双引号引起来的字符串
格式化输入:scanf(格式控制,地址列表)
格式化输出:printf(格式控制,输出列表)
字符输入:getchar()作用:等待从键盘输入一个字符
字符输出:putchar()作用:输出一个字符
以下是一个简单的例子:
//求两数之和的代码
#include<stdio.h>
int main()
{
int a,b,sum;
scanf("%d%d",&a,&b);//格式化输入
sum=a+b;
printf("两数之和为:%d",sum);//格式化输出
return 0;
}
4.转义序列
定义:转变原来的意思
换行符:
\n
表示换行,将光标移动到下一行的开头。水平制表符:
\t
表示水平制表符,通常相当于8个空格。回车符:
\r
将光标移动到当前行的开头。退格符:
\b
将光标向左移动一个位置。换页符:
\f
用于换页,通常在打印机中使用。反斜杠:
\\
表示一个反斜杠字符。单引号:
\'
表示一个单引号字符。双引号:
\"
表示一个双引号字符。空字符:
\0
表示空字符(null),常用于字符串的结束标志。八进制转义序列:
\ooo
其中ooo是1到3位的八进制数,表示对应的ASCII字符。十六进制转义序列:
\xhh
其中hh是1到2位的十六进制数,表示对应的ASCII字符。
#include <stdio.h>
int main() {
printf("Hello, World!\n"); // 换行
printf("Tab\tExample\n"); // 水平制表符
printf("Backspace\bExample\n"); // 退格
printf("Quote: \"Hello\"\n"); // 双引号
printf("Backslash: \\\n"); // 反斜杠
printf("Null character: \0End\n"); // 空字符
return 0;
}
5.转换说明
- 定义:转换说明用于格式化输入和输出函数
转换说明 数据类型 描述 %dint有符号十进制整数。 %iint有符号十进制整数(与 %d相同)。%uunsigned int无符号十进制整数。 %ounsigned int无符号八进制整数。 %xunsigned int无符号十六进制整数(小写字母)。 %Xunsigned int无符号十六进制整数(大写字母)。 %ffloat/double十进制浮点数(默认保留6位小数)。 %efloat/double科学计数法表示的浮点数(小写 e)。%Efloat/double科学计数法表示的浮点数(大写 E)。%gfloat/double根据值的大小自动选择 %f或%e(更简洁的格式)。%Gfloat/double根据值的大小自动选择 %f或%E(更简洁的格式)。%cchar单个字符。 %schar *字符串。 %pvoid *指针地址(通常以十六进制表示)。 %ldlong int有符号十进制长整数。 %luunsigned long无符号十进制长整数。 %lldlong long int有符号十进制长长整数。 %lluunsigned long long无符号十进制长长整数。 %nint *将已输出的字符数写入到指定变量中。
6.操作符和运算符
(1)操作符
- (1)算术操作符
- (2)位操作符
操作符 描述 示例 效果 &按位与 a & b逐位与操作 |按位或 a | b逐位或操作 ^按位异或 a ^ b逐位异或操作 ~按位取反 ~a逐位取反操作 <<左移 a << n将 a的二进制位左移n位>>右移 a >> n将 a的二进制位右移n位
- (4)赋值操作符
操作符 描述 示例 等价于 +=加并赋值 a += ba = a + b-=减并赋值 a -= ba = a - b*=乘并赋值 a *= ba = a * b/=除并赋值 a /= ba = a / b%=取模并赋值 a %= ba = a % b&=按位与并赋值 a &= ba = a & b|=按位或并赋值 a |= ba = a | b^=按位异或并赋值 a ^= ba = a ^ b<<=左移并赋值 a <<= ba = a << b>>=右移并赋值 a >>= ba = a >> b
- (5)单目操作符
操作符 描述 示例 ++自增 ++a,a++--自减 --a,a--!逻辑非 !a~按位取反 ~a&取地址 &a*解引用 *asizeof计算大小 sizeof(a)(type)强制类型转换 (int)a
(2)运算符
- 运算符优先级:!>算术运算符>关系运算符>&&>||>赋值运算符
- 定义:运算符是用于执行特定操作的符号或关键字。它作用于一个或多个操作数(Operands),并生成一个结果。
- 分类:
- 算术运算符:如
+、-、*、/、%。- 关系运算符:如
==、!=、>、<、>=、<=。- 逻辑运算符:如
&&、||、!。- 位运算符:如
&、|、^、~、<<、>>。- 赋值运算符:如
=、+=、-=、*=、/=。- 条件运算符:如
? :。- 其他运算符:如
sizeof、,、&(取地址)、*(解引用)。
(3)运算符与操作符的区别
- 运算符更强调功能,用于描述操作的类型(如算术、逻辑、位操作等)。
- 操作符更强调符号本身,用于描述具体的符号或关键字。
三、C控制语句
1.循环
(1)基本语法
循环类型 语法 特点 forfor (初始化; 条件; 更新) { ... }适合已知循环次数的场景 whilewhile (条件) { ... }适合条件驱动的场景 do...whiledo { ... } while (条件);至少执行一次循环体 嵌套循环 循环内包含另一个循环 用于处理多维数据或复杂逻辑 无限循环 while (1)或for (;;)需要手动退出
(2)for循环运行示例
-
a.计算从1到n的和
//计算从1到n的和
#include<stdio.h>
int main()
{
int n,sum;
scanf("%d",&n);// 输入一个n
for(int i=1;i<=n;i++)
/*int i=0是初始化数值,
i<n是循环条件,保证不会进入无限循环,
i++是每次循环需要完成的事件 */
{
sum+=i;//实现1+2+3+…n-1+n;
}
printf("从1到%d的和是:%d",n,sum);
return 0;
}
//示例,输入:5 ,输出:15;输入100,输出5050
b.求n的阶乘
//求n的阶乘,n!=1x2x3x…x(n-1)xn
#include<stdio.h>
int main()
{
int n;
long long product;//使用长长整型避免溢出
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
product*=i;//或者写成product=product*i
}
printf("%d的阶乘是%d",n,product);
return 0;
}
//示例,5的阶乘是120;10的阶乘是 3628800
c.判断从1到n之间的素数
//判断从1到n中的所有素数
//素数指的是大于1的自然数,除了1和它本身之外 ,没有其他因数的数
//1不是素数
#include<stdio.h>
#include<math.h>
int main()
{
int n;
scanf("%d",&n);
printf("素数有:");
for(int i=2;i<=n;i++)
{
int isprime=1;//先假设是素数
for(int j=2;j<i;j++)
{
if(i%2==0)
{
isprime=0;
break;
}
}
if(isprime==1)
printf("%d ",i);
}
return 0;
}
2.分支
语句 语法 描述 if c if (条件) { // 条件为真时执行的代码 }当条件为真时执行代码块。 if-else c if (条件) { // 条件为真时执行的代码 } else { // 条件为假时执行的代码 }当条件为真时执行第一个代码块,否则执行第二个代码块。 else if c if (条件1) { // 条件1为真时执行的代码 } else if (条件2) { // 条件2为真时执行的代码 } else { // 所有条件为假时执行的代码 }用于多个条件判断,依次检查条件,执行第一个为真的代码块,否则执行 else。switch c switch (表达式) { case 常量1: // 表达式等于常量1时执行的代码 break; case 常量2: // 表达式等于常量2时执行的代码 break; default: // 表达式不等于任何常量时执行的代码 break; }根据表达式的值匹配 case,执行对应的代码块,default用于处理未匹配的情况。
(1).判断从到之间的素数
//判断两数之间的所有素数
#include<stdio.h>
#include<math.h>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("从%d到%d之间所有的素数:",a,b);
for(int i=a;i<=b;i++)
{
int isprime=1;//假设一个数是素数
if(i<=1)
isprime=0;
else if(i==2)
isprime=1;
else if(i%2==0)
isprime=0;
else
{
for(int j=3;j<sqrt(i);j+=2)
{
if(i%j==0)
{
isprime=0;
break;
}
}
}
if(isprime)
{
printf("%d ",i);
}
}
return 0;
}
(2).判断闰年
//判断闰年
//闰年指的是能被4整除但不能被100整除的年份,此外能被400整除的年份也是闰年
#include<stdio.h>
int main()
{
int year;
printf("请输入年份:");
scanf("%d",&year);
if((year%4==0&&year%100!=0)||(year%400==0))
printf("%d是闰年\n",year);
else
printf("%d不是闰年\n",year);
return 0;
}
(3).四则运算器
//四则运算器
#include<stdio.h>
int main()
{
int a,b;
char c;
scanf("%d%c%d",&a,&c,&b);
switch(c)
{
case '+':
printf("%d+%d=%d\n",a,b,a+b);
break;
case '-':
printf("%d-%d=%d\n",a,b,a-b);
break;
case '*':
printf("%d*%d=%d\n",a,b,a*b);
break;
case '/':
if(b==0)
printf("Error:除数不能为0!\n");
else
printf("%d/%d=%d\n",a,b,a/b);
break;
default:
printf("Error:运算符无效(仅支持加减乘除)\n");
}
return 0;
}
(4).三个数排列大小
//三个数比较数字大小,从小到大排列
#include<stdio.h>
int main()
{
int a,b,c,temp;
scanf("%d%d%d",&a,&b,&c);
//使a<=b
if(a>b)
{
temp=a;
a=b;
b=temp;//两数进行大小交换
}
//使b<=c
if(b>c)
{
temp=b;
b=c;
c=temp;//两数进行大小交换
}
//再次检查a和b的大小关系
if(a>b)
{
temp=a;
a=b;
b=temp;//两数进行大小交换
}
printf("%d %d %d",a,b,c);
return 0;
}
3.跳转
语句 语法 描述 breakc break;用于立即终止循环( for、while、do-while)或switch语句的执行。continuec continue;跳过当前循环的剩余部分,直接进入下一次循环的条件判断。 returnc return [表达式];用于从函数中返回,并可选择返回一个值。如果函数返回类型为 void,则省略表达式。gotoc goto 标签; ... 标签: // 代码无条件跳转到指定标签处的代码,需谨慎使用,避免代码可读性降低。
四、函数
1.函数的定义
返回类型 函数名(参数列表){
//函数体
//执行代码
return [返回值];//如果返回类型非void
}
部分 描述 返回类型 函数返回值的数据类型(如 int、float、void等)。如果函数不返回值,则使用void。函数名 函数的名称,需遵循C语言标识符命名规则。 参数列表 传递给函数的参数列表,每个参数包括类型和名称,多个参数用逗号分隔。如果没有参数,可以写 void或留空。函数体 函数的具体实现代码,用 {}括起来。return 语句 如果函数有返回值,则使用 return返回值;如果返回类型为void,可以省略return或用return;结束函数。
2.声明函数原型
返回类型 函数名(参数列表);
3.调用函数
函数名(参数列表);
4.经典编程题
(1).两数交换
//用函数实现两数交换
#include<stdio.h>
void jiaohuan(int *a,int *b);//函数的声明
int main()
{
int x,y;
scanf("%d%d",&x,&y);
printf("交换前a=%d,b=%d\n",x,y);
//函数的调用
jiaohuan(&x,&y);
printf("交换后a=%d,b=%d\n",x,y);
return 0;
}
//函数
void jiaohuan(int *a,int *b)
{//注意要实现真正的交换,需要采用址传递,而不能只用值传递
int temp;
temp=*a;
*a=*b;
*b=temp;
}
(2).求阶乘
//求阶乘n!
//n!=1x2x3x……(n-1)xn
#include<stdio.h>
int jiecheng(int n)
{
int m=1;
for(int i=1;i<=n;i++)
{
m=m*i;
}
return m;
}
int main()
{
int x,y;
scanf("%d",&x);
y=jiecheng(x);
printf("%d的阶乘为%d",x,y);
return 0;
}
(3).用函数判断素数
//用函数的形式判断一个数是否为素数
#include<stdio.h>
int is_prime(int n)
{
if(n<2)
return 0;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main()
{
int x;
scanf("%d",&x);
if(is_prime(x)==1)
printf("%d是素数\n",x);
else
printf("%d不是素数\n",x);
return 0;
}
(4).求斐波那契数列(迭代法)
//斐波那契数列之和
//斐波那契数列指的是n1=n2=1,从n3开始每项等于前两项之和
//迭代法
#include<stdio.h>
int fib(int n);
int main()
{
int x;
scanf("%d",&x);
int result=fib(x);
printf("%d",result);
return 0;
}
int fib(int n)
{
if(n<=2)
return 1;
int a=1,b=1,c;
for(int i=3;i<=n;i++)
{
c=a+b;
a=b;
b=c;
}
return b;
}
(5).求最小公倍数
//枚举法求最小公倍数
/*核心思路时从两个数的较大值开始枚举,
直到找到第一个能同时被两数整除的数即为最小公倍数*/
#include<stdio.h>
int lcm(int a,int b)
{
if(a==0||b==0)
return 0;
int max=a>b?a:b;
for(int i=max; ;i++)
{
if(i%a==0&&i%b==0)
{
return i;
}
}
}
int main()
{
int x,y;
scanf("%d%d",&x,&y);
int z=lcm(x,y);
printf("最小公倍数为%d",z);
return 0;
}
5.函数的递归
1.求阶乘
//用递归写求阶乘的函数
#include<stdio.h>
int fac(int n);
int main()
{
int x;
scanf("%d",&x);
if(x<0)
{//负数没有阶乘
return 1;
}
int y=fac(x);//调用递归函数
printf("%d的阶乘是%d",x,y);
}
int fac(int n)
{
if(n==0)
{//递归终止条件:0的阶乘是1
return 1;
}
//n!=n*(n-1)!
return n*fac(n-1);
}
2.求最大公约数(辗转相除法)
//求最大公约数
/*对于两个数a和b,它们的最大公约数等于b和a%b的最大公约数
即GCD(a,b)=GCD(b,a mod b)当b=0时,a就是最大公约数 */
#include<stdio.h>
int GCD(int a,int b)
{
if(b==0)
return a;// 终止条件:当b=0时,a就是最大公约数
return GCD(b,a%b);//递归关系:GCD(a,b)=GCD(b,a mod b)
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("最大公约数为:%d\n",GCD(a,b));
return 0;
}
//使用辗转相除法求两个数的最小公倍数核心公式:两个数的
最小公倍数=两数乘积的绝对值/两数的最大公约数
五、数组
1.一维数组
- 声明格式:数据类型 数组名[数组大小];
- 数据类型:数组中元素的数据类型(如
int、float、char等)。- 数组名:数组的名称,遵循C语言标识符规则。
- 数组大小:数组的长度,必须是一个常量整数。
- 初始化:数据类型 数组名[数组大小]={元素1,元素2……元素N};
- 访问一维数组:数组名[索引];
2.一维数组经典编程题
(1).计算数组平均值
//计算数组平均值
#include<stdio.h>
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,0};//数组的定义
int sum=0;
double x;
for(int i=0;i<10;i++)//;利用循环遍历整个数组
{
sum+=arr[i];
}
x=(double)sum/10;
printf("平均值为%.2lf",x);
return 0;
}
(2).查找数组中的最大值
//查找数组中的最大值
#include<stdio.h>
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,0};//数组的定义
int max=arr[0];
for(int i=0;i<10;i++)//;利用循环遍历整个数组
{
if(arr[0]<arr[i])
max=arr[i];
}
printf("最大值为%d",max);
return 0;
}
3.二维数组
- 声明格式:数据类型 数组名[行数][列数]
- 初始化:
- 如果初始化时提供的元素个数少于每行或每列的大小,剩余元素会自动初始化为
0。- 可以省略行数
- 遍历二维数组:数组名[行索引][列索引]
4.二维数组经典编程题
(1).矩阵转置
//二维数组矩阵转置
#include<stdio.h>
#define ROWS 3
#define COLS 4
int zhuanzhi(int x[ROWS][COLS],int y[COLS][ROWS])
{
for(int i=0;i<ROWS;i++)
{
for(int j=0;j<COLS;j++)
{
y[j][i]=x[i][j];
}
}
}
int main()
{
int x[ROWS][COLS]={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
int y[COLS][ROWS];
zhuanzhi(x,y);
printf("原始矩阵:\n");
for(int i=0;i<ROWS;i++)
{
for(int j=0;j<COLS;j++)
{
printf("%4d",x[i][j]);
}
printf("\n");
}
printf("转制后的矩阵:\n");
for(int i=0;i<COLS;i++)
{
for(int j=0;j<ROWS;j++)
{
printf("%4d",y[i][j]);
}
printf("\n");
}
return 0;
}
六、初识指针
1.基本概念
- 指针变量:用于存储内存地址的变量。
- 地址运算符
&:获取变量的内存地址。- 解引用运算符
*:通过指针访问内存地址中存储的值。2.指针的声明
数据类型 *指针变量名
3.指针的初始化
- 使用
&运算符获取变量的地址。- 直接赋值为另一个指针。
- 赋值为
NULL(表示空指针)。

3298

被折叠的 条评论
为什么被折叠?



