函数(难点,重点):
1.函数的思想
拆
把一个大问题,逐步拆解成更小的问题。
拆到,能解决的程度。
2.函数的实现
//函数定义 --- 定义功能
函数定义的语法 //输入数据--函数处理数据--带出结果
返回值类型说明符 函数名 (形式参数) //函数头
{
函数体;//实现具体功能的代码
return 表达式(返回值相关);
}
step1: //确定函数名
明确函数功能 --- 函数名
step2: //确定形式参数
函数需不需要处理数据
需要的话,有哪些数据需要处理 (有哪几个,什么类型)
不需要的话,形式参数 void
step3: //实现函数的具体功能代码
实现函数体
step4:
带出什么结果,以及结果的类型
eg:
int add(int a,int b)
{
int sum = a + b;
return sum;
}
//函数调用 --- 使用功能
语法:
函数名(实际参数1,实际参数2,...);
//int add(1,2); 不对
a.函数调用语句
printf("hello");
b.函数调用表达式
int c = 1 + add(1,2);
c.函数调用作为其它函数的实参
printf("%d\n",add(1,2));
注:
函数必须先定义后使用
函数定义的位置
1.main函数之前
2.main函数之后
需要,在使用前,做函数声明
函数头 加分号 就是函数声明
3、函数嵌套调用:
自己调用自己;
栈:
1。是一种数据结构FF
c语言的5个区
栈:
1. 是一种数据结构 FILO (First In Last Out)
2. 内存上的一块空间
3. 大小肯定是有限的
4. 可以存放函数调用数据
5. 局部变量(自动变量)
自动申请,自动释放
32位 --- 4G内存空间
32位 地址总线 32位
2^32 => 2^10 * 2^10 * 2^10 *2^2
1024 1024 1024 4
1K 1M 1G
堆:
1. 空间很大
2. 手动申请,手动释放 //后面讲
字符串常量区:
"hello" //字符串常量
不能被修改 - 只读
全局区(静态区)
全局变量的
代码区
存放代码的
程序 = 数据 + 代码
汉诺塔的故事:
古印度有一个梵塔,塔上有3个座,A,B,C。
【初始状态】
开始时,A座上有64个盘子,盘子大小不一,大的在下,小的在上。
【需求】
有一个老和尚想把64个盘子从A座移动到C座,
但每次只允许移动一个盘,且在移动过程中3个座上都始终保持大盘在下,
小盘在上。在移动过程中可以利用B座。
【问题】:
要求编程输出移动的步骤。(盘子个数可以动态指定)
问题n
|--问题n-1 与 n
|--问题n-2
|---
...结束条件
hanoi(64)
|---hanoi(63)
|---hanoi(62)
|---
...
hanoi(1)
#include <stdio.h>
void move(int n ,int pole1,int pole2)
{
static int step = 1;
printf("%03d:[disk %d] : %c --> %c\n",step++,n,pole1,pole2);
}
//起始柱 辅助柱 目标柱
void hanoi(int n, int A, int B, int C)
{
if (1==n)
{
move(n,A,C);
}else
{
hanoi(n-1,A,C,B);//n-1 先挪走
puts("-------");
move(n,A,C); // 将第n个 挪到 目标柱
puts("-------");
hanoi(n-1,B,A,C);
}
}
//n = 3;
//hanoi(2,'A','C','B')
// | --------------------> hanoi(1,'A','B','C')
// move(2,'A','B'); [2:A->B]
// |----------------------->move(1,'A','C') [1:A->C]
//move(3,'A','C'); -----> [3:A->C]
//hanoi(2,'B','A','C');
int main(void)
{
int n = 0;
printf("Input numbers of disk: ");
scanf("%d",&n);
hanoi(n,'A','B','C');
return 0;
}
//数组作为函数参数
函数参数:
1.形参变量
2.实际参数
int a[3]={1,2,3};
//情况1
数组元素作为函数参数
注意:
//1.数组元素的类型 是否 与形参类型一致
//情况2
想把整个数组传入到函数中
值传递:
情况1:数组元素作为函数参数
注意:
数组元素的类型 是否与形参类型一致
情况2:
想把整个数组传入到函数中
形参和实参的规则:
1,个数相同 2,类型匹配 3,一一对应
数组名能代表整个数组//给实参时,给定 数组名
int a【10】//a 数据类型 int【10】
1.数组 作为函数 参数 ,
形式上,保持一致,被调函数中 就可以 访问到主调函数中 数组的数据
一维整型数组作为函数参数
形参 写成数组的形式 同时需要 一个接受数组长度的形参
实参 传数组名,传数组长度
2.数组作为函数参数,
因为传的是数组名,而数组名是数组首元素的地址,所以相当于将数组空间的地址传给了被调函数,
而被调函数,通过数组下标运算,可以直接访问到了主调函数中对应数组空间的数据。
所以,数组传参的这种方式,可以实现,被调函数修改主调函数中的数据
排序:
#include<stdio.h>
void printfc(int a[],int len)
{
int i=0;
for(i=0;i<len;++i)
{
printf("%d\n",a[i]);
}
return;
}
void choiseSort(int b[],int len)
{
int i=0;
int j=0;
for(i=0;i<len;++i)
{
for(j=i+1;j<len;++j)
{
if(b[j]<b[i])
{
int t=b[j];
b[j]=b[i];
b[i]=t;
}
}
}
return;
}
int main(void)
{
int a[10]={2,1,5,3,7,9,6,8,4,10};
int len=sizeof(a)/sizeof(a[0]);
choiseSort(a,len);
printfc(a,len);
return 0;
}
冒泡
#include<stdio.h>
void printfc(int a[],int len)
{
int i=0;
for(i=0;i<len;++i)
{
printf("%d\n",a[i]);
}
return;
}
void choiseSort(int b[],int len)
{
int i=0;
int j=0;
for(i=len-1;i>0;--i)
{
for(j=0;j<i;++j)
{
if(b[j]>b[j+1])
{
int t=b[j];
b[j]=b[j+1];
b[j+1]=t;
}
}
}
return;
}
int main(void)
{
int a[10]={2,1,5,3,7,9,6,8,4,10};
int len=sizeof(a)/sizeof(a[0]);
choiseSort(a,len);
printfc(a,len);
return 0;
}
插入排序
#include <stdio.h>
void insertionSort(int arr[], int n) {
int i, key, j;
for (i = 1; i < n; i++) {
key = arr[i];
j = i - 1;
// 将大于 key 的元素后移
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
// 打印数组
void printArray(int arr[], int size) {
int i;
for (i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
// 测试插入排序
int main() {
int arr[] = {12, 11, 13, 5, 6};
int n = sizeof(arr) / sizeof(arr[0]);
insertionSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
return 0;
}