windows静态库和动态库的使用 函数可变参 递归使用 多线程查找
指针内存面试题:
对整个数组取地址+1前进了整个数组。再强转成double* 根据double*步长再减去1
#include <stdio.h>int main(){double db[5] = {1.0,2.0,3.0,4.0,5.0};printf("%f\n", *((double *)(&db + 1) - 1)); // 结果输出5.0return 0;}
#include <stdio.h>#include <stdlib.h>int main(){int *p = (int *)malloc(0); //内存分配0,也会分配成功。不过会发生内存冲突printf("%p\n", p);return 0;}
静态库的使用:
导出静态库my.lib
int sub(int a, int b){return a - b;}
windows下使用静态库的两种方法:
1.项目设置

2.在代码里设置
#pragma comment(lib,"array.lib") //注意此处没有分号
#include <stdio.h>#pragma comment(lib,"my.lib")int main(){printf("%d\n", sub(13, 7)); //6return 0;}
动态库的使用:
动态库的函数必须要导出
//导出函数,可以加载的时候调用_declspec(dllexport) int add(int a, int b){return a + b;}
动态库的使用:
#include <windows.h> //使用动态库加载需要使用windows.h头文件
#include <stdio.h>#include <windows.h>typedef int(*padd)(int a, int n);//定义函数指针int main(){HMODULE mydll = LoadLibraryA("my.dll");//装载模块if (mydll == NULL){printf("装载模块失败\n");}else{padd myadd = (padd)GetProcAddress(mydll, "add");printf("%d\n", myadd(5, 8));}FreeLibrary(mydll);//卸载模块return 0;}
可以通过VS2013的调试 -->模块窗口查看。
函数的可变参数:
#include <stdarg.h> //函数可变参数的头文件
#include <stdio.h>#include <stdarg.h>int add(int n, ...){int res = 0;va_list va;va_start(va, n);for (int i = 0; i < n; i++){res += va_arg(va, int);}va_end(va);return res;}int main(){printf("%d\n", add(3, 1, 2, 3)); //6return 0;}
通过可变参数传递字符串:
#include <stdio.h>#include <stdlib.h>#include <stdarg.h>void runcmd(int n, ...){va_list va;va_start(va, n);for (int i = 0; i < n; i++){char *p = va_arg(va,char *);system(p);}va_end(va);}int main(){runcmd(3,"calc","notepad","write");//函数 依次打开 计算器 记事本 写字板return 0;}
system函数的同步与异步:
只有关闭一个才能打开下一个notepad,阻塞模式
#include <stdio.h>#include <stdlib.h>int main(){for (int i = 0; i < 10;i++){system("notepad");}return 0;}
只要在system里增加了start就可以变成同步模式:
#include <stdio.h>#include <stdlib.h>int main(){for (int i = 0; i < 10;i++){system("start notepad");}return 0;}
函数参数的副本机制:
函数参数都具有副本机制,即使在函数里改变形参,也不会改变实参。(数组例外,数组名会退化为指针)
PS:
结构体传参也有副本机制,即使里面有数组。结构体赋值本质就是内存的拷贝。
#include <stdio.h>#include <stdlib.h>struct STU{int n;int a[5];};void change(struct STU s){s.n = 6;s.a[0] = 100;printf("%d,%d\n", s.n, s.a[0]); // 6 , 100}int main(){struct STU stu = { 5, {1,2,3,4,5} };printf("%d,%d\n", stu.n, stu.a[0]); // 5 , 1change(stu);printf("%d,%d\n", stu.n, stu.a[0]); // 5 , 1return 0;}
递归的使用场景:
倒序打印一个字符串:
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>void show(char *s){if (*s == '\0'){return;}else{show(s+1);putchar(*s);}}int main(){char buf[50];scanf("%s",&buf);show(buf);return 0;}
逆序一个字符串:
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>void str_re(char *s, int n){if (n <= 1){return;}else{char tmp = *s;*s = s[n - 1];s[n - 1] = tmp;str_re(s + 1, n - 2);}}int main(){char buf[50] = { 0 };scanf("%s", &buf);printf("%s\n", buf);str_re(buf, strlen(buf));printf("%s\n", buf);return 0;}
递归求两个数的最大公约数:
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>int yue(int a, int b){if (a%b == 0)return b;elsereturn yue(b, a%b);}int main(){int a, b;scanf("%d %d", &a, &b);if (a > b)printf("%d\n", yue(a, b));elseprintf("%d\n", yue(b, a));return 0;}
递归 判断一个数组是否是递增:(逻辑递归)
#include <stdio.h>int is_dizeng(int *a, int n){if (n <= 1)return 1;elsereturn a[0] < a[1] && is_dizeng(a + 1, n - 1);}int main(){int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };if (is_dizeng(a, 10)){printf("是递增\n");}else{printf("不是递增\n");}return 0;}
自己写的另外一种方式
int is_dizeng(int *a, int n){if (n <= 1)return 1;elsereturn a[n - 1] > a[n - 2] && is_dizeng(a, n - 1);}
多线程查找
循环让cmd窗口打印时间:
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <windows.h>int main(){int i = 1;while (1){char str[30] = { 0 };sprintf(str, "title 当前时间 %d 秒", i++);system(str);Sleep(1000);}return 0;}
多线程的同步和异步实现:
下面是异步的实现方式:
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <process.h>//多线程#include <windows.h>void time(void *p){int i = 0;while (1){char str[100] = { 0 };sprintf(str, "title 当前时间%d秒", i);i++;system(str);//执行指令Sleep(1000);}}void gogo(void *p){int id = *(int *)p;for (int i = 1;; i++){if (i > 2){printf("\n%d ,%d号线程结束", i, id);break;}Sleep(1000);}_endthread();//退出线程}void main(){_beginthread(time, 0, NULL);//先执行窗口时间int a[5] = { 1, 2, 3, 4, 5 };for (int i = 0; i < 5; i++)_beginthread(gogo, 0, &a[i]);//异步getchar();}

同步实现只需要WaitForSingleObject
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <process.h>//多线程#include <windows.h>void time(void *p){int i = 0;while (1){char str[100] = { 0 };sprintf(str, "title 当前时间%d秒", i);i++;system(str);//执行指令Sleep(1000);}}void gogo(void *p){int id = *(int *)p;for (int i = 1;; i++){if (i > 2){printf("\n%d ,%d号线程结束", i, id);break;}Sleep(1000);}_endthread();//退出线程}void main(){_beginthread(time, 0, NULL);//先执行窗口时间int a[5] = { 1, 2, 3, 4, 5 };for (int i = 0; i < 5; i++){HANDLE hd = _beginthread(gogo, 0, &a[i]);WaitForSingleObject(hd, INFINITE);//同步}getchar();}

多线程查找数组元素:
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <process.h>int flag = 0;//0为没有找到,1为找到struct MyStruct{int *pfindfirst;//查找的首地址int length;//查找的长度int num;//要查找的数据int id;//线程的编号int * pfind;//找到的地址};void find(void *p){struct MyStruct *pstruct = p;//指针类型转换//遍历内存for (int *px = pstruct->pfindfirst; px < pstruct->pfindfirst + pstruct->length; px++){if (flag == 1){printf("线程%d没有找到,其他线程已经找到\n", pstruct->id);return;}if (*px == pstruct->num)//对比是否相等{pstruct->pfind = px;//赋值printf("%d号线程找到%d,%p\n", pstruct->id, *px, px);//找到提示flag = 1;return;//返回}}printf("线程%d没有找到\n", pstruct->id);}void main(){int a[1000] = { 0 };//多线程顺序查找for (int i = 0; i < 1000; i++){a[i] = i;//赋值初始化数组}int threadnum;int findnum;printf("请输入需要多少个线程\n");scanf("%d", &threadnum);printf("请输入要查找的数据\n");scanf("%d", &findnum);//动态开辟结构体数组if (1000 % threadnum != 0){struct MyStruct *pstruct = malloc(sizeof(struct MyStruct)*threadnum);for (int i = 0; i < threadnum - 1; i++){pstruct[i].pfindfirst = a + i * (1000 / (threadnum - 1));//确定查找的地址pstruct[i].length = (1000 / (threadnum - 1));//查找的长度pstruct[i].id = i;//编号pstruct[i].num = findnum;//查找的数据pstruct[i].pfind = NULL;_beginthread(find, 0, &pstruct[i]);}{int i = threadnum - 1;//处理最后一个线程pstruct[i].pfindfirst = a + (1000 / (threadnum - 1))*(threadnum - 1);//确定查找的地址pstruct[i].length = 1000 - (1000 / (threadnum - 1))*(threadnum - 1);//查找的长度pstruct[i].id = i;//编号pstruct[i].num = findnum;//查找的数据pstruct[i].pfind = NULL;_beginthread(find, 0, &pstruct[i]);}}system("pause");}

浙公网安备 33010602011771号