Question: 关于51单片机的交流电压表设计的程序，有些不理解，有没有哪位仁兄帮忙解释下，主要是写论文需要

你说你有一些不理解，不知道你哪里不理解。 这个程序就2块。 1. 读取ADC0809的值 2. 把读取的数字值换算成真实值，然后显示出来。  根据程序来看，你硬件只能显示四位数，用的共阴，扫描方式。


Question: C语言疑惑题

宏定义在预编译阶段是要展开的，展开就是8 > 2 ? 8 : 2 * 5.0，结果可想而知， 如果加上括号，就是(8 > 2 ? 8 : 2) * 5.0 结果就是40.0

理解和讨论之前请先学会如何观察！  VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

#define 宏定义只是单纯的替换文本

引用 1 楼 user-6 的回复:宏是展开，展开后注意运算顺序 A(8,2)*5.0等价于(8>2)?8:2*5.0，所以结果是8 +1. 宏定义单纯展开，这种一般写成inline函数或者加足够多的()

将表达式替换进去，相当于8 > 2 ？8  : 2*5.0，乘的是b的值，但没有意义，表达式已经选了8为最终结果。加个括号之后，会先计算表达式值为8再乘5，结果为40


Question: 新手提问：关于若干行整数要怎么处理？用数组吗？

是的，这题有一个陷阱，否则太简单了 这样改一下就好了（除非他整出-0这种流氓的测试用例）   while (scanf("%d%d", &a, &b) != EOF)     printf("Case %d: %d %c %d = %d\n",             c++, a, b < 0 ? '-' : '+', b < 0 ? -b : b, a + b);

引用 5 楼 早打大打打核战争 的回复:读一行输出一行，直到碰到EOF #include <stdio.h>  int main() {   int a, b, c = 1;    while (scanf("%d%d", &a, &b) != EOF)     printf("Case %d: %d + %d = %d\n", c++, a, b, a + b);    return 0; } 有问题的 比如  输入  -10 -5 输出应该是  Case 1: -10 - 5 = -15 你会输出 -10 + -5

用三个int变量就可以了，然后循环执行； num1, num2, sum

确实破题目，如果一次输入几千行的整数，再加上printf的输出，你们学校的机器处理时间绝对会超过1000ms. printf输出屏幕很耗时。

这种破题目出得就不严谨，不过你可以输入一行就输出一行来做，不会有问题

用getline吧。然后得到两个整数，再输出。退出条件是，没有得到两个整数


Question: POJ1789简单的最小生成树问题 实例过了，却总是WA

自己设计的一些例子也都过了且答案和自己料想的一样，求问为什么oj上却一直WA


Question: 将1到20，放在长度19的数组里，有一个数没有在里面，编程实现输入的过程

引用 3 楼 自信男孩 的回复:初始化一个数组为0，然后根据输入的数据与小标之间的对应关系，可以很好解决你的问题。 比如输入12，判断一下arr[12-1] == 12，如果等于说明已经输入，提示这次失败。  这个得看题目，除了这个数据结构是否还允许用其他的记录。你这样玩只能记录1-19, 20是否在里面必须要一个额外变量，如果不允许其他的数据结构就只能遍历，允许的话倒是能用if (!valid(value)) return; if (value>=20) {...}else{ a[value-1]=value ...}

如果只能用数组作为数据结构的话，每次输入先判断有消息，然后for判断一次是否重复即可，记录数据，length+1

int arr[20] = {0}; 输入一个置位一个 arr[data] = 1


Question: 数据结构C语言问题

简单来说没做完排序，代码有问题 引用 2 楼 qq_36984590 的回复:[quote=引用 1 楼 636f6c696e的回复:]main->Fcfs 事实上Fcfs内部不能称之为排序，因为他只做了冒泡排序的一轮，生成的数据并非是有序 Fcfs不是调用的void Fcfs这个函数吗，这个排序是什么时候用到的啊[/quote]

那我是不是把这段去了，也没有影响。

引用 1 楼 636f6c696e的回复:main->Fcfs 事实上Fcfs内部不能称之为排序，因为他只做了冒泡排序的一轮，生成的数据并非是有序 Fcfs不是调用的void Fcfs这个函数吗，这个排序是什么时候用到的啊

引用 5 楼 user-2的回复:for(i=0;i<n;i++) {   if(a[i].chansheng<a[i-1].wancheng)   {     a[i].wancheng=a[i-1].wancheng+a[i].wufu;     a[i].zhouzhuan=a[i].wancheng-a[i].chansheng;     a[i].daiquantime=a[i].zhouzhuan/a[i].wufu;   }   else   {     a[i].wancheng=a[i].chansheng+a[i].wufu;     a[i].zhouzhuan=a[i].wancheng-a[i].chansheng;     a[i].daiquantime=a[i].zhouzhuan/a[i].wufu;   } } 这段摘自你的Fcfs(),你的i从0开始自增，当i=0时， if(a[i].chansheng<a[i-1].wancheng) 实则是  if(a[0].chansheng<a[-1].wancheng)，你不觉得有问题吗？ 嗯嗯，确实有点，if里面应该加个i!=0，谢谢


Question: 想用数据结构的知识建立二叉树，编写一个后序遍历二叉树的非递归算法， 但无法运行出预期结果（提示出现错误），望指教！

引用 1 楼 张润林 的回复:82行的创建二叉树结点那里。  void CreateBiTree(BiTree *bt) { char ch; ch = getchar();     if(ch=='#') *bt=NULL;//bt是指针，*bt是结点，这里应该是bt 。后面也是。你整个这个函数把结点这指针都弄错了，这个函数需要从写     else  { *bt=(BiTree)malloc(sizeof(BiTNode)); //生成一个新结点   这里不要*         (*bt)->data=ch;  // 这里也不要  直接bt->data  结点取值用. 指针用->         CreateBiTree(&((*bt)->LChild)); //生成左子树 函数的参数是bt->Lchlid         CreateBiTree(&((*bt)->RChild)); //生成右子树 } }   113行 p->rchild == q  其他的暂时没找到  你好！很高兴你能给出解决方案，你提出的第113行的错误我已改正， 但是，对于你提出的82行代码的结点和指针的问题，我觉得没有问题，因为你看我18到23行的代码是把BiTree定义为结构体指针。 所以，BiTree *bt所定义的“*bt”按我理解应该是指针类型，而bt是“指针的指针”。 如果按照你的理解，应该还要将void CreateBiTree(BiTree *bt)改为void CreateBiTree(BiTree bt)，并将下方的 CreateBiTree递归操作中的取地址符“&”去掉。 我按你的方法修改后，运行程序结果还是原来的错误运行结果（如上面我的运行结果截图） 这该如何是好？

仅供参考：#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int nn=0; int CreateBiTree(BiTree *T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         *T = NULL;     } else {         *T = (BiTree)malloc(sizeof(BiTNode)); nn++;         (*T)->data = data;         //生成根结点         CreateBiTree(&(*T)->lchild);//构造左子树         CreateBiTree(&(*T)->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             p = p->rchild;          //访问右子树         }     }     free(stack); } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             printf("%c ",p->data);             p = p->rchild;          //访问右子树         }     }     free(stack); }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     BiTreePost *stack=(BiTreePost *)malloc(nn*sizeof(BiTreePost));     int sp=0;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || sp) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack[sp]=BT;sp++;       //存入栈中             p = p->lchild;         }         while (sp && (stack[sp-1])->tag == 'R') {//左右子树访问完毕访问根节点             sp--;BT=stack[sp];        //退栈             printf("%c ",BT->biTree->data);             free(BT);         }         if (sp) {//遍历右子树             BT=stack[sp-1];             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     }     free(stack); } void LevelOrder(BiTree T) {//层次遍历     BiTree p;     BiTree *queue;     int h=0,t=0,n=0;      if (T == NULL) return;     p=T;     queue=(BiTree *)malloc(nn*sizeof(BiTree));     queue[t]=p;t=(t+1)%10;n++;//根节点入队     while (n) {    //队列不空循环         p=queue[h];             //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         h=(h+1)%10;n--;         //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue[t]=p->lchild;t=(t+1)%10;n++;         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue[t]=p->rchild;t=(t+1)%10;n++;         }     }     free(queue); } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(&T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G


Question: c/c++ 顺序 Excel 修改？ 全局变量 结构体 字符分割

引用 2 楼 user-1的回复:[quote=引用 1 楼 qq_45220742 的回复:] 在线付费求解 文件名字叫xxx.xls又不是一定要求用excel格式，你以个文本文件叫xxx.xls不行吗 你自己可以读取就行了，读写xls文件不用库只用c估计没几个人能做到,office文档格式都是不公开的，谁没事研究这个[/quote] 那就TXT在c中读取文件用户输入 比如录入成绩

哇啦，大佬能私聊吗emmmm

引用 1 楼 qq_45220742 的回复:在线付费求解 文件名字叫xxx.xls又不是一定要求用excel格式，你以个文本文件叫xxx.xls不行吗 你自己可以读取就行了，读写xls文件不用库只用c估计没几个人能做到,office文档格式都是不公开的，谁没事研究这个

在线付费求解


Question: 编程实战综合测评系统大作业

这个点。。。有没有程序员冒个泡给点提示啥的


Question: cprimerplus p165面程序清单跑不出来

引用 3 楼 真相重于对错 的回复：for (index = 0; index < SIZE; index++);	//这句 printf("%5d", score[index]); printf("\n"); for (index = 0; index < SIZE; index++);//还有这句把for语句后面的分号去掉昨天找到了，太难发现了

头文件单独放了


Question: 救救孩子吧

#include<iostream> using namespace std;  int main(){ 	int width = 5, height = 5; 	for(int i=0;i<height;i++){ 		for (int j = 0; j < width; j++) { 				//二维表格，i，j代表第i行第j列，打印图形只不过是找ij的关系填表 		} 	} 	return 0; }


Question: 如何用 c语言实现 png输出

百度搜相关关键字。

有个库叫libpng，你可以在github上面找到


Question: 小白求书

谭浩强的C语言程序设计

引用 4 楼 云海有潮 的回复:[quote=引用 3 楼 六道佩恩的回复:]其实你再晚几个月问的话，应该有一本不错的书可以推荐 ？？？这其中还有什么门道吗[/quote] 我有个朋友在写书，，应该就是写的C语言的，

K&R的C语言程序设计跟Cprimerplus

引用 3 楼 六道佩恩的回复:其实你再晚几个月问的话，应该有一本不错的书可以推荐 ？？？这其中还有什么门道吗

C语言教程（附带C语言100例）http://download.csdn.net/detail/zhao4zhong1/8830817

其实你再晚几个月问的话，应该有一本不错的书可以推荐


Question: 求助fets读取txt的问题

解决啦，谢谢大家，因为用的是fscanf-s所以出错了

仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8

发你的文件上来我看下

引用 8 楼 user-2的回复:[quote=引用 7 楼 qq_36927001 的回复:] [quote=引用 5 楼 user-2的回复:][quote=引用 4 楼 user-2 的回复:] [quote=引用 3 楼 qq_36927001 的回复:] [quote=引用 1 楼 user-2的回复:]fgets读取一行,这个文件第一项具体有几个字符 fgets(name,sizeof(name),fp2)到7个字符就停止读取了 你可以用fgets先读取整行到内存,然后用scanf正则表达式读取字行串容错能力更好些 比如第一行，前七个字符可以是1+6个空格吗？[/quote] 可以，你这样读取程序通用性太差了，文件打个空格也得想半天，不小心弄错了，就没法运行了 char read_str[256]; fgets(read_str,256,fp2); sscanf(read_str,"%[^ ]%*[^0-9]%lf%*[^0-9]%lf[0-9.]",name,&x,&y);   没写去除前导空格，第一列必须顶格，需要的去查参数[/quote]  这样也可以  sscanf(read_str,"%s %lf %lf",name,&x,&y);[/quote] 还是不可以，只读进来了第一个字符串就出错了，read-str也被清空了[/quote] 那有可能你的分格符不是空格，是TAB，处理一下就可以了[/quote] 是空格，现在问题是遇到多个空格就崩了

引用 7 楼 qq_36927001 的回复:[quote=引用 5 楼 user-2的回复:][quote=引用 4 楼 user-2 的回复:] [quote=引用 3 楼 qq_36927001 的回复:] [quote=引用 1 楼 user-2的回复:]fgets读取一行,这个文件第一项具体有几个字符 fgets(name,sizeof(name),fp2)到7个字符就停止读取了 你可以用fgets先读取整行到内存,然后用scanf正则表达式读取字行串容错能力更好些 比如第一行，前七个字符可以是1+6个空格吗？[/quote] 可以，你这样读取程序通用性太差了，文件打个空格也得想半天，不小心弄错了，就没法运行了 char read_str[256]; fgets(read_str,256,fp2); sscanf(read_str,"%[^ ]%*[^0-9]%lf%*[^0-9]%lf[0-9.]",name,&x,&y);   没写去除前导空格，第一列必须顶格，需要的去查参数[/quote]  这样也可以  sscanf(read_str,"%s %lf %lf",name,&x,&y);[/quote] 还是不可以，只读进来了第一个字符串就出错了，read-str也被清空了[/quote] 那有可能你的分格符不是空格，是TAB，处理一下就可以了

引用 5 楼 user-2的回复:[quote=引用 4 楼 user-2 的回复:] [quote=引用 3 楼 qq_36927001 的回复:] [quote=引用 1 楼 user-2的回复:]fgets读取一行,这个文件第一项具体有几个字符 fgets(name,sizeof(name),fp2)到7个字符就停止读取了 你可以用fgets先读取整行到内存,然后用scanf正则表达式读取字行串容错能力更好些 比如第一行，前七个字符可以是1+6个空格吗？[/quote] 可以，你这样读取程序通用性太差了，文件打个空格也得想半天，不小心弄错了，就没法运行了 char read_str[256]; fgets(read_str,256,fp2); sscanf(read_str,"%[^ ]%*[^0-9]%lf%*[^0-9]%lf[0-9.]",name,&x,&y);   没写去除前导空格，第一列必须顶格，需要的去查参数[/quote]  这样也可以  sscanf(read_str,"%s %lf %lf",name,&x,&y);[/quote] 还是不可以，只读进来了第一个字符串就出错了，read-str也被清空了

引用 5 楼 user-2的回复:[quote=引用 4 楼 user-2 的回复:] [quote=引用 3 楼 qq_36927001 的回复:] [quote=引用 1 楼 user-2的回复:]fgets读取一行,这个文件第一项具体有几个字符 fgets(name,sizeof(name),fp2)到7个字符就停止读取了 你可以用fgets先读取整行到内存,然后用scanf正则表达式读取字行串容错能力更好些 比如第一行，前七个字符可以是1+6个空格吗？[/quote] 可以，你这样读取程序通用性太差了，文件打个空格也得想半天，不小心弄错了，就没法运行了 char read_str[256]; fgets(read_str,256,fp2); sscanf(read_str,"%[^ ]%*[^0-9]%lf%*[^0-9]%lf[0-9.]",name,&x,&y);   没写去除前导空格，第一列必须顶格，需要的去查参数[/quote]  这样也可以  sscanf(read_str,"%s %lf %lf",name,&x,&y);[/quote] 嗯嗯，感谢大佬，正在看这个函数

引用 4 楼 user-2 的回复:[quote=引用 3 楼 qq_36927001 的回复:] [quote=引用 1 楼 user-2的回复:]fgets读取一行,这个文件第一项具体有几个字符 fgets(name,sizeof(name),fp2)到7个字符就停止读取了 你可以用fgets先读取整行到内存,然后用scanf正则表达式读取字行串容错能力更好些 比如第一行，前七个字符可以是1+6个空格吗？[/quote] 可以，你这样读取程序通用性太差了，文件打个空格也得想半天，不小心弄错了，就没法运行了 char read_str[256]; fgets(read_str,256,fp2); sscanf(read_str,"%[^ ]%*[^0-9]%lf%*[^0-9]%lf[0-9.]",name,&x,&y);   没写去除前导空格，第一列必须顶格，需要的去查参数[/quote]  这样也可以  sscanf(read_str,"%s %lf %lf",name,&x,&y);

引用 3 楼 qq_36927001 的回复:[quote=引用 1 楼 user-2的回复:]fgets读取一行,这个文件第一项具体有几个字符 fgets(name,sizeof(name),fp2)到7个字符就停止读取了 你可以用fgets先读取整行到内存,然后用scanf正则表达式读取字行串容错能力更好些 比如第一行，前七个字符可以是1+6个空格吗？[/quote] 可以，你这样读取程序通用性太差了，文件打个空格也得想半天，不小心弄错了，就没法运行了 char read_str[256]; fgets(read_str,256,fp2); sscanf(read_str,"%[^ ]%*[^0-9]%lf%*[^0-9]%lf[0-9.]",name,&x,&y); 没写去除前导空格，第一列必须顶格，需要的去查参数

引用 1 楼 user-2的回复:fgets读取一行,这个文件第一项具体有几个字符 fgets(name,sizeof(name),fp2)到7个字符就停止读取了 你可以用fgets先读取整行到内存,然后用scanf正则表达式读取字行串容错能力更好些 比如第一行，前七个字符可以是1+6个空格吗？

引用 1 楼 user-2 的回复:fgets读取一行,这个文件第一项具体有几个字符 fgets(name,sizeof(name),fp2)到7个字符就停止读取了 你可以用fgets先读取整行到内存,然后用scanf正则表达式读取字行串容错能力更好些 然后用sscanf正则表达式读取字行串容错能力更好些


学会使用spy++

引用 6 楼 轻箬笠 的回复:[quote=引用 5 楼 六道佩恩 的回复:] 就是说，只在主窗口中使用PostQuitMessage是吧？  我是这么认为的。而且在子窗口调用这个函数，还有可能造成程序的崩溃。[/quote] 程序崩溃是因为资源没释放造成的吗？而且，这样的话，是不是说明子窗口和主窗口必须用不同的窗口类？

引用 5 楼 六道佩恩 的回复:就是说，只在主窗口中使用PostQuitMessage是吧？  我是这么认为的。而且在子窗口调用这个函数，还有可能造成程序的崩溃。

引用 4 楼 轻箬笠 的回复:反正我干了这么多年，没怎么用过这个函数。而且子窗口的话，一般destroywindow基本就可以了 就是说，只在主窗口中使用PostQuitMessage是吧？

引用 3 楼 六道佩恩 的回复:[quote=引用 2 楼 轻箬笠 的回复:] https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-postquitmessage PostQuitMessage function Indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message. 这个函数一般用在WM_DESTROY后面，所以不存在这个问题吧 你发这个我知道啊，所以一般子窗口的处理方式是不发送WM_QUIT消息是吧？[/quote] 反正我干了这么多年，没怎么用过这个函数。而且子窗口的话，一般destroywindow基本就可以了

引用 2 楼 轻箬笠 的回复:https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-postquitmessage PostQuitMessage function Indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message. 这个函数一般用在WM_DESTROY后面，所以不存在这个问题吧 你发这个我知道啊，所以一般子窗口的处理方式是不发送WM_QUIT消息是吧？


Question: PostQuitMessage和PostMessage( WM_QUIT ) 有区别吗？

引用 9 楼 赵4老师 的回复:https://bbs.csdn.net/topics/390374955 意外收获啊，感谢感谢

引用 10 楼 早打大打打核战争 的回复:Windows NT 4的源码在1999年就泄露了，Windows 2000的源码在2001年也泄露了，楼主到现在还不知道~~~ 完全不知道这事。。。 这不是商业机密吗？竟然会泄漏？？

参考PostQuitMessage源代码

引用 5 楼 赵4老师 的回复:windows_2000_source_code\win2k\private\ntos\w32\ntuser\client\client.c     3381: /**************************************************************************\     3382: * PostQuitMessage     3383: *     3384: * 22-Jul-1991 mikeke    Created     3385: \**************************************************************************/     3386:      3387: VOID PostQuitMessage(     3388:     int nExitCode)     3389: {     3390:     NtUserCallOneParam(nExitCode, SFI__POSTQUITMESSAGE);     3391: }  哇，强，竟然有源码，你是怎么弄到的，可以发我一份吗？ 还有就是，我觉得这几个源码给的有问题，虽然PostQuitMessage的源码给了，但是它调用的NtUserCallOneParam没有；PostMessage没有，在WU32PostMessage里调用了PostMessage应该是更低一层的函数，所以对比WU32PostMessage和只有一行代码的PostQuitMessage，额，感觉没啥用啊

d:\windows_2000_source_code\win2k\private\mvdm\wow32\wumsg.c      1509: /*++     1510:     void PostQuitMessage(<nExitCode>)     1511:     int <nExitCode>;     1512:      1513:     The %PostQuitMessage% function informs Windows that the application wishes     1514:     to terminate execution. It is typically used in response to a WM_DESTROY     1515:     message.     1516:      1517:     The %PostQuitMessage% function posts a WM_QUIT message to the application     1518:     and returns immediately; the function merely informs the system that the     1519:     application wants to quit sometime in the future.     1520:      1521:     When the application receives the WM_QUIT message, it should exit the     1522:     message loop in the main function and return control to Windows. The exit     1523:     code returned to Windows must be the <wParam> parameter of the WM_QUIT     1524:     message.     1525:      1526:     <nExitCode>     1527:         Specifies an application exit code. It is used as the wParam parameter     1528:         of the WM_QUIT message.     1529:      1530:     This function does not return a value.     1531: --*/     1532:      1533: ULONG FASTCALL WU32PostQuitMessage(PVDMFRAME pFrame)     1534: {     1535:     register PPOSTQUITMESSAGE16 parg16;     1536:      1537:     GETARGPTR(pFrame, sizeof(POSTQUITMESSAGE16), parg16);     1538:      1539:     PostQuitMessage(INT32(parg16->wExitCode));     1540:      1541:     FREEARGPTR(parg16);     1542:     RETURN(0);     1543: }

d:\windows_2000_source_code\win2k\private\mvdm\wow32\wumsg.c:      1338: /*++     1339:     BOOL PostMessage(<hwnd>, <msg>, <wParam>, <lParam>)     1340:     HWND <hwnd>;     1341:     WORD <msg>;     1342:     WORD <wParam>;     1343:     LONG <lParam>;     1344:      1345:     The %PostMessage% function places a message in a window's application queue,     1346:     and then returns without waiting for the corresponding window to process the     1347:     message. Messages in a message queue are retrieved by calls to the     1348:     %GetMessage% or %PeekMessage% function.     1349:      1350:     .*     1351:     .* DA's: the following parameters section should be identical to the     1352:     .*       parameters section in the sdmsg.ref file. If there is a change     1353:     .*       to this section, the identical change should be made in the other     1354:     .*       file.     1355:     .*     1356:      1357:     <hwnd>     1358:         Identifies the window that is to receive the message. If this parameter     1359:         is 0xFFFF (-1), the message is sent to all top-level windows.     1360:      1361:     <msg>     1362:         Specifies the message to be sent.     1363:      1364:     <wParam>     1365:         Specifies additional message information. The contents of this     1366:         parameter depends on the message being sent.     1367:      1368:     <lParam>     1369:         Specifies additional message information. The contents of this     1370:         parameter depends on the message being sent.     1371:      1372:     The return value is TRUE if the message is posted, or FALSE if it is not.     1373:      1374:     An application should never use the %PostMessage% function to send a message     1375:     to a control.     1376:      1377:     .cmt     1378:     27-Oct-1990 [ralphw]     1379:      1380:     The following is a rewording of the previous documentation. However, it     1381:     needs confirmation from development as to its technical accuracy before it     1382:     can be released for public consumption.     1383:      1384:     If the message is being sent to another application, and the <wParam> or     1385:     <lParam> parameters are used to pass a handle or pointer to global memory,     1386:     the memory should be allocated by the %GlobalAlloc% function using the     1387:     GMEM_NOT_BANKED flag. In a system using expanded memory (EMS), this ensures     1388:     that the memory is not in in a different bank of memory from the application     1389:     using the memory.     1390:     .endcmt     1391: --*/     1392:      1393: ULONG FASTCALL WU32PostMessage(PVDMFRAME pFrame)     1394: {     1395:     LONG l;     1396:     UINT f2;     1397:     WPARAM f3;     1398:     LPARAM f4;     1399:     HWND hwnd;     1400:     register PPOSTMESSAGE16 parg16;     1401:     MSGPARAMEX mpex;     1402:     DWORD err = NO_ERROR;     1403:      1404:     GETARGPTR(pFrame, sizeof(POSTMESSAGE16), parg16);     1405:      1406:     // Apps should never use PostMessage to post messages that have     1407:     // pointers to structures, because those messages will show up in     1408:     // GetMessage, and if GetMessage tries to thunk them (ie, tries to     1409:     // call back to the 16-bit kernel to allocate some 16-bit memory to     1410:     // copy the converted 32-bit structure into), we have no way of     1411:     // knowing when to free that 16-bit memory.     1412:     //     1413:     // BUGBUG 22-Aug-91 JeffPar:  a flag should be added to ThunkMsg16     1414:     // indicating whether or not such allocations are permissible;  this     1415:     // flag should be passed on to all the ThunkXXMsg16 subfunctions,     1416:     // and each of those subfunctions should assert the flag is false     1417:     // whenever allocating 16-bit memory.     1418:      1419:      1420:     //     1421:     // Used by 16->32 DDE thunkers.     1422:     //     1423:      1424:     WOW32ASSERT(fWhoCalled == FALSE);     1425:     fWhoCalled = WOWDDE_POSTMESSAGE;     1426:      1427:     f2 = (UINT)WORD32(parg16->f2);     1428:     f3 = (WPARAM)(WORD32(parg16->f3));     1429:     f4 = (LPARAM)(LONG32(parg16->f4));     1430:      1431:     mpex.lReturn = 0;     1432:     mpex.Parm16.WndProc.hwnd   = parg16->f1;     1433:     mpex.Parm16.WndProc.wMsg   = (WORD)f2;     1434:     mpex.Parm16.WndProc.wParam = (WORD)f3;     1435:     mpex.Parm16.WndProc.lParam = f4;     1436:     mpex.iMsgThunkClass = 0;     1437:      1438:     // The Reader.exe shipped with Lotus 123MM version has a message     1439:     // synchronization problem.  Force proper synchronization by     1440:     // converting this PostMessage call to a SendMessage().     1441:     if ((f2 == WM_VSCROLL) &&     1442:          ((f3 == SB_THUMBTRACK) || (f3 == SB_THUMBPOSITION)) &&     1443:          (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_SENDPOSTEDMSG) ) {     1444:      1445:         l = (LONG)WU32SendMessage(pFrame);     1446:         FREEARGPTR(parg16);     1447:         RETURN((ULONG) l);     1448:     }     1449:      1450:     hwnd = ThunkMsg16(&mpex);     1451:      1452:     // Note: ThunkMsg16 may have caused 16-bit memory movement     1453:     FREEARGPTR(pFrame);     1454:     FREEARGPTR(parg16);     1455:      1456:     WOW32ASSERT(fWhoCalled == WOWDDE_POSTMESSAGE);     1457:     fWhoCalled = FALSE;     1458:     if (hwnd) {     1459:      1460:         l = PostMessage(hwnd, mpex.uMsg, mpex.uParam, mpex.lParam);     1461:      1462:         if (!l)     1463:             err = GetLastError();     1464:      1465:         mpex.lReturn = l;     1466:         if (MSG16NEEDSTHUNKING(&mpex)) {     1467:             (mpex.lpfnUnThunk16)(&mpex);     1468:         }     1469:      1470:      1471:         // If the post message failed, then the message was probably one     1472:         // that has pointers and therefore can not be posted. (MetaDesign     1473:         // tries to post these kind of messages.) If the destination was a     1474:         // WOW app, then make it into a private message, and try the post     1475:         // again.  We don't have to worry about thunking since both the source     1476:         // and destination are in the WOW address space.     1477:      1478:         if (err == ERROR_INVALID_PARAMETER) {     1479:             PWW   pww;     1480:             DWORD dwpid;     1481:      1482:             pww = FindPWW(hwnd);     1483:      1484:             // was added for WM_DRAWITEM messages which are probably intended     1485:             // for owner drawn std-type classes.  see bug #2047 NTBUG4     1486:             if (pww != NULL && GETICLASS(pww, hwnd) != WOWCLASS_WIN16) {     1487:      1488:                 // make sure we're in the same vdm process     1489:                 if (!(GetWindowThreadProcessId(hwnd, &dwpid) &&     1490:                       (dwpid == GetCurrentProcessId()))) {     1491:                           return 0;     1492:                 }     1493:      1494:                 mpex.lReturn = PostMessage(hwnd, f2 | WOWPRIVATEMSG, f3, f4);     1495:             }     1496:         }     1497:     }     1498:      1499:     FREEARGPTR(parg16);     1500:     RETURN((ULONG)mpex.lReturn);     1501: }

引用 2 楼 轻箬笠 的回复:Remarks The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.  When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message.  好像就发个WM_QUIT吧，发完就立即返回了 文字描述里就这一个差别——“该函数只是向系统指示线程在将来某个时间请求退出”，我想过，真的是因为调用了PostQuitMessage才通知系统线程将要退出的吗？我觉得应该是系统检测了WM_QUIT消息开始准备的，既然消息循环都是检测WM_QUIT消息退出，那干嘛非得在调用PostQuitMessage后准备，完全可以检测WM_QUIT来准备

引用 1 楼 赵4老师 的回复:参考PostQuitMessage源代码 windows API不是闭源的吗？


Question: 多线程编程：生产者-消费者问题。

这个例子很简单的。。。至于有偿吗，建议看下侯捷的win32多线程程序设计这本书，讲的很好。其中有你想要的

std::thread 开启2线程，一个负责生产，压入数据，一个负责处理. 生产者通知消费者处理可以用std::mutex和std::condition_variable 来做,记得要做empty判断，通知到的时候正在阻塞才收到，处理中不知道，所以要对消费者的队列判断是否处理完毕，没有处理完毕就继续处理，直到OVER.


Question: 请大佬指点迷津

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。

引用 1 楼 focuslight的回复:划黑线是定义类型为struct mstop的结构变量， 百度typedef   C 中利用scanf()函数输入字符串，在按下回车后'\n'字符是被存储在了缓存区的，如果下一次继续读入字符这个换行符可能会产生影响，也可能不会产生影响。总结如下：  不会产生影响的情况：第二次输入为“字符串”（或数字）；  scanf("%s",a); scanf("%s",b); printf("%s\n",a); printf("%s\n"，b);  如果输入为:  hello world  则输出也为：  hello world  scanf()函数更基于获取单词（get world）而不是获取字符串（get string）；scanf()是以第一个非空白字符开始读入的，故第一次读入字符所输入的'\n'，在第二个scanf()函数开始时被忽略掉了。（“%d”同理）   会产生影响的情况：第二次读入的是‘字符’：  scanf("%c",&a); scanf("%c",&b); printf("%c\n",a); printf("%c\n",b);  如果输入h，在按下回车后会直接输出：  h   则直接就会输出为h和两个空行：   h   因为读入的是字符，所以在第一个字符读完后的'\n', 在运行第二个scanf()时直接被读取了，所以第二个printf()函数输出为两个'\n'; 如果想消除'\n'的影响可以在中间加个getchar()函数； 大佬，现在又有新问题了，就是执行了一两个函数后就会发现，比如输入3但是出来的还是菜单，但按一下enter键，到第二个菜单就可以，这是怎么回事啊

引用 1 楼 focuslight的回复:划黑线是定义类型为struct mstop的结构变量， 百度typedef   C 中利用scanf()函数输入字符串，在按下回车后'\n'字符是被存储在了缓存区的，如果下一次继续读入字符这个换行符可能会产生影响，也可能不会产生影响。总结如下：  不会产生影响的情况：第二次输入为“字符串”（或数字）；  scanf("%s",a); scanf("%s",b); printf("%s\n",a); printf("%s\n"，b);  如果输入为:  hello world  则输出也为：  hello world  scanf()函数更基于获取单词（get world）而不是获取字符串（get string）；scanf()是以第一个非空白字符开始读入的，故第一次读入字符所输入的'\n'，在第二个scanf()函数开始时被忽略掉了。（“%d”同理）   会产生影响的情况：第二次读入的是‘字符’：  scanf("%c",&a); scanf("%c",&b); printf("%c\n",a); printf("%c\n",b);  如果输入h，在按下回车后会直接输出：  h   则直接就会输出为h和两个空行：   h   因为读入的是字符，所以在第一个字符读完后的'\n', 在运行第二个scanf()时直接被读取了，所以第二个printf()函数输出为两个'\n'; 如果想消除'\n'的影响可以在中间加个getchar()函数； 非常感谢你的耐心解答，问题已解决

1.第一个问题，不必在while(ch!=0)外打印菜单并getch();给ch个初始不等于0的值就行了 循环外printf打印菜单开始的到循环的全删了 换成ch=1;   2.定义一个mstop类型的变量 stop


Question: 我有11个十六进制的数，如何把他们拼到一起？

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

#include<iostream> #include<string.h> using namespace std; int main() {     int s[11]{ 0x5, 0xc5, 0xb3, 0xea };     char str[100];     for (int i = 0; i < 4; i++)          sprintf(str + i * 2, %02x", (usigned char)s[i]);     printf("%s", str);     return 0; }

我觉得用个FOR就可以了· test_1 = '易燃易爆炸' bytes = test_1.encode('utf-8')#编码 你们要的十六进制数一长串~~~~巴拉巴拉巴拉什么玩意儿的··· bytes_3 = str(bytes)[2:-1]      #去掉头子和尾巴· bytes_4 = []                         #建个空列表 for i in bytes_3:     if i == '\\' or i == 'x':         continue     else:bytes_4.append(i)     把东西放进去 bytes_5 = ''.join(bytes_4)         #变成一个玩意儿了~ 我是这样的~看大神们了·~

引用 1 楼 user-9 的回复:使用itoa  #include<iostream> #include<string.h> using namespace std; int main() { 	int s[11]{ 0x5, 0xc5, 0xb3, 0xea }; 	char str[100]=""; 	char tmp[10]; 	for (int i = 0; i < 4; i++)  		sprintf(&str[strlen(str)], "%02s", itoa(s[i], tmp, 16)); 	printf("%s", str); 	return 0; }  直接用%02x就可以了，使用snprintf和itoa反而把问题复杂化了

引用 2 楼 lin5161678 的回复:[quote=引用 1 楼 user-9 的回复:] 使用itoa  #include<iostream> #include<string.h> using namespace std; int main() { 	int s[11]{ 0x5, 0xc5, 0xb3, 0xea }; 	char str[100]=""; 	char tmp[10]; 	for (int i = 0; i < 4; i++)  		sprintf(&str[strlen(str)], "%02s", itoa(s[i], tmp, 16)); 	printf("%s", str); 	return 0; } 既然已经知道sprintf 为什么不直接 %02x [/quote] ++ 直接用0x02x就可以了

printf / sprinf

#include<iostream> #include<string.h> using namespace std; int main() {     int s[11]{ 0x5, 0xc5, 0xb3, 0xea };     char str[100];     char tmp[10];     str[0]=0;     for (int i = 0; i < 4; i++)          sprintf(str, "%s%02x",str,(usigned char)s[i]);     printf("%s", str);     return 0; }

引用 2 楼 lin5161678 的回复:[quote=引用 1 楼 user-9 的回复:] 使用itoa  #include<iostream> #include<string.h> using namespace std; int main() { 	int s[11]{ 0x5, 0xc5, 0xb3, 0xea }; 	char str[100]=""; 	char tmp[10]; 	for (int i = 0; i < 4; i++)  		sprintf(&str[strlen(str)], "%02s", itoa(s[i], tmp, 16)); 	printf("%s", str); 	return 0; } 既然已经知道sprintf 为什么不直接 %02x [/quote] 我也这么觉得，没有用itoa的必要  #include<iostream> #include<string.h> using namespace std; int main() {     int s[] = { 0x5, 0xc5, 0xb3, 0xea };     char str[1024]={};     for (int i = 0; i < ARRAYSIZE(s); i++)          sprintf(&str[strlen(str)], "%02x", s[i]);     printf("%s", str);     return 0; }

引用 1 楼 user-9 的回复:使用itoa  #include<iostream> #include<string.h> using namespace std; int main() { 	int s[11]{ 0x5, 0xc5, 0xb3, 0xea }; 	char str[100]=""; 	char tmp[10]; 	for (int i = 0; i < 4; i++)  		sprintf(&str[strlen(str)], "%02s", itoa(s[i], tmp, 16)); 	printf("%s", str); 	return 0; } 既然已经知道sprintf 为什么不直接 %02x


Question: 深度遍历怎么算啊，右边写的这些对吗

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

我看着没问题😊，我也在学数据结构呢！


Question: C语言报错，求帮忙

代码不全不好定位问题呢

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

引用 5 楼 jiayoua1888 的回复:[quote=引用 2 楼 bob76012 的回复:] 增加宣告 LinkList *p; 加上后报这个错：error C2275: 'LinkList' : illegal use of this type as an expression[/quote]  发一下整个project

引用 2 楼 bob76012 的回复:增加宣告 LinkList *p; 加上后报这个错：error C2275: 'LinkList' : illegal use of this type as an expression

引用 1 楼 user-4 的回复:p未定义..怎么定义啊

增加宣告 LinkList *p;

p未定义..


Question: 求教#define的 语句jie'da 指结构体指针

引用 5 楼 user-1 的回复:这里进行了两次强转第一次把运算结果强转成WORD 第二次强转成指向unsigned char xdata的指针类型了解了，原来是两次强转，我再来结合上下文学习学习，谢谢O(∩_∩)O

引用 3 楼 user-1 的回复:这只是 代码中的类型强转，指针在内存中就是一个DWORD值，不存在什么类型的，可是你需要用指针调用数据或函数，就需要告诉这个指针应该怎么去读取对应的内容，就是类型了 比如你内存中有个地址 0x504000 这个地址对应的值为 1 int a=0x504000; int b=*a这样编译器认为是错误的，可是你明白你要干什么所以就可以这样b=*(int*)a把强制转为int指针，然后读取0x504000这个位置存的int值,b=1就是结果 所以这个地方的：(unsigned char xdata *) 并不是定义了一个指向无符号char型的指针，而是一个强制类型转换 把数组test3的第一个元素左移8位并加上第二个元素的结果WORD值 强制转换成指向U char 型的指针？ 不知道我这样理解对不对？

引用 1 楼 user-1 的回复:*(unsigned char xdata *) (WORD)((poniter->test3[0] << 8) + poniter->test3[1]) = poniter->test3[2]把这个运算定义成RECORD() 程序中调用就用宏来代替 *(unsigned char xdata *)   (WORD)    ((poniter->test3[0] << 8) + poniter->test3[1])      =    poniter->test3[2] 这个就是一个a=b的算式，运算优先都用括号了首先感谢您的回答，但是还是不太理解，半路出家小白求解惑，能不能麻烦帮忙再细说一下 运行中调用宏替换以及a=b可以理解，就是程序中record的部分都调用这个把b赋值给a? b:就是结构体里面的test3数组的第三个元素，这应该是一个byte吧？ a：*(unsigned char xdata *)   (WORD)    ((poniter->test3[0] << 8) + poniter->test3[1])    红色的是把数组test3第一个元素左移8位然后加上数组test3第二个元素 绿色的是定义了一个指向无符号类型 char字符的指针 然后就不理解了，WORD 用在这里怎么理解？这个定义出来的xdata指针是先跟*结合解引用还是结合后面的？ 然后b是一个byte 为什么可以赋值给前面的word？  关于第二个define，这个#define another()       (unsigned int) *(unsigned char xdata *)(WORD)((poniter->test3[0] << 8) + poniter->test3[1] ) 没有=，这个是调用another时候用一个指针来替换吗？


Question: 大佬们，帮帮忙

出来了，谢谢呀😊。。。。。。

1/i，int/int==int，因此你得到的一直为0，y始终没有超过3，改为1.0/i


Question: 有点懵，不知道怎么写？

result=a*b*c; printf("体积为:%d",result); return 0;

首先19行缺少分号，其次你这resul应该是通过之前输入的值计算出来，而不是用户手动输入，所以应该改为 prntf("体积为:%d\n", result);

楼上的正解，不过result这个变量最好在声明长宽高变量时一并声明了，有的早期的C编译器是不允许在好多语句之后再声明变量的。 int height,width,long,result;


Question: int[ , ,  ]a 是什么表示法

定义 一个 int数组b, 并且分配大小为int[3]的空间，即定义数组b有3个元素

参照 int[] b=new int[3];

引用 3 楼 jsx_SEVEN 的回复:C#可以这样声明数组 [ , , ]三维数组，[ , ]二维 [3,2,3]三行两列三层 3*2*3=18赞


引用 2 楼 636f6c696e的回复:是Convert.ToInt32吧，这个有四舍五入的 (int)3.9是不做四舍五入，直接舍去小数部分 能回一下我吗？( •̥́ ˍ •̀ू )

楼主是不是打错字了呀，百度根本没有Tolent32和Tolent64

不了解Convert.Tolent32 但推测是四舍五入得到一个整数 那么a是3 b是4 c=(int)3.9，这里不是四舍五入是直接舍弃小数，所以c是3 所以a+b+c是3+4+3=10

引用 1 楼 轻箬笠 的回复:楼主是不是打错字了呀，百度根本没有Tolent32和Tolent64我打错了

引用 2 楼 636f6c696e 的回复:是Convert.ToInt32吧，这个有四舍五入的 (int)3.9是不做四舍五入，直接舍去小数部分 这个回答很棒


Question: 为什么不是2010？

ref x x是引用传递,所以方法里面修改了i的值,外部的x也是同一个对象,所以x.i也是20

引用 1 楼 轻箬笠 的回复:不是做C#的。从C++的角度说下，ref是引用，在传参之后，会改变传入参数的值。比如 void func(int &a) {  a = 20; } int main() { int a = 10; func(a); printf("a=%d\n", a);//这里a已经是20了。因为func传入的参数是引用，所以会改变原来的值  很棒！ return 0; }  引用 1 楼 轻箬笠 的回复:不是做C#的。从C++的角度说下，ref是引用，在传参之后，会改变传入参数的值。比如 void func(int &a) {  a = 20; } int main() { int a = 10; func(a); printf("a=%d\n", a);//这里a已经是20了。因为func传入的参数是引用，所以会改变原来的值 return 0; }很棒


Question: c语言课题求大佬指导下

引用 楼主 qq_45332109的回复:[quote=引用 1 楼 user-1的回复:]是不是西安理工大学的？我也是这个电智的 对对对 你写完没 [/quote]
没写完全不会，没思路

引用 1 楼 user-1的回复:是不是西安理工大学的？我也是这个电智的 对对对 你写完没 😳😳😳😳😳😳

是不是西安理工大学的？我也是这个电智的


Question: G723.1源码程序运行方式

已经搜了很多次了，但是依旧没有答案，不知道该怎么运行

百度搜相关关键字。


Question: C语言求最大公约数最小公倍数的程序

#include<stdio.h> //最大公约数 int gcd(int m, int n)  {     return n == 0 ? m : gcd(n, m % n); } //最小公倍数 int lcm(int m, int n) {     return (long long)m * n / gcd(m, n); } int main(void) {     int m, n, B, S;     printf("请输入两个数:");     scanf("%d%d", &m, &n);     B = lcm(m, n);     S = gcd(m, n);     printf("最大公约数为%d\n", B);     printf("最小公倍数为%d\n", S); }

int max(int M,int n) { 		int temp = M; 		if(m < M) { 			temp = m; 		} 		int i; 		for(i = temp;i >= 2;i--) { 			if(M % i==0 && m %i ==0) { 				break; 			} 		} 		return i; 	}


Question: 数据读取了用不了怎么办

scanf的取址符不全。

引用 1 楼 user-1的回复:scanf的取址符不全。 该改成什么呢？能具体指点一下吗？


Question: 新人学习，有些不懂，还请大佬指教。

第一张图给你答案了，格式不同

不好意思，EBCDIC 里的1个字节需要 8个 bit 才能与ASCII 里 7个bit表示的字符对应上。ASCII 里 7个bit 已经可以表示常用的128个字符（包括不可见的控制字符），用8个bit 则可以表示扩展后的更多字符，具体你可以百度等搜索。ASCII 与 EBCDIC 的转换编码表你可以百度 IBM 的网站。

1 个bit 就像1 盏灯，有灭和亮两种状态，用数字表示，可以定义为 0 和 1.  2 个bit 就像2 盏灯，每盏灯有灭和亮两种状态，用数字表示，可以定义为 0 和 1，组合如下：   1#灯  2#灯   0     0   0     1   1     0   1     1  4个状态可以表示4个意思、4个人物等。如你可以定义 00 表示赵一，01表示 钱二，10表示 张三，11表示 李四  3 个bit 就像3 盏灯，每盏灯有灭和亮两种状态，用数字表示，可以定义为 0 和 1，组合如下：   1号灯  2号灯  3号灯 代表含义例如：   0      0      0     我   0      0      1     爱   0      1      0     你   0      1      1     塞   1      0      0     北   1      0      1     的   1      1      0     雪   1      1      1     !  8个状态可以表示8个意思，例如上面的7个字和1个标点，如果你和你女朋友约定好了这些代表含义，你用3 盏灯的8个灭和亮的组合就可以向女朋友传递8个字符的信号。  ... 7 个bit 就像7 盏灯，每盏灯有灭和亮两种状态，用数字表示，可以定义为 0 和 1，总共有2的7次方即128种组合。 用数字表示，可以表达 0 -- 127 。这128个数字用来表达英语里的字母（大写26个、小写26个）、数字字符（0-9）、标点符号(就是我们键盘上常见的) 就足够了。那么哪个数字表示 大写字母 A，哪个数字代表 小写字母 a 呢？不同的人可以做出不同的规定（王八的屁股——规定，没有什么道理可讲）。其中有两个著名的规定： 1）美国国家标准学会(American National Standard Institute , ANSI )制定的ASCII(American Standard Code for Information Interchange，美国信息交换标准代码） 2）IBM 公司制定的 EBCDIC(Extended Binary Coded Decimal Interchange Code，广义二进制编码的十进制交换码）  在 ASCII 里，65代表大写字母 A，97代表小写字母 a。其它的你可以百度等搜索。 在 EBCDIC里，193代表大写字母 A，129代表小写字母 a。其它的你可以百度等搜索。  在 C 语言里，规定（王八的屁股——规定，没有什么道理可讲）char字符在内存里用当前操作系统的编码（ASCII或EBCDIC）的对应值表示，所以在 DOS/WINDOWS/LINUX 等 ASCII 编码的操作系统里，C 语言的 cChar1='a' 和 cChar2=97 两个字符在内存里的值都是 97.但是在IBM AS/400小型计算机或 ES/9000 大型计算机的 OS/400 等操作系统里，C 语言的 cChar1='a'在内存里的值是129，和97的cChar2 不同。 此书的作者可能没有用过 IBM 的小型计算机或大型计算机，不了解 EBCDIC编码。 书上的例子在 Windows 下运行，结果当然是对的。

字符型变量和整数变量在内存中都是一样的，只是范围问题而已，你百度ascii.  char xxx = 'a'; 这句的含义是xxx存储的是'a'的ascii表对应的数字. %c解释成字符类型，%d解释成数字类型

话说，好歹也把代码敲一遍啊，提问的时候COPY上来啊。如果你这么喜欢拍照，我希望你多上传点美女。

你应该先学学怎么提问

Format Specification Fields: printf and wprintf Functions A format specification, which consists of optional and required fields, has the following form:  %[flags] [width] [.precision] [{h | l | I64 | L}]type  Each field of the format specification is a single character or a number signifying a particular format option. The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign is followed by a character that has no meaning as a format field, the character is copied to stdout. For example, to print a percent-sign character, use %%.  The optional fields, which appear before the type character, control other aspects of the formatting, as follows:  type  Required character that determines whether the associated argument is interpreted as a character, a string, or a number (see Table R.3).  flags  Optional character or characters that control justification of output and printing of signs, blanks, decimal points, and octal and hexadecimal prefixes (see Table R.4). More than one flag can appear in a format specification.  width  Optional number that specifies the minimum number of characters output. (See printf Width Specification.)   precision  Optional number that specifies the maximum number of characters printed for all or part of the output field, or the minimum number of digits printed for integer values (see Table R.5).  h | l | I64 | L  Optional prefixes to type-that specify the size of argument (see Table R.6). printf Type Field Characters The type character is the only required format field ; it appears after any optional format fields. The type character determines whether the associated argument is interpreted as a character, string, or number. The types C and S, and the behavior of  c and s with printf functions, are Microsoft extensions and are not ANSI-compatible.   Table R.3   printf Type Field Characters  Character Type Output Format  c int or wint_t When used with printf functions, specifies a single-byte character; when used with wprintf functions, specifies a wide character.  C int or wint_t When used with printf functions, specifies a wide character; when used with wprintf functions, specifies a single-byte character.  d int Signed decimal integer.  i int  Signed decimal integer.  o int  Unsigned octal integer.  u int  Unsigned decimal integer.  x int Unsigned hexadecimal integer, using “abcdef.”  X int Unsigned hexadecimal integer, using “ABCDEF.”  e  double Signed value having the form [ – ]d.dddd e [sign]ddd where d is a single decimal digit, dddd is one or more decimal digits, ddd is exactly three decimal digits, and sign is + or –.  E double Identical to the e format except that E rather than e introduces the exponent.  f double Signed value having the form [ – ]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision.  g double Signed value printed in f or e format, whichever is more compact for the given value and precision. The e format is used only when the exponent of the value is less than –4 or greater than or equal to the precision argument. Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.  G double Identical to the g format, except that E, rather than e, introduces the exponent (where appropriate).  n  Pointer to integer  Number of characters successfully written so far to the stream or buffer; this value is stored in the integer whose address is given as the argument.  p Pointer to void Prints the address pointed to by the argument in the form xxxx:yyyy where xxxx is the segment and yyyy is the offset, and the digits x and y are uppercase hexadecimal digits.  s String  When used with printf functions, specifies a single-byte–character string; when used with wprintf functions, specifies a wide-character string. Characters are printed up to the first null character or until the precision value is reached.  S String When used with printf functions, specifies a wide-character string; when used with wprintf functions, specifies a single-byte–character string. Characters are printed up to the first null character or until the precision value is reached.

int printf(const char *format, ...) 函数把输出写入到标准输出流 stdout ，并根据提供的格式产生输出。  format 可以是一个简单的常量字符串，但是您可以分别指定 %s、%d、%c、%f 等来输出或读取字符串、整数、字符或浮点数。还有许多其他可用的格式选项，可以根据需要使用。如需了解完整的细节，可以查看这些函数的参考手册。

引用 5 楼 冷风1023的回复:存储都是一样的，打印出不同，是因为打印的格式不一样。 printf("%c\n",int1); printf("%d\n",int2); 那，这两种打印格式分别什么意思？

字符a的ascii值为97，所以你得到的值为97. 你把数字或者字母换了，你就得到不一样的值和字符，这样好理解一点。


Question: 如何使用c语言实现选择执行某一程序？？？

system("xx.exe");


Question: c语言求最大值问题

#include<stdio.h> //主函数  int main(){ int max(int x,int y); int a,b,c; scanf("%d %d",&a,&b); c=max(a,b); printf("max=%d\n",c); return 0; } //求两个整数中较大者的max函数 int max(int x,int y) {  if(x>y){ return (x);} else  { return(y);} }

写错了是： if(x>y){ return (x);} else  { return(y);} 引用 1 楼 user-2 的回复:输入是1,2这种格式，而不是1 2 还有你max函数的逻辑是多此一举 if(x>y){ return (x);} else (x<=y) { return(y);}


Question: 为什么运行完第一个压缩文件后，就直接退出了，不能接着运行第二个过程。

自己调试下，一般是出现内存越界程序挂了


Question: 救救孩子，有大神能帮我建立一个链表吗？

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633


Question: 求助 c语言文件转换为链表 链表输出后有乱码

写入读取均以二进制文件模式，格式化写入时尽量可以控制到每个字节，不要用fprintf格式化 fwrite写入整个结构 fread读入整个结构

#include <stdio.h> #include <string.h> #include <stdlib.h>  struct dormitory { 	char room[4]; 	char bed[2]; 	char condition[4]; 	char studentcode[10]; 	char name[20]; 	char classcode[5]; 	int year; 	int month; 	int day; 	 	struct dormitory *next; } *p,*p1,*tail,*tail1,head,head1,t;  void showmenu(); void choose(int a); void save(); void informationA(); void informationB(); void modification(); void cancel(); void file_link(); void show(); int checkcheck1(char a[10]); int checkcheck2(char a[10],char c[10]);  int main() { 	int x,y; 	showmenu(); 	printf("请输入功能序号\n"); 	 	for(x=1;;x++)    { 		scanf("%d",&y); 		if(y!=7) 		{choose(y);} 		else 		{break;} 	}  	return 0;  }  void showmenu( )  { 	 system("cls"); 	 printf("******欢迎使用宿舍管理系统******\n"); 	 printf(" 本宿舍楼包含三层，每层二十个房间，例（301）\n"); 	 printf(" 1.录入床位信息\n"); 	 printf(" 2.输入学号，查询住宿信息\n"); 	 printf(" 3.输入宿舍号，查询住宿信息\n"); 	 printf(" 4.输入宿舍号、床位号，修改住宿信息\n"); 	 printf(" 5.输入宿舍号、床位号，删除住宿信息\n"); 	 printf(" 6.输出全部数据\n"); 	 printf(" 7.退出\n"); 	 return;  }  void choose(int a) { 	 switch(a) 	 { 	 case 1: save();break; 	 case 2: informationA();break; 	 case 3: informationB();break; 	 case 4: modification();break; 	 case 5: cancel();break; 	 case 6: show();break; 	 } 	 return; }   void save()  {    	 int i,x; 	 FILE *fp; 	 	fp=fopen("宿舍信息.txt","a+");       	if(fp==NULL)     { 		printf("文件打开失败\n");       exit(0);  	 } 	printf("成功进入功能1\n");    // printf("输入'0'结束功能\n"); 	printf("请输入要录入的人数\n"); 	scanf("%d",&x); 	printf("宿舍号 床位号 入住情况(yes or no) 学号 姓名 班级 入住时间(例2019 6 25)\n"); 	 	for(i=0;i<x;i++) 	{ 	  	scanf("%s %s %s %s %s %s %d %d %d",t.room,t.bed,t.condition,t.studentcode,t.name,t.classcode,&t.year,&t.month,&t.day); 	if(t.year<=2019 && t.month<=12 && t.day<=31 && checkcheck1(t.studentcode)==1 && checkcheck2(t.room,t.bed)==1 )    { 	 p=&t;  	 fprintf(fp,"%s %s %s %s %s %s %d %d %d\n",p->room,p->bed,p->condition,p->studentcode,p->name,p->classcode,p->year,p->month,p->day); 	} 	else 	{ 	  printf("输入有误\n"); 	  i--; 	  continue; 	}      fprintf(fp,"\n");      } 	  fclose(fp); 	 printf("功能结束\n"); 	 return;  }  void informationA()  { 	  	char code1[10]; 	printf("成功进入功能2\n"); 		file_link();  		printf("请输入学号\n"); 		 scanf("%s",code1); 		 		p1=head1.next; 		 while(p1!=NULL) 		{ if(strcmp(code1,p1->studentcode)==0) 			 { 			  printf("宿舍号 床位号 入住情况(yes or no) 学号 姓名 班级 入住时间(例2019 6 25)\n"); 			  printf("%s %s %s %s %s %s %d %d %d\n",p1->room,p1->bed,p1->condition,p1->studentcode,p1->name,p1->classcode,p1->year,p1->month,p1->day); 		      break; 		      } 		 else 		     p1=p1->next; 		 } 		 printf("功能结束\n"); 		 return;  }  void informationB()  { 	 int x; 	 char code1[10]; 	 	      printf("成功进入功能3\n"); 		 	   file_link();  		printf("请输入宿舍号\n"); 		 scanf("%s",code1); 		 		 p1=head1.next; 		 while(p1!=NULL) 		{  		  if(strcmp(code1,p1->room)==0) 			 { 			  printf("宿舍号 床位号 入住情况(yes or no) 学号 姓名 班级 入住时间(例2019 6 25)\n"); 			  printf("%s %s %s %s %s %s %d %d %d\n",p1->room,p1->bed,p1->condition,p1->studentcode,p1->name,p1->classcode,p1->year,p1->month,p1->day); 		       } 		  p1=p1->next; 		  } 		 printf("功能结束\n"); 		 return;  } void modification() { 	  char a[10],b[10]; 	  FILE *fp; 	  file_link();  	    fp=fopen("宿舍信息.txt","w+");       	   if(fp==NULL)        { 		 printf("文件打开失败\n");          exit(0);  	    } 	   printf("成功进入功能4\n"); 	   printf("请输入相关宿舍号、床位号\n"); 	   scanf("%s%s",a,b); 	    	    	   p1=head1.next; 	    while(p1!=NULL)      {          if(strcmp(p1->room,a)==0 && strcmp(p1->bed,b)==0) 		 { 		  printf("请输入新的住宿信息\n"); 		   printf("宿舍号 床位号 入住情况(yes or no) 学号 姓名 班级 入住时间(例2019 6 25)\n"); 	      scanf("%s %s %s %s %s %s %d %d %d",p1->room,p1->bed,p1->condition,p1->studentcode,p1->name,p1->classcode,&p1->year,&p1->month,&p1->day); 		   		 }        fprintf(fp,"%s %s %s %s %s %s %d %d %d\n",p1->room,p1->bed,p1->condition,p1->studentcode,p1->name,p1->classcode,p1->year,p1->month,p1->day); 	   p1=p1->next;      } 		printf("功能结束\n"); 	fclose(fp);      return ; }  void cancel() { 	  int x; 	  char a[10],b[10]; 	  FILE *fp; 	  file_link();  	    fp=fopen("宿舍信息.txt","w+");       	   if(fp==NULL)        { 		 printf("文件打开失败\n");          exit(0);  	    } 	   printf("成功进入功能4\n"); 	   printf("请输入相关宿舍号、床位号\n"); 	   scanf("%s%s",a,b); 	    	   p1=head1.next; 	    while(p1!=NULL)      {          if(strcmp(p1->room,a)==0 && strcmp(p1->bed,b)==0) 		 { 		 printf("删除成功\n"); 		 } 		 else 		 { 			 fprintf(fp,"%s %s %s %s %s %s %d %d %d\n",p1->room,p1->bed,p1->condition,p1->studentcode,p1->name,p1->classcode,p1->year,p1->month,p1->day); 		 } 		 p1=p1->next; 		        } 		printf("功能结束(若未提示删除成功则删除失败)\n"); 	fclose(fp);      return ; }   void file_link()  {       	     	    FILE *fp; 	    fp=fopen("宿舍信息.txt","a+");         if(fp==NULL)        { 		 printf("文件打开失败\n");          exit(0);  	    } 		head1.next=NULL; 	    tail1=&head1;          while(feof(fp)==0) 		{ 		 p1=(struct dormitory *)malloc(sizeof(struct dormitory));          fscanf(fp,"%s%s%s%s%s%s%d%d%d",p1->room,p1->bed,p1->condition,p1->studentcode,p1->name,p1->classcode,&p1->year,&p1->month,&p1->day); 		 tail1->next=p1; 	     p1->next=NULL; 		 tail1=p1; 		 } 		 		fclose(fp); 	   return;  } void show()  { 	file_link(); 	p1=head1.next; 	while(p1!=NULL) 	{ 	printf("%s %s %s %s %s %s %d %d %d\n",p1->room,p1->bed,p1->condition,p1->studentcode,p1->name,p1->classcode,p1->year,p1->month,p1->day); 	p1=p1->next; 	} 	 	return; }

不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了


Question: =与a++

优先级高说明是先与++结合，然后把这个表达式的值给=

a++是表达式，返回a自增前的值 ++a也是表达式，返回a自增后的值

完全胡扯 引用 2 楼 _cchaos 的回复:++前置 优先级高于=    int b = ++a; // a = a +1   b = a = 3 ++后置 优先级低于=    int b = a++; // b = a = 2   a = a + 1 = 3

把a++理解成函数，返回值是自增前的值

a++ 表达式的值是2 a的值是3  这里是用表达式a++的值给b初始化 不是用a的值给b初始化

int a = 2； int b = a++；  (编译器) int a = 2； int temp = a; // 下面2个乱序 a += 1; int b = temp;

你只要清楚，对b赋值的不是a的值，而是表达式a++的值，就没有你问的这个问题。

引用 1 楼 csucxy 的回复:你只要清楚，对b赋值的不是a的值，而是表达式a++的值，就没有你问的这个问题。+1

关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775 //C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+


Question: 请教VC6 /LINUX GCC 多线程的问题

引用 16 楼 赵4老师 的回复:有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core或dmp文件、……这些方法都不行！ 写日志到文件参考下面： ...     now=localtime(&tb.time); ....   谢谢赵老师！这里 localtime 没有线程安全问题吧？

引用 15 楼 老葱1# 的回复:对数据的准备，根据不同情况，有不同的处理方案， 若数据不要求有序就简单  (  比如 100万条记录，写入读出的顺序无所谓 ) ,  若文件数据是复杂的大结构， 那多个准备线程的数据块要好好定义（比若 块所在线程号，块的大小 ，数据长度）， 还有最后小碎片的策略等等，都要考虑， 至于有序性，那说的是硬盘读写， 至于内容是否需要有序，跟你的读入处理的难易有关（数据的内在相关性复杂度）。  这是 3个 数据准备线程 , 1 个写入线程， 内容无序写入的例子 while( pre_thread_complete < 3 ){           auto p = wait_and_get_block_data();           if( p->data_len == 0 ){  // meas  this pre_thread end                  pre_thread_complete ++ ;          }          else{                 file->write(   p->data, p->block_size ) ;                    if( p->data_len < p->block_size ){                        pre_thread_complete ++ ;                }          } }   若是 结构简单的很大记录条数的文件， 而且不需要记录有序 （比如基于hash），就更简单，线程都不需要写，直接用 omp 。  谢谢老师！我这需要有序。

有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core或dmp文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _MSC_VER     #pragma warning(disable:4996)     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef _MSC_VER void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef _MSC_VER     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef _MSC_VER     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

简化的源码如下，发现写文件线程多写了一块，请各位批评指正！谢谢！   /* 读文件RT:处理PT:写文件WT=1:N:1 测试 cc -DDBG -DDBG1 -DDBG2 -DDBG3 -D_LARGEFILE64_SOURCE mt1n1.c -o mt1n1 -lpthread */ /* 多线程练习程序，将输入文件每行变大写，存为输出文件 */  #ifdef _WIN32 	#if !defined(_MT) 	#error _beginthreadex requires a multithreaded C run-time library. 	#endif  	#define STRICT 1 	#define WIN32_LEAN_AND_MEAN 	#include <windows.h> 	#include <process.h>	/* _beginthread, _endthread */  	#include <io.h>			//_open(),_lseeki64(),_read(),_write(),_close() 	#include <fcntl.h>      //_O_BINARY 	#include <sys/stat.h>   //_S_IWRITE 	#include <time.h>		//_tzset() #else 	#include <pthread.h> 	#include <sys/types.h>	//off64_t 	#include <sys/stat.h>   //off_t, S_IRGRP,... 	#include <unistd.h>		//lseek64(),close(),read(),write() 	#include <fcntl.h>      //open64 	//#include <sys/time.h>	//struct timeval 	 #endif  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h>  #ifdef DBG #define DBGPRT printf #else #define DBGPRT ;// #endif  #ifdef DBG1 #define DBGPRT1 printf #else #define DBGPRT1 ;// #endif  #ifdef DBG2 #define DBGPRT2 printf #else #define DBGPRT2 ;// #endif  #ifdef DBG3 #define DBGPRT3 printf #else #define DBGPRT3 ;// #endif  //取得[a,b)之间的随机整数，使用（rand() % (b-a)）+ a （结果值将含a不含b）。 #define random_1(a,b) ((rand()%(b-a))+a) //取得取得[a,b]之间的随机整数，使用（rand() % (b-a+1)）+ a （结果值将含a含b）. #define random_2(a,b) ((rand()%(b-a+1))+a)  //#define BUF_LEN     16*1024*1024  /* 16MB */ //#define FIND_BACK   64*1024       /* 64KB */ #define BUF_LEN     1*1024  /* 1KB */ #define FIND_BACK   256       /* 0.25KB */ /*   |    16MB          |                   |   |------------------|-------------------|   |         |<-64KB--|   p1           p2    p3 */ size_t buf_len = BUF_LEN;  //最大线程数 #define MAX_PT_NUM  60  typedef struct buf_t { 	int bufstat; //0:free,1:reading,2:read end,3:processing,4:proc end,5:writing 	int fileBlockNo; 	int buflen; 	char *bufptr; } BUF_T;  #ifdef _WIN32 CRITICAL_SECTION g_cs_bufi, g_cs_bufo; HANDLE hEvent_bufi, hEvent_bufo, hEvent_r[MAX_PT_NUM], hEvent_w[MAX_PT_NUM]; #else pthread_mutex_t g_mutex_r[MAX_PT_NUM], g_mutex_w[MAX_PT_NUM], bufi_mutex = PTHREAD_MUTEX_INITIALIZER, bufo_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t g_condv_r[MAX_PT_NUM], g_condv_w[MAX_PT_NUM], bufi_threshold_cv = PTHREAD_COND_INITIALIZER, bufo_threshold_cv = PTHREAD_COND_INITIALIZER; #endif /* int  giReadBufStat[MAX_PT_NUM];  //0:free,1:reading,2:read end,3:processing,4:proc end->0 int  giWriteBufStat[MAX_PT_NUM]; //0:free,3:processing,4:proc end,5:writing,6:write end->0 int  giWriteBufIdx = 0; int  giFileBlockNo[MAX_PT_NUM], giRFBN = 0; */ int  giRFBN = 0; BUF_T gtReadBuf[MAX_PT_NUM]; BUF_T gtWriteBuf[MAX_PT_NUM];  //线程数 int  giTN = 3; int  eof_err = 0, rtf_exit = 0, ptf_exit = 0, wtf_exit = 0; //char *bufi[MAX_PT_NUM], *bufo[MAX_PT_NUM]; //int  bufilen[MAX_PT_NUM], bufolen[MAX_PT_NUM];  struct thread_data { 	long thread_id; 	int  err; 	int  fd; #ifdef _WIN32 	__int64 offset; 	__int64 len; #else 	off_t offset; 	off_t len; #endif }; struct thread_data thread_data_array[MAX_PT_NUM+2];  #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) 	#define DELTA_EPOCH_IN_MICROSECS	11644473600000000Ui64 	#define DELTA_EPOCH_IN_MICROSECS10	116444736000000000Ui64 #else 	#define DELTA_EPOCH_IN_MICROSECS	11644473600000000ULL 	#define DELTA_EPOCH_IN_MICROSECS10	116444736000000000ULL #endif  #if defined(_MSC_VER) /* Winsock.h, Winsock2.h  * Structure used in select() call, taken from the BSD file sys/time.h.  */ struct timeval {         long    tv_sec;         /* seconds */         long    tv_usec;        /* and microseconds */ };  /* Structure crudely representing a timezone.    This is obsolete and should never be used.  */ struct timezone   {     int tz_minuteswest;		/* Minutes west of GMT.  */     int tz_dsttime;		/* Nonzero if DST is ever in effect.  */   };  int gettimeofday(struct timeval *tv, struct timezone *tz) { 	FILETIME ft; 	unsigned __int64 tmpres = 0; 	static int tzflag = 0;  	if (NULL != tv) 	{ 		GetSystemTimeAsFileTime(&ft);  		tmpres |= ft.dwHighDateTime; 		tmpres <<= 32; 		tmpres |= ft.dwLowDateTime;  		tmpres /= 10;  /*convert into microseconds*/ 		/*converting file time to unix epoch*/ 		tmpres -= DELTA_EPOCH_IN_MICROSECS;  		tv->tv_sec = (long)(tmpres / 1000000UL); 		tv->tv_usec = (long)(tmpres % 1000000UL); 	}  	if (NULL != tz) 	{ 		if (!tzflag) 		{ 			_tzset(); 			tzflag++; 		} 		tz->tz_minuteswest = _timezone / 60; 		tz->tz_dsttime = _daylight; 	}  	return 0; }  /* ------------------------------------------------------------------------- */ char *GetWin32ErrMsg(DWORD GLE) { 	LPVOID buf; 	LPVOID lpMsgBuf = (LPVOID)"unknown Windows error"; 	char *szMessage = buf;      if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 					  FORMAT_MESSAGE_IGNORE_INSERTS | 					  FORMAT_MESSAGE_FROM_SYSTEM | 					  FORMAT_MESSAGE_MAX_WIDTH_MASK,         NULL,         GLE,         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),         (LPTSTR) &buf,         0,         NULL)) 	{ 		int  n = strlen(szMessage); 		  if(n > 0 && szMessage[n-1] == '\n') szMessage[--n] = 0; 		  if(n > 0 && szMessage[n-1] == '\r') szMessage[--n] = 0; 		  if(n > 0 && szMessage[n-1] == '\n') szMessage[--n] = 0;         LocalFree(buf); 		return buf;     }     return lpMsgBuf; } #endif   /* ------------------------------------------------------------------------- */ void *strmovcpy(void *dest, const void *src, size_t n) /*    字符串拷贝: 将 src 的 n 个字节复制到 dest, 且在dest 之后加上 NUL    返回 dest */ {   memmove(dest, src, n);   *((char *)dest + n) = '\0';   return dest; }

谢谢老师！我这里是 1个读文件线程、giTN = 3 （可改）个处理线程、1个写文件线程。  现在的问题是： 写文件必须按块顺序。如果文件分7块，现在第3块好了，第1块还没完，必须等到第1块完成才能写，然后第2块，...... 我的测试发现，写完后又写了一块，不知道咋回事 处理线程和写文件线程如何同步最好？请直接改我的代码。谢谢！

每次发帖只能输入10000个字符？发不了完整的28K程序源码

谢谢赵老师！有邮箱方便帮我看看代码吗？发现写文件线程多写了一块

在文件大小相同的前提下：  读刚读过的文件比头次读没读过的文件快  读转速快的硬盘上的文件比读转速慢的硬盘上的文件快  读没有磁盘碎片的文件比读有磁盘碎片的文件快  读文件不处理比边读边处理快  单线程从头到尾一次读文件比多线程分别读文件各部分快（非固态硬盘上）  读固态硬盘上的文件比读普通硬盘上的文件快

这个我研究过， 结论:          多线程写入， 但并不一定有性能提升，           RAID5的随机读取性能非常好（当使用大数据块时）,  但写入慢， 用多线程写入更慢 .          普通无 raid 硬盘，多线程有一定的写入性能提高，我的笔记本线程数4个到6个性能最好，不能再多 （按）。  从原理上多线程应该不如 单线程顺序块写入的速度（磁头是单线程的）。 或许是 线程调度原因，多线程得到了更多的调度时间。   实际使用  3线程数据准备 + 1线程顺序数据写入 。    总之，  所在盘不要有操作系统盘，系统缓存 共享数据文件等，尽量少的其他磁盘操作，写入尽量有序， 目的尽量减少寻磁过程 。 如果一定要多线程写, 则要 8k 对齐。

我把处理部分简化成：把一个大的文本文件内容变成大写，如何把代码发上来？有900多行

https://bbs.bccn.net/viewthread.php?tid=495534&extra=page%3D1&frombbs=1  可从这里复制粘贴我的完整代码进行测试，谢谢！

我看着那些生产者、消费者问题的文章，还是不知道该如何解决我这个实际问题

各位高手请拿我的程序当靶子，狠狠批评！只有这样才能学到真东西。  这论坛怎么样才能上传附件给大家免费下载？以便调试

多线程并发访问需要加锁

#ifdef _WIN32 unsigned __stdcall writef_thread_func(void *threadarg) #else void *writef_thread_func(void *threadarg) #endif { 	struct thread_data *my_data; 	long taskid; 	int  rc = 0, i = 0, k, iWFBN = 1; 	size_t len; #ifdef _WIN32 	__int64 write_len = 0; 	int  write_ret1; #else 	off_t write_len = 0; 	ssize_t write_ret1; #endif  	my_data = (struct thread_data *) threadarg; 	taskid = my_data->thread_id; 	DBGPRT3("@writef_thread_func(), taskid=%ld, fd=%d\n", taskid, my_data->fd);  	while(1) 	{ #ifdef _WIN32 #else DBGPRT3("@writef_thread_func(): thread %ld locking mutex.\n", taskid); pthread_mutex_lock(&bufo_mutex); #endif while (1) { #ifdef _WIN32 EnterCriticalSection( &g_cs_bufo ); #else #endif 	for(i = 0, k = -1; i < giTN; i++) 	{ DBGPRT3("@writef_thread_func(): thread %ld, gtWriteBuf[%d].bufstat=%d, gtWriteBuf[%d].fileBlockNo=%d\n", taskid, i, gtWriteBuf[i].bufstat, i, gtWriteBuf[i].fileBlockNo); if(gtWriteBuf[i].bufstat == 4 && gtWriteBuf[i].fileBlockNo == iWFBN) { 	k = i; 	break; } 	} #ifdef _WIN32 	if(k >= 0) 	{ gtWriteBuf[k].bufstat = 5; LeaveCriticalSection( &g_cs_bufo ); break; 	} 	LeaveCriticalSection( &g_cs_bufo ); #else 	if(k >= 0) break; #endif 	DBGPRT3("=== writef_thread_func(): thread %ld, Going into wait, giRFBN=%d, iWFBN=%d ...\n", taskid, giRFBN, iWFBN); 	if((rtf_exit == 1 || eof_err != 0) && giRFBN == iWFBN) break; #ifdef _WIN32 	DBGPRT3("=== writef_thread_func(): thread %ld, before WaitForSingleObject...\n", taskid); 	WaitForSingleObject( hEvent_bufo, INFINITE ); 	DBGPRT3("*** writef_thread_func(): thread %ld, after WaitForSingleObject.\n", taskid); #else 	pthread_cond_wait(&bufo_threshold_cv, &bufo_mutex); 	DBGPRT3("*** writef_thread_func(): thread %ld Condition signal received.\n", taskid); #endif } #ifdef _WIN32 #else gtWriteBuf[k].bufstat = 5; pthread_mutex_unlock(&bufo_mutex); #endif len = gtWriteBuf[k].buflen; DBGPRT3("@writef_thread_func(): thread %ld Writing file, k=%d, len=%d ...\n", taskid, k, len); #ifdef _WIN32 write_ret1 = _write(my_data->fd, gtWriteBuf[k].bufptr, len); #else write_ret1 = write(my_data->fd, gtWriteBuf[k].bufptr, len); #endif write_len += write_ret1; if(write_ret1 != len) { #ifdef _WIN32 	printf("Error: _write, GetLastError()=%d, errno=%d(%s)\n", GetLastError(), errno, strerror(errno)); #else 	printf("Error: write失败, errno=%d(%s)\n", errno, strerror(errno)); #endif 	rc = -1; 	goto end; } #ifdef _WIN32 _commit(my_data->fd); #endif gtWriteBuf[k].bufstat = 0;  #ifdef _WIN32 SetEvent(hEvent_w[k]); #else DBGPRT3("@writef_thread_func(): thread %ld pthread_cond_signal, write_ret1=%d ...\n", taskid, write_ret1); pthread_cond_signal(&g_condv_w[k]); #endif end: if(rc < 0) break; //if(buf1ostat == 2 || buf2ostat == 2) continue; //if(eof_err != 0) break; //if(rtf_exit != 0 && ptf_exit != 0) break; if((rtf_exit == 1 || eof_err != 0) && giRFBN == iWFBN) break; iWFBN++; 	} 	DBGPRT3("writef_thread_func(): thread %ld End, rc = %d, write_len = %ld.\n", taskid, rc, write_len); 	wtf_exit = 1; 	for(i = 0; i < giTN; i++) 	{ #ifdef _WIN32 SetEvent(hEvent_r[i]); #else pthread_cond_signal(&g_condv_r[i]); #endif 	} 	my_data->err = rc; #ifdef _WIN32 	_endthreadex( 0 ); 	return 0; #else 	pthread_exit(NULL); #endif }  int  main(int argc, char *argv[]) { #ifdef _WIN32 	HANDLE  hThread[MAX_PT_NUM];     unsigned  uiThreadID[MAX_PT_NUM]; #else   pthread_t threads[MAX_PT_NUM]; #endif   int  rc, *taskids[MAX_PT_NUM];   int  i, t = 0;   int  fd1, fd2; 	struct timeval begin, current; 	double elapsed;  	if(argc < 3) 	{ printf("多线程练习程序，将输入文件每行变大写，存为输出文件\n"); printf("用法：%s 输入文件名 输出文件名 [maxBufLen(MB) [maxThreadNum]]\n", argv[0]); return 1; 	} 	if(argc >= 4) buf_len = atoi(argv[3]) * 1024 * 1024L; 	if(argc >= 5) giTN = atoi(argv[4]); 	gettimeofday(&begin, 0); #ifdef _WIN32 	if((fd1 = _open(argv[1], _O_BINARY)) == -1) #else 	if((fd1 = open64(argv[1], O_RDONLY | O_LARGEFILE)) == -1) #endif 	{ printf("Open file error!\n"); return -1; 	} #ifdef _WIN32 	if((fd2 = _open(argv[2], _O_BINARY | _O_WRONLY | _O_CREAT, _S_IREAD | _S_IWRITE)) == -1) #else 	if((fd2 = open64(argv[2], O_CREAT | O_WRONLY | O_TRUNC | O_LARGEFILE, 	                 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) #endif 	{ printf("Create file error!\n"); #ifdef _WIN32 _close(fd1); #else close(fd1); #endif return -2; 	} 	DBGPRT("--- fd1=%d, fd2=%d\n", fd1, fd2);   srand(time(0));    memset(gtReadBuf, 0x00, sizeof(gtReadBuf));   memset(gtWriteBuf, 0x00, sizeof(gtWriteBuf));    #ifdef _WIN32 	InitializeCriticalSection( &g_cs_bufi ); 	InitializeCriticalSection( &g_cs_bufo ); 	hEvent_bufi = CreateEvent( NULL, FALSE, FALSE, NULL ); 	hEvent_bufo = CreateEvent( NULL, FALSE, FALSE, NULL ); #else #endif  	for(i = 0; i < giTN; i++) 	{ if((gtReadBuf[i].bufptr = (char *)malloc(buf_len + 1)) == NULL) { 	printf("Insufficient memory available for bufi[%d]\n", i); 	return -1; } if((gtWriteBuf[i].bufptr = (char *)malloc(buf_len + 1)) == NULL) { 	printf("Insufficient memory available for bufo[%d]\n", i); 	return -1; } #ifdef _WIN32 	hEvent_r[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); 	hEvent_w[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); #else pthread_mutex_init(&g_mutex_r[i], NULL); pthread_mutex_init(&g_mutex_w[i], NULL); pthread_cond_init (&g_condv_r[i], NULL); pthread_cond_init (&g_condv_w[i], NULL); #endif 	} 	t = giTN+1; 	thread_data_array[t].thread_id = t; 	thread_data_array[t].err = 0; 	thread_data_array[t].fd = fd2; 	DBGPRT("Creating thread %d\n", t); #ifdef _WIN32     hThread[t] = (HANDLE)_beginthreadex( NULL,	// security                                      0,// stack size                                      &writef_thread_func,                                      (void *) &thread_data_array[t],	// arg list                                      0,//initflag                                    &uiThreadID[t] );       if ( hThread[t] == 0 ) 	{ printf("ERROR: Failed to create thread: _beginthreadex(writef_thread_func)\n"); exit(-1); 	} #else 	rc = pthread_create(&threads[t], NULL, writef_thread_func, (void *) &thread_data_array[t]); 	if (rc) 	{ printf("ERROR: return code from pthread_create(writef_thread_func) is %d\n", rc); exit(-1); 	} #endif  	for(t = 0; t < giTN; t++) 	{ thread_data_array[t].thread_id = t; thread_data_array[t].err = 0; thread_data_array[t].fd = 0; DBGPRT("Creating thread %d\n", t); #ifdef _WIN32     hThread[t] = (HANDLE)_beginthreadex( NULL,	// security                                      0,// stack size                                      &proc_thread_func,                                      (void *) &thread_data_array[t],	// arg list                                      0,//initflag                                    &uiThreadID[t] );       if ( hThread[t] == 0 ) 	{ printf("ERROR: Failed to create thread: _beginthreadex(proc_thread_func)\n"); exit(-1); 	} #else rc = pthread_create(&threads[t], NULL, proc_thread_func, (void *) &thread_data_array[t]); if (rc) { 	printf("ERROR: return code from pthread_create(proc_thread_func) is %d\n", rc); 	exit(-1); } #endif 	}  	thread_data_array[t].thread_id = t; 	thread_data_array[t].err = 0; 	thread_data_array[t].fd = fd1; 	DBGPRT("Creating thread %d\n", t); #ifdef _WIN32     hThread[t] = (HANDLE)_beginthreadex( NULL,	// security                                      0,// stack size                                      &readf_thread_func,                                      (void *) &thread_data_array[t],	// arg list                                      0,//initflag                                    &uiThreadID[t] );       if ( hThread[t] == 0 ) 	{ printf("ERROR: Failed to create thread: _beginthreadex(readf_thread_func)\n"); exit(-1); 	} #else 	rc = pthread_create(&threads[t], NULL, readf_thread_func, (void *) &thread_data_array[t]); 	if (rc) 	{ printf("ERROR: return code from pthread_create(readf_thread_func) is %d\n", rc); exit(-1); 	} #endif  	/* Wait for all threads to complete */ #ifdef _WIN32 	for (i = 0; i < giTN+2; i++) 	{ DBGPRT("--- WaitForSingleObject(hThread[%d])...\n", i); WaitForSingleObject( hThread[i], INFINITE ); 	} #else     DBGPRT("--- pthread_join()...\n"); 	for (i = 0; i < giTN+2; i++) 	{ pthread_join(threads[i], NULL); DBGPRT("=== After pthread_join(), i = %d, err = %d\n", i, thread_data_array[i].err); 	} #endif  	/* Clean up and exit */ #ifdef _WIN32 	DeleteCriticalSection( &g_cs_bufi ); 	DeleteCriticalSection( &g_cs_bufo );  #else 	for(i = 0; i < giTN; i++) 	{ pthread_mutex_destroy(&g_mutex_r[i]); pthread_mutex_destroy(&g_mutex_w[i]); pthread_cond_destroy(&g_condv_r[i]); pthread_cond_destroy(&g_condv_w[i]); 	} 	pthread_mutex_destroy(&bufi_mutex); 	pthread_mutex_destroy(&bufo_mutex); 	pthread_cond_destroy(&bufi_threshold_cv); 	pthread_cond_destroy(&bufo_threshold_cv); #endif      gettimeofday(¤t, (struct timezone*) 0);     elapsed = (current.tv_sec - begin.tv_sec) +               ((current.tv_usec - begin.tv_usec) / 1000000.0F);     printf("--- 耗时 %f 秒\n", elapsed); #ifdef _WIN32 	// Destroy the thread object. 	for (i = 0; i < giTN+2; i++) 	{ CloseHandle( hThread[i] ); 	} #else 	pthread_exit (NULL); #endif 	return 0; }  程序分几个帖子发出如上，缩进几乎全没了。请赵老师多多批评指正！谢谢！

谢谢赵老师！ 只能连续发3个帖子。   /* ------------------------------------------------------------------------- */ #ifdef _WIN32 unsigned __stdcall readf_thread_func(void *threadarg) #else void *readf_thread_func(void *threadarg) #endif { 	struct thread_data *my_data; 	long taskid; 	int  rc = 0, read_ret; 	int  i, k, n; 	char *rem_buf = NULL; 	char *p, *p1, *p2, *p3; 	int  rem_len = 0; 	char tmpbuf[BUF_LEN+1];  	my_data = (struct thread_data *) threadarg; 	taskid = my_data->thread_id; 	DBGPRT1("@readf_thread_func(), taskid=%ld\n", taskid);  	for(n = 1; ; n++) 	{ 		DBGPRT1("@readf_thread_func(): thread %ld locking mutex.\n", taskid); #ifdef _WIN32 #else 		pthread_mutex_lock(&bufi_mutex); #endif 		while (1) 		{ #ifdef _WIN32 		EnterCriticalSection( &g_cs_bufi ); #else #endif 			for(i = 0, k = -1; i < giTN; i++) 			{ //				if(giReadBufStat[i] == 0) 				if(gtReadBuf[i].bufstat == 0) 				{ 					k = i; 					break; 				} 			} #ifdef _WIN32 			if(k >= 0) 			{ //				giReadBufStat[k] = 1; //				giFileBlockNo[k] = n; 				gtReadBuf[k].bufstat = 1; 				gtReadBuf[k].fileBlockNo = n; 				LeaveCriticalSection( &g_cs_bufi ); 				break; 			} 			LeaveCriticalSection( &g_cs_bufi ); #else 			if(k >= 0) break; #endif #ifdef _WIN32 			DBGPRT1("=== readf_thread_func(): thread %ld, before WaitForSingleObject...\n", taskid); 			WaitForSingleObject( hEvent_bufi, INFINITE ); 			DBGPRT1("*** readf_thread_func(): thread %ld, after WaitForSingleObject.\n", taskid); #else 			DBGPRT1("=== readf_thread_func(): thread %ld, Going into wait...\n", taskid); 			pthread_cond_wait(&bufi_threshold_cv, &bufi_mutex); 			DBGPRT1("*** readf_thread_func(): thread %ld Condition signal received.\n", taskid); #endif 		} 		DBGPRT1("@readf_thread_func(): thread %ld Reading file, k=%d ...\n", taskid, k);  #ifdef _WIN32 #else //		giReadBufStat[k] = 1; //		giFileBlockNo[k] = n; 		gtReadBuf[k].bufstat = 1; 		gtReadBuf[k].fileBlockNo = n; 		pthread_mutex_unlock(&bufi_mutex); #endif 		DBGPRT1("@readf_thread_func(): thread %ld Unlocking mutex.\n", taskid);  //		p1 = bufi[k]; 		p1 = gtReadBuf[k].bufptr; //		if(rem_len > 0) memmove(bufi[k], rem_buf, rem_len); 		if(rem_len > 0) memmove(p1, rem_buf, rem_len); #ifdef _WIN32 //		read_ret = _read(my_data->fd, bufi[k] + rem_len, buf_len - rem_len); 		read_ret = _read(my_data->fd, p1 + rem_len, buf_len - rem_len); #else //		read_ret = read(my_data->fd, bufi[k] + rem_len, buf_len - rem_len); 		read_ret = read(my_data->fd, p1 + rem_len, buf_len - rem_len); #endif 		DBGPRT1("@readf_thread_func(): thread %ld read_ret1 = %d\n", taskid, read_ret); 		if(read_ret == 0) 		{ 			eof_err = 1; //			giReadBufStat[k] = 0; 			gtReadBuf[k].bufstat = 0; 			goto end; 		} 		else if(read_ret == -1) 		{ 			eof_err = -1; //			giReadBufStat[k] = 0; 			gtReadBuf[k].bufstat = 0; 			rc = -1; 			goto end; 		} 		//p = bufi[k] + rem_len; 		//p[read_ret] = 0x00; 		//strmovcpy(tmpbuf, p1, read_ret + rem_len); 		//printf("*** buf_len=%d, read_ret=%d, rem_len=%d, p1=[%s]\n", buf_len, read_ret, rem_len, tmpbuf); 		printf("*** buf_len=%d, read_ret=%d, rem_len=%d\n", buf_len, read_ret, rem_len); 		if(read_ret == buf_len - rem_len) 		{ 			p = p3 = p1 + buf_len - 1; 			while(*p != '\n') 			{ 				if(p3 - p >= FIND_BACK) 				{ 					eof_err = 2; 					goto end; 				} 				p--; 			} 			p2 = p; 			read_ret = p2 + 1 - p1; 			rem_buf = p2 + 1; 			rem_len = buf_len - read_ret; 			//strmovcpy(tmpbuf, rem_buf, rem_len); 			//printf("=== buf_len=%d, read_ret=%d, rem_len=%d, rem_buf=[%s]\n", buf_len, read_ret, rem_len, tmpbuf); 			printf("=== buf_len=%d, read_ret=%d, rem_len=%d\n", buf_len, read_ret, rem_len); 		} 		else 		{ 			read_ret += rem_len; 			rem_buf = NULL; 			rem_len = 0; 		} //		bufilen[k] = read_ret; 		gtReadBuf[k].buflen = read_ret; 		//printf("--- #%d:[\n%*.*s\n]\n", n, read_ret, read_ret, p1); 		//strmovcpy(tmpbuf, p1, read_ret); 		//printf("--- #%d:[\n%s]\n", n, tmpbuf); 		DBGPRT1("--- @readf_thread_func(): thread %ld, block no = #%d, k=%d, len(read_ret)=%d\n", taskid, n, k, read_ret); 		 //		giReadBufStat[k] = 2; 		gtReadBuf[k].bufstat = 2; #ifdef _WIN32 		SetEvent(hEvent_r[k]); #else 		pthread_cond_signal(&g_condv_r[k]); #endif end: 		if(eof_err != 0) break; 	}  	DBGPRT1("@readf_thread_func(): thread %ld End, rc = %d.\n", taskid, rc); 	my_data->err = rc; 	rtf_exit = 1; 	giRFBN = n; #ifdef _WIN32 	SetEvent(hEvent_bufo); 	for(i = 0; i < giTN; i++) 	{ 		SetEvent(hEvent_r[i]); 	} 	_endthreadex( 0 ); 	return 0; #else 	pthread_cond_signal(&bufo_threshold_cv); 	for(i = 0; i < giTN; i++) 	{ 		pthread_cond_signal(&g_condv_r[i]); 	} 	pthread_exit(NULL); #endif }  /* ------------------------------------------------------------------------- */ #ifdef _WIN32 unsigned __stdcall proc_thread_func(void *threadarg) #else void *proc_thread_func(void *threadarg) #endif { 	struct thread_data *my_data; 	long taskid; 	int rc = 0, i = 0, k;  	my_data = (struct thread_data *) threadarg; 	taskid = my_data->thread_id; 	DBGPRT2("@proc_thread_func(), taskid=%ld\n", taskid);  	while(1) 	{ #ifdef _WIN32 //		if((rtf_exit == 1 || eof_err != 0) && giReadBufStat[taskid] == 0) goto end; 		if((rtf_exit == 1 || eof_err != 0) && gtReadBuf[taskid].bufstat == 0) goto end; //		if(giReadBufStat[taskid] != 2) 		if(gtReadBuf[taskid].bufstat != 2) 		{ 			DBGPRT2("@proc_thread_func(): thread %ld, before WaitForSingleObject(hEvent_r).\n", taskid); 			WaitForSingleObject( hEvent_r[taskid], INFINITE ); 			DBGPRT2("@proc_thread_func(): thread %ld, after WaitForSingleObject(hEvent_r).\n", taskid); 		} //		if(giWriteBufStat[taskid] != 0) 		if(gtWriteBuf[taskid].bufstat != 0) 		{ 			DBGPRT2("@proc_thread_func(): thread %ld, before WaitForSingleObject(hEvent_w).\n", taskid); 			WaitForSingleObject( hEvent_w[taskid], INFINITE ); 			DBGPRT2("@proc_thread_func(): thread %ld, after WaitForSingleObject(hEvent_w).\n", taskid); 		} #else 		DBGPRT2("@proc_thread_func(): thread %ld locking mutex bufi_mutex. giReadBufStat[taskid]=%d\n", taskid, giReadBufStat[taskid]); 		//pthread_mutex_lock(&bufi_mutex); 		pthread_mutex_lock(&g_mutex_r[taskid]); //		while (giReadBufStat[taskid] != 2) 		while (gtReadBuf[taskid].bufstat != 2) 		{ //			if((rtf_exit == 1 || eof_err != 0) && giReadBufStat[taskid] == 0) goto end; 			if((rtf_exit == 1 || eof_err != 0) && gtReadBuf[taskid].bufstat == 0) goto end; //			DBGPRT2("=== proc_thread_func(): thread %ld, Going into wait bufi. giReadBufStat[taskid]=%d, rtf_exit = %d, eof_err = %d...\n", taskid, giReadBufStat[taskid], rtf_exit, eof_err); 			DBGPRT2("=== proc_thread_func(): thread %ld, Going into wait bufi. gtReadBuf[taskid].bufstat=%d, rtf_exit = %d, eof_err = %d...\n", taskid, gtReadBuf[taskid].bufstat, rtf_exit, eof_err); //			pthread_cond_wait(&g_condv_r[taskid], &bufi_mutex); 			pthread_cond_wait(&g_condv_r[taskid], &g_mutex_r[taskid]); 			DBGPRT2("*** proc_thread_func(): thread %ld Condition signal received. \n", taskid); 		} 		DBGPRT2("@proc_thread_func(): thread %ld locking mutex bufo_mutex.\n", taskid); 		//pthread_mutex_lock(&bufo_mutex); 		pthread_mutex_lock(&g_mutex_w[taskid]); //		while (giWriteBufStat[taskid] != 0) 		while (gtWriteBuf[taskid].bufstat != 0) 		{ 			DBGPRT2("=== proc_thread_func(): thread %ld, Going into wait bufo...\n", taskid); //			pthread_cond_wait(&g_condv_w[taskid], &bufo_mutex); 			pthread_cond_wait(&g_condv_w[taskid], &g_mutex_w[taskid]); 			DBGPRT2("*** proc_thread_func(): thread %ld Condition signal received.\n", taskid); 		} 		DBGPRT2("@proc_thread_func(): thread %ld Unlocking mutex.\n", taskid); //		pthread_mutex_unlock(&bufo_mutex); //		pthread_mutex_unlock(&bufi_mutex); 		pthread_mutex_unlock(&g_mutex_w[taskid]); 		pthread_mutex_unlock(&g_mutex_r[taskid]); #endif 		 //		DBGPRT2("@proc_thread_func(): thread %ld Processing file, giReadBufStat[taskid]=%d, giWriteBufStat[taskid]=%d ...\n", taskid, giReadBufStat[taskid], giWriteBufStat[taskid]); 		DBGPRT2("@proc_thread_func(): thread %ld Processing file, gtReadBuf[taskid].bufstat=%d, gtWriteBuf[taskid].bufstat=%d ...\n", taskid, gtReadBuf[taskid].bufstat, gtWriteBuf[taskid].bufstat); 		//i = 0; 		//if(giReadBufStat[taskid] == 2 && giWriteBufStat[taskid] == 0) 		{ //			giReadBufStat[taskid] = 3; //			giWriteBufStat[taskid] = 3; 			gtReadBuf[taskid].bufstat = 3; 			gtWriteBuf[taskid].bufstat = 3; #ifdef _WIN32 			//Sleep(random_1(5,20) * 1000); #else 			//sleep(random_1(5,20)); #endif //			for(i = 0; i < bufilen[taskid]; i++) 			for(i = 0; i < gtReadBuf[taskid].buflen; i++) 			{ //				bufo[taskid][i] = toupper(bufi[taskid][i]); 				gtWriteBuf[taskid].bufptr[i] = toupper(gtReadBuf[taskid].bufptr[i]); 			} //			bufolen[taskid] = bufilen[taskid]; 			gtWriteBuf[taskid].buflen = gtReadBuf[taskid].buflen;  //			giReadBufStat[taskid] = 0; //			giWriteBufStat[taskid] = 4; 			gtReadBuf[taskid].bufstat = 0; 			gtWriteBuf[taskid].bufstat = 4; 			gtWriteBuf[taskid].fileBlockNo = gtReadBuf[taskid].fileBlockNo; #ifdef _WIN32 			DBGPRT2("@proc_thread_func(): thread %ld SetEvent ...\n", taskid); 			SetEvent(hEvent_bufi); 			SetEvent(hEvent_bufo); #else 			DBGPRT2("@proc_thread_func(): thread %ld pthread_cond_signal ...\n", taskid); 			pthread_cond_signal(&bufi_threshold_cv); 			pthread_cond_signal(&bufo_threshold_cv); #endif 		} //		if(eof_err != 0 && buf1istat != 1 && buf2istat != 1) break; 	} //	printf("proc_thread_func(): thread %ld End, rc = %d, proc_len = %ld.\n", taskid, rc, proc_len); end: 	DBGPRT2("proc_thread_func(): thread %ld End, rc = %d\n", taskid, rc); 	my_data->err = rc; 	ptf_exit = 1; #ifdef _WIN32 	_endthreadex( 0 ); 	return 0; #else 	pthread_exit(NULL); #endif }

多线程访问同一个资源发生冲突时需要加锁。


Question: 求大佬帮忙c语言。

用指针怎么写啊，我加for循环判断的话前后两个数据怎么比较

简单的自动生成不重复的编号，复杂点的，需要每输入一个去检查以前的有没有重复


Question: 求助求助，学生党过二级啊啊～

放弃吧！不适合你！

计算机二级证书有毛毛用啊。直接不考了呗

基础的循环书上肯定都有 要是连这点拓展能力没有的话 还是省省报考费吃顿好点的吧 给了你这题的答案  考试换一个推导公式你该不会还是不会

这都不会？不可能过二级了，放弃吧

嗯，我想出来了，，，，，，，，，，

人家还是学生，楼上的大虾们别打击他的学习积极性啊。  只不过，楼主一点都不想，坐等别人现成的答案，对你考二级帮助有限啊


Question: 运行程序if-else为什么会else内先运行后条件判断

引用 2 楼 寻找千千万万个她的回复:但是程序条件判断是满足的，执行的是key=0； 没看到完整代码，有两点猜测： 1：外面还有一层循环，第二次循环的时候执行的if后面的语句 2：key初始化的值就是0，以至于在基于结果的判断方式下，你误认为执行了if后面的key=0

这种要自己学会加打印调试   K1=0;                 K2=1;                 printf("%d\n", key);                 if(K11==K1&&K22==K2)//K11=1,K22=1                 {                     printf("if\n");                     key=0;                 }                 else                 {                    printf("else\n");                    K11=K1;                     K22=K2;                 } 引用 2 楼 寻找千千万万个她 的回复:但是程序条件判断是满足的，执行的是key=0；

引用 2 楼 寻找千千万万个她的回复:但是程序条件判断是满足的，执行的是key=0； 条件怎么满足的？？？？

但是程序条件判断是满足的，执行的是key=0；

K1=0 K11=1 K11 == K1不满足当然走else分支呀  A&&B是A和B都为真才走上面的分支 A||B是A和B有一个为真才走上面的分支


Question: 素数回文数

21行 应该是if (n == m) n是你备份的判断成功的素数 m是你将素数倒序输出的结果 k这时候应该为0


Question: 关于数据结构中定义结构体的问题（萌新小白）

为了让小白理解概念！

为了好看，让结构看起来更直观一点， CSNode *tree； CSTree tree； 可以对比一下两种方式

请考虑下可扩展性，设计数据结构的人和使用数据结构的人不一定是同一个，况且定义CSNode有没有什么损失


Question: 求大佬帮忙

引用 1 楼 user-1的回复:ls -l /etc; cd /tmp; mkdir subdir; cd subdir; touch newdoc; chmod +x newdoc; cd /root; 谢谢大佬了，问题已经解决


Question: 我看不懂这段代码，尤其看不懂第二句

C# lamda表达式，表示一个匿名函数，=>前面的是参数，后面的是函数体。你可以把它当作一个函数。 fibs.Count(x=>x!=5);等价于寻找fibs数组中不等于5的元素个数，这里即6，输出的时候*2就是12

引用 楼主 sweetswing 的回复:what is the output of  this code? int[ ] fibs={0,1,1,2,3,5,8}; int n= fibs.Count(x=>x!=5); Console.WriteLine(n*2);   A  12 B  Error C  10 D  6   正确答案是A  我看不懂这段代码，尤其看不懂第二句int n= fibs.Count(x=>x!=5); 什么意思？   语言是C# 我找不到合适的版块，就发到这里来了 Count 是求数组中元素个数的 x=>x!=5是条件，你理解=>的意义就能看明白了 不等于5的元素有6个,输出*2=12个


Question: 大家帮帮忙，c语言课程设计

第一题用递归函数调用就可以逆序了！ 第二题就是比较大小，求商，求余等函数的用法！ 第三题直接搞个文本文件去查吧！哈哈

引用 4 楼 weixin_45325219 的回复:[quote=引用 3 楼 Italink的回复:]你愿意花费帮别人做作业吗？ 你连自己的作业都不愿意做，为什么会指望别人呢 不做就算了，，，，，[/quote] 确实，论坛里的没人欠你一个课程设计，大学是你自己的上，不是别人替你上的。

引用 4 楼 weixin_45325219 的回复:[quote=引用 3 楼 Italink的回复:]你愿意花费帮别人做作业吗？ 你连自己的作业都不愿意做，为什么会指望别人呢 不做就算了，，，，，[/quote] 现在的学生真的是，好像别人欠你的一样。

c++的话，感觉第三题可以偷懒用std::map或者std::unordered_map

第二题的答案，仅供参考：  #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #include <math.h>  int main() { 	int randnum = 0; 	int mynum = 0; 	int count = 0; 	int i = 0; 	int j = 0; 	char arr1[5]; 	char arr2[5]; 	int place_num = 0; 	int right_num = 0;  	srand((unsigned int)time(NULL)); 	randnum = (rand() % (9999 - 1000 + 1)) + 1000; 	//printf("randnum = %d\n", randnum); 	itoa(randnum, arr1, 10);  	while(1){ 		place_num = 0; 		right_num = 0; 		while(1){ 			printf("please input your number(1000-9999):"); 			scanf("%d", &mynum); 			if((mynum > 999) && (mynum < 10000)){ 				break; 			} 		} 		count++; 		if(mynum == randnum){ 			printf("you gussed right!\n"); 			break; 		} 		itoa(mynum, arr2, 10);  		for(i = 0; i < 4; i++){ 			for(j = 0; j < 4; j++){ 				if(arr1[i] == arr2[j]){ 					right_num++; 				} 			} 		} 		for(i = 0; i < 4; i++){ 			if(arr1[i] == arr2[i]){ 				place_num++; 			} 		} 		printf("right_num = %d, place_num = %d\n", right_num, place_num); 	}  	//printf("randnum = %d\n", randnum); 	//printf("mynum = %d\n", mynum); 	printf("total number of your gussed: %d\n", count); 	//printf("%s, %s\n", arr1, arr2); 	return 0; }

引用 3 楼 Italink的回复:你愿意花费帮别人做作业吗？ 你连自己的作业都不愿意做，为什么会指望别人呢 不做就算了，，，，，

你愿意花费帮别人做作业吗？ 你连自己的作业都不愿意做，为什么会指望别人呢

求代码，和流程图😊

我怎么感觉第3题，似乎容易许多呢？


Question: 求大佬

引用 1 楼 自信男孩的回复:两个都选A，第一个问题是1+2+3+4 = 10，因为i = 2能执行第二个while。 第二个问题，i++改成++i都没有改变< 3，并且执行第二个while的条件也是i= 2； 懂了，感谢大佬！！！

引用 1 楼 自信男孩的回复:两个都选A，第一个问题是1+2+3+4 = 10，因为i = 2能执行第二个while。 第二个问题，i++改成++i都没有改变< 3，并且执行第二个while的条件也是i= 2； 那个continue只是跳出了第一个循环，而且继续进行了do while的循环吗？


Question: 航向角 定位坐标 滤波

卡尔曼滤波~


Question: warning C4013

warning很清楚了调用printf没加头文件所以找不到定义，懂了么？ 在studs_score.c前面加一行#include <stdio.h>  引用 3 楼 weixin_44777704 的回复:[quote=引用 1 楼 636f6c696e的回复:]你不应该优先解决error的问题么？warning不影响编译，warning的原因是没加头文件 error那块没问题，就这块有问题。后来把它们整到一个文件里，改些东西后，运行正常。[/quote]

引用 2 楼 赵4老师的回复:在studs_score.c前面加一行#include <stdio.h> 那块是调用文件的，，，还要加这个？

引用 1 楼 636f6c696e的回复:你不应该优先解决error的问题么？warning不影响编译，warning的原因是没加头文件 error那块没问题，就这块有问题。后来把它们整到一个文件里，改些东西后，运行正常。

在studs_score.c前面加一行#include <stdio.h>


Question: 求大佬帮助

/* course_desing.c */  #include <stdio.h>  int main(void) {         printf("Hellow, world!\n");         printf("Game Over!\n");          return 0; }

估计500块有人帮你写写吧


Question: 求大佬帮忙看C语言链表十行程序

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633


Question: 求教指向指针的指针

应当明确： 1）指针本身即代表内存地址，不论是一级，二级，直到多级指针，其本身就是一个变量，会占据一定的内存空间，并且此内存空间是用来存放同类型的内存地址的； 2）对指针逐步进行解引用，编译器将会逐步提取保存在此内存空间中的有效数据，再根据CPU相关指令，执行相应的运算操作。

输出第n个单词！把指针的指针和多维数组理解透彻！

p=a+n-1; 表示p中保存的是数组a中第n个元素的地址；而数组a的第n个元素又指向了某个字符串。 所以， printf("%s\n",*p); 实际上就是输出某个字符串。 VS2015调试如下  对于数组和指针，请参考 《C++中指针的数组和数组的指针》 希望能够帮到你

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！


Question: c语言逻辑运算符短路机制和结合性

为什么++K没有运算呢，按道理&不应该两边都运算才对吗，怎么结果K还是1呢

输出的结果应该是:2 1  1。因为|| &&结合是从左向右，++i已经为真，所以后面的j, k都不会运算和判断了。

还是少用这些稀奇古怪的特性为好，

引用 楼主 南山之上的回复:萌新关于短路机制和结合性的问题。 具体题目见下面截图 题目后面打错了个字，“所以输出是2，1，2”。


Question: c语言

纠正一下： 注释中的“自然数”，不恰当，有可能是第一个，下标可能为 0 ； 改为：非负整数；

第2题： int search(int num[],int a); int main() { int xy[10]; int cnt =0; int ret_val = -1;    // 置-1是做标记，没找到返回0，找到时返回下标（自然数）； int a = 3;    //假设a=3； for(cnt = 0;cnt<10;cnt++) { scanf("%d",xy[cnt]); } ret_val = search(xy,a); printf("ret_val=%d",a); }  int search(int num[],int a) { int i=0; int ret_result = 0;  for(i=0;i<10;i++) { if(num[i] == a) { ret_result = i; break; } } return ret_result;  }

1、求矩阵对角线元素之和：  fun01() { int a[3][3]; int xRow=0,xCol=0; int xAdd = 0;  for(xRow = 0;xRow<3;xRow++) { for(xCol=0;xCol<3;xCol++) { if(xRow == xCol)    //对角线 行、列相同 { xAdd += a[xRow][xCol]; } } } printf("add val:%d",xAdd); }


Question: 性感大学生在线求救c语言代码段

引用 8 楼 自信男孩的回复:代码中还有其他问题，比如scanf中对与name和new_mimal应该去掉&，因为数组名本身就是地址，是数组的首地址。 嗯，发现了，已经改了，谢谢指点

引用 4 楼 牧牛童子的回复:圈1那个地方是指那个if 语句吗？若是的话，直接空着不写就能达到你的目的。 了解

引用 2 楼 拥抱Linux的回复:说好的 性感大学生 呢？ 无图无真相！ 腿毛浓密算性感吗哈哈哈哈哈哈哈

没图也来提问

圈1那个地方是指那个if 语句吗？若是的话，直接空着不写就能达到你的目的。

引用 2 楼 拥抱Linux 的回复:说好的 性感大学生 呢？ 无图无真相！ 可能说的是姓敢的大学生

说好的 性感大学生 呢？ 无图无真相！

你这流程感人  反正最后都是zhucaidan(); if(用户相等) {  输入原始密码 输入新密码 再输一次 修改成功  } else {  用户不存在 } zhucaidan();


Question: 程序看不懂，求解析

很明显，楼主发的这段代码不太全，应该把头文件<reg51.h>的代码发上来，一看就是在头文件中定义了很多变量，也许自己看看头文件里的内容就明白了。

引用 2 楼 qq_45217035 的回复:[quote=引用 1 楼 拥抱Linux的回复:]书上有的——《C语言程序设计：从入门到放弃》。 好嘞，谢谢啊。我等下下去看书，程序真的使人头秃[/quote] 楼主牛，还是别看书了，别入门直接放弃得了。

这是串口那节的，书上有答案，或者自己接个c52单片机，试试 就知道什么功能了

引用 1 楼 拥抱Linux的回复:书上有的——《C语言程序设计：从入门到放弃》。 好嘞，谢谢啊。我等下下去看书，程序真的使人头秃

书上有的——《C语言程序设计：从入门到放弃》。


Question: 求求大佬们给我改道题吧！谢谢了

引用 5 楼 user-1的回复:****** enter info。目测实现的是这个功能，但是各种异常都没有处理，很容易就会崩溃。 嗯，我会改进的，很高兴能在这里得到您的帮助，谢谢

引用 3 楼 user-1的回复:do    {  a[i]=*p;       i++; }    while(*p);	  这个操作之前没有清零，逻辑估计都是错误的，你要先清零并且保证a[i]的操作i不能越界。 感谢懂了 ，你能给我说下这个程序实现了什么功能吗？我有点看不懂

引用 1 楼 user-1的回复:上面那个帖子不是已经给你指出了其中4个错误吗，照着改了就行了啊，你千万别说你不懂C语法，所以指出了错误你也不会改。 谢谢你，其实我第四条没懂，其他还好


Question: 急用！！谁会写！谢谢！

请参考 #include <iostream>  #define ITEMNUM 3 #define CAT 1 #define Mouse -1 #define PEANUT 1  void ShowStep(int nItemIndex, int nDestination) { 	std::string strItem = ""; 	switch (nItemIndex) 	{ 		case 0: 			strItem = "猫"; 			break; 		case 1: 			strItem = "海狸鼠"; 			break; 		case 2: 			strItem = "花生"; 			break; 		default: 			strItem = "空"; 			break; 	}  	if (0 == nDestination) 	{ 		std::cout << "出发地 ---------- " << strItem.c_str() << " ----------> 目的地" << std::endl; 	} 	else 	{ 		std::cout << "出发地 <---------- " << strItem.c_str() << " ---------- 目的地" << std::endl; 	} }   int GetDestinationItemsValue(int* pDestination, int nSize) { 	int nValue = 0; 	for (int i = 0; i < nSize; i++) 	{ 		nValue += pDestination[i]; 	}  	return nValue; }  int GetDepartureItemsValue(int* pDeparture, int nSize) { 	int nValue = 0; 	for (int i = 0; i < nSize; i++) 	{ 		nValue += pDeparture[i]; 	}  	return nValue; }  int GetItemFromDeparture(int* pDeparture, int nSize, int nIdxLastAdded) { 	int nValue = GetDepartureItemsValue(pDeparture, nSize); 	int nZeroIdx = -1; 	for (int i = 0; i < nSize; i++) 	{ 		if (pDeparture[i] != 0 && nZeroIdx == -1)//记录第一个没有被带走物品 		{ 			nZeroIdx = i; 		}  		if (nValue - pDeparture[i] != 0 && 0 != pDeparture[i] && nIdxLastAdded != i) 		{ 			return i; 		} 	}  	//每次从出发地出发，不允许不带东西，默认带走第一个没有被带走的物品 	return nZeroIdx; }  int GetItemFromDestination(int* pDestination, int nSize, int nIdxLastAdded) { 	int nValue = GetDestinationItemsValue(pDestination, nSize); 	if (nValue == 0)//目的地物品属性值为零时，需要带走一个物品 	{ 		for (int i = 0; i < nSize; i++) 		{ 			if (nValue - pDestination[i] != 0 && 0 != pDestination[i] && nIdxLastAdded != i) 			{ 				return i; 			} 		} 	}  	return -1; }  int main() { 	int nDeparture[ITEMNUM] = { CAT, Mouse, PEANUT };//出发地的物品属性值 	int nDestination[ITEMNUM] = { 0, 0, 0 };//目的地的物品属性值  	int nRemainNum = ITEMNUM; 	int nIdx = -1; 	while (0 != nRemainNum) 	{ 		//从出发地带走一样物品到出发地 		nIdx = GetItemFromDeparture(nDeparture, ITEMNUM, nIdx); 		ShowStep(nIdx, 0); 		if (-1 != nIdx && nIdx < ITEMNUM) 		{ 			nRemainNum--; 			nDestination[nIdx] = nDeparture[nIdx]; 			nDeparture[nIdx] = 0; 		}  		//如果出发地还有东西没有带走，则需要从目的地返回 		if (nRemainNum != 0) 		{ 			nIdx = GetItemFromDestination(nDestination, ITEMNUM, nIdx); 			ShowStep(nIdx, 1); 			if (nIdx != -1) 			{ 				nRemainNum++; 				nDeparture[nIdx] = nDestination[nIdx]; 				nDestination[nIdx] = 0; 			} 		} 	}   	std::cout << "按任意键退出" << std::endl; 	getchar();  	return 0; }


Question: linux 消息队列函数msgrcv:函数出现Identifier removed errno:43

引用 4 楼 weixin_44199758 的回复:struct share_use_st {     long int msg_type;     char text[BUFSIZ]; }; struct share_use_st sh_data; 我觉得你这个问题主要查找同步方面的问题看看

引用 2 楼 weixin_44199758 的回复:len 是4096 你的sh_data定义呢

len 是4096


Question: 救救孩子吧，有一道题不会

这么可怜，都没人理你，这单我接了。  #include <stdio.h> #include <stdlib.h> #include <string.h>  struct node { 	int data; 	struct node *next; };  struct node *head = NULL;  int sortList(struct node *head) { 	if (head == NULL) { 		return -1; 	}	  	struct node *tmp1 = NULL; 	struct node *tmp2 = NULL; 	int tmpData = 0;  	for (tmp1 = head; tmp1 != NULL; tmp1 = tmp1->next) { 		for (tmp2 = tmp1->next; tmp2 != NULL; tmp2 = tmp2->next) { 			if (tmp1->data > tmp2->data) { 				tmpData = tmp1->data; 				tmp1->data = tmp2->data; 				tmp2->data = tmpData;	 			} 			 		}  	} 	 	return 0; }  int insertList(struct node **head, int data) { 	struct node *newData = (struct node*)malloc(sizeof(struct node)); 	memset(newData, 0, sizeof(struct node));  	newData->data = data; 	newData->next = NULL;  	if (*head == NULL) { 		*head = newData; 	} else { 			struct node *pos = NULL;  			for (pos = *head; pos->next != NULL; pos = pos->next) { 			} 			 			pos->next = newData; 	}   	return 0; }  int printList(struct node *head) { 	struct node *pos = NULL;  	for (pos = head; pos != NULL; pos = pos->next) { 		printf("%d ", pos->data); 	} 	printf("\n"); 	 }   int main(int argc, char **argv) { 	srand(time(NULL)); 	int i = 0;  	for (i = 0; i < 10;i++) { 		insertList(&head, rand() % 100); 	} 	printf("Before Sort: \n"); 	printList(head); 	sortList(head); 	printf("After Sort: \n"); 	printList(head); 		 }

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633


Question: 请求大佬帮忙 ，帮忙，写一个纯c的程序。

引用 1 楼 jsx_SEVEN的回复: #include <stdio.h> #include <stdlib.h> #include <math.h>  //1、输入N int InputN() { 	int N; 	printf("输入N:"); 	scanf("%d", &N); 	while (N % 7 != 0) 	{ 		printf("数列的总项数不是7的倍数，请重新输入："); 		scanf_s("%d", &N); 	} 	return N; }  //2、数列通式 //这类题目也可以用递归，但是这道题会溢栈 //所以用了迭代 int Series(int res_2, int res_1, int res, int count, int n)   //第count-2项、第count-1项、第count项、迭代变量count、n { 	if (n < 1) 		return 0; 	else if (n == 1 || n == 2) 		return 0; 	else if (n == 3) 		return 1; 	else if (count < n) 		return Series(res_1, res, res_2 + res_1 + res, count + 1, n);  //迭代计算下一个(count+1)、直到第n个 	else  		return res; } int getSeriesN(int n) { 	return Series(0, 0, 1, 3, n); }  //3、计算并输出数列前n项的平方根之和 //有疑问：一个数的平方根应该是两个，且互为相反数，求和没意义 void Sum(int n) { 	float sum = 0.0; 	int i = 1; 	while (i <= n) 	{ 		sum += sqrt(getSeriesN(i)); 		i++; 	} 	printf("%f\n", sum); }  //4、按行输出 void Output(int n) { 	int i; 	int cnt = 0; 	for ( i = 1; i <= n; i++) 	{ 		printf("%d", getSeriesN(i));  		cnt++; 		if (cnt % 7 == 0)           //每打印7个换行 			printf("\n"); 		else 			printf("------"); 	} }  int main() { 	int n; 	n = InputN(); 	Sum(n); 	Output(n); 	return 0; }  谢谢，谢谢大佬🌚🌚🌚🌚🌚

感谢大佬，非常感谢。。。。。。


Question: C语言模拟汽车自助购票

请求大家帮帮忙，深深地感谢

请求大家帮帮忙，深深地感谢


Question: c# c

C#跟C/C++根本不是一个等级上的语言，C#是微软专门为.net平台定制的语言，是一种虚拟机语言（因此和本机代码的C/C++/D有本质区别），是Java的竞争者。C++是一种开放语言标准，全世界各组织和企业有广泛实现和变种，相比之下，C#离不开.net平台，而.net离不开windows

.netcore了解一下


Question: C Primer Plus 如何选择

引用 13 楼 liups 的回复:说一下吧： 孩子明显更喜欢数学这些，最终一拿起编程就兴趣不大，最终假期基本在看数学这些。 去学校报到后，开了一门程序设计，是C和C++,教材是C++ Primer Plus英文版，有点吃力，隔远了我能给他的帮助也有限，不过终于肯下功夫到计算机上面了 谢谢大家仍然关心这个帖子。再补充一下吧： 英文版教材确实比较吃力，他们学长也是自己拿中文版在看，孩子去网上下载了一本北大郭炜的新标准C++，这个书也不错。最后期末成绩也有90多分，谢谢大家关心了

引用 13 楼 liups 的回复:说一下吧： 孩子明显更喜欢数学这些，最终一拿起编程就兴趣不大，最终假期基本在看数学这些。 去学校报到后，开了一门程序设计，是C和C++,教材是C++ Primer Plus英文版，有点吃力，隔远了我能给他的帮助也有限，不过终于肯下功夫到计算机上面了  多好的孩子啊,为什么非要学C? 这个不急的, 数学才是基础和核心, 数学是脑子问题, 是天赋问题, 决定了能走多块多远, 编码是体力活动, 中等智力水平工种.  假设: 1. 数学天赋很好, 编程零基础, 让人拉着跑, 一年后起飞了, 但是, 可能创造奇迹, 比如, 两年后超越师傅. 2. 数学天赋很一般, 编程浸淫多年, 让人拉着跑, 半年起飞, 但是, 和领跑也许差不多吧.  总结, 编程就是为了解决问题, 思维没有, 只能抄.   另外, 你儿子要学啥他自己不知道去找资料找老师啊,还需要你费心? 我小舅子从初中就开始盘算着大学的事情了,现在高三了, 基本已经稳了. 全是自己在操心.

引用 15 楼 赵4老师 的回复:好像我说的不是中文版似的。 当时是想趁假期在家里教他

好像我说的不是中文版似的。

多说一句，类似情况还是别用英文版，他们初学阶段更适合中文版

不管哪个版本，不建议 C Primer Plus 入门。内容太多太细了。还是推荐《明解C语言 第3版 入门篇》。C Primer Plus 适合补漏和提高用。

版本就买最新的，语言的话还是推荐中文的，很多专有名词需要先熟悉一下，因为有些单词的翻译和日常中的语意有差别

引用 1 楼 老马何以识途 的回复:難度沒問題？那就英文版咯！说明一下难度的问题：1、我可以辅导一下，将来大学里面估计也问题不大吧；2、英文没有问题的。

引用 1 楼 老马何以识途 的回复:難度沒問題？那就英文版咯！ 国内能买到英文纸质版吗？

難度沒問題？那就英文版咯！

説了難度不是問題，那就不需要看那些基礎書了。推薦英文版，是因爲翻譯素質參差不齊，當然如果有好的版本也行。

这样的话，我倒是建议英文版，中文版的问题在于术语翻译可能会有多种版本。 提前了解下英文相关的术语，将来网上找资料也方便一点 引用 10 楼 liups 的回复:引用 9 楼 user-6 的回复:除非英文很好的话，还是建议中文版，一般大学教材都是中文版吧外国语学校6年出来的，应该可以了吧

除非英文很好的话，还是建议中文版，一般大学教材都是中文版吧

你搜索下载Win-TC，里面自带。

引用 6 楼 赵4老师 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。  英语也是一门计算机语言的说。  关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”  C语言教程（附带C语言100例）http://download.csdn.net/detail/zhao4zhong1/8830817  Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt 赵老师你这个教程积分需要太多了！能传一份吗？