C语言基础语法复习-第一遍
C语言复习代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "stdlib.h"
#include <windows.h>
#include <process.h>
#include <time.h>
#include <locale.h>
#include <math.h>
#include <windows.system.h>
#include <stdbool.h>
#include <time.h>
#include <stdarg.h>
#define NMB 100
#define N 1024
#define path "D:\\Database\\1E.txt"
typedef unsigned long int ULI;
//进制问题,刚开始学C的时候第一步内容
void binary()
{
signed short int x = 10;
signed int y = 100;
signed long z = 1000;
signed long long u = 10000;
printf("%hd ", x); printf("%d\n", sizeof(x));
printf("%d ", y); printf("%d\n", sizeof(y));
printf("%ld ", z); printf("%d\n", sizeof(z));
printf("%lld ", u); printf("%d\n", sizeof(u));
printf("%u ", _CRT_INT_MAX);
printf("%u\n", INT_MIN);
printf("%a\n", x);
printf("%#o\n", x);
printf("%#x\n", x);
printf("%#d\n", x);
double xm = 1.23242342562343253452345234523452345234523632513254325342;
for (int i = 0; i < 200; i++)
{
printf("%.*f\n", i, xm);//小数位从变量列表中取值
}
//2019.10.9 xcode platform
char *str6[5] = { "winver","calc","devmgmt.msc","notepad","fine" };
char **p = str6;
/* 这里存放的是第n个字符串的地址,而不是本身内容,指针数组的本质在于存放指针,批量修改指针,达到不损害原来数据的目的,也能同时修改一些想要的特性。原来普通数组的名字就是指针,指针数组名更加是指针了,str就是一个指针,存放的是第一个winver的地址,害,指针数组的名字当然是二级指针啦,不用写方括号,直接来二级指针定义一个名字就行了。*/
printf("%p %p %p\n", str6[0], str6[1], str6[2]);
int num = 012;
printf("%d\n", num);
int num1 = 0x12;
printf("%d\n", num1);
double num2 = 012; //can not handle the number above the eight
short int num3 = sizeof(SHRT_MIN);
short int a = SHRT_MAX;
signed int rate = 4.9999f;
printf("%d", sizeof(unsigned short int));
printf("%f", 12.1);
printf("%d", 12.1);
short b = USHRT_MAX;
printf("%d\n", rate); //short can only hold 4byte(32bit)
printf("catch up short int = :%d", sizeof(b));
getchar();
/*
short
int
long
long long
float
double
char
byte
*/
float aX = 10.3;
float bX = 22.9;
//int num3 = (int)aX + bX;
int ak = (int)(aX + bX);
int m4 = 97;
//printf("%d,%d,%c", num, num1, num2); // 32 ,33?
putchar('\a');
putchar('\101');
putchar('\x42');
putchar('\n');
*(int*)(&x) = 99;//把地址(右值)强行改为int*类型,再解引用取出值,这个解引用出来的值是可以改变的,就是说const是个假的const
printf("x address is:%p\n", &x);
printf("x=%d", x);
//以下代码相当于 int a = 15; 注意中央处理器中寄存器的操作, ax寄存器和内存赋值变量的关键
//不能用a + 1 = 2这种代码就是因为a + 1不是变量, 只有变量能从寄存器中获得值, 内存中只能对变量操作.
//_asm
//{
// mov eax, 15
// mov a, eax//相当于c语言里面int a ; a=15;
//}
//result: const is not absolute constant, because it can be changed by *(int*)etc; *can stratch the content by address, and (int*)can transfer the type of the parameter
//..................................................
char abc[100] = { 0 };
char riven[59] = { 0 };
scanf("%3s%2s", abc, riven);
printf("%s\n%s\n", abc, riven);
int m60 = 0;
unsigned char gtx = 255; //unsigned char 只有一个字节(byte),就是8位,显然最大只能存储255,最小是0,一共2^8个元素啊
scanf("%d", &num1);
printf("num1=%i\n", num1);
char str[9] = { 0 };
_itoa(num1, str, 2); // 用字符串来接收整数,不同进制的数处理过后当作字符串来保存在字符型数组中的一个函数
printf("%s\n", str);
printf("%f\n", (float)(num1));
_itoa(num1, str, 5);
printf("%d\n", gtx);
//.............................................................
unsigned int aT = -2;
printf("%u,%p\n", aT, &aT); //无符号用%u打印,这玩意打印的是补码
printf("%d\n", sizeof(aT)); // DWORD 四字节== 双字,四字节
for (int i = 0; i < aT; i++) //
{
printf("hello russul");
}
printf("%d\n", aT);
}
//2020-5-22
void 十级指针初次见面()
{
int a = 10;
int b = 15;
int *p = &a;
int **pp = &p;
int ***ppp = &pp;
int ****p4 = &ppp;
int *****p5 = &p4;
int ******p6 = &p5;
int *******p7 = &p6;
int ********p8 = &p7;
int *********p9 = &p8;
int **********p10 = &p9;
****p5 = &b; // can saw as 1-level pointer like p: ****p5 equals to p
********p10 = &p;//like a 2-level pointer ,nice
**pp = 3;//unknown perameter int value is 3;
*pp = &a;
printf("a=%d address of a is %p", a, *pp);
//printf("%d %p",*****p5,p5);
const int c = 30;
//ppp=&b; //it only can store 2-level pointer value?
int const *p1; //pointer can be changed ,but value not
const int *p2; //pointer can be changed ,but value not
int *const p3 = &a; //maze perameter like ,pointer can not be changed,pointer can not be changed,while value can be changed ,shu zu
//int const*const p5; //do nothing
//const int*const p6;//do nothing
}
//...........................declearation.....................
//***************************2020.6.20(六,珍珠园)***************************
char **g_pp;//全局二级指针变量
int imax = 8;
int jmax = 12;
char str[10] = "1267";
int ipos = 1;
int maze[10] = { 58,6,3,17,13,8,0,22,9,91 };
//const int num3 = 100;
//int ax[num3];
// *(int*)&num3 = 3;
//
//
void writefile()
{
system("tasklist >> d:\\Code\\1.txt");
}
void findqq()
{
char str[4096];
scanf("%4096s", str);
char *p = strstr(str, "Wechat.exe");
if (p == NULL)
{
printf("wei xin not \n");
}
else
{
printf("yes\n");
}
}
void keyboard()
{
keybd_event(0x5b, 0, 0, 0);
keybd_event('M', 0, 0, 0);
keybd_event('M', 0, 2, 0);
keybd_event(0x5b, 0, 2, 0);
}
void open_google_website()
{
ShellExecuteA(0, "open", "https://www.google.com", 0, 0, 1);
}
void 数组大小用const变量来定()
{
unsigned int riven = 10;
const unsigned vampire = 10;
int *parr[N];
int arr[N];
}
void nvidia()
{
int a = 3;
for(2;!a;printf("continue"));
}
//typedef unsigned long int NUM;
void pointer_matrix()
{
int num = 0;
int(*p)[10] = (int(*)[])malloc(sizeof(int) * 30);// matrix pointer,instead of normal pointer,especially 2 dimentional maze.指针数组变量,这个p本身相当于二级指针,行指针的意思,当然可以后面跟两个下标符号当作二位数组了,这里就是int型的二维数组
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 10; j++)
{
p[i][j] = num++;
printf("%3d", p[i][j]);
}
printf("\n");
}
void*p1 = malloc(32345678909999);//nearly 29TB ??
printf("%p", p1);
}
void show_str(char **str)
{
for (int i = 0; i < 5; i++)
{
printf("%s\n", str[i]);
}
}
void two_dimentional_maze()
{
int(*p)[5] = (int(*)[5])malloc(sizeof(int) * 30);//给5列,这里的5好像还是需要的,毕竟是行指针,一行有几个元素是需要知道的
for (int i = 0, num = 0; i < 30; i++, num++)
{
printf("5%d ", p[i / 5][i % 5] = num);
if ((i + 1) % 5 == 0)
{
putchar('\n');
}
}
}
void two_dimentional_maze2()
{
int **pp = (int **)malloc(sizeof(int *) * 5);
int num = 0;
for (int i = 0; i < 5; i++)
{
pp[i] = (int *)malloc(sizeof(int) * 5);
num++;
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%4d ", pp[i][j]);
}
}
//2020.6.17
int **pp2 = (int **)calloc(3, 4);
for (int i = 0; i < 3; i++)
{
pp2[i] = (int *)malloc(4 * (sizeof(int)));
}
int num1 = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", pp2[i][j] = num1++);
}
printf("\n");
}
}
//function pointer
void runmsg()
{
printf("hello world!");
}
//数组名作为函数参数,退化为指针形式
void run(int a[5])
{
printf("%\nfun=%d", sizeof(a));
a = a + 1;
int b[5];
}
//函数指针数组
int getmax(int a, int b)
{
return a > b ? a : b;
}
int getmin(int a, int b)
{
return a < b ? a : b;
}
//2020.6.18 函数指针数组
int func_pointer()
{
int(*p)(int a, int b) = getmax;
int(*p2)(int a, int b) = getmin;
p(3, 4); // p3 p3+1 p3+2 p3+3 p3+4
int(*p3[2])(int a, int b) = { getmax, getmin};//函数指针数组里的每一个函数都会被指针所代表,函数名不需要,因为指针的存在省去了函数名和数组名。p3是函数指针数组名,这里的*的存在是因为存放的每个元素都是函数指针类型
printf("%ld ", sizeof(p3));// 64bit OS ,equals to 48
for (int i = 0; i < 6; i++)
{
printf("\n%d", p3[i](100, 10)); //p3[i]是一个函数指针类型
printf("\n%d", (*(p3 + i))(100, 10));//等价写法
}
printf("\n");
for (int(**pp)(int, int) = p3; pp < p3 + 5; pp++)
{
printf("\n%d", ((*pp)(100, 10)));//p3自己是二级,函数名本身是一级指针,降级到一级即可,解引用一次,千万别别解两次,注意逻辑
}
return 0;
}
// Created by novigard on 2020/5/9.
void srand_time_seed()
{
time_t ts;
unsigned int data = time(&ts);
srand(data);
int a[100];
for (int i = 0; i < 100; i++)
{
a[i] = rand() % 100;
printf("%d\n", a[i]);
}
/*
int number;
time_t ts;
unsigned int data = time(&ts);
srand(data);
number = rand() % 100 + 1;
int guess = 0;
while (guess != number)
{
scanf("%d", &guess);
if (guess == 4)
{
abort();
}
if (guess<number)
{
puts("small");
}
else if (guess > number)
{
puts("larger than");
}
else
{
printf("yes");
}
}
*/
}
void init_maze()
{
int a[3][4];
int num = 0;
//initilize solution 1
for (int *p = &a[0][0]; p < &a[0][0] + 12; p++)
{
*p = num;
num++;
}
//initilize solution 2
for (int i = 0; i < 12; i++)
{
a[i / 4][i % 4] = num;
num++;
}
//print the matrix
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", a[i][j]);
}
}
}
void sec(const int *p) //if has const ,only read
{
//常量不可以当作左值,虽然这个const修饰的玩意是个伪常量,也不行
//*p = 10;
//上面一行错误
}
void pointer_maze()
{
int a[3] = { 1, 2, 0 };
int *p[3] = { &a[0], a + 1, a + 2 };//a[0]相当于*(a+0),就是a+0解引用,a+0解引用之后取地址就是再次引用回去,又变成指针类型了,升级类型,解引用是降级类型
for (int i = 1; i < 3; i++)
{
for (int j = 0; j < 3 - i; j++)
{
if (*p[j] > *p[j + 1])
{
int *ptmp = p[j];
p[j] = p[j + 1];
p[j + 1] = ptmp;
}
}
}
for (int k = 0; k < 3; k++)
{
printf("%d ", a[k]);
}
printf("\nnew\n");
for (int i = 0; i < 3; i++)
{
printf("%d ", *p[i]);
}
}
void input_p()
{
int data = 50;
printf("%p", &data);
int *p = NULL;
//*p=2;
scanf("%p", &p); //give value to the pointer p , if p has value ,then *p can be showed by printf function.let p point to data by scanf function.
printf("data=%d", *p);
//system("pause");
}
//2020.6.15
void getPointer()
{
int a[5] = { 3, 1, 0, 2, 4 };
int b[2][3] = { 0,1,2,3,4,5 };
int *p1 = a;//这里p1与a是同类型,这是关键,他们都是一级指针类型
int *p2 = a + 3;
printf("%p\n", p1);
(*p1)++;
printf("%d", *p1);
// part 2/
// b内容就是地址,b的地址就是代表自己,是二级指针的意思,b本身就是放地址的变量?b是行指针
printf("b=%p,&b=%p,*b=%p\n", b, &b, *b);
printf("b+1=%p,&b+1=%p,*b+1=%p", b + 1, &b + 1, *b + 1);
for (int i = 0; i < 5; i++) {
p1[i] = *(a + i);
printf("%d ", p1[i]); // positive direction give the value to the pointer matrix,p2p mapping may be
}
printf("\n");
// to change the matrix of pointer ,nonetheless original maze
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4 - i; j++) {
if (p1[j] > p1[j + 1]) {
int *ptemp = p1[j];
p1[j] = p1[j + 1];
p1[j + 1] = ptemp;
}
}
}
for (int i = 0; i < 5; i++) {
printf("%d ", p1[i]); //p1[i]'s every value is int number of the matrix
}
for (int i = 0; i < 5; i++)
{
printf("%d ", a[i]);
}
// part 3/
int zz[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int yy[3][5];//第一次复习,先歇会。。。。
int(*p)[4] = zz;//this pointer can point to line of zz,把解引用提高优先级了,显然,这里p是一个数组指针,行指针
int *px = *zz;//二级指针给解了一级,一级指针,当然是行指针(*zz)整体是一个行指针类型,看好了,是整体
int *py = &zz[3][5];
printf("%p\n", px);
printf("%p ,%p\n", px, px + 1); //line pointer
printf("%p ,%p\n", zz, zz + 1); //same as the 'p' == line pointer
printf("%p ,%p\n", &zz, &zz + 1);//all pointer 是一个二级指针吧
printf("%p ,%p\n", py, py + 1); //column pointer
printf("%d ,%d\n", *zz[6], *zz[0] + 1);
//a + i == &a[i] a下标i元素的地址通过a+i来找到,这俩一样的
//below is the question test~~
printf("%p ,%p\n", zz, *zz);
printf("%p ,%p\n", zz[0], *(zz + 0)); printf("%p ,%p\n", zz[2], *(zz + 2));
printf("%p ,%p\n", &zz[0], &zz[0][0]);
printf("%p ,%p\n", zz[1], zz + 1);
printf("%p ,%p\n", &zz[1][0], *(zz + 1) + 0);
printf("%p ,%p\n", &zz[2], zz + 2);//用的时候才存在升级和降级,这里直接给下标降了一级,再取地址又升了一级,等于没升没降
printf("%d ,%d\n", zz[1][0], *(*(zz + 1) + 0));//两边都解两次,语法上没问题,意义也相同
printf("%d ,%d\n", *zz[2], *(*(zz + 2) + 0));
//2020.6.16 traverse_maze()
int tmp = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
//yy[i][j]=tmp++;
yy[i][j] = tmp++;
printf("%3d ", *(*(yy + i) + j));
}
printf("\n");
}
// malloc free
int n;
scanf("%d", &n);
int *pb = (int*)malloc(n*sizeof(int));
for (int i = 0; i < n; i++)
{
pb[i] = i;
printf("%d ", pb[i]);
}
free(pb);
// infinite malloc 一直分配内存
while (1)
{
void *pc = malloc(1024 * 1024);
}
}
/*
函数指针和代码区地址联系
函数指针变量和数据区地址相连。
*/
//函数.指针.数组 的一些应用
void pointer_knowledge()
{
int a[6] = { 9,2,0,4,7,9 };//数组名理论上是一个常量,不可以作为左值获取其他参数的值,实际上就是指针,或者说类似于引用的东西,没法当作左值来用,没有内存实体
printf("%d\n", sizeof(a));//数组没有副本机制,作为参数退化为指针,这时就可以当作左值了
}
void reverse_maze_with_pointer(int *p, int length)
{
for (int *phead = p, *pback = phead + length - 1; phead <= pback; phead++, pback--)
{
int tmp = *phead;
*phead = *pback;
*pback = tmp;
}
}
void reverse_maze_with_flag(int a[], int length)
{
for (int i = 0; i < length / 2; i++)
{
int tmp = a[i];
a[i] = a[length - i - 1];
a[length - i - 1] = tmp;
}
}
void byte_ocupy()
{
char a = 'a';//字符变量a占用(1byte)
wchar_t wct = L'我';//宽字符变量(2byte) 而 ‘A’作为字符常量占4byte
char *p = "hello world";//p 占4byte 和字符常量‘A’一样,直接打印某个字符是当作右值常量来打印,4byte,赋给左值变量就变成变量的大小了(1-2byte)
int fine = 2;
printf("%d,%d,%d,%d,%d,%d", sizeof(a), sizeof('A'), sizeof(""), sizeof("ABCDE"), sizeof("我"), sizeof(wct), sizeof(p));
//1,4,1,6,3,2,4
}
void color_change()
{
system("color 4f");
system("title helo");
system("pause");
}
static void run1(int *p, int length)
{
for (int i = 0; i < length; i++)
{
printf("%d\n", p[i]);
}
}
void mazepara()
{
int a[5] = { 1,2,3,4,5 };
int *p = (int[]) { 1, 2, 3, 4, 5, 6 };//p是一个可变指针,同时也是一个数组名,这样玩当然好处多多,数组初始化和以前一样,这种并不是其余默认为0的那种,栈上面开辟内存存放p指向的数组
}
void two_dimentional_maze_pointer()
{
int a[3][4] = { 34,23,95,78,93,77,58,68,98,34,98,43 };//a是常量,下面的p是变量,其他的都一样,二位数组而已,本质上没啥不同
int(*p)[4] = (int[][4]) { 34, 23, 95, 78, 93, 77, 58, 68, 98, 34, 98, 43 };//数组指针,也是行指针
}
//add的返回值是int类型
int add(int a, int b)//add他自己是一个函数名,是可以用函数指针来指向的
{ //所以,函数指针p可以表示add,跟p同类型的getop()当然也可以表示add
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int divi(int a, int b)
{
return a / b;
}
/*
接口确定,操作不确定,设计模式问题,接口固化,统一接口,简单工厂模式,改接口不改变函数实现。根据客户需求接口固化,很有好处。取最大值,最小值,等等一类的操作都是同一个函数,不同参数而已,这样就上层封装了一下接口,这样就能很方便。
*/
void func_pointer_emmm()//中间可以作为接口来使用,批量管理很多函数
{
//函数指针指向的东西是函数,代表一个函数名,加减没有意义
int(*p)(int, int) = add;//函数名的本质,刚才是数组名的本质,现在都了解了
int c = p(3, 4);
printf("%d\n", c);
}
//getop是函数指针类型,用getop()类型的玩意(相当于p),来接收add、
//函数指针后面加括号就是函数了啊,函数就是这么来的啊。。
void func_pointer_op_interface(int(*p)(int, int), int a, int b)//一个函数指针带两个参数,一共三个参数搞定
{
printf("%d\n", p(a, b));//在外部调用同一个函数 func_pointer_op_interface,里面变得是参数,add,1,2; sub,1,2.。。。。。
}
/*用函数指针类型作为返回值的函数,你能看出来getop函数的类型吗?哈哈*/
int(*getop())(int, int)
{
return add;
}
int(*getop4())(int, int)
{
}
int(*y())(int, int)
{
return sub;
}
int(*getop3(int a, int b, int c, int d, int e, int(*y())(int, int), double t))(int, int)
{
int k = y(3, 4);
int f = (a + b + c + d - e)*k;
return getop4(4, 5);
}
void func_pointer_op_return_value()
{
printf("%d\n", getop()(1, 3));
}
//***************************2020.6.21(日,珍珠园)***************************
//函数指针数组与多线程
void func_pointer_maze()
{
//p is 函数指针数组名,自己是二级函数指针。当然也可以被指针指向(三级函数指针),语言里所有名字都有指针背景。//加了一个数组相当于又套了一层指针,往深又加了一层。往上又增加了一级
int(*p[4])(int, int) = { add,sub,mul,divi };//左值很多时候用的是身份,是一个定义,右值是给这个定义赋值的值
for (int i = 0; i < 4; i++)
{
printf("%d ", p[i](2, 3));
//等价写法,在哪解一样的,都可以解引用
printf("%d ", (*(p + i))(2, 3));
}
int(*s)(int, int) = NULL;//啥玩意没事干了,给了一个函数指针,还弄了个空值。。。
int(**pp)(int, int) = s;//二级函数指针 == 三级原始指针。指向上面那个一级函数指针
for (pp; pp <= p + 6; pp++)
{
printf("\n%d", (*pp)(100, 100));//解一层,就是一个一级指针,其实也是函数名(可以当成函数名来使用)
}
int a[3] = { 3, 4, 5 };
int *pa = (int[]) { 4, 5, 6 };//栈上面开辟空间
//函数指针数组的指针,(二级函数型数组指针)把函数当成数组里面的元素来管理而已,问题不大
//二级指针pp就是一个游标,可用来遍历整个数组,取出地址*pp就可以当作函数名,外面给上小括号和形参就直接用了,普通函数估计都是一级指针的另一种形式吧。
//int(**pp)(int, int) = (int(*[])(int, int)) { add, divi };//pp相当于某个函数指针数组的别名,但权限高,有内存实体
//上面一行左值是二级函数指针 右值是一级函数指针数组(本质上是一个数组)
//第一个*是函数指针数组的指针,第二个*是【】的替代写法,用*pp代替pp【】
int c = (*(pp + 1))(600, 30);//二级函数指针(函数指针数组)解一次之后的一级函数指针可以当作函数名用
c = pp[0](30, 1);
printf("\n\n\n\nc=%d\n", c);
//堆上开辟个p2,二级函数指针?*p2是一个函数指针名,只不过是因为函数指针涉及到函数,所以本身就有一层指针,指向函数的指针就自然是一个二级指针了。
int(**p2)(int, int) = malloc(sizeof(int(*)(int, int)) * 4);
*p2 = add;
*(p2 + 1) = sub;
*(p2 + 2) = mul;
int k = p2[0](5, 1);
printf("k=%d ", k);
}
//************2020.6.26(五,珍珠园)内存模型大数据,检索1GB数据,排序,查找等****************
//获取文件的行数
int getimax()
{
int line = 0;
FILE *pf = fopen(path, "r");//读文件模式打开路径
if (pf == NULL)
{
printf("open failed!\n");
return -1;
}
else
{
while (!feof(pf))
{
char readstr[30000] = { 0 };
fgets(readstr, 30000, pf);
line++;
}
fclose(pf);
}
return line;
}
//获取问文件中最长的一行的宽度
int getjmax()
{
int width = 0;
FILE *pf = fopen(path, "r");//读文件模式打开路径
if (pf == NULL)
{
printf("open failed!\n");
return -1;
}
else
{
while (!feof(pf))
{
char readstr[30000] = { 0 };
fgets(readstr, 30000, pf);//fgets把文件的内容读取后保存到这个字符数组里面,这一步能理解,一次获取一行字符串
readstr[29999] = '\0';//最后为字符串结束
int strlength = strlen(readstr);//获取字符串长度
if (strlength > width)
{
width = strlength;
}
if (strlength > 2)
{
puts(readstr);
}
}
fclose(pf);
return width;
}
}
//copy str to mem
void loadfromFile()
{
g_pp = (char **)malloc(sizeof(char*)*imax);
memset(g_pp, '\0', sizeof(char*)*imax);//内存清零
FILE *pf = fopen(path, "r");
if (pf == NULL)
{
printf("open fail\n");
return -1;
}
else
{
for (int i = 0; i < imax; i++)
{
char str[1024] = { 0 };
fgets(str, 1024, pf);//按行读取字符串
str[1023] = '\0';
int strlength = strlen(str);
if (strlength < 11)
{
g_pp[i] = malloc(sizeof(char)*(strlength + 1));
strcpy(g_pp[i], str);//拷贝到分配的内存中
}
}
}
}
//搜索函数
void search_file(char*str)
{
char strpath[100] = { 0 };
sprintf(strpath, "D:\\%s.txt", str);
FILE*pf = fopen(strpath, "w");
if (g_pp != NULL)
{
for (int i = 0; i < imax; i++)
{
if (g_pp[i] != NULL)
{
char *p = strstr(g_pp[i], str);
if (p != NULL)
{
puts(g_pp[i]);//打印,查找的意思
//fputs(g_pp[i],pf);//输出到文件
}
}
}
}
fclose(pf);
system(strpath);
}
void search_file_fun()
{
while (1)
{
char str[100] = { 0 };
scanf("%s", str);
search_file(str);
}
}
//2020.6.27 迷途指针(野指针问题)
void lost_p()
{
int *p = (int*)malloc(sizeof(int)*10);//这里如果不加上一个int*的强转,显然用void*类型,步长是不确定的。
void *chil = p;//void 类型的指针可以接受但是无法打印内容,明显的,他的步长不知道,但是可以强制转换指针类型进行打印输出,一般用于参数和返回值等等,一般不明确类型的时候只是传递地址所用。malloc本质上就是空指针类型,只是分配内存空间
chil = NULL;//空指针表明这个指针不指向任何地址,通过强转可以把地址(数字)转换为“指针”
}
//以下是密码全排列的三个函数
void count_combiniton()
{
//用指针的方式循环一个数组
for (char*p = str; *p != '\0'; p++)
{
printf("%p\n", p);
putchar(*p);
}
}
//swap two para
void swap(int *pa, int*pb)
{
int temp = *pa;
*pa = *pb;
*pb = temp;
}
//all_permutation
void permutation(char*pbegin)
{
if (!*pbegin)
{
printf("%d ", ipos++);
puts(str);//输出字符串
}
for (char *p = pbegin; *p != '\0'; p++)
{
//pbegin++;
swap(p, pbegin);
permutation(pbegin + 1);
swap(p, pbegin);
}
}
//2020.6.28(家)
//quick_sort
void quick_sort(int *arr, int iLeft, int iRight)
{
int i = iLeft;
int j = iRight + 1;
if (i < j)
{
do
{
do
{
i++;
} while (arr[i] <= arr[iLeft] && i <= iRight);//最靠近右边小于等于他的
do
{
j--;
} while (arr[j] >= arr[iLeft] && j > iLeft);//最左边大于等于他的
if (i < j)
{
swap(&arr[i], &arr[j]);
}
//swap(&arr[iLeft], &arr[j]);
//show(arr, 10);
} while (i < j);
swap(&arr[iLeft], &arr[j]);
//show(arr, 10); printf("\n");
quick_sort(arr, iLeft, j - 1);
quick_sort(arr, j + 1, iRight);
}
}
//heap_sort() 后面再看
//web cgi learning html
void cgi_web()
{
printf("Content-type:text/html \n\n");
printf("hello web!\n");
}
//string deep know 其实c没有提供字符串相加等这些操作也没有String类型,字符串没有被封装到C语言里面。用数组来操作
void string_op()
{
char str1[20] = "calc";//字符数组了解一下。sizeof(str1)应该是20,而不是5.strlen是4
char *p1 = (char[]) { 'm', 's', 'p', 'a', 'i', 'n', 't', '\0' };//这里如果不加这个结束符号,开始烫烫烫
char *p2 = "notepad"; //这个p2存储代码区的地址,没法改变的。
*str1 = 'A';
printf("%s\n", str1);//这里虽然传递是首地址str1,但是输出的东西却是整个字符串,奇怪吗?哈哈
*p1 = 'B';//p1存储栈上数据区的数据,
printf("%s\n", p1);
*p2 = 'X';//这里如果执行直接报异常,
printf("%s\n", p2);
}
//comapre string
void compare_string()
{
char *p5 = "132";
char str[100];
//printf("%p\n",p);
//printf("%p\n", str);
//scanf("%p",&p);
//scanf("%p", p);
//scanf("%p", str);
char *p = "%s";
printf(p, "123");
//printf("%s\n",p);
}
void input_p1()
{
int data = 50;
printf("%p", &data);
int *p = NULL;
*p = 2;
scanf("%p", &p); //give value to the pointer p , if p has value ,then *p can be showed by printf function.let p point to data by scanf function.
printf("data=%d", *p);
}
void snake()
{
//const unsigned int n = 5;
scanf("%d",&n);
//int maze[n][n] = { 0 };
//for (int i = 0; i < n; i++)
//{
// if (i == 0)
// maze[i][0] = 1;
// else if (i == 1)
// {
// maze[i][0] = 4 * (n - 1);
// maze[0][i] = 2;
// }
// else
// {
// maze[i][0] = maze[i - 1][0] - 1;
// maze[0][i] = maze[0][i - 1] + 1;
// }
//}
//for (int i = 0; i < n; i++)
//{
// for (int j = 1; j < n; j++)
// {
// }
//}
//for (int i = 0; i < n; i++)
//{
// if (i >= 1)
// maze[0][i] = maze[0][i - 1] + 1;
//}
//for (int i = 0; i < n; i++)
//{
// for (int j = 0; j < n; j++)
// {
// printf("%d ", maze[i][j]);
// }
// printf("\n");
//}
} //按照这个思路想下去,最后能搞出来,变通一下即可,整体思想是有道理的。外层的层数控制并没有考虑,这个是试验方面,想到的是通项公式,这点是有点违背原理的。
void 位运算符()
{
unsigned int a = 3;
unsigned int b = 5;
unsigned int d = a & b;//遇到1不变,遇0置0,显然用来重置为0比较好
unsigned int c = a | b;//遇到0不变,遇1置1,显然用来重置为1比较好
unsigned int e = a ^ b;//遇到0不变,遇1取反,显然用来加密解密比较好
}
void 下划线布尔类型和三目运算符()
{
_Bool kitty = true;
kitty ? printf("yes\n") : printf("no");
}
void sprintf函数()
{
int dv;
char cmd[100];
scanf("%d%s", &dv, &cmd);
char strcmd[200] = { 0 };
sprintf(strcmd, "for /l %%i in (1,1,%d) do %s", N, cmd);//映射
system(strcmd);
}
void 可见字符的范围()
{
for (char ch = 32; ch < 127; ch++)//可见字符范围
{
putchar(ch);
}
}
void 枚举类型复习()
{
enum fighter { f16, mig29, su35, su27, j20, f22, su57, mig31, typhon };
enum fighter x02s = mig29;
if (x02s == mig29)
{
printf("bear-fighter");
}
else
{
printf("none-bear");
}
getchar();
}
void 纯malloc分配内存()//没有左值接收方
{
while (-1)
{
malloc(1 * 1024 * 1024);
}
}
void do_while循环条件在块中()
{
int i = 3;
printf("%p\n", &i);
do
{
printf("notepad\n");
i--;//这里有一个后置--。 很明显,最后一个1执行完成之后先置0,后判断,那么给数字几就是几次,没有多的次数
} while (i);//一开始不满足条件会多执行一次,(最后不满足就正常退出)。3 2 1 可以,0进不去了
getchar();
}
void dowhile递减循环条件在括号内()
{
int i = 3;
printf("%p\n", &i);
do
{
printf("notepad\n");
/* i--是先用再减,用完之后再减,cpp中尽量避免不必要的保存,尽量用前置,在这里有效循环数字是x 3 2 1
--i就不一样,减好了再用 这里有效循环数字是x 2 1 。多的那一次直接进来就被减掉了,和放在上面没啥区别,如果这样放在上面会造成少一次循环,这里正好 */
} while (--i);
}
void 用dowhile实现大小写转换()
{
char cha;
do
{
cha = getchar();
if (cha > 'A'&&cha < 'Z')
{
cha = cha + 32;
}
putchar(cha);
getchar();//缓冲回车键
} while (cha != '\t');//以tab结束循环,结束这个do while循环
}
void windows窗体类按句柄找程序()
{
HWND win = FindWindowA("Chrome_WidgetWin_1", "StryServer218?-?Synology?DiskStation - 配置文件 1 - Microsoft? Edge");
if (win != NULL)
{
printf("hello russul\n");
int i = 0;
do
{
SetWindowPos(win, NULL, i, i * 700 / 1000, 400, 400, 1);
i++;
} while (i < 990);
}
system("pause");
}
void goto的用法()
{
int i = 0;
Riven: if (i <= 20)
{
printf("hello\n");
i++;
Sleep(2000);
goto Riven;
}
}
void 打印盒子()
{
MessageBoxA(0, "hello", "title", 0);
}
void 多线程打印盒子()
{
for (int i = 0; i < 5; i++)
{
_beginthread(打印盒子, 0, NULL);
}
}
DWORD WINAPI mymsg(LPVOID lp)
{
MessageBoxA(0, "hello", "title", 0);
}
int mul_thread()
{
HANDLE hthread;
DWORD threadid;
for (int i = 0; i < 5; i++)
{
hthread = CreateThread(
NULL,//safe attrribute
NULL,//stack
mymsg,//function address,use mymsg
NULL,//function parameters
0,//execuate instantly
&threadid//id
);//multil thread
WaitForSingleObject(hthread, INFINITE);//mul_thread sychronize
CloseHandle(hthread);
}
}
void 利用goto语句实现不同差数列求和叠加()
{
int i = 0,n=0;
A:if (i < 20)
{
i += 1;
n += 3;
goto A;
}
printf("%d\n", n);
}
void 大数分解easy()//将161719分解为两个数,一个是11的倍数,一个是13的倍数
{
int sum = 1617;
int x = 0;
int y = 0;
while (y >= 0 && y < sum)
{
if (y % 14 == 0)
{
x = sum - 14 * y;
printf("y found!\n");
if (x > 0 && x % 3 == 0)
{
x /= 3;
printf("x=%d ; y=%d\n", x, y);
//break;
}
}
y += 1;
}
for (int i = 0; i < 100 / 13 + 1; i++)
{
if ((1617 - 11 * i) % 13 == 0)
{
printf("%d");
}
}
}
void 百鸡百钱()
{
//公鸡5块钱,母鸡3块钱,小鸡一块钱3只
for (int cock = 0; cock <= 20; cock++)
{
//printf("vv\n");
for (int hen = 0; hen <= 34; hen++)//如果把for的内部循环变量放到函数内部当成成员变量,很容易造成一次循环之后内部循环体进不去,无法实现外层一次内层n次的效果。
{
if (hen * 3 + cock * 5 + (100 - cock - hen) / 3 == 100 && (100 - cock - hen) % 3 == 0)
{
printf("%d %d %d\n", cock, hen, (100 - cock - hen));
}
//0 25 75 results;
//4 18 78
//8 11 81
//12 4 84
}
}
}
void 指针作为形参的简单函数(int *a, int *b, int *c)
{
*a = 10;
*b = 15;
*c = *a + *b;
printf("addr_a=%p\n", &a);
printf("a=%d\n", *a);
printf("addr_b=%p\n", &b);
printf("b=%d\n", *b);
printf("addr_c=%p\n", &c);
printf("c=%d\n", *c);
}
void 可变参数(int num, ...)
{
int res = 0;//result
va_list argp;//存储参数开始的地址
va_start(argp, num);//从首地址开始读取后面的数据
for (int i = 0; i < num; i++)
{
res += va_arg(argp, int);//读取一个数据按照int解析
}
va_end(argp);
return res;
}
int 可变参数1(int num, ...)
{
int res = 0;//result
va_list argp;//存储参数开始的地址
va_start(argp, num);//从首地址开始读取后面的数据
for (int i = 0; i < num; i++)
{
char str[50];
sprintf(str, "%s", va_arg(argp, char*));
system(str);//读取一个数据按照int解析
}
va_end(argp);
return res;
}
void 可变参数2(int start, ...)
{
va_list argp;
va_start(argp, start);
int argvalue = start;
do
{
argvalue = va_arg(argp, int);//不断读取
printf("%d\n", argvalue);
} while (argvalue != -1);
va_end(argp);
}
void caseer()
{
int m, n, x, y;
m = n = x = y = 1;
switch (m)
{
case 0:x *= 2;//skip
case 1:
{
switch (n)
{
case 1:x += 4;
case 2:y = y * 2; break;
case 3:x++;
default:printf("hello\n");
}
}
case 2:x--;
case 3:y--;
default:x++; y++;
}
printf(" %d %d", x, y);
int num = 80;
int *p = #
printf("%d", *p);
int *f = 0, *d = 1, *e = 0;
printf("f_add=%p\n", &f);
printf("d_add=%p\n", &d);
printf("e_add=%p\n", &e);
指针作为形参的简单函数(&f, &d, &e);
printf("f_add2=%p\n", &f);
printf("f_add2=%p\n", &d);
printf("f_add2=%p\n", &e);
printf("%d\n", &e);
}
int recurrence(int num)//从0加到100递归第一种,固定数值从小到大
{
if (num == 100)
{
return num;
}
else
{
return recurrence(num + 1) + num;
}
}
int recurrence1(int num)//从0加到100递归第二种,固定数值从大到小
{
if (num == 0)
{
return 0;
}
else
{
return recurrence1(num - 1) + num;
}
}
double Fibonacci_sequence(double generation)
{
if (generation == 1 || generation == 2)
{
return 1;
}
else
{
return Fibonacci_sequence(generation - 1) + Fibonacci_sequence(generation - 2);
}
}
void show_pic()
{
int i = 0;
while (1)
{
HWND win = GetDesktopWindow();
HDC windc = GetWindowDC(win);
HDC Memdc = CreateCompatibleDC(0);
//LET IN
HBITMAP bit = (HBITMAP)LoadImage(win, TEXT("3.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE, LR_CREATEDIBSECTION);
SelectObject(Memdc, bit);
BitBlt(windc, 0, 0, 613, 385, Memdc, 0, 0, SRCCOPY);
}
}
void consume_cpu()
{
for (int i = 0; i < 2; i++)
{
_beginthread(run, 0, NULL);
}
}
void 无限循环分配栈内存()
{
while (1)
{
int num[1024];
}
}
void maze1()
{
int a[2][2] = { { 0,1 },{ 2,3 } };
printf("a-00=%d\n", a[0][0]);
printf("a-01=%d\n", a[0][1]);
printf("a-10=%d\n", a[1][0]);
printf("a-11=%d\n", a[1][1]);
}
void main()
{
//void(*p_xiaoai)() = runmsg;//函数指针变量,自己在数据区,存储了代码区函数的地址,回调,修改的是指针变量
putchar('\101');
system("pause");
}
//第一遍复习,2020.7.25 done