typedef相关知识
-
typedef和#define的一点小区别typedef int * int_ptr; 与 #define int_ptr int * 作用都是用int_ptr代表 int * ,但是二者不同,正如前面所说 ,#define在预处理 时进行简单的替换,而typedef不是简单替换 ,而是采用如同定义变量的方法那样来声明一种类型。也就是说; #define int_ptr int * int_ptr a, b; //相当于int * a, b; 只是简单的宏替换 typedef int* int_ptr; int_ptr a, b; //a, b 都为指向int的指针,typedef为int* 引入了一个新的助记符 这也说明了为什么下面观点成立 typ
-
IRPhook原理:直接IoGetDeviceObjectPointer根据名称获取驱动对象,然后更改分发函数数组元素即可HOOK指定IRP分发函数。//irphook.h/////////////////////////////////////////////////////////////////////////////////////// typedef BOOLEAN BOOL;typedef unsigned long DWORD;typedef DWORD * PDWORD;typedef unsigned long ULONG;typedef unsigned short WORD;typedef unsigned char BYTE;typedef BYTE * LPBYTE;#define IOCTL_TCP_QUERY_INFORMATION_EX 0x00120003//#define MAKEPORT(a, b) ((WORD)(((UCHAR)(a))|((WORD)((
-
BM#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;#define rep(i,a,n) for(ll i=a;i<n;i++)#define per(i,a,n) for(ll i=n-1;i>=a;i--)#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define fi first#define se second#define SZ(x) (ll)(x).size()typedef vector<ll>VI;typedef pair<ll,ll>PII;const int mod=1e9+7;ll powmod(ll a,ll b){ ll res=1; a%=mod; assert
-
基本的二叉树操作之:二叉树的创建/**/ //abc空格空格de空格g空格空格f空格空格空格 /***/ include<stdio.h> include<stdlib.h> typedef char DataType; typedef struct Node { DataType Data; struct Node *lchild, *rchild; }BinNode; typedef BinNode* BinTree; BinTree CreateTree() { BinTree T; char ch = getchar(); if(ch== ' ') T =NULL; else { T=(BinTree)malloc(sizeof(BinTree)); T->Data =ch; T->lchild =CreateTree(); T->rchild =CreateTree(); } return T; }
typedef相关课程
typedef相关教程
- 1. http 请求 11 个处理阶段介绍 Nginx 将一个 Http 请求分成多个阶段,以模块为单位进行处理。其将 Http请求的处理过程分成了 11 个阶段,各个阶段可以包含任意多个 Http 的模块并以流水线的方式处理请求。这 11 个 Http 阶段如下所示:typedef enum { NGX_HTTP_POST_READ_PHASE = 0, NGX_HTTP_SERVER_REWRITE_PHASE, NGX_HTTP_FIND_CONFIG_PHASE, NGX_HTTP_REWRITE_PHASE, NGX_HTTP_POST_REWRITE_PHASE, NGX_HTTP_PREACCESS_PHASE, NGX_HTTP_ACCESS_PHASE, NGX_HTTP_POST_ACCESS_PHASE, NGX_HTTP_TRY_FILES_PHASE, NGX_HTTP_CONTENT_PHASE, NGX_HTTP_LOG_PHASE } ngx_http_phases;网上有人做了一个非常形象的图片,如下图所示。我们可以看到 11 个阶段的处理顺序,以及每个阶段中涉及到的相关模块以及模块之间的顺序。
- 2.1 SkipList 数据结构 面试官提问: Redis zset 数据结构的底层实现是什么?为什么要使用跳跃表?题目解析:在介绍跳跃表(SkipList,简称跳表)之前,我们可以以单链表数据结构作为对比。 (单链表结构示意图)在单链表中,我们查询一个元素的时间复杂度是 O (N),其中 N 是链表的长度,因为需要诶个遍历节点,单链表不支持数组的随机插入和删除,也不支持数组的自动排序,显然不适合作为 zset 的实现方式。跳跃表的基础定义可参考维基百科定义参考定义,我们给出 C 语言的结构体定义:typedef struct zskiplistNode { sds ele; double score; struct zskiplistNode *backward; struct zskiplistLevel { struct zskiplistNode *forward; unsigned int span; } level[];} zskiplistNode;typedef struct zskiplist { struct zskiplistNode *header, *tail; unsigned long length; int level;} zskiplist;候选人需要描述跳表的数据结构,可以通过画图或者其他方式给出定义。 (典型的跳跃表结构,图片来自网络,侵删)从结构体可以看出,节点有不同的定义:sds:存储的字符串对象;score:分数,跳表中所有节点按照 score 由大到小排列;backward:指向后退节点的指针;forward:指向下一个节点的指针;level:数组,数组中的每一个元素包括了指向其他节点的指针,level 的长度在 1 到 32(2^5)之间。其中跳表的主要组成结构有:表头:表示跳表的入口;表尾:表示跳表的尾部,数值全部都是 NULL;节点:保存具体数值,并且具有层结构;层:就是上述 level 定义中的单个元素,保存前一个节点的指针,以及该层下个节点向前跨越的数值(span)。跳表的查询过程本质上是自上而下的二分查找,插入和查询过程都相对复杂,这里不做赘述。在阐述基本定义之后,我们需要关注跳跃表的核心特点:本质是随机化数据结构,可以在对数(logN)时间内完成对数据的查找、插入、删除操作;跳跃表在 Redis 的唯一应用,就是作为有序集合支撑底层数据结构。
- 2. 案例 我们来完成一个简单的自定义 http 模块,来实现前面Echo模块的最简单形式,即使用指令输出 “hello, world” 字符串。首先新建一个目录echo-nginx-module,然后在目录下新建两个文件config和ngx_http_echo_module.c[root@server echo-nginx-module]# pwd/root/shencong/echo-nginx-module[root@server echo-nginx-module]# lsconfig ngx_http_echo_module.c两个文件内容分别如下:[root@server echo-nginx-module]# cat config ngx_addon_name=ngx_http_echo_module# 指定模块名称HTTP_MODULES="$HTTP_MODULES ngx_http_echo_module"# 指定模块源码路径NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_echo_module.c"[root@server echo-nginx-module]# cat ngx_http_echo_module.c#include <ngx_config.h>#include <ngx_core.h>#include <ngx_http.h>/* Module config */typedef struct { ngx_str_t ed;} ngx_http_echo_loc_conf_t;static char *ngx_http_echo(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);static void *ngx_http_echo_create_loc_conf(ngx_conf_t *cf);static char *ngx_http_echo_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);/* 定义指令 */static ngx_command_t ngx_http_echo_commands[] = { { ngx_string("echo"), /* 指令名称,利用ngx_string宏定义 */ NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, /* 用在 location 指令块内,且有1个参数 */ ngx_http_echo, /* 处理回调函数 */ NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_echo_loc_conf_t, ed), /* 指定参数读取位置 */ NULL }, ngx_null_command};/* Http context of the module */static ngx_http_module_t ngx_http_echo_module_ctx = { NULL, /* preconfiguration */ NULL, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ ngx_http_echo_create_loc_conf, /* create location configration */ ngx_http_echo_merge_loc_conf /* merge location configration */};/* Module */ngx_module_t ngx_http_echo_module = { NGX_MODULE_V1, &ngx_http_echo_module_ctx, /* module context */ ngx_http_echo_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING};/* Handler function */static ngx_int_tngx_http_echo_handler(ngx_http_request_t *r){ ngx_int_t rc; ngx_buf_t *b; ngx_chain_t out; ngx_http_echo_loc_conf_t *elcf; /* 获取指令的参数 */ elcf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module); if(!(r->method & (NGX_HTTP_HEAD|NGX_HTTP_GET|NGX_HTTP_POST))) { /* 如果不是 HEAD/GET/PUT 请求,则返回405 Not Allowed错误 */ return NGX_HTTP_NOT_ALLOWED; } r->headers_out.content_type.len = sizeof("text/html") - 1; r->headers_out.content_type.data = (u_char *) "text/html"; r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = elcf->ed.len; if(r->method == NGX_HTTP_HEAD) { rc = ngx_http_send_header(r); if(rc != NGX_OK) { return rc; } } b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if(b == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer."); return NGX_HTTP_INTERNAL_SERVER_ERROR; } out.buf = b; out.next = NULL; b->pos = elcf->ed.data; b->last = elcf->ed.data + (elcf->ed.len); b->memory = 1; b->last_buf = 1; rc = ngx_http_send_header(r); if(rc != NGX_OK) { return rc; } /* 向用户发送相应包 */ return ngx_http_output_filter(r, &out);}static char *ngx_http_echo(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){ ngx_http_core_loc_conf_t *clcf; clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); /* 指定处理的handler */ clcf->handler = ngx_http_echo_handler; ngx_conf_set_str_slot(cf,cmd,conf); return NGX_CONF_OK;}static void *ngx_http_echo_create_loc_conf(ngx_conf_t *cf){ ngx_http_echo_loc_conf_t *conf; conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_echo_loc_conf_t)); if (conf == NULL) { return NGX_CONF_ERROR; } conf->ed.len = 0; conf->ed.data = NULL; return conf;}static char *ngx_http_echo_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child){ ngx_http_echo_loc_conf_t *prev = parent; ngx_http_echo_loc_conf_t *conf = child; ngx_conf_merge_str_value(conf->ed, prev->ed, ""); return NGX_CONF_OK;}这样一个第三方模块包就完成了,接下来我们要向之前使用第三方模块一样,将它编译进 Nginx,具体操作如下。[root@server shencong]# cd nginx-1.17.6/[root@server nginx-1.17.6]# ./configure --prefix=/root/shencong/nginx-echo --add-module=/root/shencong/echo-nginx-module...[root@server nginx-1.17.6] # make && make install...[root@server nginx-1.17.6]# cd ../nginx-echo/sbin/[root@server sbin]# ./nginx -Vnginx version: nginx/1.17.6built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) configure arguments: --prefix=/root/shencong/nginx-echo --add-module=/root/shencong/echo-nginx-module接下来,我们只要在 nginx.conf 中加入我们的指令,并给一个参数,就能看到我们自定义的输出了。...http { ... server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } location /test { echo hello,world; } ... }}...最后我们请求主机的80端口,URI=/test,浏览器输出"hello, world",说明我们的自定义模块成功了!
- 3. 示例程序 #include <stdio.h>#include <string.h>#define StudentNumbers 50#define NameLength 50typedef struct{ int id; char name[NameLength]; int age; int score; int flag;} Student;int add(Student student, Student Students[]);int del(int id, Student students[]);int display(Student students[]);int update(int id, Student students[]);int search(char name[], Student students[]);int main(){ int id = -1; char name[NameLength]; int choice = 0; int stop = 0; Student students[StudentNumbers]; Student student; for (int i = 0; i < StudentNumbers; i++) { students[i].id = i; students[i].flag = 0; } while (stop == 0) { printf("-------------------------\n"); printf("* 学生管理系统 *\n"); printf("-------------------------\n"); printf("1 添加\n"); printf("2 修改成绩\n"); printf("3 查询\n"); printf("4 删除\n"); printf("5 显示学生列表\n"); printf("0 退出程序\n"); printf("请直接输入数字选项:"); scanf("%d", &choice); switch (choice) { case 1: printf("请输入学生姓名:"); scanf("%s", student.name); printf("请输入学生的年龄:"); scanf("%d", &student.age); printf("请输入学生成绩:"); scanf("%d", &student.score); add(student, students); break; case 2: printf("请输入要修改成绩的学生编号:"); scanf("%d", &id); update(id, students); break; case 3: printf("请输入要查找的学生姓名:"); scanf("%s", name); search(name, students); break; case 4: printf("请输入要删除的学生编号:"); scanf("%d", &id); del(id, students); break; case 5: display(students); break; case 0: stop = 1; break; default: printf("输入选项有误\n"); break; } } return 0;}int add(Student student, Student students[]){ for (int i = 0; i < StudentNumbers; i++) { if (students[i].flag == 0) { strcpy(students[i].name, student.name); students[i].age = student.age; students[i].score = student.score; students[i].flag = 1; return 0; } } return 1;}int del(int id, Student students[]){ for (int i = 0; i < StudentNumbers; i++) { if (students[i].id == id) { students[i].flag = 0; return 0; } } return 1;}int display(Student students[]){ printf("******************\n"); printf("学生列表\n"); printf("******************\n"); for (int i = 0; i < StudentNumbers; i++) { if (students[i].flag == 1) { printf("学生编号:%d,学生姓名:%s,年龄:%d,成绩:%d\n", students[i].id, students[i].name, students[i].age, students[i].score); } } printf("******************\n"); return 0;}int update(int id, Student students[]){ int score = -1; printf("请输入新的成绩:"); scanf("%d", &score); for (int i = 0; i < StudentNumbers; i++) { if (students[i].id == id) { students[i].score = score; return 0; } } return 1;}int search(char name[], Student students[]){ for (int i = 0; i < StudentNumbers; i++) { if (strcmp(name, students[i].name) == 0) { printf("学生编号: %d,学生姓名: %s,年龄: %d,成绩: %d\n", students[i].id, students[i].name, students[i].age, students[i].score); return 0; } } printf("没有查找到相关学生信息。\n"); return 1;}很多人可能会第一次接触这么长的程序,会产生畏惧的心理。其实不用担心。要相信自己可以看懂的。我们分开来讲解一下。在程序的最开始我们需要引入程序中可能需要使用的函数的头文件。这里我们因为要使用 printf 、 scanf 等,所以需要 stdio 函数库。因为要使用 strcpy 、 strcmp 函数,所以需要 string 函数库。#include <stdio.h>#include <string.h>为了便于程序中的维护,不用在很多出修改共用的数值。所以这里定义了一个常量#define StudentNumbers 50#define NameLength 50为了存储学生的信息。我们用了 struct 来定义学生的信息。里面包含学生的编号 id ,姓名 name 这是一个字符串,年龄 age ,成绩 score ,标志位 flag 这个变量是用来表示是否有学生信息存储在该位置的。不过这里我们使用了之前没有介绍的一个 typedef 。这个关键字使用的好处是使得后面使用这个 struct 的时候不用每次都用关键字 struct 来定义,只要用这个结构的名称直接定义就可以了,如同我们定义整数等内置类型一样方便。typedef struct{ int id; char name[NameLength]; int age; int score; int flag;} Student;为了便于维护,我们没有按照函数出现的顺序来写。不过 C 语言一直秉承着先定义再使用的原则。所以。如果你使用的函数没有在使用前出现,而是在后面的话,那么你就需要先让编译器知道这个函数的基本情况。这个时候我们会先把函数的定义写在前面。我们可以看到下面我们定义了这个系统的功能。每个功能我们都会写一个函数。其实不写这些函数,把所有的功能写在 main 函数内部也是可以的。但是这样会在维护上存在问题。进行测试也会变得困难。int add(Student student, Student Students[]);int del(int id, Student students[]);int display(Student students[]);int update(int id, Student students[]);int search(char name[], Student students[]);这里定义了一些需要使用的变量。stop 变量是用来控制程序循环的,也就是控制程序在什么时候可以结束循环的。我们定义了一个 Student 的数组,用来存储学生的信息。用一个单独的变量来存储单条的学生信息。int id = -1;char name[NameLength];int choice = 0;int stop = 0;Student students[StudentNumbers];Student student;这里我们通过循环来初始化我们的数组。for (int i = 0; i < StudentNumbers; i++){ students[i].id = i; students[i].flag = 0;}循环语句如果在不改变条件的情况下会一直循环。确保我们的系统可以一直运行。while (stop == 0)在接收到输入后。我们就会通过 switch 来进行相应的匹配。完成对应的操作。这比使用大量的 if 语句简约了很多。switch (choice)在子程序中,也就是实现增、删、改、查这些功能程序中。我们用了循环语句来访问数组中的元素。同时,利用了判断语句与特定的变量,来判断该位置是否存有学生信息。运行结果:utopia@DESKTOP:~$ ./test-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:1请输入学生姓名:张三请输入学生的年龄:22请输入学生成绩:100-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:1请输入学生姓名:李四请输入学生的年龄:21请输入学生成绩:90-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:1请输入学生姓名:王二请输入学生的年龄:23请输入学生成绩:99-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:5******************学生列表******************学生编号:0,学生姓名:张三,年龄:22,成绩:100学生编号:1,学生姓名:李四,年龄:21,成绩:90学生编号:2,学生姓名:王二,年龄:23,成绩:99******************-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:2请输入要修改成绩的学生编号:1请输入新的成绩:80-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:5******************学生列表******************学生编号:0,学生姓名:张三,年龄:22,成绩:100学生编号:1,学生姓名:李四,年龄:21,成绩:80学生编号:2,学生姓名:王二,年龄:23,成绩:99******************-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:4请输入要删除的学生编号:1-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:5******************学生列表******************学生编号:0,学生姓名:张三,年龄:22,成绩:100学生编号:2,学生姓名:王二,年龄:23,成绩:99******************-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:1请输入学生姓名:张五请输入学生的年龄:20请输入学生成绩:70-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:5******************学生列表******************学生编号:0,学生姓名:张三,年龄:22,成绩:100学生编号:1,学生姓名:张五,年龄:20,成绩:70学生编号:2,学生姓名:王二,年龄:23,成绩:99******************-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:3请输入要查找的学生姓名:张五学生编号: 1,学生姓名: 张五,年龄: 20,成绩: 70-------------------------* 学生管理系统 *-------------------------1 添加2 修改成绩3 查询4 删除5 显示学生列表0 退出程序请直接输入数字选项:在程序中,我们首先添加了 3 条学生的记录。然后我们进行了列表显示。接着,我们尝试修改了其中一个学生成绩,并再次查看列表,发现成绩修改生效了。然后,我们删除了一个学生,列表显示结果其已经被删除了。然后我们又尝试添加了一个学生。列表显示结果添加成功。最后我们按照姓名查找了一个学生。
- ES6+ 展开语法 零基础深入浅出讲解 ES6+ 的语法及使用
- 8-1 章节概述 - 开发文章详情接口 Spring Cloud分布式微服务实战
typedef相关搜索
-
tab
table
tableau
tablelayout
table样式
taif
tail
talk
tamcat
tan
target属性
task
tbody
tcl tk
TCP IP
tcp ip协议
tcpdump
tcpip
tcpip协议
tcp连接