C语言高级技术、基础数据结构

第一周

周一无…没上课…

2020/8/4 DOS命令

DOS命令:(命令 查询:HELP 命令 / 命令/?
HELP ->帮助,罗列命令

DOS分为内部命令 (常用,在内存中) 与外部命令 (偶尔用,程序过大,一般在磁盘中,如 .exe .bat(批处理命令) .com .bin)

cmd 叫做命令解释器 命令提示符

DOS内部命令

0 转换盘符命令
转换盘符
1 DATE 日期命令 显示、修改日期
2 TIME 时间命令 显示、修改时间
3 VER->版本命令
ver
4 dir 命令 显示盘中的目录
dir
dir/?
忘记了命令的作用,或者要了解该命令的用法,在命令后加/?就可以了
在这里插入图片描述
help dir 帮助命令
老师的
在这里插入图片描述
我的(刚学,也不知道什么情况
知道是解析了,但是还是打不出来 /(ㄒoㄒ)/~~
就用命令+/? 也可实现相同功能啦 ~ )

在这里插入图片描述
help出现这种情况怎么办??
我目前只能这样设置path了,环境变量怎么设置都不行。(还失手把以前配置的所有都删了,试了好多方法都没找回,我的电脑path上只有那一个路径在这里插入图片描述
的时候才可以运行help,加别的都不行??)
哭哭/(ㄒoㄒ)/~~
解决办法:加上这句话 path=c:\windows\system32,然后再用help 虽然这不是长久之计 害…
在这里插入图片描述

dir /ah 显示隐藏项目
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
5 type 显示文本文件中的内容
只能用于显示文本文件中的内容
type
6 copy 复制文件
在这里插入图片描述
用于合成文件
在这里插入图片描述
一些小花样
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通配符 13 中详解。1

7 erase / del 删除文件 (不能用于删除文件夹
8 MD 创建文件夹
在这里插入图片描述
在这里插入图片描述

9 RD 删除文件夹

在这里插入图片描述

10 CD 改变位置 进入文件夹
在这里插入图片描述
11 . 一点为当前文件夹
… 两点为父级
在这里插入图片描述
12 绝对路径 CD、文件父\文件子
13 * 表示0~n个字符 通配符 ?表示一个字符
14 REN 改名字
在这里插入图片描述
改后缀名
在这里插入图片描述
15 xcopy 复制文件和目录树。
在这里插入图片描述
不拷空文件夹
在这里插入图片描述
拷空文件夹
在这里插入图片描述
16 文件名:
CON 控制台
作为输出就是输出到显示器
在这里插入图片描述
作为输入就是从键盘输入
在这里插入图片描述

NUL 空设备
在这里插入图片描述

COM 串口
PRN 并口(这两个不要使用

17 CLS 清屏

18 fc / comp 比较两个文件
在这里插入图片描述
(可用于查找两个程序之间的区别)
在这里插入图片描述
功能很多
在这里插入图片描述

19 find 查找字符串
在这里插入图片描述

20 sort 排序文件内容
在这里插入图片描述

21 color 调屏幕颜色
背景前景
在这里插入图片描述
在这里插入图片描述
程序中也可 变颜色
在这里插入图片描述
hrgb
22 move 移动文件
23 ctrl + break 终结
ctrl + c 强行结束
24 pause 暂停 ctrl + s 暂停
25 ctrl + p 打印
26 title 换标题
27 promrt $P $G
28 mode
29 输入命令搜索顺序 ->先看是否为内部,先.com->.exe->.bat->path->命令搜索路径:多条路径,“;”分号间隔
set xx=YY
30 设置路径
在这里插入图片描述

在这里插入图片描述

补充:一个还原C盘的DOS命令(8/6讲 8/13写…)
唉 不过录屏没录到。。蓝屏了
就这吧 以后再看
attrib
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2020/8/5 C数据类型

前面没怎么听 直接放杨大佬的笔记吧。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • float误差太大,少用
    在这里插入图片描述
  • 整数比较大的时候用long long int
    在vc++ long double 等价于double
    在dc++ long double 有问题 (Windows不行 Linux可以)
    PTA
  • scanf 和 printf 的区别
    在这里插入图片描述
    -判断x是否等于0.2?
    在这里插入图片描述

外部命令

###.com
###.exe
###.bat
在这里插入图片描述
在这里插入图片描述
1 tree 以图形显示驱动器或路径的文件夹结构
在这里插入图片描述

2

批处理命令

创建一个扩展名为 .bat文本文件
将要执行的一批DOS命令写入该文件中

输入批处理文件名(即批处理命令)
就可以按文件里学好的命令依次执行

echo
放在批处理命令中
echo off
echo on
隐藏命令

隐藏一条命令直接在批处理命令前加@
在这里插入图片描述
if命令

errorlevel

if errorlevel 1 goto error
goto end //如果主函数出口返回值不为0 则代表程序错误
连接main.c和fac.c进行编译成project.exe文件运行
在这里插入图片描述

在这里插入图片描述
for命令
在这里插入图片描述
在这里插入图片描述
pause 暂停
在这里插入图片描述
在这里插入图片描述
3 管道命令
pipe
在这里插入图片描述
命令 > 输出文件
命令 < 输入文件
命令1|命令2|命令3
(命令1输出作为命令2输入)

输出 > >>
新建一个out.txt 并输出out.txt文件中
在这里插入图片描述
在这里插入图片描述
< 输入
从控制台输入到 in.txt 中 用文件当键盘输入
在这里插入图片描述
从文件输入 从文件输出
在这里插入图片描述
刷题网站用的判断答案是否正确的方法
在这里插入图片描述
在这里插入图片描述
管道命令
type in.txt这个命令的输出 -> 作为test的输入 -> 输出到屏幕
在这里插入图片描述
4 more命令
逐屏显示输出。
在这里插入图片描述
在这里插入图片描述
打回车走一行 打空格走一页
5 shift命令 没听清楚 ? ?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

集成开发环境 DC++

编译程序 gcc.txt
路径 D:\Dev-Cpp\MinGW64\bin
在这里插入图片描述

序号命令用途生成
1gcc test.c编译(含预处理)并连接自动生成a.exe
2gcc test.c -o test.exe编译(含预处理)并连接生成**test.exe
3gcc -c test.c -o test.o编译生成目标文件test.o
4gcc test.c -o test.exe连接test.o和系统库生成test.exe
5gcc File1.o File2.o -o Project.exe连接File1.o、File2.o和系统库生成Project.exe
6gcc -E fac.c预处理显示结果
1
在这里插入图片描述
在这里插入图片描述
2
在这里插入图片描述

3 4
在这里插入图片描述

怎么建一个工程项目?

1
在这里插入图片描述
2
在这里插入图片描述
3
在这里插入图片描述
OK啦~~

程序相关

%f%g
3.23.2000003.2
3.03.0000003
cout << f; // 是%g的用法(c++中)
%e 。。

项目实例(求阶乘)

#include <stdio.h>

double Fac(int x);

int main(int argc, char *argv[]) 
{
	int n;
	double f;
	scanf("%d",&n);
	f = Fac(n);
	printf("%g\n",f); 
	return 0;
}

double Fac(int x)
{
	double y = 1.0;
	int k;
	for(k = 2; k <= x; ++k)
	{
		y *= k;
	}
	return y;
}

在这里插入图片描述
在这里插入图片描述
同名头文件,专门在fac.h中写声明,不被编译,“不起作用”。

dos命令编译运行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
预处理fac.c
gcc -E fac.c
可以看程序处理之后变成什么样了,从而知道自己怎么错了。
(gcc -E fac.c -o hh.txt 输出到txt中
gcc -E fac.c > hh.txt 一样 )
在这里插入图片描述
预处理后的main
在这里插入图片描述
宏替换
在这里插入图片描述

2020/8/6

C 库函数 - sscanf()

C 库函数 int sscanf(const char *str, const char *format, …) 从字符串读取格式化输入。
下面是 sscanf() 函数的声明。

int sscanf(const char *str, const char *format, …)
format – 这是 C 字符串,包含了以下各项中的一个或多个:空格字符、非空格字符 和 format 说明符。
在这里插入图片描述

C 库函数 - sprintf()

C 库函数 int sprintf(char *str, const char *format, …) 发送格式化输出到 str 所指向的字符串。

下面是 sprintf() 函数的声明。

int sprintf(char *str, const char *format, …)
str – 这是指向一个字符数组的指针,该数组存储了 C 字符串。
format – 这是字符串,包含了要被写入到字符串 str 的文本。
在这里插入图片描述

#include <stdio.h>
#include <string.h>
int main()
{
	char a[100];
	int x = 365;
	sprintf(a,"%d",x);
	printf("%s(%d)\n", a, strlen(a) );
	return 0; 
}
#include <stdio.h>
#include <string.h>
int main()
{
	char a[100] ;
	double x = 2049.578;
	sprintf(a, "%.2f", x);
	printf("%s(%d)\n", a, strlen(a));
	return 0;
}

输出字符串a 以及在括号中的字符串的长度
在这里插入图片描述
(这之前是8/13 来偷偷补充的,后面也有改进~)

不同内存中的变量

函数变量都在栈中
进栈出栈
(还没听…)

此图片来源:《深入理解C指针》2
在这里插入图片描述
变量类型
在这里插入图片描述
今天讲前两个~

int x; //<==>auto int x;
//auto不用写

register int k;//在 CPU里面的变量
register double f;
for(k=2;k<=n;++k)f*=k;//频繁访问k,就直接定义为寄存器变量,就不用在内存和CPU之间调来调去了,大大提升程序运行效率
//早期比较有用,现在意义不大,编译器有自动优化

把内存分为两个区域
栈 自动进行管理 返回地址 参数 函数值 局部变量
堆 手工分配内存 malloc / free

自动分配内原理

实例1

#include <stdio.h>

void G()
{
	int y;
	printf("%p\n",&y); //%p专门用来打印地址
}

void F()
{
	int x;
	printf("%p\n",&x);
	G();
}

int main()
{
	int a;
	printf("%p\n",&a);
	F();
	return 0;
}

运行结果:
000000000065FE1C
000000000065FDDC
000000000065FD9C

栈示意图(先进的在下面)(中间的空当有别的数据)
在这里插入图片描述

实例2

#include <stdio.h>

void G()
{
	int y;
	printf("y: %p\n",&y);
}

void F()
{
	int x;
	printf("x: %p\n",&x);
	G();
}

int main()
{
	int a;
	printf("a: %p\n",&a);
	G();
	F();
	return 0;
}

运行结果:
a: 000000000065FE1C
y: 000000000065FDDC
x: 000000000065FDDC
y: 000000000065FD9C
G退房之后,F住进来了,住到G的房间
在这里插入图片描述
实例3
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

0全部是垃圾值,不一定是0;102是G函数留下的垃圾值

实例4
在这里插入图片描述

函数参数(一级指针)

函数参数的生命周期问题
例1

/*
结果是0 ?还是1 ?
ans:0
*/
#include<stdio.h>
void F(int x)
{
	++x;
 } 

int main()
{
	int a = 0;
	F(a);
	printf ("%d\n",a);
	return 0;
}

F中x的改变与main中的a无关

Fx:0 -> 1
maina:0

函数名(表达式){ }
形参 - 参数
实参 - 表达式

//把F中的x换成a
#include<stdio.h>
void F(int a)
{
	++a;
 } 

int main()
{
	int a = 0;
	F(a);
	printf ("%d\n",a);
	return 0;
}

F中a的改变与main中的a无关

Fa:0 -> 1
maina:0
小结:局部变量在函数或代码块内定义的变量,仅在该函数或代码块内起作用。
不同函数或代码块内定义的同名的局部变量,是不同的变量。彼此毫无关系。
变量名可以同名,函数名不行。(c中)

例2
用(一级)指针 参数是a的地址

/*
ans:11 21
*/
#include<stdio.h>
void F(int *x)
{
	++ (*x);
	//优先级相同 不过不加括号也行 单目由右往左计算 
 } 

int main()
{
	int a = 10, b=20;
	F(&a);
	F(&b);
	printf ("%d %d\n",a,b);
	return 0;
}

课上小练习~~
在这里插入图片描述
选A!只要输出, 不用改。
在这里插入图片描述
B B 要修改

可变参数的函数怎么写?

(参数个数可变)
至少有一个参数。
加一个头文件 #include<stdarg.h>
arg:参数
Borland:Turbo C、Borland C++、C++ Builder
MS:Quick C、Visual Studio (Visual C++)、VS Code
F(a,b);
F(a,b,c,d)
从右往左传

栈 先取地址 ---- 参数怎么压栈的?
在这里插入图片描述
操作栈的函数

//取下一个参数
type va_arg(va_list argptr, type);
//少用   C99新标准中引入的“函数”
void va_copy(va_list target, va_ list source);
//将指针 argptr 指向 last_parm 的下一个参数
void va_start(va_list argptr,last_ parm);
//将指针 argtr 恢复为初始状态
void va_end(va_list argptr) ;

实例3 (参数不定)

#include<stdio.h>
#include<stdarg.h>

double sum(int n, ...);

int main(){
	double x,y,z;
	x = sum(0);
	y = sum(2,3.7,0.8);
	z = sum(6,3.9,7,0.8,2,3.7,0.8);
	printf("%g %g %g\n", x, y, z);
	return 0;
}

double sum(int n, ...)
{
	double s = 0.0, x;
	int k = n;
	va_list p; //头文件中的类型 定义好的 
	va_start(p,n); //宏替换 指向b了 。last_ parm
	while(k)  
	{
		x=va_arg(p, double);  //宏替换 取八个值 ,同时指针往后移八个
		s += x; 
		--k;
	}
	va_end(p); //还原 重新指向a 与strat相应 
	return s;
}

结果
3.7+0.8=4.5
在这里插入图片描述

//printf函数的声明
int __cdecl printf(const char * __restrict__ _Format,...);
//简化
int printf(const char *f,...);

在这里插入图片描述
在这里插入图片描述
选CCCC ! 我选对啦。嘻嘻 ~
注意前面有提到参数是从右往左传的。排除A、B。
a++是先传参数再++。a传完以后才变成三,在主函数里证明一下( ఠൠఠ )ノ
在这里插入图片描述
反过来为什么是333 ???
在这里插入图片描述

#include <stdio.h>

void F(int x, int y, int z)
{
	printf("%d %d %d\n", x, y, z);
} 

int main()
{
	int a=0;
	F(a++, a++, a++); 
	printf("%d\n",a);
	return 0;
}

2020/8/7

指针的使用


在这里插入图片描述
注意:不要调用pow(t,3),耗时,就用t* t* t
pow(t,3)=exp(3.0 * log(t))
在这里插入图片描述
三个都换成指针(不好,容易把 t 改掉)
在这里插入图片描述
a=5; —> *(&a)=5;
在这里插入图片描述
const int *p;
int const *p; 可交换位置
//常量的指针 指针p可以修改,但指针所指变量 *p不可以修改 p=25不可以
在这里插入图片描述
int const p=&a;
//常指针
在这里插入图片描述
const int
const p=&a;
//常量的常指针

这三个p有什么不同?? 还是不清楚。。
在这里插入图片描述
所以可以把上面例子里的*t改成const double *t 就比较安全
在这里插入图片描述

数组中的方括号

定义时
方括号表示数组,并给出尺寸,方括号不
使用时
方括号是下标运算符

数组名[下标]
*(数组名 + 下标)
地址[偏移量]
*(地址 + 偏移量)

double a[100];
a <===> &a[0]
a[k]<===>*(a+k)
#include<stdio.h>

int main()
{
	double a[5]={0.5,1.5,2.5,3.5,4.5};
	printf("%g\n", a[1]);
	printf("%g\n", *(a + 1));
	printf("%g\n", *(1 + a));
	printf("%g\n", 1[a]);
	
	printf("%g\n", (a + 2)[-1]) ;
	printf("%g\n", (&a[2])[-1]) ;

	return 0;
 } 

结果全是1.5
在这里插入图片描述
结果是b b

运用指针操作数组

在这里插入图片描述
写成函数
在这里插入图片描述
在这里插入图片描述

二级指针

#include <stdio.h>
#include <stdlib.h>

void Create(double **a, int n);
void Destro y(double **a); 
void Input (double *a, int n);
void Output(const double *a, int n);

int main()
{
	double *a;
	int n;
	scanf("%d", &n);
	
	Create(&a,n); //二级指针
	 
/*	//分配内存 
	a = (double*)malloc(n *sizeof (double)) ;
	if (a == NULL)
	{
		puts ("Not enough nenory!") ;
		exit( 1) ;//慎用 可以return 1; 
	}*/ 
	
	Input(a, n);
	Output(a, n);
	
	Destroy(&a); 
/*	//回收内存 
	free(a);
	a = NULL;  //已经退房了,a还指向那个房间,是非法的 
	*/ 
	return 0;
}

void Create(double **a, int n)
{
	*a = (double*)malloc(n *sizeof (double)) ;
	if (*a == NULL)
	{
		puts ("Not enough nenory!") ;
		exit(1); //以后换成善后 
	}
}

void Destroy(double **a)
{
	free(*a);
	*a = NULL; 
} 

void Input (double *a, int n)
{
	int k;
	for(k = 0; k< 10; ++k)
	{
		scanf("%lf",&a[k]);
		// 等于 scanf("%lf", a + k);
	}
}
void Output(const double *a, int n)
{
	int k;
	for(k = 0; k< 10; ++k)
	{
		printf("%g",a[k]);
		// 等于 printf("%g",k[a]);
	}
}

二维数组

在这里插入图片描述
地址的计算公式
在这里插入图片描述

#include<stdio.h>

int main()
{
	double a[3][4];//行主序
	
	// Input(a,3,4);
	
	for (i = 0; i < 3; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			scanf("%lg",&a[i][j]);
		}
	}
	
	// Output(a,3,4)
	
	for (i = 0; i < 3; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			printf("%lg",a[i][j]);
		}
	}
	return 0}
方法Ⅰ 以一维数组代二维数组
#include<stdio.h>

void Input(double *a,int m, int n);
void Output(const double *a, int m, int n);

int main()
{
	double a[3 * 4];//行主序
	Input(a, 3, 4);
	Output (a, 3, 4);
	return 0;
}

void Input(double *a,int m, int n)
{
	int i, j;
	for (i = 0; i < 3; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			scanf("%lg",&a[i * n + j]);
		}
	}
}

void Output(const double *a, int m, int n)
{
	int i,j;
	for (i = 0; i < 3; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			printf("%6.2",a[i* n + j]);
		}
		putchar('\n');
	}
}

在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>

void Create(double **a, int m, int n);
void Destroy(double **a);
void Input(double *a,int m, int n);
void Output(const double *a, int m, int n);

int main()
{
	double *a;//行主序
	int m, n;
	scanf("%d%d" ,&m, &n);
	Create(&a, m ,n);
	Input(a, m, n);
	Output (a, m, n);
	Destroy(&a);
	return 0;
}

void Create(double **a,int m, int n)
{
	*a = (double*)malloc(m * n * sizeof (double)) ;
	if (*a == NULL)
	{
		puts ("Not enough nenory!") ;
		exit(1); //以后换成善后 
	}
}

void Destroy(double **a)
{
	free(*a);
	*a = NULL; 
} 

void Input(double *a,int m, int n)
{
	int i, j;
	for (i = 0; i < m; ++i)
	{
		for (j = 0; j < n; ++j)
		{
			scanf("%lg",&a[i * n + j]);
		}
	}
}

void Output(const double *a, int m, int n)
{
	int i,j;
	for (i = 0; i < m; ++i)
	{
		for (j = 0; j < n; ++j)
		{
			printf("%6.2f",a[i* n + j]);
		}
		putchar('\n');
	}
}

运行结果:
在这里插入图片描述

方法Ⅱ 以指针数组代二维数组

在这里插入图片描述
double **a; //二级指针

#include <stdio.h>
#include <stdlib.h>

void Input(double **a,int m, int n);
void Output(double **a, int m, int n);

int main()
{
	double **a;
	int m,n,i,j;
	
	
	scanf("%d%d",&m,&n);
	a = (double**)malloc(m * sizeof( double*));
	for (i = 0; i < m; ++i)
	{
		a[i] = (double*)malloc(n * sizeof(double));
	}
	
	Input(a, m, n);
	Output(a, m, n);
	
	return 0;
}

void Input(double **a,int m, int n)
{
	int i, j;
	for (i = 0; i < m; ++i)
	{
		for (j = 0; j < n; ++j)
		{
			scanf("%lg",&a[i * n + j]);
		}
	}
}

void Output(double **a, int m, int n)
{
	int i, j;
	for (i = 0; i < m; ++i)
	{
		for (j = 0; j < n; ++j)
		{
			printf("%6.2f",a[i* n + j]);
		}
		putchar('\n');
	}
}

第二周

2020/8/10

一维数组与二维数组

在这里插入图片描述
一维

#include <stdio.h>

void Input(double *a,int n);
// void Input(double a[],int n); a[]不是数组  与上面一样 
// 参数是要放到栈中的 数组放不下 
void Output(const double *a, int n);
// void Ouput(const double a[], int n);

int main()
{
	int n;
	scanf("%d",&n);
	double a[n];
	Input(a, n);
	Output(a, n);
	
	return 0;
	/*
		允许变量中间定义
	*/
 } 
 
void Input(double *a,int n)
{
	int k;
	for (k = 0;k < n; ++k)
	{
		scanf("%lf", &a[k]);
	}
}
void Output(const double *a, int n)
{
	int k;
	for (k = 0;k < n; ++k)
	{
		scanf("%8.2f", a[k]); //double输出不加 l 
	}
}

二维

#include <stdio.h>

void Input(int m, int n, double (*a)[n]) ;//行指针 
void Output(int m, int n, double (*a)[n]) ;


int main()
{
	int m,n;
	scanf("%d%d", &m, &n);
	double a[m][n];
	Input(m, n, a);
	Output(m, n, a);
	
	return 0;
}

void Input(int m, int n, double (*a)[n])
{
	int i,j;
	for (i = 0; i < m; ++i)
	{
		for (j = 0; j < n; ++j)
		{
			scanf("%lf", &a[i][j]);
		}
	}
}

void Output(int m, int n, double (*a)[n])
{
	int i,j;
	for (i = 0; i < m; ++i)
	{
		for (j = 0; j < n; ++j)
		{
			printf("%8.2f",a[i][j]);
		}
		putchar('\n');
	}
}

两者不同 ?
double (*a)[n];
double *a[n];

函数指针

什么是函数?
在这里插入图片描述
什么是函数指针?
在这里插入图片描述
进一步了解函数指针
在这里插入图片描述
函数指针的使用
例1

#include <stdio.h>

double Fac(int n);
double Fib(int n);

int main()
{
	int n;
	double f;
	double (*p)(int n); //定义函数指针
	
	printf("n= ?");
	scanf("%d", &n);
	
	p= Fac;
	f= (*p)(n);  //调用所指函数
	printf("f= %g\n");
	p= Fib;
	f = (*p)(n);  //调用所指函数
	printf("f= %g\n");
	return 0;
}

double Fac(int n)
{
	double f= 1.0;
	int k;
	for (k=2;k<= n; k++)
	{
		f*=k;
	}
	return f;
}

double Fib(int n)
{
	double f1= 1.0, f2=1.0, f= 1.0;
	int k;
	for (k=3;k<= n; k++)
	{
		f = f1 + f2;
		f1 = f2;
		f2 = f;
	}
	return f;
}

例2(与上指针类型不一样)
在这里插入图片描述
定积分
在这里插入图片描述
改成 s = 0.0
实数运算 用 0.5* 不要用 / 2 (/ 2.0) 实数除法慢得多
整数运算不要用 0.5*

C语言有优化功能
在这里插入图片描述
逐渐听不懂…
在这里插入图片描述
在这里插入图片描述

本人已崩溃。。。இ௰இ

下午
在这里插入图片描述
double *

#include <stdio.h>
void Input(double *a, int n);
void Output(const double *a, int n);
int Max(const double *a, int n);

int main()
{
	double a[100];
	int n, k;
	scanf("%d", &n);
	Input(a, n);
	Output(a, n);
	k = Max(a, n);
	printf("Max = %g\n", a[k]);
	printf("k = %d\n", k);
	return 0; 
}
void Input(double *a, int n)
{
	int k;
	for(k = 0; k < n; ++k)
	{
		scanf("%lf", &a[k]);
	}
}

void Output(const double *a, int n)
{
	int k;
	for (k = 0; k < n; ++k)
	{
		printf("%6.2f", a[k]);
	}
	
	putchar('\n');
}

int Max(const double *a, int n)
{
	int p = 0, k;
	for (k = 1; k < n; ++k)
	{
		if (a[k] > a[p])
		{
			p = k;
		}
	}
	return p;
}

在这里插入图片描述
int *
在这里插入图片描述
char *

怎么跨越变量类型?

写出通用的输入函数
使用 void *
void *q;

原C语法中的比较函数

int strcmp(const char *s,const char *t);

自己写的比较函数

#include <stdio.h>
#include <math.h>

#define eps 1e-8

void Input(void *a, int n, int size);
void Output(void *a, int n, int size);
int Max(void *a, int n, int (*Cmp)(const void *x,const void *y), int size);

int RealCmp(const void *x, const void *y);

int main()
{
	double a[100];
	int n, k;
	scanf("%d", &n);
	Input(a, n, sizeof(double));
	Output(a, n, sizeof(double));
	k = Max(a, n, RealCmp, sizeof(double));
	//printf("Max = %g\n", a[k]);
	printf("k = %d\n", k);
	return 0; 
}

void Input(void *a, int n, int size)
{
	int k;
	for(k = 0; k < n; ++k)
	{
		scanf("%lf", a + k * size); //&a[k] <=> a+k
	}
}

void Output(void *a, int n, int size)
{
	int k;
	for (k = 0; k < n; ++k)
	{
		printf("%6.2f", *(double *)(a + k * size));
	}
	putchar('\n');
}

int Max(void *a, int n, int (*Cmp)(const void *x,const void *y), int size)
{
	int p = 0, k;
	for (k = 1; k < n; ++k)
	{
		if (Cmp(a + k * size, a + p * size) > 0) // a[k] > a[p]
		{
			p = k;
		}
	}
	return p;
}

int RealCmp(const void *x, const void *y)
{
	int r; 
	if (fabs(*(double *)x - *(double *)y) < eps) //eps 误差值 
	{
		r = 0; //不要写成return r; 一个入口 一个出口 结构化的流程图 
	}
	else if (*(double *)x > *(double *)y)
	{
		r = 1;
	}
	else
	{
		r = -1;
	}
	return r;
}

在这里插入图片描述
改进代码

在这里插入图片描述

2020/8/11

穷举法/枚举法/完全归纳法

#include <ctype.h>
isupper,islower,isalpha,isdigit,isspace
空格、水平制表、垂直制表、回车、换行、换页 
n is a prime

在这里插入图片描述
改进

int IsPrime(int n)
{
	int ok = n > 1;
	int k, m = sqrt(n) + eps;
	for (k = 2; ok && k <= n; ++k)
	{
		ok = n % k != 0; 
	 } 
	return ok;
 } 

在这里插入图片描述
在这里插入图片描述
运用逻辑运算

/*
	张老师、王老师和孙老师分别教三门课:语文、数学和外语,但不知道他们具体教哪门课 ,只知道 
	张老师上课全部用汉语__
	外语老师是个学生的哥哥
	王老师是女老师,她向数学老师问了一个问题_
	  根据以上情况分析这三名老师分别教什么课?
	  
	用整数表示课程: 1 -语文,2-数学,3_-外语
	用变量z, w, s分别表示张老师、王老师和孙老师所教课程
	使变量z, w, s穷举所有可能,判断是否符合条件:_
	1) z ? w且_z ? s且 w ?_s三位老师所教课程各不相同
	2) z ? 3张老师不教外语
	3) w ? 3且 W ? 2王老师不教外语、数学
*/

#include <stdio.h>

int main()
{
	int z, w, s;
	for (z = 1;z <= 3; ++z)
	{
		if (z != 3)
		{
			for (w = 1; w <= 3; ++w )
			{
				if (w != 3 && w != 2 && w != z)
				{
					s = 6 - z - w;
					printf("%d%d%d\n", z, w, s);
				}
			}
		}
	}
	return 0;
}
/*
	体育之家
	老张家是体育之家, 三个儿子分别在科技学院、艺术学院和财经学院读书,他们分别打足球、篮球和排球。
已知:
	老大不在科技学院读书,
	老二不在艺术学院读书,
	打排球的儿子不在财经学院读书,
	打足球的儿子在科技学院读书,
	老二不打足球。
	请问张家三个儿子分别在什么学校读书?分别打什么球?
*/

#include <stdio.h>

int main()
{
	int a0, b0, c0; //老大老二老三就读的学校 (0-科技, 1-艺术 ,2-财经)
	int a1, b1, c1; //老大老二老三所玩的球 (0-足球,1-篮球,2-排球) 
	
	for (a0 = 0; a0 <3; ++a0)//老大学校三种循环 
	{
		for (b0 = 0; b0 < 3; ++b0) //老二学校三种循环 
		{
			if (b0 != a0) //老大学校不等于老二学校 
			{
				c0 = 3 - a0 -b0; //三人所读的学校互斥 
				for (a1 = 0; a1 < 3; ++a1)  //老大球三种循环 
				{
					for (b1 = 0; b1 < 3; ++b1) //老二球三种循环 
					{
						if (b1 != a1) //老大球类不等于老二球类 
						{
							c1 = 3 - a1 - b1; //三人玩的球互斥 
							
							if(a0 != 0 //老大不在科技学院读书 
							&& b0 != 1 //老二不在艺术学院读书
							&& ((a1 != 2 || a0 != 2)
								&& (b1 != 2 || b0 != 2)
								&& (c1 != 2 || c0 != 2)
							   )//打排球的儿子不在财经学院读书(要么不打排球,要么不在财经学院读书) 
							&& b1 != 0 //老二不打足球
							&& ((a1 == 0 && a0 == 0)
								|| (b1 == 0 && b0 == 0)
								|| (c1 == 0 && c0 == 0)
							   )//打足球的儿子在科技学院读书
							 )
							{
								printf("%d%d%d\n",a0,b0,c0);
								printf("%d%d%d\n",a1,b1,c1);
							}
						}
					}
				 } 
			}
		}
	}
	return 0;
}

害,越来越难了,越学越发现自己好辣鸡哇。
啥都不知道,很多知识都要补充呜呜。
但是最重要的是坚持啦,不管怎么样要坚持下去!!

用减法的方法把字符变成数字

在这里插入图片描述
在这里插入图片描述
format 格式

用循环

#include <stdio.h>

void ScanDec(int *x)
{
	int s = 0, d;
	char c;
	while (c = getchar(), isdigit(c))
	{
		d = c - '0'; //'50' - '48' = 2
		s = s * 10 + d;
	}
	*x = s;
}

int main()
{
	int x;
	ScanDec(&x); // scanf("%d", &x); //假设输入 25376 
	printf("%d\n",x);
	return 0;
}

25376

2020/8/12

递归显示字符

#include <stdio.h>

void Show(int n,char c)
{
	if (n > 0)
	{
		Show(n - 1,c);
		putchar(c);
	}
 } 

void Para1(int w, int h, int s, char c)
{
	if (h > 0 && w > 0)
	{
		Para(w, h-1, s + 1, c);
		Show(s, ' ');
		Show(w,c);
		putchar('\n'); 
	} 
}

void Para(int w,int h, char c)
{
	Para1(w, h, 0, c);
}

int main()
{
	Para(15,5,'*');
	return 0;
}

在这里插入图片描述
反向四边形
在这里插入图片描述

八皇后问题 回溯

国际象棋的棋盘
在这里插入图片描述

在n*n 的棋盘上摆上n个皇后,使它们相互不能吃掉对方

//八皇后问题
//在n*n的棋盘上摆上 n个皇后,使它们互相之间不能吃掉对方 
#include <stdio.h>

int z = 0;//计数 

//显示棋盘 
void Show(char (*a)[100], int n)
{
	int i, j;
	putchar('\n');
	++z;
	printf("No.%d:\n", z);
	for (i = 0; i < n; ++i)
	{
		for (j = 0; j < n ; ++j)
		{
			putchar(' ');
			putchar(a[i][j] ? 'Q' : '.');
		}
		putchar('\n');
	}
	putchar('\n');
 } 

// 判断棋盘 第i0行 第j0列的位置是否安全
int IsSafe(char (*a)[100], int n, int i0, int j0)
{
	int safe = 1;
	int i, j;
	// 检查i0前面的所有行第j0列有无皇后 
	for (i = i0 - 1; safe && i >= 0; --i)
	{
		safe = !a[i][j0]; 
	} 
	
	// 检查i0前面所有行主斜线 (左上到右下)上有无皇后
	for (i = i0 - 1, j = j0 - 1; safe && i >= 0 && j >= 0; --i, --j)
	{
		safe = !a[i][j];
	}
	
	// 检查i0前面所有行副斜线 (右上到左下)有无皇后
	for (i = i0 - 1, j = j0 + 1; safe && i >= 0 && j < n; --i, ++j)
	{
		safe = !a[i][j];
	}
	return safe;
}

void Queen(char (*a)[100], int n, int r)
{
	int k; 
	if(r == n)
	{
		Show(a, n);
	}
	else
	{
		for (k = 0; k < n; ++k)
		{
			if (IsSafe(a, n, r, k))
			{
				a[r][k] = 1;
				Queen(a, n, r + 1);
				a[r][k] = 0;
			}
		 } 
	} 
}

int main()
{
	char a[100][100] = {0};
	int n;
	scanf("%d", &n);
	Queen(a, n, 0);
	return 0;
}

在这里插入图片描述
下午没听课,后续会补充的(o_ _)ノ

2020/8/13

今天学长讲课嘿嘿嘿~
可是学长讲的好无聊,感觉到他很用心了,但是很无聊~

C++ STL

Standard Template Library
11个容器+算法+迭代器

1.vector

另一个同学写的详细的vector操作讲解

还发现了这个童鞋写的数据结构目录 存一下
数据结构-算法-STL_目录

动态的数组 随意添加删除元素、数组大小

#include <iostream>
#include <vector>
using namespace std;

//全局 变量没有初值的话能够为0的全部是0 
int a[10][10];
//bool类型 true  false
bool flag = true, f = false;
/* 
if (flag) {
	//true进入该语句 
} else {
	//false进入该语句 
}*/ 

int main()
{
	cin >> n; 
	cout << 0 << endl; 
	// vector<int> vec(n);定义了一个大小为n 元素全部为0 名叫vec的vector容器 
	vector<int> vec(n,  1); 
	vector<int> vec3(n,  1); 
	// 定义了一个  N*N名叫vec2的二维vector容器 
	vector<vector<int> > vec2(n, vector<int>(n, 0); //要打空格  因为sin>> 
	//三维的怎么定义?
	
	//operators
	vec.at(5); ==vec(5); //at会进行安全检查、不会溢出、不会访问到异常值 
	vec.clear();//清空
	vec.empty(); //判断该容器是否为空 、返回的是 bool 类型
	//重点 
	vec.erase(s.begin() + a);//删除vec[a]
	vec.erase(s.begin() + a, s.begin() + b);//删除vec[a]到vec[b]所有的元素
	vec.insert(pos, x);//在第pos位插入x 
	vec.insert(pos, vec3.begin(), vec3.end());//在第pos位插入一个区间 
	vec.insert(pos, n, x);//在第pos位插入n个x 
	
	
	vec.front();//返回vec的第一个元素 = vec[0];
	vec.back();//返回vec的最后一个元素
	vec.pop_back();//删除最后一个元素 
	vec.push_back(x);//在末尾加入一个元素 
	
	vec.size();//返回数组大小 
	vec.resize(s); //重设数组大小为n 
	
	return 0;
 } 
2.队列
#include <queue>
#include <iostream>
using namespace std; 

int main()
{
	//定义一个que 的队列
	queue <int> que;
	que.push(x);//在队列里面加入x
	que.pop();//删除队首的元素
	que.front();//访问队首元素
	que.empty();//判断队空?
	que.size();//放回队列元素个数
	que.back();//访问队尾元素
	return 0;
}
3.栈
#include <stack>
using namespace std;
int main()
{
	//定义栈
	stack<int> s;
	s.push(x);//栈中加入元素
	s.pop();//删除栈顶元素
	s.empty();//判断容器空?
	s.size();//栈大小
	s.top();//访问栈项元素
	return 0;
}
4.双向队列
#include <deque>
using namespace std;

int main()
{
	//定义一个名为d的双向队列
	deque<int> d;
	d.at(a);
	d.back();//队尾元素
	d.clear();
	d.empty();
	d.erase();
	d.front();
	d.insert();
	
	d.pop_ back();//删除队尾
	d.pop_ front();//删除队首
	d.push_ back(x);//加入队尾
	d.push_ front(x);//加入队首
	
	d.resize();
	d.size();
	return 0;	
}
5.优先队列
#include <queue>
using namespace std;

int main()
{
	//元素为int容器为vector,优先级 为greater<int>, less<int>
	//greater<int>小的优先
	//less<int>.大的优先
	priority_ queue<int, vector<int>, greater<int> > que;
	que.empty();
	que.pop();
	que.push();
	que.size();
	que.top();
	return 0 :
}

学长推荐了一个刷题网站 全英文的
http://judge.u-aizu.ac.jp/onlinejudge/
在这里插入图片描述
还有这个
http://poj.org/
在这里插入图片描述
下午木有课 嘻嘻 ε=ε=ε=(~  ̄▽ ̄)~

后记 小知识

1 不区分大小写
2 按向上键 可以翻到以前发出的命令
3 exit 退出
4 文件说明 前面是路径 后面再给出文件名
5 回到根目录 CD
6 temp 临时文件 存在这里
7 有空格 加 “”
在这里插入图片描述
8 头文件打开方式
按下ctrl 用鼠标点开
9 devc++中ctrl+m分屏
ctrl可以在同名的.c文件和头文件之间切换

推荐书籍

在这里插入图片描述

在这里插入图片描述


  1. *表示0~n个字符 通配符 ?表示一个字符 ↩︎

  2. 在推荐书籍里 ↩︎

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值