C语言基础知识总结

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.转义序列

定义:转变原来的意思

  1. 换行符\n
    表示换行,将光标移动到下一行的开头。

  2. 水平制表符\t
    表示水平制表符,通常相当于8个空格。

  3. 回车符\r
    将光标移动到当前行的开头。

  4. 退格符\b
    将光标向左移动一个位置。

  5. 换页符\f
    用于换页,通常在打印机中使用。

  6. 反斜杠\\
    表示一个反斜杠字符。

  7. 单引号\'
    表示一个单引号字符。

  8. 双引号\"
    表示一个双引号字符。

  9. 空字符\0
    表示空字符(null),常用于字符串的结束标志。

  10. 八进制转义序列\ooo
    其中ooo是1到3位的八进制数,表示对应的ASCII字符。

  11. 十六进制转义序列\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)单目操作符
操作符描述示例
++自增++aa++
--自减--aa--
!逻辑非!a
~按位取反~a
&取地址&a
*解引用*a
sizeof计算大小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.分支

语句语法描述
ifc if (条件) { // 条件为真时执行的代码 } 当条件为真时执行代码块。
if-elsec if (条件) { // 条件为真时执行的代码 } else { // 条件为假时执行的代码 } 当条件为真时执行第一个代码块,否则执行第二个代码块。
else ifc if (条件1) { // 条件1为真时执行的代码 } else if (条件2) { // 条件2为真时执行的代码 } else { // 所有条件为假时执行的代码 } 用于多个条件判断,依次检查条件,执行第一个为真的代码块,否则执行 else
switchc 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; 用于立即终止循环(forwhiledo-while)或 switch 语句的执行。
continuec continue; 跳过当前循环的剩余部分,直接进入下一次循环的条件判断。
returnc return [表达式]; 用于从函数中返回,并可选择返回一个值。如果函数返回类型为 void,则省略表达式。
gotoc goto 标签; ... 标签: // 代码 无条件跳转到指定标签处的代码,需谨慎使用,避免代码可读性降低。

四、函数

1.函数的定义

返回类型 函数名(参数列表){
    //函数体
    //执行代码
    return [返回值];//如果返回类型非void
}
部分描述
返回类型函数返回值的数据类型(如 intfloatvoid 等)。如果函数不返回值,则使用 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.一维数组

  • 声明格式:数据类型 数组名[数组大小];
  1. 数据类型:数组中元素的数据类型(如 intfloatchar 等)。
  2. 数组名:数组的名称,遵循C语言标识符规则。
  3. 数组大小:数组的长度,必须是一个常量整数。
  • 初始化:数据类型 数组名[数组大小]={元素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.二维数组

  • 声明格式:数据类型 数组名[行数][列数]
  • 初始化
  1. 如果初始化时提供的元素个数少于每行或每列的大小,剩余元素会自动初始化为 0
  2. 可以省略行数
  • 遍历二维数组:数组名[行索引][列索引]

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.基本概念

  1. 指针变量:用于存储内存地址的变量。
  2. 地址运算符 &:获取变量的内存地址。
  3. 解引用运算符 *:通过指针访问内存地址中存储的值。

2.指针的声明

数据类型 *指针变量名

3.指针的初始化

  1. 使用 & 运算符获取变量的地址。
  2. 直接赋值为另一个指针。
  3. 赋值为 NULL(表示空指针)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值