当前位置:   article > 正文

C语言入门知识整理_c语言中fac

c语言中fac

C语言入门知识整理

0 推荐书籍

如果你想要更详细的C语言知识体系,请参考下列书籍,本章将对一些重要的内容进行整理,这部分知识主要适合编程以及算法入门,会忽略一些不必要深究的细节
1.《C程序设计》
2.《C程序设计学习辅导》
3.《程序设计C语言实验指导》
4.《C Prime Plus》
其中前三本书较为基础,适合入门初学者使用,最后一本书的译本十分精彩,可谓C语言入门全集,里面会对知识广度做详细介绍,推荐阅读!

1 头文件、主函数、注释

1.1 头文件

所谓头文件,是指程序预处理的时候由编译器操作的部分(这句话可跳过,初学不用深入理解),那么为什么先介绍头文件呢?因为头文件中包含了许多常用的库函数,方便我们对程序进行操作,下面举例说明:
首先给出常用的头文件:

//常用
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
//不常用
#include<asset.h>
#include<errno.h>
#include<float.h>
#include<limits.h>
#include<locale.h>
#include<signal.h>
#include<time.h>
#include<stddef.h>
#include<stdarg.h>
#include<setjmp.h>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

接下来对常用的头文件做一下简单介绍,了解一些有用的库函数,方便程序设计(这部分可先略读,直接进入 1.2 主函数 部分进行阅读,等后面知识学完后再进行查阅)
(1)#include<stdio.h>
库变量——
size_t:这是无符号整数类型,它是 sizeof 关键字的结果
这个变量很有用,例如你写unsigned变量时,其值就是size_t类型,再比如,需要动态分配内存空间的时候,需要写n*sizeof(int),即分配了n个int变量的空间

库宏——
EOF:这个宏是一个表示已经到达文件结束的负整数
这个宏会广泛的存在于题目的输入条件中,实际上EOF为-1,标志着文件的结束,例如我们可以这样来使用:while(scanf(“%d”,&n)!=EOF),我们在输入n的时候,顺便检查其是否到达了文件末尾,若到达了,则退出读入

库函数——

函数作用例如
int scanf(const char *format, …)从标准输入 stdin 读取格式化输入scanf(“%d”,&n)
int sscanf(const char *str, const char *format, …)从字符串读取格式化输入sscanf(str,“%d”,&n)
int printf(const char *format, …)发送格式化输出到标准输出 stdoutprintf(“%d”,n)
int sprintf(char *str, const char *format, …)发送格式化输出到字符串sprintf(str,“%d”,n)
int getchar(void)从标准输入 stdin 获取一个字符(一个无符号字符)char ch = getchar()
char *gets(char *str)从标准输入 stdin 读取一行,并把它存储在 str 所指向的字符串中。当读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定char s[50]; gets(s);
int putchar(int char)把参数 char 指定的字符(一个无符号字符)写入到标准输出 stdout 中putchar(ch)
int puts(const char *str)把一个字符串写入到标准输出 stdout,直到空字符,但不包括空字符。换行符会被追加到输出中puts(s)

这几个库函数必须掌握,用法十分常见
(2)#include<math.h>
该函数库为数学类的函数,涉及数学的初等运算

库函数——

函数作用例如
double fabs(double x)返回 x 的绝对值fabs(f)
double sqrt(double x)返回 x 的平方根sqrt(f)
double pow(double x, double y)返回 x 的 y 次幂pow(2,10)=1024
double ceil(double x)返回大于或等于 x 的最小的整数值ceil(4.9)=5
double floor(double x)返回小于或等于 x 的最大的整数值floor(4.9)=4

(3)#include<string.h>
库宏——
NULL:这个宏是一个空指针常量的值
库函数——
该函数库主要处理字符串操作,包括拼接、复制、比较大小、长度等

函数作用例如
void *memset(void *str, int c, size_t n)复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符memset(a,0,sizeof(a))
int strcmp(const char *str1, const char *str2)把 str1 所指向的字符串和 str2 所指向的字符串进行比较strcmp(“hello”,“Hello”)>0
char *strcat(char *dest, const char *src)把 src 所指向的字符串追加到 dest 所指向的字符串的结尾str = strcat(“Hello”,“World”)
char *strcpy(char *dest, const char *src)把 src 所指向的字符串复制到 deststrcpy(str,str1)
size_t strlen(const char *str)计算字符串 str 的长度,直到空结束字符,但不包括空结束字符int len = strlen(str)

(4)#include<stdlib.h>
库函数——
该函数库主要处理内存动态分配处理和程序运行状态操作

函数作用例如
int abs(int x)返回 x 的绝对值abs(n)
void exit(int status)使程序正常终止exit(0)
void *malloc(size_t size)分配所需的内存空间,并返回一个指向它的指针malloc(sizeof(int))
void *calloc(size_t nitems, size_t size)分配所需的内存空间,并返回一个指向它的指针calloc(n,sizeof(int))
void *realloc(void *ptr, size_t size)尝试重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小realloc(ptr,sizeof(int))
void free(void *ptr)释放之前调用 calloc、malloc 或 realloc 所分配的内存空间free(ptr)

(5)#include<ctype.h>
库函数——
该函数库主要处理单个字符,涉及ASCII码的转换

函数作用例如
int tolower(int c)该函数把大写字母转换为小写字母tolower(‘A’)
int toupper(int c)该函数把小写字母转换为大写字母toupper(‘a’)
int isalnum(int c)该函数检查所传的字符是否是字母和数字isalnum(‘7’)
int isalpha(int c)该函数检查所传的字符是否是字母isalpha(‘a’)
int isdigit(int c)该函数检查所传的字符是否是十进制数字isdigit(‘9’)
int islower(int c)该函数检查所传的字符是否是小写字母islower(‘a’)
int isupper(int c)该函数检查所传的字符是否是大写字母isupper(‘A’)
int isspace(int c)该函数检查所传的字符是否是空白字符isspace(’ ')

1.2 主函数

所谓主函数,指main函数,这里直接记住写法即可:

int main(){

	return 0;
}
  • 1
  • 2
  • 3
  • 4

别忘记加return 0;这是程序正常执行结束的标志(因为程序内部错误会返回其他值,这里不必深究)

1.3 注释

这里介绍两种常用的注释:// 和 /* */

//1.此注释为行注释,只能注释一行
/*

2.此注释为段落注释,可注释一个段落

*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2 变量定义及类型

类型名 + 变量名 = 赋初值;
很简单,举例说明:

int a = 10;			//定义整数a=10
double f = 0.22;	//定义浮点数f=0.22
char s = 'A';		//定义字符s = 'A'
int b[10] = {1,2};	//定义整数数组b[0]=1,b[1]=2
  • 1
  • 2
  • 3
  • 4

这些都是对变量的定义,定义变量就必须指定类型,因此这两个概念一起理解

3 简单程序结构(分支、循环、选择)

有了变量之后,接下来就是定义一些简单的程序结构,这里主要介绍3种:分支、循环、选择

3.1 分支

简单来说,就是程序需要判断什么,举例:

if(a >= 10){
	b = 1;
}else{
	b = 2;
}
  • 1
  • 2
  • 3
  • 4
  • 5

a > = 10 a>=10 a>=10,我们就将 b = 1 b=1 b=1,否则 b = 2 b=2 b=2,这里很好理解,稍微复杂一些的判断结构有:

if(条件1){

}else if(条件2){
	if(条件4){
		
	}else if(条件5){
	
	}
}else if(条件3){

}else{

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

也就是说,判断可以嵌套,判断之中含有判断,一层一层的叠加

3.2 循环

简单来说,你需要重复做一件事情,那么需要不断循环!举例:

int sum = 0;
for(int i=1;i<=10;i++){
	sum += i;
}
  • 1
  • 2
  • 3
  • 4

显而易见,这里 s u m sum sum可以从1累加到10,输出即为55,就是高斯求和的展开式,复杂一些,可以有如下结构:

for(int i=1;i<=10;i++){
	for(int j=1;j<=10;j++){
		for(int k=1;k<=10;k++){

		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

比如多层循环等等

3.3 选择

选择是一种特殊的结构,这里单指switch:

switch(a){
	case 1:b = 10;break;
	case 2:b = 100;break;
	case 3:b = 1000;break;
	default:b = 1;break;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们考察a的值,a若为1,则b的值为10,a若为2,则b的值为100,a若为3,则b的值为1000,a若为其他,则b的值为1000,这里要注意的是,break的作用是跳出switch,而不是顺序执行(初学者记住每句话后加break即可)

4 简单程序

有了前3个概念之后,我们就可以写出简单的程序了,主体框架如下:

//1.头文件部分

//2.主函数

//输入输出 + 简单结构
  • 1
  • 2
  • 3
  • 4
  • 5

再加上输入/输出,这样一个简单的程序就完成了(输入/输出请参考1.1(1)#include<stdio.h>库,要求掌握所有的输入输出基本函数),比如举个例:

#include<stdio.h>
int main(){
	//输入
	//程序处理
	//输出
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这一块书写应熟练,是整个程序基本的框架
学完这些之后,可练习:
团体程序设计天梯赛-L1组
所有5分和10分的题目

5 子程序

有了主程序之后,接下来就引入了子程序的概念,所谓子程序,是指相对于主程序的一个子函数,这个子函数可以完成一项或多个重复的功能,为了避免程序调用的时候,频繁书写重复的语句,因此定义一个子程序并反复调用是最佳的选择,例如,我们有一个阶乘函数:

int fac(int n);
  • 1

接下来在主程序中,我们需要反复调用它:

int fac(int n){
	int res = 1;
	for(int i=1;i<=n;i++){
		res *= i;
	}
	return res;
}
int main(){
	int a = fac(5);
	int b = fac(11);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

至此,子程序就介绍结束了

6 递归

所谓递归,就是一系列重复的操作,那么这和之前的子程序有什么区别呢?子程序是一次操作完成一个或多个既定的功能,调用一次,返回结果;而递归是调用自己N次,逐层返回后才能得结果,例如,还是刚刚的阶乘函数,递归写法:

int fac(int n){
	if(n == 1){
		return 1;
	}
	return fac(n-1)*n;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

fac函数中调用fac函数自身,这叫递归,递归有结束的时候,这就是边界条件,当n=1时,n!=1

7 数组

7.1 一维数组

顾名思义——数组,就是将一串数字按照成组的方式排列起来,一维就是线性的,例如:
1 2 3 4 5 6这就是6个线性排列的数字,放置在一个容器中,这个容器就是数组:

int a[6] = {1,2,3,4,5,6};
  • 1

我们可以通过下标对数组进行访问,下标从0-(n-1),如a[3]=4

7.2 二维数组及多维数组

二维,在一维基础上增加了一个维度,也就是拥有行、列两个维度:

int a[2][3] = {{1,2,3},{4,5,6}};
  • 1

数字1-6分成两行表示了,这也就是矩阵的表示法
同样地,也可以通过下标进行访问,如a[1][2]=6

8 结构体与枚举

8.1 结构体

结构体,通俗理解就是一个打包的数据类型集合,比方说我们要记录一本图书,就需要书名、ISBN号、价格、字数等多种信息,把这些信息打包,就是一个结构体,可表述为{书名、ISBN号、价格、字数}
这里要掌握结构体的两种定义方法:
(1)普通定义

struct book{
	char book_name[20];
	char ISBN[20];
	double price;
	int words;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这样我们就定义了一个结构体,包含了以上4个信息
(2)复杂定义

typedef struct{
	char book_name[20];
	char ISBN[20];
	double price;
	int words;
}book;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

重命名意义下更常用一些(程序设计)

8.2 枚举

枚举,同一块存储空间可共用不同的类型定义,只能选择其中之一的类型
这一块可暂时略过,因为算法实践中基本不使用这种技术

9 指针

这一块是C语言最为核心和精彩的一部分,但对于初学者而言,无需深入了解,指针在系统设计、文件访问有着相当深入的应用
我们主要介绍指针访问数组的情形,例如这样:
一维数组,依旧保存了6个数字,我们已经可以用下标的方式对其访问了,那么,如何用指针访问呢?
我们可以把指针看作一个箭头,开始指向数组头,即第一个格子,然后每加1,指向的格子就向后移动一格,这样,输出数组元素的值,等价于输出指针箭头指向的格子内元素的值,例如,要输出a[3]:

int a[6] = {1,2,3,4,5,6};
int *ptr = a; 				//创建指针
printf("%d",*(ptr+3));
  • 1
  • 2
  • 3

这样,就完成了 7.1部分 同样的功能,二维指针原理同上

10 排序

这里介绍C语言库中自带的一个函数qsort(此处可参考1.1部分 阅读库),

void qsort(void* base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));
  • 1

参数:
1 void* base,待排序数组,排序之后的结果仍放在这个数组中
2 size_t num,数组中待排序元素数量
3 size_t width。各元素的占用空间大小(单位为字节)
4 int(__cdecl*compare),指向函数的指针,用于确定排序的顺序(需要用户自定义一个比较函数)
例如,我们对一个无序的数组进行排序:

int cmp_int(const void* _a , const void* _b){
    int* a = (int*)_a;   
    int* b = (int*)_b;
	return *a - *b;
}
int main(){
	int a[6] = {5,1,6,3,4,2};
	qsort(a,6,sizeof(int),cmp_int); 
	
	return 0;
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这样就完成了排序,方便快捷(C++有更好的方法,sort函数)

结束语

希望大家在掌握了C语言基本知识的基础上,再回看1.1库函数这一节,深入理解并记忆这些基本的库函数,相信对后面的程序与算法设计大有帮助!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/850138
推荐阅读
相关标签
  

闽ICP备14008679号