• 关于

    define()函数

    的搜索结果

回答

void T##(){}###### #define DEFINE_FUNC(f)  f void DEFINE_FUNC(func1)() {} 更详细的拼接函数名,可以参考gsoap.比如: #define DEFINE_FUNC(f)  fn_##f void DEFINE_FUNC(fun1) {} #######define make_fun(T) ((unsigned long *)T)();
kun坤 2020-06-09 12:16:38 0 浏览量 回答数 0

回答

函数内部对可变参数都用va_list及与它相关的三个宏来处理,这是实现变参参数的关键之处。 在中可以找到va_list的定义: typedef char * va_list; 再介绍与它关系密切的三个宏要介绍下:va_start(),va_end()和va_arg()。 同样在中可以找到这三个宏的定义: #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) #define va_end(ap) ( ap = (va_list)0 ) #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) 其中用到的_INTSIZEOF宏定义如下: #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) 来分析这四个宏: va_end(ap)这个最简单,就是将指针置成NULL。 va_start(ap,v)中ap = (va_list)&v + _INTSIZEOF(v)先是取v的地址,再加上_INTSIZEOF(v)。_INTSIZEOF(v)就有点小复杂了。( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )全是位操作,看起来有点麻烦,其实不然,非常简单的,就是取整到sizeof(int)。比如sizeof(int)为4,1,2,3,4就取4,5,6,7,8就取8。对x向n取整用C语言的算术表达就是((x+n-1)/n)*n,当n为2的幂时可以将最后二步运算换成位操作——将最低 n - 1个二进制位清 0就可以了。 va_arg(ap,t)就是从ap中取出类型为t的数据,并将指针相应后移。如va_arg(ap, int)就表示取出一个int数据并将指针向移四个字节。 因此在函数中先用va_start()得到变参的起始地址,再用va_arg()一个一个取值,最后再用va_end()收尾就可以解析可变参数了。
a123456678 2019-12-02 02:01:46 0 浏览量 回答数 0

问题

关于waitpid函数的一个问题

"深入理解计算机系统"一书中的两个例子, 利用waitpid函数回收僵死子进程。 #include "csapp.h" #define N 30 int main() { int status, i; pid_t pid; ...
杨冬芳 2019-12-01 19:33:47 826 浏览量 回答数 1

万券齐发助力企业上云,爆款产品低至2.2折起!

限量神券最高减1000,抢完即止!云服务器ECS新用户首购低至0.95折!

问题

C语言 如何在宏定义中使用可变参数

有一个记录日志的函数,想用宏定义进行包装,简化调用方法,但是xlc报如下的错误: void _log(const int level, char* file, int line, const char* fmt, ...){ va_...
a123456678 2019-12-01 19:43:24 1151 浏览量 回答数 1

问题

偶数矩阵,神答案,我看不懂

给定矩阵由0,1组成,使用最少的改变(使0变成1),使得任何元素的上下左右元素(如果存在)和为偶数 输入: 测试组数, 矩阵大小n ,矩阵每一个数 输出: 最小翻转次数,无法实现则输出-1有谁能给我解释一下下面代码的check()函数和整段...
a123456678 2019-12-01 19:45:07 851 浏览量 回答数 1

回答

解决如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <semaphore.h> #define SIZE 1024 #define TIMER 5 #define LENTH 4 char buffer[SIZE]; pthread_mutex_t mutex; //设置初始化互斥量 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //设置线程挂起和回复的条件变量 void *thread_play_0(void *arg); void Error_print(int num,char *pStr) //封装一个检测函数,主要检测线程的建立等一系列操作是否正确 { if(num != 0) { perror(pStr); exit(EXIT_FAILURE); } } int main(void) { int ret; pthread_t id; //创建线程 pthread_attr_t thread_attr; //设置线程属性 ret = pthread_attr_init(&thread_attr); Error_print(ret,"Init error\n"); ret = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); //设线程属性为脱离,线程结束后不需要返回,能在后台与主线同时执行 Error_print(ret,"Init error\n"); ret = pthread_mutex_init(&mutex,NULL); Error_print(ret,"Init error\n"); ret = pthread_create(&id, &thread_attr,thread_play_0,NULL); Error_print(ret,"Create error\n"); while(scanf("%s",buffer)) { //设置恢复和退出条件 if(strncmp("stop",buffer,LENTH) == 0) { //退出 pthread_mutex_lock(&mutex); printf("-------Goodbye-------\n"); sleep(1); break; } if(strncmp("start",buffer,TIMER) == 0) { //恢复线程 pthread_mutex_lock(&mutex); pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); sleep(1); } } exit(EXIT_SUCCESS); } void *thread_play_0(void *arg) //线程执行函数 { while (1) { pthread_mutex_lock(&mutex); //循环打印 printf("It's a flash,input stop to stop,input pause to pause.\n"); pthread_mutex_unlock(&mutex); sleep(1); if (strncmp("stop", buffer, LENTH) == 0) { //退出线程 break; } if (strncmp("pause", buffer, TIMER) == 0) { //挂起线程 strcpy(buffer," "); pthread_mutex_lock(&mutex); printf("---------Flash is paused---------\n"); printf("Input start to play the flash again.\n"); pthread_cond_wait(&cond,&mutex); pthread_mutex_unlock(&mutex); } } pthread_exit(NULL); }
杨冬芳 2019-12-02 02:27:29 0 浏览量 回答数 0

问题

单片机智能小车循迹延时

#include #define uchar unsigned char #define uint unsigned int sbit IN1=P1^0; sbit IN2=P1^1; sbit IN3=P1^2; sbit IN4=P...
a123456678 2019-12-01 19:22:33 1068 浏览量 回答数 1

回答

修正:还是去掉会误导Novice的内容吧,不谈C99变长数组的GCC Extension了。你这代码的错误在于,将函数参数声明成数组类型,在C标准中,将参数声明成数组类型等同于声明成指针类型,下面两个声明是等价的:int length(SUB a[]); int length(SUB *a); 而你在length里写sizeof(a),sizeof不是function,它只有两种形式: sizeof unary-expression sizeof ( type-name ) 你在函数中写个 sizeof(a),等同于写sizeof(SUB *),a的类型是SUB *,所以得到的结果是指针的大小,而sizeof(a[0]),等同于sizeof(SUB)。怎么可能正确呢? C中定义数组,习惯用#define N 3这种形式将长度定义成常量。如果数组长度是编译器察看后面初始化式自动计算出来的,也可以这样写啊: #define ARRAY_LEN (sizeof(array)/sizeof(array[0]))sizeof不是函数!它的返回值是编译时期,编译器计算出来的!对于sizeof(array),它是第一种形式,编译器相当于作了这样的操作:先得到array的类型SUB array[4],然后再计算sizeof(SUB array[4])。C语言中数组定义时都是有大小的,所以这种计算一定OK简而言之,在C语言中,你无法写出这样的工具函数:int length(Type a[]);
a123456678 2019-12-02 02:35:56 0 浏览量 回答数 0

回答

修正:还是去掉会误导Novice的内容吧,不谈C99变长数组的GCC Extension了。你这代码的错误在于,将函数参数声明成数组类型,在C标准中,将参数声明成数组类型等同于声明成指针类型,下面两个声明是等价的:int length(SUB a[]); int length(SUB *a); 而你在length里写sizeof(a),sizeof不是function,它只有两种形式: sizeof unary-expression sizeof ( type-name ) 你在函数中写个 sizeof(a),等同于写sizeof(SUB *),a的类型是SUB *,所以得到的结果是指针的大小,而sizeof(a[0]),等同于sizeof(SUB)。怎么可能正确呢? C中定义数组,习惯用#define N 3这种形式将长度定义成常量。如果数组长度是编译器察看后面初始化式自动计算出来的,也可以这样写啊: #define ARRAY_LEN (sizeof(array)/sizeof(array[0]))sizeof不是函数!它的返回值是编译时期,编译器计算出来的!对于sizeof(array),它是第一种形式,编译器相当于作了这样的操作:先得到array的类型SUB array[4],然后再计算sizeof(SUB array[4])。C语言中数组定义时都是有大小的,所以这种计算一定OK简而言之,在C语言中,你无法写出这样的工具函数:int length(Type a[]);
a123456678 2019-12-02 02:36:03 0 浏览量 回答数 0

回答

0?0DLR(liuyu *root) /*中序遍历 递归函数*/ {if(root!=NULL) {if((root->lchild==NULL)&&(root->rchild==NULL)){sum++; printf("%d\n",root->data);} DLR(root->lchild); DLR(root->rchild); } return(0); } 法二: int LeafCount_BiTree(Bitree T)//求二叉树中叶子结点的数目 { if(!T) return 0; //空树没有叶子 else if(!T->lchild&&!T->rchild) return 1; //叶子结点 else return Leaf_Count(T->lchild)+Leaf_Count(T->rchild);//左子树的叶子数加 上右子树的叶子数 }//LeafCount_BiTree 注:上机时要先建树。例如实验二的方案一。 ① 打印叶子结点值(并求总数) 思路:先建树,再从遍历过程中打印结点值并统计。-------------------------写了个比较简单的,包括建立二叉树,还有你需要的递归函数,不懂可追问 #include <stdio.h> #include <malloc.h> #define CURRENT 0 #define LEFT 1 #define RIGHT 2 typedef struct BiTree { char data; //数据 BiTree* lchild; //左孩子节点 BiTree* rchild; //右孩子节点 BiTree* parent; //父节点 }BiTree; void InitBiTree(BiTree* tree) //构造空二叉树 { tree = NULL; } void CreateTree(BiTree* tree, char data) //给二叉树赋值 { tree->data = data; tree->parent = NULL; tree->lchild = NULL; tree->rchild = NULL; } int InsertChild(BiTree* tree, int pos, char data) //给孩子节点赋值 { if (pos == LEFT) { if (tree->lchild != NULL) { printf("insert left child error!\n"); return false; } BiTree* t = (BiTree*)malloc(sizeof(BiTree)); tree->lchild = t; t->data = data; t->lchild = NULL; t->rchild = NULL; t->parent = tree; return 1; } else if (pos == RIGHT) { if (tree->rchild != NULL) { printf("insert right child error!\n"); return 0; } BiTree* t = (BiTree*)malloc(sizeof(BiTree)); tree->rchild = t; t->data = data; t->lchild = NULL; t->rchild = NULL; t->parent = tree; return 1; } return 0; } int PreOrderTraverse(BiTree* tree, int* countchildren, int* countleaves) // 递归函数 { BiTree* p = tree; if (p) { (*countchildren)++; // 如果那个节点有数据,就增加子节点数 int lnull, runll; if (lnull = PreOrderTraverse(p->lchild, countchildren, countleaves)) { if (runll = PreOrderTraverse(p->rchild, countchildren, countleaves)) { if (lnull == -1 && runll == -1) // 如果左右节点都为空,则增加叶子节点数 { (*countleaves)++; } return 1; } } return 0; } else { return -1; } } int main() { BiTree bt; int countchildren = 0; int countleaves = 0; InitBiTree(&bt); CreateTree(&bt, 's'); InsertChild(&bt, LEFT, 'i'); InsertChild(bt.lchild, LEFT, 'A'); InsertChild(bt.lchild->lchild, LEFT, 'x'); InsertChild(bt.lchild, RIGHT, 'B'); InsertChild(bt.lchild->rchild, RIGHT, 'y'); InsertChild(&bt, RIGHT, 'o'); PreOrderTraverse(&bt, &countchildren, &countleaves); printf("countchildren : %d\n", countchildren); printf("countleaves : %d\n", countleaves); return 0; }
聚小编 2019-12-02 01:24:35 0 浏览量 回答数 0

回答

文件 main.cpp 代码如下: #include<malloc.h> // malloc()等 #include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等 #include<stdlib.h> // atoi(),exit() #include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等 #define ClearBiTree DestroyBiTree // 清空二叉树和销毁二叉树的操作一样 typedef struct BiTNode { int data; // 结点的值 BiTNode *lchild,*rchild; // 左右孩子指针 }BiTNode,*BiTree; int Nil=0; // 设整型以0为空 void visit(int e) { printf("%d ",e); // 以整型格式输出 } void InitBiTree(BiTree &T) { // 操作结果:构造空二叉树T T=NULL; } void CreateBiTree(BiTree &T) { // 算法6.4:按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中定义), // 构造二叉链表表示的二叉树T。变量Nil表示空(子)树。修改 int number; scanf("%d",&number); // 输入结点的值 if(number==Nil) // 结点的值为空 T=NULL; else // 结点的值不为空 { T=(BiTree)malloc(sizeof(BiTNode)); // 生成根结点 if(!T) exit(OVERFLOW); T->data=number; // 将值赋给T所指结点 CreateBiTree(T->lchild); // 递归构造左子树 CreateBiTree(T->rchild); // 递归构造右子树 } } void DestroyBiTree(BiTree &T) { // 初始条件:二叉树T存在。操作结果:销毁二叉树T if(T) // 非空树 { DestroyBiTree(T->lchild); // 递归销毁左子树,如无左子树,则不执行任何操作 DestroyBiTree(T->rchild); // 递归销毁右子树,如无右子树,则不执行任何操作 free(T); // 释放根结点 T=NULL; // 空指针赋0 } } void PreOrderTraverse(BiTree T,void(*Visit)(int)) { // 初始条件:二叉树T存在,Visit是对结点操作的应用函数。修改算法6.1 // 操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次 if(T) // T不空 { Visit(T->data); // 先访问根结点 PreOrderTraverse(T->lchild,Visit); // 再先序遍历左子树 PreOrderTraverse(T->rchild,Visit); // 最后先序遍历右子树 } } void InOrderTraverse(BiTree T,void(*Visit)(int)) { // 初始条件:二叉树T存在,Visit是对结点操作的应用函数 // 操作结果:中序递归遍历T,对每个结点调用函数Visit一次且仅一次 if(T) { InOrderTraverse(T->lchild,Visit); // 先中序遍历左子树 Visit(T->data); // 再访问根结点 InOrderTraverse(T->rchild,Visit); // 最后中序遍历右子树 } } void PostOrderTraverse(BiTree T,void(*Visit)(int)) { // 初始条件:二叉树T存在,Visit是对结点操作的应用函数 // 操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次 if(T) // T不空 { PostOrderTraverse(T->lchild,Visit); // 先后序遍历左子树 PostOrderTraverse(T->rchild,Visit); // 再后序遍历右子树 Visit(T->data); // 最后访问根结点 } } void main() { BiTree T; InitBiTree(T); // 初始化二叉树T printf("按先序次序输入二叉树中结点的值,输入0表示节点为空,输入范例:1 2 0 0 3 0 0\n"); CreateBiTree(T); // 建立二叉树T printf("先序递归遍历二叉树:\n"); PreOrderTraverse(T,visit); // 先序递归遍历二叉树T printf("\n中序递归遍历二叉树:\n"); InOrderTraverse(T,visit); // 中序递归遍历二叉树T printf("\n后序递归遍历二叉树:\n"); PostOrderTraverse(T,visit); // 后序递归遍历二叉树T }
琴瑟 2019-12-02 01:25:03 0 浏览量 回答数 0

回答

递归调用本身需要使用系统栈,每次分配函数内存以及栈都需要时间.不过这个过程耗时并不多,可以说,单纯的递归本身并不比非递归慢多少. 然而,实践中就会发现,递归处理部分问题,特别是递推类问题时会表现出效率极低.这个问题的出现是因为重复计算. 举例说,用递归求解斐波那契数列的第n项,一般的递归公式为 f(n) = f(n-1)+f(n-2) f(2) = 1 f(1) = 1 请尝试模拟计算机运行这个递归,你会发现,其中的某一项f(x)并不是只算了一次.当你计算f(5)的时候,你会试图计算f(4)和f(3),然而在你计算f(4)的时候其实也要计算f(3),这样f(3)就被调用了两次. 想象这个过程是指数型扩展的,效率会随着n的增大极快地下降. 要解决这个问题,可以使用记忆化思想. 定义记忆数组r,函数体改为: define f(n): if r[n] is defined, then simply return r[n] as the answer. else, f(n) = f(n-1) + f(n-2) before return the value, take it down in r[n]. 如此改进之后的递归函数效率上与递推算法相差无几.
寒凝雪 2019-12-02 01:24:26 0 浏览量 回答数 0

回答

递归调用本身需要使用系统栈,每次分配函数内存以及栈都需要时间.不过这个过程耗时并不多,可以说,单纯的递归本身并不比非递归慢多少. 然而,实践中就会发现,递归处理部分问题,特别是递推类问题时会表现出效率极低.这个问题的出现是因为重复计算. 举例说,用递归求解斐波那契数列的第n项,一般的递归公式为 f(n) = f(n-1)+f(n-2) f(2) = 1 f(1) = 1 请尝试模拟计算机运行这个递归,你会发现,其中的某一项f(x)并不是只算了一次.当你计算f(5)的时候,你会试图计算f(4)和f(3),然而在你计算f(4)的时候其实也要计算f(3),这样f(3)就被调用了两次. 想象这个过程是指数型扩展的,效率会随着n的增大极快地下降. 要解决这个问题,可以使用记忆化思想. 定义记忆数组r,函数体改为: define f(n): if r[n] is defined, then simply return r[n] as the answer. else, f(n) = f(n-1) + f(n-2) before return the value, take it down in r[n]. 如此改进之后的递归函数效率上与递推算法相差无几.
沉默术士 2019-12-02 01:24:24 0 浏览量 回答数 0

问题

Linux下编译C++文件出现问题

写了一个Course类,编译g++ -std=c++11 Course.cpp时出现提示刚看的C++ Primer,小白,还请给位前辈指点一下,谢谢。Course.h #ifndef COURSE #define COURSE #incl...
杨冬芳 2019-12-01 20:24:10 858 浏览量 回答数 1

回答

知道汉诺塔的递归程序的意思吗 就是先控制一个不动,让剩余的排列好,然后再移动第一个,再排列好剩余的 这个程序也是这个意思 举个例子说 1234 1。先保持1不动,排列234 2。保持2不动,排列34 3。保持3不动,排列4 4。得到4;输出1234。 5。然后跳转到3,将3与4互换, 6。得到3;输出1243。 7。跳转到2,将2与3互换, 8。重复3-6,得1324,1342。 9。跳转到2,将2与4互换,得到1423,1432。 以下省略若干步。。 最后就得到全排列 解答完毕 一个比较好的全排列算法(C语言) -|killniu 发表于 2006-4-18 23:39:00 我有一个比较好的全排列算法,我验证了3、4、5的结果是正确的。 程序中没有使用递归,只是几个循环,速度还令人满意。 在C466A,Win2000的机器上,进行8个数字的全排列,结果不显示,重定向到一个文本文件中,耗时不到一秒钟 。9个数字的全排列耗时6秒种。10个数字的全排列55秒种。(以上都不显示结果,均重定向到一个文本文件) 11个数字的全排列(不显示结果,在原程序中不定义ISPRINT)耗时大约16秒钟。 。 欢迎各位指点 算法为:用两个数组,一个数组存放当前结果,第二个数组是每一个数是否已经使用的标志。比如对10个数进 行全排列,第一个结果是:0 1 2 3 4 5 6 7 8 9。 然后把每一个数的使用标志均置为1。 然后开始主循环: 先打印当前的结果。 在前一个得到的结果中,从后往前找第一个由小到大排列的数。每找一次均置当前位上的数字的使用标志 为0,然后找第一个比这个数大但是没有使用过的数。 比如前一个结果是:4 1 9 7 8 2 5 0 6 3,那么从后往前第一个由小到大排列的数是0,第一个比0大但是没有 使用过的数是3(因为比0大的数字里只有6和3)。最后由小到大依次打印剩余没有使用过的数字。所以下一个 结果是4 1 9 7 8 2 5 3 0 6。 源程序为(在BC++3.0下编译成功): #i nclude<stdio.h>/*这两个库函数是习惯性的加上去的^_^。*/ #i nclude<stdlib.h> #define ISPRINT/*是否打印结果的标志*/ #define MAX 200/*最大的数*/ unsigned int *_NUM;/*用于存放一条结果的数组指针*/ char *_NUMFLAG;/*用于存放是否已经使用的标志*/ #define NUM(j) (*(_NUM+(j)))/*第j位的数字*/ #define NUMFLAG(j) (*(_NUMFLAG+(j)))/*数字j是否已经使用的标志,0为没有使用,1为已经使用*/ #define NUMUSE(j) (*(_NUMFLAG+(*(_NUM+(j)))))/*第j位上的数字是否已经使用的标志,0为没有使用,1为已 经使用*/ void main() { unsigned int number,j; int i; printf(" Input number=");scanf("%u",&number); if((number>=MAX)||(number<=1)){puts("输入数据错误。");exit(-1);} /*初始化内存和第一个结果*/ _NUM=(unsigned int*)malloc(sizeof(unsigned int)*number); if(!_NUM){puts("分配给_NUM出现内存不足");exit(-1);} _NUMFLAG=(char*)malloc(sizeof(char)*number); if(!_NUMFLAG){puts("分配给_NUMFLAG出现内存不足");exit(-1);} for(i=0;i<number;i++)NUM(i)=i,NUMFLAG(i)=1;/*初始化第一条结果和使用标志*/ do{/*主循环*/ #ifdef ISPRINT/*打印结果*/ for(j=0;j<number;j++)printf("%d ",NUM(j));/*打印一条结果。*/ puts("");/*并换行*/ #endif NUMUSE(number-1)=0;//置最后一位数字的使用标志为0. /*在前一个结果中从后往前寻找第一个从小到大排列的数,并存放到变量j中*/ for(i=number-2;i>=0;i--){ NUMUSE(i)=0; if(NUM(i)<NUM(i+1))break; } if(i<0)break;/*从这里退出主循环.*/ for(j=NUM(i)+1;j<number;j++){ if(!NUMFLAG(j))break; } NUMFLAG(j)=1; NUM(i)=j; for(j=0,i++;i<number;j++) if(!NUMFLAG(j))NUM(i++)=j,NUMFLAG(j)=1; }while(1); /*释放内存*/ free(_NUM); free(_NUMFLAG); } /*程序结束*/ 当然了这个程序的速度并不是最快的,程序中还有很大的优化余地,还可以减少一些循环,或者采用其他更好的算法。 下载源程序http://263.csdn.net/FileBBS/files/2001_8/T_387_1.zip
琴瑟 2019-12-02 01:24:37 0 浏览量 回答数 0

问题

函数转换时碰到问题,未破,求助各位朋友,非常感谢!!!

编译时的错误提示: pmd/pmdEDU.cpp: In function ‘int ( getEntryFuncByType(EDU_TYPES))(pmdEDUCB, void*)’:pmd/pmdEDU.cpp:94:4: erro...
杨冬芳 2019-12-01 20:20:17 835 浏览量 回答数 1

问题

函数转换时碰到问题,未破,求助各位朋友,非常感谢!!!

编译时的错误提示: pmd/pmdEDU.cpp: In function ‘int ( getEntryFuncByType(EDU_TYPES))(pmdEDUCB, void*)’:pmd/pmdEDU.cpp:94:4: erro...
杨冬芳 2019-12-01 20:20:17 776 浏览量 回答数 1

问题

Linux文件同步写的阻塞时间疑惑

这里有两份代码,都是读1.dat的内容同步写到2.dat。1.dat的内容是1亿个1,大小95.37MB。另:延迟写的速度大概是2s 1.利用fcntl函数 #include "apue.h" #include &lt;fcntl.h&gt...
a123456678 2019-12-01 19:45:39 992 浏览量 回答数 1

问题

宏中使用函数名的问题

#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #define call_optimized(function, arguments) {\ printf("\n-------...
杨冬芳 2019-12-01 19:34:10 983 浏览量 回答数 1

回答

inline就和它字面意思一样,“将代码插入进去“。 加了inline的函数,我们期望编译器直接将代码插入到调用的地方,比如下面代码 static inline void hello_world(void) { printf("hello world\n"); } int main() { hello_world(); hello_world(); } 那么编译器会把这段代码看成 int main() { printf("hello world\n"); printf("hello world\n"); } 就和宏展开一样。因此省去了函数调用,加快了一点点运行速度。同时代码中有了两个printf("hello world\n"),增加了一点重复的代码,也就是所谓的 使用inline会增加二进制映像的大小。 但是inline不是绝对会有效果的,它更像一种建议,编译器会智能地处理inline,在可以展开的时候才会展开。 有几种情况下使用inline没有效果,其实都和inline本身展开的特点相关。 1.函数地址被引用 typedef void (*hello)(void); int main() { hello f=hello_world; f(); } 这种情况下,inline不会被展开,那么inline没有任何效果。 2. 函数是对外接口,考虑下面这种情况。 a.h ---- #ifndef __A_H__ #define __A_H__ inline void hello_world(void); #endif a.c ---- #include <stdio.h> inline void hello_world(void) { printf("hello world\n"); } main.c ---- #include "a.h" int main() { hello_world(); } 在这个例子中,程序编译时,是先把a.c编译成a.o,main.c编译成main.o,然后将a.o和main.o链接起来。可想而知,在这个过程中,main.c根本没法将hello_world()展开。其实这个情况和情况一是类似的,在这里,hello_world的地址被引用了。只不过这个地址是在链接时候才确定的。 这也是为什么inline函数都是static的。 没有开启优化的情况下gcc默认不展开inline函数,简单的说就是不优化的情况下,inline没有任何作用
a123456678 2019-12-02 03:14:55 0 浏览量 回答数 0

回答

在我的方法中奖提供一个create_delegate函数,可通过下面两种方法来调用:create_delegate(&object, &member_function)create_delegate(&function)第一种方法创建一个对象并提供一个operator()成员函数,第二个方法生成一个函数指针,两种方法都兼容 type function<...>. 1 class A 2 { 3 int i; 4 public: 5 A(int k):i(k) {} 6 7 auto get()const ->int { return i;} 8 auto set(int v)->void { i = v;} 9 10 auto inc(int g)->int& { i+=g; return i;} 11 auto incp(int& g)->int& { g+=i; return g;} 12 13 auto f5 (int a1, int a2, int a3, int a4, int a5)const ->int 14 { 15 return i+a1+a2+a3+a4+a5; 16 } 17 18 auto set_sum4(int &k, int a1, int a2, int a3, int a4)->void 19 { 20 i+=a1+a2+a3+a4; 21 k = i; 22 } 23 24 auto f8 (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const ->int 25 { 26 return i+a1+a2+a3+a4+a5+a6+a7+a8; 27 } 28 29 static auto sqr(double x)->double { return x*x; } 30 }; 请注意你并不需要一定使用 C++ 的 auto 函数语法,你也可以使用传统的方法,然后我们使用下面方法创建一个类:`1A a(11);`接下来我们创建委派: 1 auto set1 = create_delegate(&a,&A::set); 2 auto inc = create_delegate(&a,&A::inc); 3 std::function<int(int&)> incp = create_delegate(&a,&A::incp); 4 auto af5 = create_delegate(&a,&A::f5); 5 auto set_sum4= create_delegate(&a,&A::set_sum4); 6 auto af8 = create_delegate(&a,&A::f8); 7 auto sqr = create_delegate(&A::sqr); // static function </int(int&)> 1 set1(25); 2 int x = 5; 3 int k = inc(x); 4 k = incp(x); 5 std::cout << "a.get():" << a.get() << std::endl; 6 std::cout << "k: " << k << std::endl; 7 std::cout << "x: " << x << std::endl; 8 std::cout << "af5(1,2,3,4,5): " << af5(1,2,3,4,5) << std::endl; 9 10 set_sum4(x,1,2,3,20); 11 std::cout << "after set_sum4(x,1,2,3,20)" << std::endl; 12 std::cout << "a.get(): " << a.get() << std::endl; 13 std::cout << "x: " << x << std::endl; 14 std::cout << "af8(1,2,3,4,5,6,7,8): " << af8(1,2,3,4,5,6,7,8) << std::endl; 15 std::cout << "sqr(2.1): " << sqr(2.1) << std::endl; 执行上述程序的打印结果如下: 1 a.get():30 2 k: 35 3 x: 35 4 af5(1,2,3,4,5): 45 5 after set_sum4(x,1,2,3,20) 6 a.get(): 56 7 x: 56 8 af8(1,2,3,4,5,6,7,8): 92 9 sqr(2.1): 4.41 关键点 对于一个不是 volatile 和 const 的简单函数而言,实现是非常简单的,我们只需要创建一个类保存两个指针,一个是对象,另外一个是成员函数: 1 template <class T, class R, class ... P> 2 struct _mem_delegate 3 { 4 T* m_t; 5 R (T::*m_f)(P ...); 6 _mem_delegate(T* t, R (T::*f)(P ...) ):m_t(t),m_f(f) {} 7 R operator()(P ... p) 8 { 9 return (m_t->*m_f)(p ...); 10 } 11 }; 可变模板 variadic template 允许定义任意个数和类型参数的operator()函数,而create_function 实现只需简单返回该类的对象: 1 template <class T, class R, class ... P> 2 _mem_delegate<T,R,P ...> create_delegate(T* t, R (T::*f)(P ...)) 3 { 4 _mem_delegate<T,R,P ...> d(t,f); 5 return d; 6 } 实际中,我们需要另外的三个实现用于覆盖 const、volatile 和 const volatile 三种成员函数,这也是为什么传统使用 #define 宏很便捷的原因,让你无需重写代码段,下面是完整的实现: 1 template <class F> 2 F* create_delegate(F* f) 3 { 4 return f; 5 } 6 #define _MEM_DELEGATES(_Q,_NAME)\ 7 template <class T, class R, class ... P>\ 8 struct _mem_delegate ## _NAME\ 9 {\ 10 T* m_t;\ 11 R (T::*m_f)(P ...) _Q;\ 12 _mem_delegate ## _NAME(T* t, R (T::*f)(P ...) _Q):m_t(t),m_f(f) {}\ 13 R operator()(P ... p) _Q\ 14 {\ 15 return (m_t->*m_f)(p ...);\ 16 }\ 17 };\ 18 \ 19 template <class T, class R, class ... P>\ 20 _mem_delegate ## _NAME<T,R,P ...> create_delegate(T* t, R (T::*f)(P ...) _Q)\ 21 {\ 22 _mem_delegate ##_NAME<T,R,P ...> d(t,f);\ 23 return d;\ 24 } 25 26 _MEM_DELEGATES(,Z) 27 _MEM_DELEGATES(const,X) 28 _MEM_DELEGATES(volatile,Y) 29 _MEM_DELEGATES(const volatile,W)
a123456678 2019-12-02 01:56:37 0 浏览量 回答数 0

问题

linux socket 求助,总是提示 Connection refused

linux系统 服务器端: #define PROT 8888 #define BACKLOG 5 int main(int argc, char const *argv[]) { int server_socket...
a123456678 2019-12-01 19:55:29 1663 浏览量 回答数 1

问题

C程序编译错误(小程序)

#include #define MAXLINE 100 //most input int compare1(int savewl[]);// array name of save and the first character of t...
a123456678 2019-12-01 20:27:03 837 浏览量 回答数 1

回答

本节主要问题是如何处理15.4小节中提到的Point对象。仔细回一下,在C代码中包含了如下这些工具函数: /* Destructor function for points */ static void del_Point(PyObject *obj) { free(PyCapsule_GetPointer(obj,"Point")); } /* Utility functions */ static Point *PyPoint_AsPoint(PyObject *obj) { return (Point *) PyCapsule_GetPointer(obj, "Point"); } static PyObject *PyPoint_FromPoint(Point *p, int must_free) { return PyCapsule_New(p, "Point", must_free ? del_Point : NULL); } 现在的问题是怎样将 PyPoint_AsPoint() 和 Point_FromPoint() 函数作为API导出, 这样其他扩展模块能使用并链接它们,比如如果你有其他扩展也想使用包装的Point对象。 要解决这个问题,首先要为 sample 扩展写个新的头文件名叫 pysample.h ,如下: /* pysample.h */ #include "Python.h" #include "sample.h" #ifdef __cplusplus extern "C" { #endif /* Public API Table */ typedef struct { Point *(*aspoint)(PyObject *); PyObject *(*frompoint)(Point *, int); } _PointAPIMethods; #ifndef PYSAMPLE_MODULE /* Method table in external module */ static _PointAPIMethods *_point_api = 0; /* Import the API table from sample */ static int import_sample(void) { _point_api = (_PointAPIMethods *) PyCapsule_Import("sample._point_api",0); return (_point_api != NULL) ? 1 : 0; } /* Macros to implement the programming interface */ #define PyPoint_AsPoint(obj) (_point_api->aspoint)(obj) #define PyPoint_FromPoint(obj) (_point_api->frompoint)(obj) #endif #ifdef __cplusplus } #endif 这里最重要的部分是函数指针表 _PointAPIMethods . 它会在导出模块时被初始化,然后导入模块时被查找到。 修改原始的扩展模块来填充表格并将它像下面这样导出: /* pysample.c */ #include "Python.h" #define PYSAMPLE_MODULE #include "pysample.h" ... /* Destructor function for points */ static void del_Point(PyObject *obj) { printf("Deleting point\n"); free(PyCapsule_GetPointer(obj,"Point")); } /* Utility functions */ static Point *PyPoint_AsPoint(PyObject *obj) { return (Point *) PyCapsule_GetPointer(obj, "Point"); } static PyObject *PyPoint_FromPoint(Point *p, int free) { return PyCapsule_New(p, "Point", free ? del_Point : NULL); } static _PointAPIMethods _point_api = { PyPoint_AsPoint, PyPoint_FromPoint }; ... /* Module initialization function */ PyMODINIT_FUNC PyInit_sample(void) { PyObject *m; PyObject *py_point_api; m = PyModule_Create(&samplemodule); if (m == NULL) return NULL; /* Add the Point C API functions */ py_point_api = PyCapsule_New((void *) &_point_api, "sample._point_api", NULL); if (py_point_api) { PyModule_AddObject(m, "_point_api", py_point_api); } return m; } 最后,下面是一个新的扩展模块例子,用来加载并使用这些API函数: /* ptexample.c */ /* Include the header associated with the other module */ #include "pysample.h" /* An extension function that uses the exported API */ static PyObject *print_point(PyObject *self, PyObject *args) { PyObject *obj; Point *p; if (!PyArg_ParseTuple(args,"O", &obj)) { return NULL; } /* Note: This is defined in a different module */ p = PyPoint_AsPoint(obj); if (!p) { return NULL; } printf("%f %f\n", p->x, p->y); return Py_BuildValue(""); } static PyMethodDef PtExampleMethods[] = { {"print_point", print_point, METH_VARARGS, "output a point"}, { NULL, NULL, 0, NULL} }; static struct PyModuleDef ptexamplemodule = { PyModuleDef_HEAD_INIT, "ptexample", /* name of module */ "A module that imports an API", /* Doc string (may be NULL) */ -1, /* Size of per-interpreter state or -1 */ PtExampleMethods /* Method table */ }; /* Module initialization function */ PyMODINIT_FUNC PyInit_ptexample(void) { PyObject *m; m = PyModule_Create(&ptexamplemodule); if (m == NULL) return NULL; /* Import sample, loading its API functions */ if (!import_sample()) { return NULL; } return m; } 编译这个新模块时,你甚至不需要去考虑怎样将函数库或代码跟其他模块链接起来。 例如,你可以像下面这样创建一个简单的 setup.py 文件: # setup.py from distutils.core import setup, Extension setup(name='ptexample', ext_modules=[ Extension('ptexample', ['ptexample.c'], include_dirs = [], # May need pysample.h directory ) ] ) 如果一切正常,你会发现你的新扩展函数能和定义在其他模块中的C API函数一起运行的很好。 >>> import sample >>> p1 = sample.Point(2,3) >>> p1 <capsule object "Point *" at 0x1004ea330> >>> import ptexample >>> ptexample.print_point(p1) 2.000000 3.000000 >>>
哦哦喔 2020-04-17 18:20:13 0 浏览量 回答数 0

问题

关于C++6.0的图像水平镜像变换

关于C++6.0的图像水平镜像变换 头文件 #ifdef MYDLL_EXPORTS #define MYDLL_API __declspec(dllexport) #else #define MYDLL_API __declspec(dl...
a123456678 2019-12-01 20:06:08 1024 浏览量 回答数 1

回答

qsort 功 能: 使用快速排序例程进行排序 用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *)); 各参数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针,用于确定排序的顺序 程序例: #include <iostream> using namespace std; #include <stdlib.h> #include <string.h> int compare( const void *a, const void *b); char * list[5]= {"cat","car","cab","cap","can"}; int main() pascal 例程 program quicksort; const max = 100000; max = 1000; type tlist = array[1..max] of longint; var data : tlist; i : longint; procedure qsort(var a : tlist); procedure sort(l,r: longint); var i,j,x,y: longint; begin i:=l; j:=r; x:=a[(l+r) div 2]; repeat while a[i]<x do inc(i); while x<a[j] do dec(j); if i<=j then begin y:=a[i];a[i]:=a[j];a[j]:=y; inc(i);dec(j); end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r); end; begin sort(1,max); end; begin write('Creating ',Max,' random numbers between 1 and 500000'); randomize; for i:=1 to max do data:=random(500000); writeln; writeln('Sorting...'); qsort(data); writeln; for i:=1 to max do begin write(data:7); if (i mod 10)=0 then writeln; end; end. c/c++ c函数qsort()和bsearch()的用法 使用qsort()排序 并 用 bsearch()搜索是一个比较常用的组合,使用方便快捷。 qsort 的函数原型是void __cdecl qsort ( void *base, size_t num, size_t width, int (__cdecl *comp)(const void *, const void* ) ) 其中base是排序的一个集合数组,num是这个数组元素的个数,width是一个元素的大小,comp是一个比较函数。 比如:对一个长为1000的数组进行排序时,int a[1000]; 那么base应为a,num应为 1000,width应为 sizeof(int),comp函数随自己的命名。 qsort(a,1000,sizeof(int ),comp); 其中comp函数应写为: int comp(const void *a,const void *b) { return *(int *)a-*(int *)b; } 是对一个二维数组的进行排序: int a[1000][2]; 其中按照a[0]的大小进行一个整体的排序,其中a[1]必须和a[0]一起移动交换。 qsort(a,1000,sizeof(int)*2,comp); int comp(const void *a,const void *b) { return ((int *)a)[0]-((int *)b)[0]; } 对字符串进行一个排序: char a[1000][20]; qsort(a,1000,sizeof(char)*20,comp); int comp(const void *a,const void *b { return strcmp((char *)a,(char *)b); } 对一个结构体进行排序: typedef struct str { char str1[11]; char str2[11]; }str,*stri; str strin[100001]=; int compare(const void *a,const void *b) { return strcmp( ((str*)a)->str2 , ((str*)b)->str2 ); } qsort(strin,total,sizeof(str),compare); 程序例: #include<iostream.h> #include<stdlib.h> #include<string.h> #define N 8 int compare(const void *a,const void *b); void main() { char s[8][10]={"January","February","March","April","May","June","July","September"}; int i; qsort(s,8,sizeof(char)*10,compare); for(i=0;i<N;i++) { for(j=0;j<10;j++) cout<<s[j]; cout<<endl; } } int compare(const void *a,const void *b) { if(strlen((char *)a)!=strlen((char *)b)) return strlen((char *)a)-strlen((char*)b); return (strcmp((char *)a,(char *)b)); }//vc++ 6.0 // VS2008编译通过,具有代表性的例子 #include <stdlib.h> #include <stdio.h> #include <string.h> int compare(const void *arg1,const void *arg2); int main(int argc,char **argv) { int i; argv++; argc--; qsort((void *)argv,(size_t)argc,sizeof(char *),compare); for(i=0;i<argc;++i) { printf("%s ",argv); printf("\n"); } } int compare(const void *arg1,const void *arg2) { return _stricmp(*(char **)arg1,*(char **)arg2); } 在运行输入cmd,在qsort.exe 参数1 参数2 将会排序 下面讲解下Pascal的快排代码 program kuaipai; var save:array[-1..10000000]of longint;//保存数字的数组 n,i:longint; procedure qsort(x,y:longint); var a,b,c,em,d,mid,e,i,j,k,l:longint; begin i:=x;//i代表第一个数字的数组坐标,下面叫“左指针” j:=y;//j代表第二个数字的数组坐标 叫"右指针" mid:=save[(x+y)div 2];//取,这2个数字中间的数组坐标(二分) repeat while save[i]<mid do inc(i); //在中间这个数字的左边,找比中间数大的数字 while save[j]>mid do dec(j);//在中间数右边,找比中间数小的数字 if i<=j//如果左指针在右指针左边 then begin em:=save[i];//交换2个数字的值,这个你会冒泡排序,或者选择排序任意一个,应该明白 save[i]:=save[j]; save[j]:=em; inc(i); dec(j); end; until i>j;//左指针跑到右指针右边了。。。 if i<y then qsort(i,y);//如果左指针,没到界限,那么 从左指针到界限进行上述排序 if j>x then qsort(x,j);//如果右指针没跑到,左界限,那么从右指针到左界限排序 end; begin randomize;//优化程序用的,暂时你不用会 readln(n);//读入,表示有N个数字 for i:=1 to n do//读入这N个数字 read(save[i]); qsort(1,n);//从第一个数字,到最后一个数字排序 for i:=1 to n do//输出 write(save[i],' '); end.
游客886 2019-12-02 01:17:29 0 浏览量 回答数 0

问题

Linux 文件 IO 的一个问题

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <...
a123456678 2019-12-01 19:48:25 973 浏览量 回答数 1

问题

C语言中的静态函数是怎么调用的(例如 下面stack.cpp 最后里面的Stackincrease_H函数)

#ifndef _STACK_H #define _STACK_H // // 定义栈的通用类型 数据结构 // 使用线性表的存储结构思想,在数据模型中记录存储容量,和数据实际存储容量 #define STACKSTORAGE...
a123456678 2019-12-01 19:48:06 846 浏览量 回答数 1

回答

1;如wolf所说,多一个&a,多return 0;2;a,b,c没定义3;我记得标准c是没max函数的。看不到你的include,不知道你引用了哪些头文件。应该要定义一个max宏:三#define max(x,y) (((x)>(y))?(x),(y))
a123456678 2019-12-02 02:16:23 0 浏览量 回答数 0

问题

Linux 文件 IO 的一个问题

在下面的代码中:在下面的代码中: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h&...
a123456678 2019-12-01 20:07:45 844 浏览量 回答数 1
阿里云企业服务平台 陈四清的老板信息查询 上海奇点人才服务相关的云产品 爱迪商标注册信息 安徽华轩堂药业的公司信息查询 小程序定制 上海微企信息技术相关的云产品 国内短信套餐包 ECS云服务器安全配置相关的云产品 天籁阁商标注册信息 开发者问答 阿里云建站 自然场景识别相关的云产品 万网 小程序开发制作 视频内容分析 视频集锦 代理记账服务 北京芙蓉天下的公司信息查询