c语言笔记

c语言是什么 

       C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言,所以说学习C语言是进入编程世界的必修课。

  • C语⾔是一门编译型计算机语⾔,C语言源代码都是文本文件,文本文件本身无法执行,必须通过编译器翻译和链接器的链接,生成⼆进制的可执执行件,可执行文件才能执行。
  • C语⾔代码是放在 .c 为后缀的文件中的,要得到最终运行的可执行程序,中间要经过编译和链接2个过程。

1.编译器:计算机语言转换成机器能够执行的机器指令。

2.集成开发环境(IDE)用于提供程序开发环境的应⽤程序,⼀般包括代码编辑器、 编译器 、 调试器和图形用户页面等页面。集成了代码编写功能、分析功能、编译功能、调试功能等⼀体化的开发软件服务套。

1.输出一个hello word

1.#include<stdio.h> 这是一个头文件,其中就包含当前的printf函数()。

2.printf(“hello word”) 双引号引起来的一些字符叫字符串

3.分号:代表当前语句结束

4.return 0;当执行的过程中,遇到return代表当前的函数结束;return 0;代表语句正常结束。return -1;代表语句异常结束。

5.方法的返回值类型 int

6.  .exe代表可执行程序(当我们代码写好后就变成了这个.exe)

7. 源代码(.c)    经过预编译,编译,汇编,链接变成      可执行程序(.exe)

8.main函数是程序的入口函数,只能有一个。

一.数据类型

10.  char(%c)      short(%d)       int(%d)       long(%ld)        long long(%lld)   

       float(%f)        double(%lf)    字符串的类型是%s;

1.1 新加的布尔类型

      C语⾔原来并没有为布尔值单独设置⼀个类型,⽽是使⽤整数 0 表示 假,⾮零值表示真。
C99 中也引入了 布尔类型 ,是专门表示真假的。
  • C语言布尔类型是_Bool或者bool,使用需要包含头文件stdbool.h
  • 布尔类型变量的取值是:true或者false
_Bool flag = true;
if (flag)
 printf("i like C\n");

 1.2 sizeof 求字节大小的(不同位数下的字节不同)

1.3 主函数main()

1.int main() 这个是一个程序的入口,main函数有且只有一个,一个c语言的程序是从本程序的main函数开执行的。

2.main函数的位置可以在任意位置,但是如果在主函数之中调用了哪些函数,必须在main函数前对其所调用函数进行生命或包含其被调用函数的头文件。

1.4 ASCLL码表

二.变量 常量

1.变量

生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)先定义再使用。 有些值是可变的(比如:年龄,体重,薪资)。
不变的值, C 语言中用 常量 的概念来表示,变得值C语言中用变量 来表示。

1.局部变量与全局变量名字不要相同,容易产生bug。

2.当局部和全局变量名字相同时,局部变量优先,就是{}main()函数内优先。

3.局部变量的作用域是变量所在的局部范围。

4.全局变量的作用域是整个过程。

5.字符串的结束标志是"/0"  --转义字符。

2.1 定义变量的方法

int age = 150;
float weight = 45.5f;
char ch = 'w';

2.2 变量的分类

  • 局部变量
  • 全局变量
  • 局部变量是放在内存的栈区的,全局变量是放在内存的静态区

2.3 变量的使用

#include <stdio.h> 
int main() 
{ 
   int num1 = 0; 
  int num2 = 0; 
   int sum = 0; 
   printf("输入两个操作数:>"); 
   scanf("%d %d", &num1, &num2); 
   sum = num1 + num2; 
   printf("sum = %d\n", sum); 
   return 0; 
} 
//这里介绍输入,输出语句 
//scanf  输入
//printf  输出

2.4 变量的作用域和生命周期

  • 作用域:作用域 (scope) 是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/或者可用的而限定这个名字的可用性的代码范围就是这个名字的作用域。
     1. 局部变量的作用域是变量所在的局部范围。
     2. 全局变量的作用域是整个工程。
     3.局部变量是放在内存的栈区的,全局变量是放在内存的静态区
  • 生命周期:变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
     1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
     2. 全局变量的生命周期是:整个程序的生命周期。

2.5 常量

C 语言中的常量分为以下以下几种:

字面常量

const 修饰的常变量

#define 定义的标识符常量

枚举常量

#include <stdio.h> 
enum Sex 
{ 
MALE, 
FEMALE, 
SECRET 
}; 
//括号中的MALE,FEMALE,SECRET是枚举常量 
int main() 
{ 
   //字面常量演示 
   3.14;//字面常量 
   1000;//字面常量 
   
   //const 修饰的常变量 
   const float pai = 3.14f;   //这里的pai是const修饰的常变量 
   pai = 5.14;//是不能直接修改的! 
   
   //#define的标识符常量 演示 
#define MAX 100 
   printf("max = %d\n", MAX); 
   
   //枚举常量演示 
   printf("%d\n", MALE); 
   printf("%d\n", FEMALE); 
   printf("%d\n", SECRET); 
   //注:枚举常量的默认是从0开始,依次向下递增1的
   return 0; 
}

三.标识符

标识符只能由字母,数字,下划线组成,且第一个字符必须为字母或者下划线。

四. 字符串+转义字符+注释

4.1 字符串

"hello wwy\n"
这种由双引号( Double Quote )引起来的一串字符称为字符串字面值( String Literal ),或者简称字符串。
  • 注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。
转义字符
释义
\?
在书写连续多个问号时使用,防止他们被解析成三字母词
\'
用于表示字符常量 '
\“
用于表示一个字符串内部的双引号
\\
用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a
警告字符,蜂鸣
\b
退格符
\f
进纸符
\n
换行
\r
回车
\t
水平制表符,通常下一个是8的倍数
\v
垂直制表符
\ddd
ddd表示1~3个八进制的数字。 如: \130 X
\xdd
dd表示2个十六进制数字。 如: \x30 0

4.2  转义字符/0的作用

  • C语⾔字符串中⼀个特殊的知识,就是在字符串的末尾隐藏放着⼀个 \0 字符,这个 \0 字符是字符串的结束标志。
  • 字符串的打印格式可以使⽤ %s 来指定

     1.我们可以看到, arr2  字符数组在打印的时候,打印了 a b c 后还打印了⼀些随机值,这就是因为 arr2  在末尾的地⽅没有 \0 字符作为结束标志,在打印的时候没有停止。
     2.但是 arr1  的打印就是完全正常的,就是因为 arr1  数组是使⽤字符串常量初始化的,数组中有 \0 作为技术标志,打印可以正常停止。
     3.我们也可以在arr2 后面主动放一个'\0',那么打印就正常了。

4.3 算术操作符:+、-、*、/、%

     C语⾔中为了⽅便运算,提供了⼀系列操作符,其中有⼀组操作符叫:算术操作符。分别是: + - * / % ,这些操作符都是双⽬操作符。
      注: 操作符也被叫做:运算符,是不同的翻译,意思是⼀样的。
1. + - 都是有2个操作数的,位于操作符两端的就是它们的操作数,这种操作符也叫双⽬操作符。
2.运算符 * ⽤来完成乘法
3. 运算符 / 用 来完成除法。
除号的两端如果是整数,执行的是整数除法,得到的结果也是整数。
     如果希望得到浮点数的结果,两个运算数必须⾄少有⼀个浮点数,这时 C 语⾔就会进⾏浮点数除法。 float x=6.0/4    这样结果才有小数。
4. 运算符 % 表示 求模运算,即返回两个整数相除的余值。这个运算符只能⽤于整数,不能用于浮点数。
负数求模的规则是,结果的正负号由第⼀个运算数的正负号决定。

4.4 各运算符之间的优先级

第1优先级:各种括号,如()、[]等、成员运算符.;
第2优先级:所有单目运算符,如++、-、!、~等;
第3优先级:乘法运算符*、除法运算符1、求余运算符%;
第4优先级:加法运算符+、减法运算符-;第5优先级:移位运算符<<、>>;
第6优先级:大于运算符。>、大于等于运算符>=、小于运算符<、小于等于运算符<=;

4.5 注释

1. 代码中有不需要的代码可以直接删除,也可以注释掉
2. 代码中有些代码比较难懂,可以加一下注释文字
    注释有两种风格:
  • C语言风格的注释 /*xxxxxx*/ 缺陷:不能嵌套注释
  • C++风格的注释 //xxxxxxxx 可以注释一行也可以注释多行

五. 语句与语句分类

5.1 if条件判断语句

如果你好好学习,你就会考研成功,加入腾讯
如果你不学习,毕业等于失业,回家种地。
这就是选择!

以上就是一个简单的选择语句。

5.2 复合语句

复合语句其实就是代码块,成对括号中的代码就构成⼀个代码块,也被称为复合语句。

5.3 控制语句

控制语句用于控制程序的执⾏流程,以实现程序的各种结构⽅式(C语⾔支持三种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,C语⾔有九种控制语句。
可分成以下三类:
1. 条件判断语句也叫分⽀语句:if语句、switch语句;
2. 循环执行语句:do while语句、while语句、for语句;
3. 转向语句:break语句、goto语句、continue语句、return语句。
后期会给⼤家⼀⼀介绍控制语句。

六.printf函数

1. 输出的值默认是右对齐,即输出内容前⾯会有空格;如果希望改成左对⻬,在输出内容后⾯添加空 格,可以在占位符的 % 的后⾯插⼊⼀个 - 号。
2.printf() 的作⽤是将参数⽂本输出到屏幕。它名字⾥⾯的 f 代表 format (格式化),表⽰可以
定制输出⽂本的格式。
3. printf() 参数与占位符是⼀⼀ 对应关系,如果有 n 个占位符, printf() 的参数就应该有 n + 1 个。如果参数个数少于对应的占位符, printf() 可能会输出内存中的任意值。
4.printf() 允许限定占位符的最小宽度
  • 例:printf("%5d\n",123)     结果为:  123                                                                                 %5d 表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。
  • 例:printf("%5d\n",123456789)    结果为:123456789                                                                                                                                                                                                                                            

5.%6.2f 表⽰输出字符串最小宽度为6,⼩数位数为2。所以,输出字符串的头部有两个 空格

       float类型,默认小数点后有6位数字

七.scanf函数

1.它的第⼀个参数是⼀个格式字符串,里面会放置占位符(与 printf() 的占位符基本⼀致),告诉编 译器如何解读用户的输⼊,需要提取的数据是什么类型。
这是因为 C 语⾔的数据都是有类型的, scanf() 必须提前知道用户输⼊的数据类型,才能处理数
据。
2.它的其余参数就是存放用户输⼊的变量,格式字符串里面有多少个占位符,就有多少个变量。
上面示例中, scanf() 的第⼀个参数 %d ,表示用户输⼊的应该是⼀个整数。 %d 就是⼀个占位
符, % 是占位符的标志, d 表示 整数。第⼆个参数 &i 表示 ,将用户从键盘输⼊的整数存⼊变量
i
注意:变量前⾯必须加上 & 运算符(指针变量除外),因为 scanf() 传递的不是值,⽽是地址,
即将变量 i 的地址指向用户输⼊的值。
如果这⾥的变量是指针变量(⽐如字符串变量),那就不⽤加 & 运算符。

3.在scanf中如果参数是数组,因为数组本来就是地址,所以不需要取地址  例:printf("%s",arr);

4.scanf() 处理数值占位符时,会⾃动过滤空白字符,包括空格、制表符、换行符等

八.条件操作符

1.条件操作符也叫三目操作符,需要接受三个操作数的,形式如下:
  • exp1 ? exp2 : exp3
条件操作符的计算逻辑是:如果 exp1 为真, exp2 计算,计算的结果是整个表达式的结果;如果
exp1 为假, exp3 计算,计算的结果是整个表达式的结果。
#include <stdio.h>
int main()
{
 int a = 0;
 int b = 0;
 scanf("%d %d", &a, &b);
 int m = a>b ? a : b;  //此处就是三目运算符的操作
 printf("%d\n", m);
 
 return 0;
}

九.逻辑操作符:&& , || , !

逻辑运算符提供逻辑判断功能,⽤于构建更复杂的表达式,主要有下⾯三个运算符。
  ! :逻辑取反运算符(改变单个表达式的真假)。
  && :与运算符,就是并且的
意思(两侧的表达式都为真,则为真,否则为假)。
|| :或运算符,就是或者的意思(两侧至少有⼀个表达式为真,则为真,否则为假)。
注:C语⾔中,非0表示真,0表示假

十.swith语句

除了 if 语句外,C语言还提供了 switch 语句来实现分支结构。
switch 语句是⼀种特殊形式的 if...else 结构,用于判断条件有多个结果的情况。它把多重
else if 改成更易用、可读性更好的形式。
switch (expression) {
 case value1: statement
 case value2: statement
 default: statement
}
上⾯代码中,根据表达式 expression 不同的值,执行相应的 case 分支 。如果找不到对应的值,
就执行  default 分支。
注:
  • switch 后的 expression 必须是整型表达式
  • case 后的值,必须是整形常量表达式

10.1 if语句和switch语句的对比

输⼊任意⼀个整数值,计算除3之后的余数

用if语句来写

#include <stdio.h>
int main()
{
 int n = 0;
 scanf("%d", &n);
 if(n%3 == 0)
 printf("整除,余数为0\n");
 else if(n%3 == 1)
 printf("余数是1\n");
 else
 printf("余数是2\n");
 return 0;
}
如果使用switch语句改写,就可以是这样的:
#include <stdio.h>
int main()
{
 int n = 0;
 scanf("%d", &n);
 switch(n%3)
 {
 case 0:
 printf("整除,余数为0\n"); 
 break;
 case 1:
 printf("余数是1\n"); 
 break;
 case 2:
 printf("余数是2\n"); 
 break;
 }
 return 0;
}
上述的代码中,我们要 注意 的点有:
  •  case 和后边的数字之间必须有空格
  • 每⼀个 case 语句中的代码执⾏完成后,需要加上 break ,才能跳出这个switch语句。

10.2 switch语句中的break

1.switch 语句也是分支效果的,只有在 switch 语句中使用  break 才能在跳出 switch 语句,如果某⼀个 case 语句的后边没有 break 语句,代码会继续玩下执行,有可能执行其他 case 语句中的代码,直到遇到 break 语句或者 switch 语句结束
2. 所以在 switch 语句中 break 语句是⾮常重要的,能实现真正的分⽀效果。
3.当然, break 也不是每个 case 语句都得有,这就得根据实际情况来看了。

10.3 switch语句中的default

在使⽤ switch 语句的时候,我们经常可能遇到⼀种情况,比如 switch 后的表达式中的值⽆法匹 配代码中的 case 语句的时候,这时候要不就不做处理,要不就得在 switch 语句中加入default 子句

switch (expression) {
 case value1: statement
 case value2: statement
 default: statement
}
switch 后边的 expression 的结果不是 value1 ,也不是 value2 的时候,就会执行default 子句。

十一.数组

11.1 一维数组

1. 数组的概念

 数组是⼀组相同类型元素的集合;

  • 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
  • 数组中存放的多个数据,类型是相同的。

11.1⼀维数组的创建和初始化

type arr_name[常量值];
存放在数组的值被称为数组的元素,数组在创建的时候可以指定数组的⼤⼩和数组的元素类型。
  • type 指定的是数组中存放数据的类型,可以是: charshortintfloat 等,也可以自定义的类型
  • arr_name 指的是数组名的名字,这个名字根据实际情况,起的有意义就行。
  • [] 中的常量值是用来指定数组的大小的,这个数组的大小是根据实际的需求指定就⾏。
⽐如:我们现在想存储某个班级的20人的数学成绩,那我们就可以创建⼀个数组,如下:
int math[20];

11.2初始化

//完全初始化
int arr[5] = {1,2,3,4,5};
//不完全初始化
int arr2[6] = {1};//第⼀个元素初始化为1,剩余的元素默认初始化为0
//错误的初始化 - 初始化项太多
int arr3[3] = {1, 2, 3, 4};

11.3. 一维数组的下标

int arr[10] = {1,2,3,4,5,6,7,8,9,10};

11.4 一维数组的打印

#include <stdio.h>
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
 int i = 0;
 for(i=0; i<10; i++)
 {
 printf("%d ", arr[i]);
 }
 return 0;
}

11.2 二维数组

1.⼆维数组的创建
type arr_name[常量值1][常量值2];
例如:
int arr[3][5];
double data[2][8];
2.二维数组的按照行初始化

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

3.不完全初始化

int arr1[3][5] = {1,2};
int arr2[3][5] = {0};

 

4.打印二维数组(完全初始化)里面的元素

5.初始化时省略行,但是不能省略列

int arr5[][5] = {1,2,3};
int arr6[][5] = {1,2,3,4,5,6,7};
int arr7[][5] = {{1,2}, {3,4}, {5,6}};

6.二维数组的下标

int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

       图中最右侧绿色的数字表示行号,第一行蓝色的数字表示列号,都是从0开始的,比如,我们说:第2行,第4列,快速就能定位出7。
7.二维数组的一道练习题
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int a[3][3] = {1,2,3,4,5,6,7,8,9};
	int i = 1;
	int m = 1;
	for (i = 0; i <= 2; i++)
		m = m * a[i][i];
		printf("m=%d\n", m);
	return 0;
}

还有一些练习题可以去我的博客c语言练习题里面查看


十二.函数

1. 函数的概念

其实在C语言也引⼊函数(function)的概念,有些翻译为:子程序,子程序这种翻译更加准确⼀些。
C语言中的函数就是⼀个完成某项特定的任务的⼀小段代码。这段代码是有特殊的写法和调用方法的。
C语言的程序其实是由无数个小的函数组合⽽成的,也可以说:⼀个大的计算任务可以分解成若干个较小的函数(对应较小的任务)完成。同时⼀个函数如果能完成某项特定任务的话,这个函数也是可以复用的,提升了开发软件的效率。
在C语言中我们⼀般会见到两类函数:
• 库函数
• 自定义函数

2. 库函数

       C语言标准中规定了C语⾔的各种语法规则,C语⾔并不提供库函数;C语⾔的国际标准ANSI C规定了⼀些常用的函数的标准,被称为标准库,那不同的编译器⼚商根据ANSI提供的C语⾔标准就给出了⼀系列函数的实现。这些函数就被称为库函数。
      我们前面内容中学到的 printf scanf 都是库函数,库函数的也是函数,不过这些函数已经是现成的,我们只要学会就能直接使⽤了。有了库函数,⼀些常见的功能就不需要程序员自己实现了,一定程度提升了效率;同时库函数的质量和执行效率上都更有保证。各种编译器的标准库中提供了⼀系列的库函数,这些库函数根据功能的划分,都在不同的头⽂件中进行了声明。 库函数相关头文件: https://zh.cppreference.com/w/c/header 有数学相关的,有字符串相关的,有日期相关的等,每⼀个头文件中都包含了,相关的函数和类型等。
     2.2 库函数的使用方法
库函数的学习和查看⼯具很多,比如:
C/C++官方的链接: https://zh.cppreference.com/w/c/header
  2.3  函数的语法形式
  1. ret_type fun_name(形式参数)
  2. {
  3. }
• ret_type 是函数返回类型
• fun_name 是函数名
• 括号中放的是形式参数
• { }括起来的是函数体

3. 形参和实参

3.1 实参

    实参称为实际参数,简称实参。 实际参数就是真实传递给函数的参数。

3.2 形参
      形参只是形式上存在的,不会向内存申请空间,不会真实存在的,所以叫形式参数。形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形参的实例化。
3.3 实参和形参的关系
      虽然我们提到了实参是传递给形参的,他们之间是有联系的,但是形参和实参各自是独立的内存空间。

4.函数的声明和定义

    例如我们在调用我们写的函数时,我们将函数的定义放在函数main()函数的后边,那么将无法运行。

      解决办法:在mian函数前面,就是函数调用之前先声明⼀下  某某  这个函数,声明函数只要交代清楚:函数名,函数的返回类型和函数的参数就能正常编译了。

例:

5. 多个文件(很重要,可以隐藏文件赚钱)

       ⼀般在企业中我们写代码时候,代码可能比较多,不会将所有的代码都放在⼀个⽂件中;我们往往会根据程序的功能,将代码拆分放在多个文件中。
      ⼀般情况下,函数的声明、类型的声明放在头文件(.h)中,函数的实现是放在源文件(.c)⽂件中。
    如下:
add.c
//函数的定义
int Add(int x, int y)
{
return x+y;
}
add.h
//函数的声明
int Add(int x, int y);

test.c  

#include <stdio.h>
#include "add.h"
int main()
{
int a = 10;
int b = 20;
//函数调用
int c = Add(a, b);
printf("%d\n", c);
return 0;
}

6.static 和 extern 函数

static 和 extern 都是C语⾔中的关键字。
static 是 静态的的意思,可以用来:
• 修饰局部变量
• 修饰全局变量
• 修饰函数

 extern 是用来声明外部符号的

在了解 static extern 之前说⼀下:作用域和生命周期。

上面第二章2.4说过了

6.1static函数延长生命周期,改变结果
//代码1
#include <stdio.h>
void test()
{
int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<5; i++)
{
test();
}
return 0;
}

/代码2
#include <stdio.h>
void test()
{
//static修饰局部变量
static int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<5; i++)
{
test();
}
return 0;
}
     代码1的test函数中的局部变量i是每次进⼊test函数先创建变量(⽣命周期开始)并赋值为0,然后 ++,再打印,出函数的时候变量⽣命周期将要结束(释放内存)。
  • 结果是 1 1 1 1 1
      代码2中,我们从输出结果来看,i的值有累加的效果,其实 test函数中的i创建好后,出函数的时候是 不会销毁的,重新进⼊函数也就不会重新创建变量,直接上次累积的数值继续计算。
结论:static修饰局部变量改变了变量的生命周期,生命周期改变的本质是改变了变量的存储类型,本 来⼀个局部变量是存储在内存的栈区的,但是被 static 修饰后存储到了静态区。存储在静态区的变 量和全局变量是⼀样的,生命周期 就和程序的⽣命周期⼀样了,只有程序结束,变量才销毁,内存才 回收。但是作用域不变的。
  • 结果是 1 2 3 4 5 

6.2全局变量被static修饰
⼀个全局变量被static修饰,使得这个全局变量只能在本源⽂件内使⽤,不能在其他源⽂件内使用。 本质原因是全局变量默认是具有外部链接属性的,在外部的⽂件中想使⽤,只要适当的声明就可以使用;但是全局变量被 static 修饰之后,外部链接属性就变成了内部链接属性,只能在⾃⼰所在的源文件内部使用了,其他源文件,即使声明了,也是⽆法正常使用的。

使用建议:如果⼀个全局变量,只想在所在的源文件内部使用,不想被其他文件发现,就可以使用
static修饰。
使用建议:⼀个函数只想在所在的源文件内部使用,不想被其他源文件使用,就可以使⽤ static
饰。

extern 函数

十三.函数递归

13.1递归的定义

  递归其实是⼀种解决问题的方法,在C语言中,递归就是函数自己调用自己。
#include <stdio.h>
int main()
{
 printf("hehe\n");
 main();//main函数中⼜调⽤了main函数
 return 0;
}
上述就是⼀个简单的递归程序

13.2递归的思想

    把⼀个大型复杂问题层层转化为⼀个与原问题相似,但规模较小的子问题来求解;直到⼦问题不能再 被拆分,递归就结束了。所以递归的思考方式就是把大事化小的过程。
递归中的递就是递推的意思,归就是回归的意思

递归的经典例子

举例1:求n的阶乘
n的阶乘的公式: n =   n ∗ ( n − 1)!

#include <stdio.h>
int Fact(int n)
{
 if(n==0)
 return 1;
 else
 return n*Fact(n-1);
}
int main()
{
 int n = 0;
 scanf("%d", &n);
 int ret = Fact(n);
 printf("%d\n", ret);
 return 0;
}

举例2:求第n个斐波那契数

代码实现:

int Fib(int n)
{
 int a = 1;
 int b = 1;
 int c = 1;
 while(n>2)
 {
 c = a+b;
 a = b;
 b = c;
 n--;
 }
 return c;
}
int main()
{
 int n = 0;
 scanf("%d", &n);
int ret = Fib(n);
 printf("%d\n", ret); 
 printf("\ncount = %d\n", count);
 return 0;
}

十四.struct 结构体

     C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的,假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不行的。描述⼀个学生需要名字、年龄、学号、身高、体重等;描述⼀本书需要作者、出版社、定价等。C语⾔为了解决这个问题,增加了结构体这种自定义的数据类型,让程序员可以自己创造适合的类型。

结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:
标量、数组、指针,甚⾄是其他结构体

14.1结构体的声明

struct tag
{
 member-list;
} variable-list;

例:描述一个学生结构体

  • 特别注意:结构体最后的分号不能省略
struct Stu
{
 char name[20];//名字
 int age;//年龄
char sex[5];//性别
 char id[20];//学号
}; //分号不能丢

14.2结构体变量的定义和初始化

//代码1:变量的定义
struct Point
{
 int x;
 int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//代码2:初始化。
struct Point p3 = {10, 20};
struct Stu //类型声明
{
 char name[15];//名字
 int age; //年龄
};
struct Stu s1 = {"zhangsan", 20};//初始化
struct Stu s2 = {.age=20, .name="lisi"};//指定顺序初始化
//代码3
struct Node
{
 int data;
 struct Point p;
 struct Node* next; 
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

14.3结构体成员访问操作符

1.结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。
#include <stdio.h>
struct Point
{
 int x;
 int y;
}p = {1,2};
int main()
{
 printf("x: %d y: %d\n", p.x, p.y);
 return 0;
}
使用方式:结构体变量.成员名

2.结构体成员的间接访问

 有时候我们得到的不是⼀个结构体变量,而是得到了⼀个指向结构体的指针。
#include <stdio.h>
struct Point
{
 int x;
 int y;
};
int main()
{
 struct Point p = {3, 4};
 struct Point *ptr = &p;
 ptr->x = 10;
 ptr->y = 20;
 printf("x = %d y = %d\n", ptr->x, ptr->y);
 return 0;
}
使用方式:结构体指针->成员名

十五.深入理解指针(1)

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值