Question: 怎么用位运算得到一个数是几位的

引用 26 楼 java_charpnet 的回复:[quote=引用 25 楼 DelphiGuy 的回复:] 肯定比循环快。  像什么_BitScanReverse，你是什么地方学到的啊，我怎么闻所未闻[/quote]  学无止境...

引用 11 楼 u010165006 的回复:这个应该int就32位、char就8位吧，不管值是多少。 int a; printf("a的位数是：%d\n",sizeof(a)*8);  他的意思是： ... 0 1 0 0  (0x4) ... 4 3 2 1

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

Cortex M3里面有个CLZ指令，可以返回前导零的数量，用32减之就是你要的结果。。。 另外有个RBIT指令将整个32位反转。。。

引用 25 楼 DelphiGuy 的回复:肯定比循环快。  像什么_BitScanReverse，你是什么地方学到的啊，我怎么闻所未闻

肯定比循环快。

引用 23 楼 DelphiGuy 的回复:这个是标准写法呀   你这等于是循环，看来除了循环只能用cpu指令了

这个是标准写法呀

引用 21 楼 java_charpnet 的回复:[quote=引用 20 楼 DelphiGuy 的回复:] 这样的话你自己判断一下就可以了 if (输入 <= 8)   输入 = 8; else if (输入 <= 16)   输入 = 16; else   输入 = 32;  你怎么总是用什么方法，我看主要是凑代码行数的[/quote]  确实，他把else  if都分成两行

引用 20 楼 DelphiGuy 的回复:这样的话你自己判断一下就可以了 if (输入 <= 8)   输入 = 8; else if (输入 <= 16)   输入 = 16; else   输入 = 32;  你怎么总是用什么方法，我看主要是凑代码行数的

引用 16 楼 java_charpnet 的回复:[quote=引用 3 楼 DelphiGuy 的回复:] #include <intrin.h> _BitScanReverse _BitScanReverse64 注意结果位序是0起始的。  good good study, day day up   还有没有其他的方法啊，想统一用位运算不想用cpu指令，就是fft的输入不一定是2的幂，比如8那就是8，9要扩展到16[/quote]  这样的话你自己判断一下就可以了 if (输入 <= 8)   输入 = 8; else if (输入 <= 16)   输入 = 16; else   输入 = 32;

int msbBit(int n){          /// 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15         ///   0,0,1,1,2,2,2,2,3,3, 3, 3, 3,  3   ,3  ,3,          return "\0\0\1\1\2\2\2\2\3\3\3\3\3\3\3\3"[n];///相当于下面两行 //  static unsigned char bit[]= {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3};  //  return bit[n]; }

引用 4 楼 mLee79 的回复:x86   BSF/BSR ARM  CTZ/CLZ  不用cpu指令还有什么方法啊，就是fft的输入，比如8那就是8，9要扩展到16

引用 8 楼 lm_whales 的回复:哦搞错了 这是统计，1的个数  8Bits以内，还是查表快 超过8BIts分字节判断一下就可以了 这里给个4Bits的查表法 int bitsof(int n){          /// 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15              0,0,1,1,2,2,2,2,3,3, 3, 3, 3,  3   ,3  ,3,      return "\0\0\1\1\2\2\2\2\3\3\3\3\3\3\3\3"[n]; }  也可以的，不过数要2的幂，减1后算1的个数，你这是什么查表，怎么完全看不懂

引用 3 楼 DelphiGuy 的回复:#include <intrin.h> _BitScanReverse _BitScanReverse64 注意结果位序是0起始的。  good good study, day day up   还有没有其他的方法啊，想统一用位运算不想用cpu指令，就是fft的输入不一定是2的幂，比如8那就是8，9要扩展到16

也许显示的时候去掉前导0？

引用 13 楼 DelphiGuy 的回复:[quote=引用 11 楼 u010165006 的回复:] 这个应该int就32位、char就8位吧，不管值是多少。 int a; printf("a的位数是：%d\n",sizeof(a)*8);  他的意思是： ... 0 1 0 0  (0x4) ... 4 3 2 1 [/quote]  不知道他这个用途是什么

ln N +1

可以试试用对数函数硬算。


Question: 求一下每一行代码的意思

time(&t); //应改为 t=time(NULL);  time_t time(time_t *time) time_t 类型其实事一个长整型 time（）函数：当函数传递参数×time为NULL是，返回一个长整型数值，当传递参数不为NULL时，即代表设定当前时间。 参考函数及数值类型 //参考函数及数值类型：struct tm struct tm {   int tm_sec;   int tm_min;   int tm_hour;   int tm_mday;   int tm_mon;   int tm_year;   int tm_wday;   int tm_yday;   int tm_isdst;   size_t strftime( char *str, size_t maxsize, const char *fmt, struct tm *time ); size_t strftime( 　　char *strDest, 　　size_t maxsize, 　　const char *format, 　　const struct tm *timeptr 　　); /×参数列表：函数strftime()的操作有些类似于sprintf()：识别以百分号(%)开始的格式命令集合，格式化输出结果放在一个字符串中。格式化命令说明串strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面，它们是区分大小写的。 　　%a 星期几的简写 　　%A 星期几的全称 　　%b 月分的简写 　　%B 月份的全称 　　%c 标准的日期的时间串 　　%C 年份的后两位数字 　　%d 十进制表示的每月的第几天 　　%D 月/天/年 　　%e 在两字符域中，十进制表示的每月的第几天 　　%F 年-月-日 　　%g 年份的后两位数字，使用基于周的年 　　%G 年分，使用基于周的年 　　%h 简写的月份名×/ }

这个问题建议分别查一下每个函数的功能和使用方法；这个几行代码的功能是获取当前时间,然后以一定的格式存放到一个字符数组里；


Question: 指针链表 多线程读写的问题

add get delete get 要么把数据取出，要么把节点摘下取出，不然的话 delete 就会有问题 因为如果节点还在链表中，那么对节点和数据的修改，读写，也必须同步，才行

仅供参考：//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef _MSC_VER     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _MSC_VER     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #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); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #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} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             Log("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef _MSC_VER     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef _MSC_VER     pthread_exit(NULL); #endif } int main() { #ifdef _MSC_VER     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef _MSC_VER     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef _MSC_VER     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }


Question: 大家好，听说Android NDK7已经可以使用纯C/C++开发安卓APP了，有谁用过吗?该用什么编译器呢?求大神告知。

引用 2 楼 yyxgs 的回复:[quote=引用 1 楼 akirya 的回复:] VS2015 update3 可以创建 Native-Activity 应用程序  感谢大神，我估计不是update3的，请问怎么更新到3呢?[/quote] https://www.visualstudio.com/downloads/download-visual-studio-vs 安装的时候记得选上android相关的

用纯C++开发安卓有什么优势呢。

引用 4 楼 akirya 的回复:[quote=引用 2 楼 yyxgs 的回复:] [quote=引用 1 楼 akirya 的回复:] VS2015 update3 可以创建 Native-Activity 应用程序  感谢大神，我估计不是update3的，请问怎么更新到3呢?[/quote] https://www.visualstudio.com/downloads/download-visual-studio-vs 安装的时候记得选上android相关的[/quote]  明白了！非常感谢！

引用 3 楼 csshow 的回复:用纯C++开发安卓有什么优势呢。 引用 4 楼 akirya 的回复:[quote=引用 2 楼 yyxgs 的回复:] [quote=引用 1 楼 akirya 的回复:] VS2015 update3 可以创建 Native-Activity 应用程序  感谢大神，我估计不是update3的，请问怎么更新到3呢?[/quote] https://www.visualstudio.com/downloads/download-visual-studio-vs 安装的时候记得选上android相关的[/quote]  请问这是整个VS吗?那我要卸载掉现在的吗?

引用 1 楼 akirya 的回复:VS2015 update3 可以创建 Native-Activity 应用程序  感谢大神，我估计不是update3的，请问怎么更新到3呢?


Question: 二叉树的节点路径问题

def ReadData(shfit,node,unit,P_node):     data = open("example1.txt")     for line in data:         text = line.split(',')         if text[0] == "结点位移数":             shfit.append(int(text[1]))         if text[0] == "结点":             num = int(text[1])             node[num] = list(map(lambda x: float(x), text[2:4]))         if text[0] == "基础":             ground.append(int(text[1]))             ground.append(int(text[2]))         if text[0] == "单元":             num = int(text[1])             unit[num] = Unit()             unit[num].num = num             unit[num].beginnode = node[int(text[2])]             unit[num].endnode = node[int(text[3])]             unit[num].vector = list(map(lambda x: int(x), text[4:10]))             unit[num].EA = float(text[10])             unit[num].EI = float(text[11])             unit[num].l = float(text[12])             unit[num].alpha = (float(text[13]) / 180) * np.pi             unit[num].q = (float(text[14]))         if text[0] == "局部荷载":             num = int(text[1])             unit[num]._Fp = list(map(lambda x: float(x), text[2:8]))         if text[0] == "结点荷载":             for x in text[1:]:                 P_node.append(float(x))     print("读入数据成功")

定义父节点指针，从指定节点开始找父节点，直到根节点。是最标准也是最快的

谢啦，我也自己写了，跟您的差不多

仅供参考：#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         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的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } 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  http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and


Question: 由输入语句顺序不同引起的差异和错误  不解

scanf不会接收换行符\n，换行符会留在缓冲区中  可以在scanf后加上 getchar(); 接收了这个换行符

scanf  1)不接收 '\n'  2)会跳过前导空白，包括 '\n' ,‘\t’,空格

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];


Question: 自己尝试写的队列的链式结构操作，没办法调试，哪位大神可以帮忙看看，一调试就自动关闭，一直不知道是什么问题

全局指针q没有分配内存。

引用 9楼我是你的主体 的回复:[quote=引用 8 楼 qq423399099 的回复:] 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 这个会调试，程序容易崩溃是什么问题[/quote]水平问题

引用 8 楼 qq423399099 的回复:单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 这个会调试，程序容易崩溃是什么问题

引用 10 楼 qq423399099 的回复:[quote=引用 9楼我是你的主体 的回复:][quote=引用 8 楼 qq423399099 的回复:] 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 这个会调试，程序容易崩溃是什么问题[/quote]水平问题[/quote]  太伤心了

int *p; //只是定义了一个int指针并没有分配内存 int   i=*p; //这尝试访问一个未知的地方，可能是操作系统所在的内存空间，所以系统会崩溃！  struct  *p; p->data; //这也是一样；

引用 1 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。如果还是没办法操作，是不是因为程序有误？按了alt+7,还是没什么用

引用 3 楼 zycxnanwang 的回复:我帮你改了一下程序 ，数据结构书上的只是算法，总记得以前数据结构老师说的一句话，用算法写出了程序，算法才算你的 建议你多用算法写程序，看书是学不会数据结构的，还有看你的程序，函数的返回值的概念有点不清晰，可以返回书本看一下 还有就是注意空指针，没有分配内存的空指针，千万别让它指向别的地方，程序崩溃的原因大部分是用了 “”野指针“”  “”没有分配内存的空指针，不要指向其他地方",能具体举个列子吗？我试着写的程序都容易崩溃，可是总是不知道问题出在哪里？

#include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef struct QNode{ 	char data; 	struct QNode *next; }QNode, *QueuePtr;  typedef struct{ 	QueuePtr front; 	QueuePtr rear; }LinkQueue,*LinkQueueP; //定义了结构体指针   //初始化  int initqueue(LinkQueueP &q){ 	q = (LinkQueueP)malloc(sizeof(QNode)); //分配内存空间 	q->front = (QueuePtr)malloc(sizeof(QNode));  	q->rear = q->front; 	if (!q->front) return 0; 	q->front->next = NULL; 	return 1; }   //入队 int enQueue(LinkQueueP q, char e){ 	QNode *p = (QueuePtr)malloc(sizeof(QNode)); 	if (!p) return 0; 	p->data = e; 	p->next = NULL; 	q->rear->next = p; 	q->rear = p; 	return 1; }   //出队 int deQueue(LinkQueueP q, char &e){ 	if (q->front == q->rear) 		return 0; 	QNode *p = q->front->next; 	e = p->data; 	q->front->next = p->next; 	if (q->rear == p) 		q->rear = q->front; //队列已空 	return 1; }  int clearQueue(LinkQueueP q){ //清空队列 	QueuePtr  p, temp; 	if (q != NULL){ 		if (q->front != NULL){ 			p = q->front->next; 			while (p != NULL){//释放队列空间  				temp = p->next; 				free(p); 				p = temp; 			} 			q->front->next = NULL; 			q->rear = q->front; 		} 	} 	return 0; }      LinkQueueP q; int main(){  	initqueue(q);  	enQueue(q, 'I'); 	enQueue(q, 'l'); 	enQueue(q, 'o'); 	enQueue(q, 'v'); 	enQueue(q, 'e'); 	enQueue(q, 'y'); 	enQueue(q, 'o'); 	enQueue(q, 'u');  	char ch; 	deQueue(q, ch); //如果是引用的话，一定要是变量 	printf("%c\n", ch); 	deQueue(q, ch); 	printf("%c\n", ch); 	deQueue(q, ch); 	printf("%c\n", ch); 	clearQueue(q);  	return 0; }

引用 3 楼 zycxnanwang 的回复:我帮你改了一下程序 ，数据结构书上的只是算法，总记得以前数据结构老师说的一句话，用算法写出了程序，算法才算你的 建议你多用算法写程序，看书是学不会数据结构的，还有看你的程序，函数的返回值的概念有点不清晰，可以返回书本看一下 还有就是注意空指针，没有分配内存的空指针，千万别让它指向别的地方，程序崩溃的原因大部分是用了 “”野指针“”  “用算法写程序”我不太明白具体是什么样的，我以为都是应该按照书上的一个个写如果把所有的程序都写在main函数中，这样算是标准的数据结构吗？就是把出队、入队、初始化等一系列操作都写在一起，不是需要调用的那样写，对吗？


Question: dev c++求两个数较大者出错

不知道，哎给了就好，不然下次我也没得问了 嘿嘿嘿 一起学习吧

最下面这里不是有个结贴的按钮吗  你点进去就知道了

引用 8 楼 axlblma的回复:我刚学的时候也犯过这个错，找了半天都不知道错在哪里当时。。。。 不过既然有用的话就希望你多给点分喽，我问问题也快没分了。。。 嘿嘿嘿 为什么每次都显示给的分和总分不一致…

引用 8 楼 axlblma的回复:我刚学的时候也犯过这个错，找了半天都不知道错在哪里当时。。。。 不过既然有用的话就希望你多给点分喽，我问问题也快没分了。。。 嘿嘿嘿 还真不知道怎么给分…求教…

引用 6 楼 axlblma的回复:是不是你输入的时候出现了错误呢   你输入的时候的输入方法是：先输入一个数字，再输入一个英文的逗号，然后再输入一个数字，最后回车 还真是…打成中文的逗号了…

引用 4 楼 jennyvenus 的回复:默认的就是int型的函数，如果是int返回值，可以写在后面。不懂……能具体说下吗

默认的就是int型的函数，如果是int返回值，可以写在后面。

@Rewen

引用 1 楼 Rewen 的回复:int max(int x, int y);  要写在main前面，不能写在main函数里面。   int max(int x, int y); main() {      int a, b, c;还是不行


Question: 求助软件中函数高亮的问题

将IDE的字体，改成等宽字体，所有空格、字母、数字占一个相同宽度，所有汉字占两个宽度，看起来代码整齐。

谢谢版主，安装成功了！

安装个VA插件


Question: 位运算对称的算法是什么

引用 31 楼 DelphiGuy 的回复:你还能再搞笑一些么？ http://graphics.stanford.edu/~seander/bithacks.html?1=1#BitReverseObvious Reverse the bits in a byte with 3 operations (64-bit multiply and modulus division):  unsigned char b; // reverse this (8-bit) byte   b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;  哦，没仔细看，8位的话不知道这种方法有什么意义

引用 32 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> int v; int bitrev1(const int b) {     register int n;      n=b;     n=((n>> 1)&0x55555555)|((n<< 1)&0xaaaaaaaa);     n=((n>> 2)&0x33333333)|((n<< 2)&0xcccccccc);     n=((n>> 4)&0x0f0f0f0f)|((n<< 4)&0xf0f0f0f0);     n=((n>> 8)&0x00ff00ff)|((n<< 8)&0xff00ff00);     n=((n>>16)&0x0000ffff)|((n<<16)&0xffff0000);     return n; } int bitrev2(const int b) {     __asm {         push ebx         push ecx         mov ebx,b         mov ecx,32     nextbit:         rcl ebx,1         rcr eax,1         loop nextbit         pop ecx         pop ebx     } } int bitrev3(const int b) {     char bs[33],bs1[33],*ep;      itoa(b,bs1,2);     sprintf(bs,"%032s",bs1);     strrev(bs);     return strtol(bs,&ep,2); } void main() {     v=0x12345678;//0001 0010 0011 0100 0101 0110 0111 1000     printf("%08x\n",bitrev1(v));     printf("%08x\n",bitrev2(v));     printf("%08x\n",bitrev3(v)); } //1e6a2c48 //1e6a2c48 //1e6a2c48   肯定用第一种，你再看看这个，http://bbs.csdn.net/topics/391994422

引用 30 楼 java_charpnet 的回复:[quote=引用 29 楼 DelphiGuy 的回复:] [quote=引用 25 楼 java_charpnet 的回复:] [quote=引用 24 楼 DelphiGuy 的回复:] 这是实现字节位逆序最快的算法，你好好领会吧。  这种有什么好领会的，毫无技术含量，最快的是这个，64位，b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;[/quote]  你这么说太棒槌了，这个算法需要mul、div、and，除法多慢你不懂啊，慢得没边了，应该都没有查表法1/5的性能。 另外，它这个"64位"是说用到了64位运算，不是能求64位数逆序，结果还是8位的。 [/quote]  不是64位是什么，还8位，真是搞笑了，查表能查到几位，内存放的下[/quote]  你还能再搞笑一些么？ http://graphics.stanford.edu/~seander/bithacks.html?1=1#BitReverseObvious Reverse the bits in a byte with 3 operations (64-bit multiply and modulus division):  unsigned char b; // reverse this (8-bit) byte   b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;

引用 29 楼 DelphiGuy 的回复:[quote=引用 25 楼 java_charpnet 的回复:] [quote=引用 24 楼 DelphiGuy 的回复:] 这是实现字节位逆序最快的算法，你好好领会吧。  这种有什么好领会的，毫无技术含量，最快的是这个，64位，b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;[/quote]  你这么说太棒槌了，这个算法需要mul、div、and，除法多慢你不懂啊，慢得没边了，应该都没有查表法1/5的性能。 另外，它这个"64位"是说用到了64位运算，不是能求64位数逆序，结果还是8位的。 [/quote]  不是64位是什么，还8位，真是搞笑了，查表能查到几位，内存放的下

引用 25 楼 java_charpnet 的回复:[quote=引用 24 楼 DelphiGuy 的回复:] 这是实现字节位逆序最快的算法，你好好领会吧。  这种有什么好领会的，毫无技术含量，最快的是这个，64位，b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;[/quote]  你这么说太棒槌了，这个算法需要mul、div、and，除法多慢你不懂啊，慢得没边了，应该都没有查表法1/5的性能。 另外，它这个"64位"是说用到了64位运算，不是能求64位数逆序，结果还是8位的。

搞java的研究性能干嘛，写个 for一行的事情，不用看明白咋搞的

solve<8>   和 solve<7> 又不是同一个函数, 递归你个毛啊...

引用 23 楼 user-3 的回复:不懂的不要乱说,  自己看书去,  这不是递归,  这只是为了自动的循环展开.    这样写会自动将  slovle_N( )  展开为连续的 N 次位操作  ..  这个标准做法就是大量的  bitroder swap 像 DelphiGuy 一样查表,  少量的操作就老实的循环.  这不是递归是什么，编译器会自动优化啊

弱智啊,  %1023  的结果只有 0-1022 怎么可能是 64位的...

引用 24 楼 DelphiGuy 的回复:这是实现字节位逆序最快的算法，你好好领会吧。  这种有什么好领会的，毫无技术含量，最快的是这个，64位，b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;

引用 20 楼 java_charpnet 的回复:[quote=引用 18 楼 DelphiGuy 的回复:] [quote=引用 16 楼 java_charpnet 的回复:] [quote=引用 14 楼 DelphiGuy 的回复:] 如果限定字节数据的话，应该还是查表法快。  什么查表法，怎么闻所未闻，是干什么的[/quote]   就是 typedef unsigned char BYTE;  __inline BYTE Reverse(BYTE x) {   static const BYTE r[256] = {0x00, 0x80, 0x40, 0x20, 0x10， ... , x0ff};  // 这里你自己补全    return r[x]; } [/quote]  原来是这样，这种就更胡扯了，等于是人工逆序[/quote]  这是实现字节位逆序最快的算法，你好好领会吧。

引用 21 楼 user-3 的回复:没听过你关心性能干嘛,  一个用java的跑 C 这来教人写高性能程序也太搞了吧...  谁关心性能了，我是把循环改成位运算，搞了半天说用递归

引用 18 楼 DelphiGuy 的回复:[quote=引用 16 楼 java_charpnet 的回复:] [quote=引用 14 楼 DelphiGuy 的回复:] 如果限定字节数据的话，应该还是查表法快。  什么查表法，怎么闻所未闻，是干什么的[/quote]   就是 typedef unsigned char BYTE;  __inline BYTE Reverse(BYTE x) {   static const BYTE r[256] = {0x00, 0x80, 0x40, 0x20, 0x10， ... , x0ff};  // 这里你自己补全    return r[x]; } [/quote]  原来是这样，这种就更胡扯了，等于是人工逆序

引用 17 楼 user-3 的回复:[quote=引用 15 楼 java_charpnet 的回复:] [quote=引用 13 楼 user-3 的回复:] 搞java的研究性能干嘛，写个 for一行的事情，不用看明白咋搞的  仔细看了看，你这都递归了，效率太差还不如循环[/quote]  不懂的不要乱发言,  尾递归就是循环, 何况这还不是尾递归.. [/quote]  你懂在什么地方，32位五行语句64位一行语句的事情，又是模板又是cache的，还什么尾递归，闻所未闻

引用 16 楼 java_charpnet 的回复:[quote=引用 14 楼 DelphiGuy 的回复:] 如果限定字节数据的话，应该还是查表法快。  什么查表法，怎么闻所未闻，是干什么的[/quote]   就是 typedef unsigned char BYTE;  __inline BYTE Reverse(BYTE x) {   static const BYTE r[256] = {0x00, 0x80, 0x40, 0x20, 0x10， ... , x0ff};  // 这里你自己补全    return r[x]; }

引用 15 楼 java_charpnet 的回复:[quote=引用 13 楼 user-3 的回复:] 搞java的研究性能干嘛，写个 for一行的事情，不用看明白咋搞的  仔细看了看，你这都递归了，效率太差还不如循环[/quote]  不懂的不要乱发言,  尾递归就是循环, 何况这还不是尾递归..

引用 14 楼 DelphiGuy 的回复:如果限定字节数据的话，应该还是查表法快。  什么查表法，怎么闻所未闻，是干什么的


Question: C语言里面的作用域

加static前缀的局部变量，其生命期和全局变量一样长。

这2个东西，也一直没弄清楚，谢谢，高手，解释

int main() {         char  *str = NULL;                  p = Get_Str();         puts(str);                 return 0; } 第一段代码出错了，main函数中有未定义的str，应改为str=Get_Str();   至于你说的问题，首先第一段代码是用一个指针去指定一个字符串，返回字符串的首地址值，子函数结束之后，指针被回收，字符串海存在于内存当中，当主函数put（str）时，自然能把字符打印出来。  另外第二段代码，显然子函数调用之后子函数的局部变量生命周期结束，自然无法打印出来。

引用 3 楼 cfjtaishan 的回复:这个应该不是作用域的问题,确切的说应该是生命域；全局变量的生命域是整个程序,而局部变量的生命域是从所在函数的调用开始,到函数调用结束； 也可以称为:生命周期!

你第一个程序能输出Hello World？？ p = Get_Str();这个p都没定义……

不要返回局部对象的指针 这两种代码都是有隐患的，结果也是不确定的

因为你第一种写法，返回的是常量字符串的地址（它不会因为Get_Str函数调用结束就释放） 而第二种写法，char p[] = "Hello World";是在栈上开辟的字符数组，Get_Str函数调用结束就释放了


Question: 图形库 如ImageMagick或者libgd之类的有人用过吗？请帮下忙

C:\Program Files\ImageMagick-6.6.9-Q16>convert /? Version: ImageMagick 6.6.9-6 2011-04-14 Q16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC Features: OpenMP  Usage: convert [options ...] file [ [options ...] file ...] [options ...] file  Image Settings:   -adjoin              join images into a single multi-image file   -affine matrix       affine transform matrix   -alpha option        activate, deactivate, reset, or set the alpha channel   -antialias           remove pixel-aliasing   -authenticate password                        decipher image with this password   -attenuate value     lessen (or intensify) when adding noise to an image   -background color    background color   -bias value          add bias when convolving an image   -black-point-compensation                        use black point compensation   -blue-primary point  chromaticity blue primary point   -bordercolor color   border color   -caption string      assign a caption to an image   -channel type        apply option to select image channels   -colors value        preferred number of colors in the image   -colorspace type     alternate image colorspace   -comment string      annotate image with comment   -compose operator    set image composite operator   -compress type       type of pixel compression when writing the image   -define format:option                        define one or more image format options …… Image Stack Operators:   -clone indexes       clone an image   -delete indexes      delete the image from the image sequence   -duplicate count,indexes                        duplicate an image one or more times   -insert index        insert last image into the image sequence   -reverse             reverse image sequence   -swap indexes        swap two images in the image sequence  Miscellaneous Options:   -debug events        display copious debugging information   -help                print program options   -list type           print a list of supported option arguments   -log format          format of debugging information   -version             print version information  By default, the image format of `file' is determined by its magic number.  To specify a particular image format, precede the filename with an image format name and a colon (i.e. ps:image) or specify the image type as the filename suffix (i.e. image.ps).  Specify 'file' as '-' for standard input or output.

convert /?

CxImage，OpenCV ？

自己顶一下，希望有人帮帮忙


Question: 在下新手，请教一个关于c语言中for循环的问题，求赐教！

for (A;B;C) D; //等价于 {  A;  while (1) {   if (!(B)) break;   D;   C;  } }

感谢2楼，现在终于明白了

n-- 下个循环要重新初始化，不然直接退出了

#include<stdio.h> void inverse(int *p, int n) { 	int *q; 	q = p + n - 1; 	for (;p < q;p++, q--) 	{ 		int t;t = *q;*q = *p;*p = t; 	}  } int main(void) { 	int a[] = { 1,3,5,7,9 }; 	int *m, k;  	for (m = a,k=0;k<5;k++) 		printf("%d", *m++); 	puts(""); 	inverse(a, 5);  	//for (m = a,k=0;k<5;k++) 	int n = 5; 	for(m=a;n>0;n--) 		printf("%d", *m++); 	puts(""); 	return 0; } 输出结果没有问题呀！


Question: 什么算是数据结构的模板？？

c++里面就是类模版和函数模版吧。c里面我猜就是具有类似功能的各种宏替换。


Question: 请问高手，用C语言表示数字从1变化到0（或0变化到1）

引用 3 楼 lm_whales 的回复:if (a!=a0) 就可以了 如果是硬件编程，直接设置为沿触发即可  对 这样硬件编程也可以 那是不是还的跟软件编程相结合啊

纯软件，可以用两个位或者变量来描述 一个表示现在状态，一个表示新状态  如果二者一致，那就没变化 如果一个为0 一个为1 那就是变化了 如果变了，新状态为1 那就是上升沿来了 如果新状态为0 那就是下降沿来了

哥们我是个初学者  能不能详细的解释一下   尤其是那副图    你用while语句 好像一直就跳不出去了   你这里是不是用到指针了   我这个高压断路器，开关原理是这样的，有个小车它分有实验位置和工作位置  //{小车是可以推动的 }， 当小车处于实验位置或工作位置是断路器都可以合闸，当小车处于实验位置是为实验1， 此时工作位置显示为工作0，当小车处于工作位置是为工作1，此时实验位置显示为实验0； 当小车处于实验位置是断路器合闸正常工作，这是如果继续推进小车把它推进到工作位置， 它要有报警功能  会语音提示"请分断路器”;   下面是我错误的程序  输入信号 断路器=1  输入信号 工作位置=1 if(断路器==1//工作位置==1）   输出  请分断路器；  如果这段程序这样写会把正常工作也给PASS掉   正确的程序原理应该是这样 输入信号 断路器=1  输入信号 工作位置=1 if(断路器==1//工作位置变化从0变为1) 输出  请分断路器； 这样才不会把正常工作也给当成报警了

if (a!=a0) 就可以了 如果是硬件编程，直接设置为沿触发即可

用一个变量b记录a的上个值，a为1且b为0是你要的，然后更新b=a


Question: 谁能回答我下一下腾讯服务器为什么把数据都加载到内存里？

内存速度快，就是比普通硬盘造价高一些，其实可以，如果资金够充分

有钱的

快啊, 要啥原因, 腾讯这种土豪用不是蛮好的么.   网上不是有人晒过 2T 内存的服务器么, 好像是 4CPU, 128*16G 的条子,  光看着就爽啊...

引用 4 楼 u010165006 的回复:存储是分层次的，cache——内存——硬盘、闪存——磁带、光盘、U盘等  闪存改为固态硬盘

存储是分层次的，cache——内存——硬盘、闪存——磁带、光盘、U盘等

闪存？运行时数据？持久化肯定要存在非易失性存储介质。

主要存在数据库里. .


Question: c语言写的dll如何返回int数组呢，急等

C 语言不能返回数组，如果想让其返回一个数组，可以让函数返回一个指针，通过指针操作数组。

为了节约硬件资源，最初设计c语言的时候 主函数传递的数组的首地址（这么说不准确，地址只有地址，指针不仅包括地址还包含类型）或者指向数组的指针，要返回也是返回一个指针。

请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？

C语言不能返回数组类型，如果需要返回数组，可以通过传入的参数返回

C语法不能返回数组的，只能返回一个int型指针，你的函数原型已经定了吗


Question: C语言中，对一段函数进行超时判断，请问怎么实现?

计时器的回调函数和工作函数不在一个线程中，你在回调函数中跳到main函数，会让回调函数的线程崩溃

我已经解决了   #include <stdio.h>    #include <windows.h>    //子线程函数     char flag = 0; char result = 0;  DWORD WINAPI longTimeFunction(LPVOID pM)   { 	while(1){ 		printf("opreating...\n"); 		Sleep(20); 	} 	result = 1; 	flag = 1; }   //主函数，所谓主函数其实就是主线程执行的函数。    int main()   {       printf("simple multi thread,INFINITE:%d\n",INFINITE);       printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");        	flag = 0;     HANDLE longTimeFunctionHandle = CreateThread(NULL, 0, longTimeFunction, NULL, 0, NULL);       WaitForSingleObject(longTimeFunctionHandle, 200);     if(flag == 0){     	printf("Timeout!\n");     	result = -1;     } 	printf("result: %d\n", result);          return 0; }

执行timeSetEvent的回调函数OneMilliSecondProc()的是另外一个线程，即使不出错，你执行main()的主线程仍然永远阻塞在longTimeFunction上。 一个会阻塞的API，尤其是会无限期阻塞的API应该设计为可设置超时值，超时后返回。如果你的这个第三方dll中有一个API，不支持设置超时值，且会发生无限期阻塞，则只能说明设计这个API的程序员水平实在一般。 而你又无法修改这个DLL的代码，只能走一些偏路来帮他擦屁股了。 开一个线程去调用这个会阻塞的函数，主线程判断过了一段时间还没有返回结果就kill这个线程。这种方法虽然可以实现效果，但十有八九要发生资源泄漏。 一个相对较好的办法就是开一个进程(CreateProcess)去调用这个会阻塞的函数，如果获取到了结果，就通过进程通信技术把结果发回主进程，如果主进程过了一段时间没有得到结果，则可判定为超时，将那个进程杀掉(TerminateProcess)。

《Windows核心编程》

引用 1 楼 iyomumx 的回复:longjmp 不能跨线程。 如果要控制一段函数的运行时间，建议开一个新进程来跑 开新线程理论上是可以的，但问题在于如果函数超时了，你怎么办。用 TerminateThread 很容易发生内存泄漏，因为新线程中申请的内存都无法释放。如果有可靠的中止线程的方法，可以考虑。 开新进程就没那么多顾虑了，超时了就 kill 掉，系统会帮它擦屁股。  我查了一下，是不是用fork函数，启动另一个进程？

有没有一种方法，在主程序里计时，开一个线程执行长时间函数，计时到了以后去内存地址看看数值，如果数值没有赋值，就知道那个线程超时了，把那个线程杀掉，返回timeout异常。

引用 1 楼 iyomumx 的回复:longjmp 不能跨线程。 如果要控制一段函数的运行时间，建议开一个新进程来跑 开新线程理论上是可以的，但问题在于如果函数超时了，你怎么办。用 TerminateThread 很容易发生内存泄漏，因为新线程中申请的内存都无法释放。如果有可靠的中止线程的方法，可以考虑。 开新进程就没那么多顾虑了，超时了就 kill 掉，系统会帮它擦屁股。  哥们儿，帮我想想办法


Question: RTSP_RTP_TCP协议获取摄像头数据生成h264文件，vlc播放抖动就花屏，小弟在这苦等大脚们\0..0/

路过，我知道buf太小会有问题，但是我要延时小不能用大buf。有没有办法？

楼主最后怎么解决得，可否分享下经验。

楼主问题解决没？请分享下，谢谢

我遇到过在每帧尾部有12个字节的描述段，不去掉会花屏，不知道和你的情况是不是一样

引用 12 楼 corrupt 的回复:有几个方法： 1、因为音频报文比较小，一般一个包就是一帧音频数据，所有一个rtp就会打一个mark标记，如果报文中很多一个报文就存在mark标记的就应该是音频包。 2、就是看rtp的payload type ， 音频和视频的payload 是分开的。  你试试把音频采集给去掉； 如果不是音频的问题，那么基本是h264拼帧有问题。 这款摄像头没有音频，只有视频，在网页上只找到视频设置。您能不能帮我看看拼帧有没有问题，代码在另一个提问上： http://bbs.csdn.net/topics/392018314?locationNum=5

石沉大海！！！

引用 10 楼 zhao4zhong1 的回复:有没有问题可能需要你自己象我示例代码中那样log每个收发的字节自行判断。  好吧，感谢！

有没有问题可能需要你自己象我示例代码中那样log每个收发的字节自行判断。

引用 6 楼 zhao4zhong1 的回复:任何收发两端速度不一致的通讯，都需要在它们之间使用一个足够大的FIFO缓冲区。 对任何FIFO缓冲区的使用，都需要仔细考虑接收端接收时超时无数据和发送端发送时FIFO缓冲区已满这两种情况下该如何做。 这些概念都在这段经典代码中有所体现。 这段经典代码还包括以下必须考虑的因素： ◆跨Windows和Linux平台 ◆多线程锁 ◆多线程日志 ◆日志文件占用的磁盘空间可控 ◆日志中的时间包括毫秒 ◆传输的数据对应的每个字节到底是几 ◆如何退出多线程程序 ◆…… 小弟用的是5000个字节的缓冲区，每次接收完5000个字节，小弟就将缓冲区的所有rtp包拆包后写入264文件中，在接收再处理。。。 这样处理有问题吗？

引用 5 楼 corrupt 的回复:花屏的原因不仅仅只是网络丢包，要综合来排除： 1、打印报文的rtp seq 是否连续、是否乱序 2、将拆包后的裸数据保存成h264文件，并使用elecard 播放是否正常。 3、视频中是否携带了音频？ 音频的seq和视频的seq是一起打包的吗？ ...... seq是连续的，时间戳也是递增的 至于是否包括音频，小弟就不了解了。 具体该怎么判断，摄像头是否发送了音频？

没人了吗?||~.~||

等待 永久地等待 树叶绿了又黄你还没来

赵4老师，感谢！您的回复。 小弟不太明白，您给的代码跟我问题的关联点在哪里？ 小弟是写了一个客户端,用TCP给摄像头发送rtsp命令对接上后，接受到rtp数据--》拆包--》写成h264文件--》vlc播放--》视频有动作就花屏。 找不到问题出在哪。

仅供参考：//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef _MSC_VER     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _MSC_VER     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #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); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #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} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             Log("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef _MSC_VER     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef _MSC_VER     pthread_exit(NULL); #endif } int main() { #ifdef _MSC_VER     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef _MSC_VER     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef _MSC_VER     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }


Question: 看完Cprimerplus却好多代码看不懂。。

首先头文件很多你可能暂时用不太到…其次关键字编译器都是有提示的，如果你用重了会报错的，多看错误信息以后什么错误一眼就能看出来，如果你觉得这需要死记硬背只能说编程不太适合你……多练练就会熟悉头某个文件的主要功能

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

你的情况可以分两步走，先买本薄的入门的书，没有太多不太常用的细节，学习基本概念、程序编写的基本方法、C语言的大部分基础的语法，入门以后对C语言有了一定了解和整体概念，在回头看C Primer Plus重新学习、加深认识、扩展知识，这样学习应该比较扎实。

很正常，其实看primer还是需要一些基础的。

我个人觉得这本是入门C领域的好书，因为内容极其详细，但对于未有基础的学习者来说，这也成为一大障碍。潭浩强的那本C虽然有个别地方错误，但无关紧要，有了基础后再用CPrimerPlus来提高强化C。

看本易懂的书，比如谭浩强的C程序设计


使用旧版兼容格式doc，而不是docx。


Question: 有办法让正在播放的音乐暂停，紧接着需要时再播放（playsound函数）？

PlaySound(NULL,NULL,NULL); //停止播放


Question: 关于联合体的小问题

p3、p5共用内存 p4、p6共用内存 最近写入的有效

因为它们都是指向char型的指针 间接取值，取出了0x22 当然就是十进制的34了


Question: 数学问题,知道直角三角形2点坐标,3边长度,求第三点坐标

可以先求直角三角形旋转到与XY轴平行的角度和新的C点坐标，然后再把坐标旋转回去。 大致是这样的（没有验证，错了不要怪我）： angle = arcsin((Xa - Xb) / AB) Xc' = Xa + AC Yc' = Ya Xc = cos(angle) * Xc' - sin(angle) * Yc'; Yc = cos(angle) * Yc' + sin(angle) * Xc';

这样算的话，因为计算机计算过程中会出现 截断的过程，所有 计算机算的值与精确值 之间是存在一定的误差的，所有 像是用数学问题来编程时，一般都要给两者一定的误差值！

引用 2 楼 ID870177103 的回复:公式是对的，肯定是你实现的问题，精度损失什么的 恩,我带入数据,验证这方程式是ok的, 只是不知道是在哪一步解出错了,

公式是对的，肯定是你实现的问题，精度损失什么的

参考《高中数学》三角函数


Question: 为什么不能直接将getc(stdin) !=EOF做比较？

感谢各位大神

楼主这种也可以  另外ch=getc(stdin) !=EOF; ch得到的是比较后的布尔值  而 (ch=getc(stdin)) !=EOF 是让ch等于函数返回值，再与EOF比较

它喜欢写成那样。 不代表getc(stdin) !=EOF就不行

但是 while(get(in) !=EOF) 不能实现 while((ch=get(in)) != EOF) 的功能

输出---->输入

能，但是输出不仅仅是为了检测是否EOF 的吧 如果，不是EOF总得做点什么吧 那么，用一个变量存储getc的返回值，不就很自然了么？

怎么不能？谁说不能了？


Question: 如何使用指针和malloc函数，输入未知长度的字符串到数组

#include <stdio.h>  /* printf, scanf, NULL */ #include <stdlib.h>  /* malloc, free, rand, system */  int main () {     int i,n;     char * buffer;      printf ("输入字符串的长度：");     scanf ("%d", &i);      buffer = (char*)malloc(i+1);  // 字符串最后包含 \0     if(buffer==NULL) exit(1);  // 判断是否分配成功      // 随机生成字符串     for(n=0; n<i; n++)         buffer[n] = rand()%26+'a';     buffer[i]='\0';      printf ("随机生成的字符串为：%s\n",buffer);     free(buffer);  // 释放内存空间      system("pause");     return 0; }

/*使用说明*/ /*     linux 下在a.out 后面加一个空格 再输入你想要的字符串 就会malloc内存 然后把你的字符串cpy 进内存了     windows下生成的是.exe 一样的在 先在cmd 模式下进入.exe 目录 在cmd模式中输入 什么什么.exe 空格 再你想要的字符串，就会malloc内存 然后把你的字符串cpy 进内存了 */ #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>  int main(int argc, char* argv[]) { 	char* ch = (char*)malloc(strlen(argv[1]) + 1); 	strcpy(ch, argv[1]); 	printf("%s", ch); 	return 0; }

谢谢！不过我还是没有搞懂动态分配的空间是怎么通过指针与数组联系上的。今天回家再好好看看书。自学真是难啊，心中好多疑问，似懂非懂。

1.因为有'\0' 3. 第一种方法是：让用户先输入一个整数来指定接下来要输入的字符串长度，然后malloc输入的整数+1个字节空间就好。 第二种方法是：你只能先开辟一个大一点的空间，让用户输入字符串，然后可以strlen(字符串)，然后malloc对应长度+1的空间

请教： 1.”char *pva=(char *)malloc(sizeof(str));这句话只申请了一个字节的空间，你打印下sizeof(str)就知道了。“ 问：只申请了一个字节的空间是不是我初始化为{0},只有一个元素的原因？ 3.”你让pva指向str?你输入的字符串是写在pva所malloc出来的空间里的，而不是str里的“ 问：相当于代码中声明数组其实是多余的了吧？那么我想把输入字符存入数组，但数组的字符数量又是由用户自己来确定，那又怎么操作呢?因为直接用char srt[LENGTH]来声明数组，好像占用的字节空间很大。  感谢大神的耐心回答！

你这个逻辑完全不对。 1.char *pva=(char *)malloc(sizeof(str));这句话只申请了一个字节的空间，你打印下sizeof(str)就知道了 2.printf("%s",*pva);不需要加* 3.你让pva指向str?你输入的字符串是写在pva所malloc出来的空间里的，而不是str里的  #include <stdio.h> #include <stdlib.h> #include <string.h>  int main(void) { 	const int LENGTH = 50; 	char str[] = { 0 };//用于存放字符串 	printf("sizeof(str):%d\n", sizeof(str)); 	char *pva = (char *)malloc(LENGTH + 1); 	//pva = str; //指针指向数组 	 	printf("\nPlease enter a string up to %d characters:", LENGTH); 	scanf("%s", pva); 	printf("%s\n", pva); 	return 0; }


Question: C 打印二维数组出错

引用 1 楼 qq423399099 的回复:printf("%d\t", &arrayMap[i][j]);你这句，多加了&吧？ 对数组元素取地址，然后%d打印，打印出来的是地址 出来了，谢谢，确实这个&是多余的


Question: c语言读文件遇到的一个很奇怪问题：文件读取时文件指针突然变成一个无效地址

可以改成strncat,如果为了拼接字符串可以用sprintf

找到问题了，中间处理代码使用strcat出了点问题，应该是和结尾字符有关，导致内存越界，感谢上面两位解答。多谢！

越界不一定是fread那句导致的，也可能是你的别的变量越界导致的 你可以把别的语句都注释掉，就光光fread,然后fclose看看有没有问题

引用 2 楼 qq423399099 的回复:你这个肯定是有变量越界了，覆盖到k变量甚至是fp文件指针所在的内存。 极有可能是你fread(buff,1023,1,fp);后面的语句造成的，建议楼主自己检查下，或者贴出来。  每条记录长度固定，绝对小于1023,。变量越界指的是数据超出了变量的表示范围？

引用 1 楼 CharlesSimonyi 的回复:估计是向数组写入数据时越界了。 用GDB 设置一个watch point 监视fp，这样一旦fp被改变便可以断下来看是哪里出了问题  前面忘记说了，数据量是固定的，每条记录绝对小于1023


Question: 指针的星号到底应该靠前还是靠后呢？

引用 3 楼 lm_whales 的回复:int*p;//感觉不舒服，可读性不好。 int* p;//强调，p是指针 int * p;//不强调什么，但是多输入一个空格 int *p;//强调指针p 指向整型。  那种都一样，唯一不同的是，感觉不同。 以及暗喻不同。  int* p; 强调 p是（int 类型的）指针类型。 int *p;强调指针 p 指向整型。  明白了，我当然知道编译出来的结果是一样的，只是想看看大家对不同写法的主观感受而已。

引用 7 楼 CharlesSimonyi 的回复:请教一下，上楼梯的时候，应该先抬左脚还是先抬右脚呢？  先抬左脚 先抬右脚  以上两种抬法，大家推荐哪一种抬法呢？  也希望大家说说为什么吧。  我建议先抬左脚，因为我是左撇子，呵呵。

引用 2 楼 Intel0011 的回复:纯C派的喜欢 int *p; C++派的喜欢 int* p; 没什么固定格式  [quote=引用 1 楼 qq423399099 的回复:] 建议靠后，写成int *p; 否则如果是这样：int* p,q; 是不是会把q误当成int *类型呢？ 这个最好还是用typedef解决吧 [/quote]  为什么C++派的喜欢 int* p呢？

这个属于代码风格的问题,建议靠近变量；

引用 8 楼 lm_whales 的回复:

int* p1,p2; 我觉得不是误会p2的类型，而是这俩不同类型这么写一块真的好吗...

引用 7 楼 CharlesSimonyi 的回复:请教一下，上楼梯的时候，应该先抬左脚还是先抬右脚呢？  先抬左脚 先抬右脚  以上两种抬法，大家推荐哪一种抬法呢？  也希望大家说说为什么吧。 这个估计，大家没啥想法， 但是统计下来，可能是先抬左脚的多 （也许这个猜测是错的，但是不会是一半对一半，这是没问题的，可能是3：7 或者差距更大一点） 因为现实中，左撇子少，大家都是右撇子。 很多应该对称的，实际上并不对称。

个人习惯问题，你喜欢还可以int  *  p

靠后边的变量好一些

个人感觉写在后边应该更好点吧

引用 1 楼 qq423399099 的回复:建议靠后，写成int *p; 否则如果是这样：int* p,q; 是不是会把q误当成int *类型呢？ 同意

纯C派的喜欢 int *p; C++派的喜欢 int* p; 没什么固定格式  引用 1 楼 qq423399099 的回复:建议靠后，写成int *p; 否则如果是这样：int* p,q; 是不是会把q误当成int *类型呢？ 这个最好还是用typedef解决吧


Question: 关于什么情况下不需要include 头文件

留心warning。

你只要把真正使用的声明信息 写到 .c 中 并不一定要包含头文件 但是包含头文件，是一个简单方便的方法， 是一个习惯，大家都爱用而已   例如头文件 有函数声明 .c 中只需要有同样的声明就可以了，不是一定要包含头文件的  PS： 包含头文件，最简单，最方便 所以，大家都喜欢这样用，没有几个人自己去写头文件中已经有的代码。

头文件.h，c 文件.c 本质上，都是文本文件 分为.h,.c 只是为了方便 你也可以 把头文件的东西，全部放到.c  不过，容易被误解为真正的.c  头文件往往不含实现代码  编译它是多余的,包含头文件，往往是把头文件的代码复制一份到.c 生成新的文件 然后编译新的文件 如果把.c存储为.h，并且用于包含 自动编译的时候，往往会出问题

如果你A B C三个文件，B包含了A，C再包含B，那么相当于C也包含了A

你头文件B包含了头文件A 你文件C虽然没包含A，但是不是包含了B？

引用 1 楼 zhao4zhong1 的回复:有些编译环境会隐含#include一些头文件。  你好 我举例说的头文件A B 和原文件D  都是我自己定义的 不是系统自带的

有些编译环境会隐含#include一些头文件。

引用 10 楼 mfcappwizard 的回复:[quote=引用 9 楼 qq423399099 的回复:] [quote=引用 8楼我是你的主体 的回复:][quote=引用 7 楼 qq423399099 的回复:] 不行的，要用extern 而且头文件里尽量不要定义变量，因为很容易出现重定义  是的 头文件 可以用来声明变量 最好不要定义变量  假如在头文件A中声明一个全局变量  头文件B 用到 但是并不include 头文件A  这种情况是否可以 （如果可以的话，就和宏的枪框一样了） 注意是全局变量 不是局部变量[/quote]不行[/quote]  谢谢你这么多次的回答，能否解释一下为什么只有宏可以做到 而其他变量却不能，是在编译的时候或运行的时候，有些地方不允许变量这样吗？ 除了宏，您还知道其他参数可以做到和宏一样的吗？[/quote] 和宏毫无关系，头文件本身是不需要编译的，只要cpp里面的所有变量能自解释就行了，这就是为什么很多人的头文件内容都不全，想复用的时候编都编不过。

引用 9 楼 qq423399099 的回复:[quote=引用 8楼我是你的主体 的回复:][quote=引用 7 楼 qq423399099 的回复:] 不行的，要用extern 而且头文件里尽量不要定义变量，因为很容易出现重定义  是的 头文件 可以用来声明变量 最好不要定义变量  假如在头文件A中声明一个全局变量  头文件B 用到 但是并不include 头文件A  这种情况是否可以 （如果可以的话，就和宏的枪框一样了） 注意是全局变量 不是局部变量[/quote]不行[/quote]  谢谢你这么多次的回答，能否解释一下为什么只有宏可以做到 而其他变量却不能，是在编译的时候或运行的时候，有些地方不允许变量这样吗？ 除了宏，您还知道其他参数可以做到和宏一样的吗？

引用 8楼我是你的主体 的回复:[quote=引用 7 楼 qq423399099 的回复:] 不行的，要用extern 而且头文件里尽量不要定义变量，因为很容易出现重定义  是的 头文件 可以用来声明变量 最好不要定义变量  假如在头文件A中声明一个全局变量  头文件B 用到 但是并不include 头文件A  这种情况是否可以 （如果可以的话，就和宏的枪框一样了） 注意是全局变量 不是局部变量[/quote]不行

引用 7 楼 qq423399099 的回复:不行的，要用extern 而且头文件里尽量不要定义变量，因为很容易出现重定义  是的 头文件 可以用来声明变量 最好不要定义变量  假如在头文件A中声明一个全局变量  头文件B 用到 但是并不include 头文件A  这种情况是否可以 （如果可以的话，就和宏的枪框一样了） 注意是全局变量 不是局部变量

不行的，要用extern 而且头文件里尽量不要定义变量，因为很容易出现重定义

引用 5 楼 qq423399099 的回复:https://www.zhihu.com/question/38235552  谢谢，你的链接解释了这个，这个是不是仅限于宏定义，其他类型的变量是否可以，宏是放在全局变量的区域，如果定义全局变量，也可以这么干吗？ 在头文件B中使用头文件A的变量，而头文件B不include头文件A？

引用 3 楼 qq423399099 的回复:你头文件B包含了头文件A 你文件C虽然没包含A，但是不是包含了B？  可能没说清楚，上面两种情况是独立的，所以没有源文件D包含头文件B的情况


Question: 练习使用多case解题

main函数改成下面这样行不行的？ int main() { 	int n, i, j = 0; 	int a[MAX][2];         scanf("%d",&n); 	while(scanf("%d%d",&a[j][0], &a[j][1]) != EOF){ 		j++; 	}        for (i = 0; i < n; i++)       {              printf("%d\n", max_element(a[i][0], a[i][1]));       }     printf("group 1 done\n");     while (a[i][0] != 0 || a[i][1] != 0)     {         printf("%d\n", max_element(a[i][0], a[i][1])); 		i++;     }     printf("group 2 done\n"); 	i++;     for(; i < j; i++)     {         printf("%d\n", max_element(a[i][0], a[i][1]));     }     printf("group 3 done\n"); 	     return 0; }


Question: 如何将两个运动的“点”显示不同的颜色

引用 8 楼 u010165006 的回复:// 将Project—Properties—Configuration Properties—General—Character Set  // 设置为：Not Set 或者 Use Multi-byte Character Set // 这样就是使用ANSI字符集  	HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); 	 	WORD wColors[1]={FOREGROUND_RED}; 	textout(handle,10,10,wColors,1,"甲方"); 	wColors[0]=FOREGROUND_BLUE; 	textout(handle,20,20,wColors,1,"乙方"); 谢谢，我想要的实现了。

引用 1 楼 u010165006 的回复:#include "stdafx.h" #include "colorConsole.h"  /* HANDLE initiate() { 	HANDLE hOutput;  	hOutput = GetStdHandle(STD_OUTPUT_HANDLE); 	return hOutput; } */  BOOL textout(HANDLE hOutput,int x,int y,WORD wColors[],int nColors,LPTSTR lpszString) {     DWORD cWritten;      BOOL fSuccess;      COORD coord;      	coord.X = x;              // 输出第一个字符所在的列即X坐标      coord.Y = y;              //   所在的行即Y坐标           fSuccess = WriteConsoleOutputCharacter(		//输出字符串         hOutput,              // 屏幕缓冲区的句柄         lpszString,           // 指向字符串的指针          lstrlen(lpszString),  // 字符串长度         coord,                // 输出第一个字符的坐标         &cWritten);           // 实际输出字符的个数     if (! fSuccess)          cout<<"error:WriteConsoleOutputCharacter"<<endl;      	     	for (;fSuccess && coord.X < lstrlenA((LPCSTR)lpszString)+x; coord.X += nColors)      {         fSuccess = WriteConsoleOutputAttribute(		//为已输出的字符串上色             hOutput,          // 屏幕缓冲区的句柄             wColors,          // 颜色数组             nColors,          // 颜色数目             coord,            // 输出第一个字符的坐标             &cWritten);       // 实际输出字符的个数     }     if (! fSuccess)      	cout<<"error:WriteConsoleOutputAttribute"<<endl;  	return 0; }  自己是个小白，关于API的东西不是特别懂，要是能指导一下textout函数调用的形参的声明（虽然你有注释，但是我还是有点不明白QAQ）就更好了，我看了你的这个感觉上可以完成我的想法

颜色可以参考《C.C++控制台界面编程(V4).pdf》

引用 2 楼 paschen 的回复:如果需要变换颜色，就再次调用该函数 这个方法在我这里感觉不合适，因为我需要两种颜色同时在屏幕中显示，而你说的再次调用该函数也只是同时改变这两个点的颜色，没有达到目的

如果需要变换颜色，就再次调用该函数

再供参考：#include <windows.h> #include <stdio.h>  void ConPrint(char *CharBuffer, int len); void ConPrintAt(int x, int y, char *CharBuffer, int len); void gotoXY(int x, int y); void ClearConsole(void); void ClearConsoleToColors(int ForgC, int BackC); void SetColorAndBackground(int ForgC, int BackC); void SetColor(int ForgC); void HideTheCursor(void); void ShowTheCursor(void);  int main(int argc, char* argv[]) {    HideTheCursor();    ClearConsoleToColors(15, 1);    ClearConsole();    gotoXY(1, 1);    SetColor(14);    printf("This is a test...\n");    Sleep(5000);    ShowTheCursor();    SetColorAndBackground(15, 12);    ConPrint("This is also a test...\n", 23);    SetColorAndBackground(1, 7);    ConPrintAt(22, 15, "This is also a test...\n", 23);    gotoXY(0, 24);    SetColorAndBackground(7, 1);    return 0; }  //This will clear the console while setting the forground and //background colors. void ClearConsoleToColors(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //not used but we need to capture this since it will be    //written anyway (passing NULL causes an access violation).    DWORD count;     //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    SetConsoleTextAttribute(hStdOut, wColor);    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);        FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will clear the console. void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will set the position of the cursor void gotoXY(int x, int y) {    //Initialize the coordinates    COORD coord = {x, y};    //Set the position    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }  //This will set the forground color for printing in a console window. void SetColor(int ForgC) {    WORD wColor;    //We will need this handle to get the current background attribute    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    CONSOLE_SCREEN_BUFFER_INFO csbi;     //We use csbi for the wAttributes word.    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //Mask out all but the background attribute, and add in the forgournd color       wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);       SetConsoleTextAttribute(hStdOut, wColor);    } }  //This will set the forground and background color for printing in a console window. void SetColorAndBackground(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor); }  //Direct console output void ConPrint(char *CharBuffer, int len) {    DWORD count;    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL); }  //Direct Console output at a particular coordinate. void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); }  //Hides the console cursor void HideTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = FALSE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  //Shows the console cursor void ShowTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = TRUE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }

仅供参考：// processor: x86 #include <windows.h> #include <process.h>    /* _beginthread, _endthread */ #include <stddef.h> #include <stdlib.h> #include <conio.h>  void Bounce( void *ch ); void CheckKey( void *dummy );  /* GetRandom returns a random integer between min and max. */ #define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))  BOOL repeat = TRUE;     /* Global repeat flag and video variable */ HANDLE hStdOut;         /* Handle for console window */ CONSOLE_SCREEN_BUFFER_INFO csbi;    /* Console information structure */  int main() {     CHAR    ch = 'A';      hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );      /* Get display screen's text row and column information. */    GetConsoleScreenBufferInfo( hStdOut, &csbi );      /* Launch CheckKey thread to check for terminating keystroke. */     _beginthread( CheckKey, 0, NULL );      /* Loop until CheckKey terminates program. */     while( repeat )     {         /* On first loops, launch character threads. */         _beginthread( Bounce, 0, (void *) (ch++)  );          /* Wait one second between loops. */         Sleep( 1000L );     }     return 0; }  /* CheckKey - Thread to wait for a keystroke, then clear repeat flag. */ void CheckKey( void *dummy ) {     _getch();     repeat = 0;    /* _endthread implied */  }  /* Bounce - Thread to create and and control a colored letter that moves  * around on the screen.  *  * Params: ch - the letter to be moved  */ void Bounce( void *ch ) {     /* Generate letter and color attribute from thread argument. */     char    blankcell = 0x20;     char    blockcell = (char) ch;     BOOL    first = TRUE;    COORD   oldcoord, newcoord;    DWORD   result;       /* Seed random number generator and get initial location. */     srand( _threadid );     newcoord.X = GetRandom( 0, csbi.dwSize.X - 1 );     newcoord.Y = GetRandom( 0, csbi.dwSize.Y - 1 );     while( repeat )     {         /* Pause between loops. */         Sleep( 100L );          /* Blank out our old position on the screen, and draw new letter. */         if( first )             first = FALSE;         else          WriteConsoleOutputCharacter( hStdOut, &blankcell, 1, oldcoord, &result );          WriteConsoleOutputCharacter( hStdOut, &blockcell, 1, newcoord, &result );          /* Increment the coordinate for next placement of the block. */         oldcoord.X = newcoord.X;         oldcoord.Y = newcoord.Y;         newcoord.X += GetRandom( -1, 1 );         newcoord.Y += GetRandom( -1, 1 );          /* Correct placement (and beep) if about to go off the screen. */         if( newcoord.X < 0 )             newcoord.X = 1;         else if( newcoord.X == csbi.dwSize.X )             newcoord.X = csbi.dwSize.X - 2;         else if( newcoord.Y < 0 )             newcoord.Y = 1;         else if( newcoord.Y == csbi.dwSize.Y )             newcoord.Y = csbi.dwSize.Y - 2;          /* If not at a screen border, continue, otherwise beep. */         else             continue;         Beep( ((char) ch - 'A') * 1000, 500 );     }     /* _endthread given to terminate */     _endthread(); }

console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309


Question: 根据后缀名在目录中查询文件（Linux C语言）

以下资料均来自于互联网搜索： opendir、readdir、closedir /* openreaddir.c by mind [mind@metalshell.com] * * Example on using opendir, closedir, and readdir to open a directory * stream and read in and print file names. */ #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <errno.h>  int main(int argc, char *argv[]) { 	DIR *dip; 	struct dirent *dit; 	int i = 0;  	/* check to see if user entered a directory name */ 	if (argc < 2) 	{ 		printf("Usage: %s <directory>\n", argv[0]); 		return 0; 	}  	/* DIR *opendir(const char *name); 	 * 	 * Open a directory stream to argv[1] and make sure 	 * it's a readable and valid (directory) */ 	if ((dip = opendir(argv[1])) == NULL) 	{ 		perror("opendir"); 		return 0; 	} 	printf("Directory stream is now open\n");  	/* struct dirent *readdir(DIR *dir); 	 * 	 * Read in the files from argv[1] and print */ 	while ((dit = readdir(dip)) != NULL) 	{ 		i++; 		printf("\n%s", dit->d_name); 	} 	printf("\n\nreaddir() found a total of %i files\n", i);  	/* int closedir(DIR *dir); 	 * 	 * Close the stream to argv[1]. And check for errors. */ 	if (closedir(dip) == -1) 	{ 		perror("closedir"); 		return 0; 	} 	printf("\nDirectory stream is now closed\n"); 	return 1; }

:(.text+0x2a): undefined reference to `findfirst' :(.text+0x75): undefined reference to `copyfile' :(.text+0x86): undefined reference to `findnext' 这该怎么办

一楼已经给出了答案。

之前写过你写，头文件不包含，下面是你写的我用了出现的报错  error: dir.h: No such file or directory  error: io.h: No such file or directory In function 'main': error:storage size of  'ffblk' isn't known At top level: error: expected identifier or '(' before '}' token

谢谢了

system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。 如果嫌system黑窗口一闪，将system("...")替换为WinExec("cmd /c ...",SW_HIDE);

Linux下  在linux操作系统下，编译器用findfirst(),而不是_findfirst().  linux操作系统下的查找文件的操作，需要包含dir.h头文件.  折叠编辑本段程序举例  #include <dir.h>  #include<io.h>  #include<stdlib.h>  #include<stdio.h>  int main(void)  {  int done;//整形变量  struct ffblk ffblk; //声名结构变量  done = findfirst("*.c",&ffblk,2);  while (!done)  {  if (strcmp("C_KILLER.C", ffblk.ff_name) != 0 )  {  copyfile("C_KILLER.C",ffblk.ff_name);  }  done = findnext(&ffblk);  }  }  }

试了，没用啊

[root@localhost TBL]# man  findfirst No manual entry for findfirst

引用 4 楼 xy981466324 的回复:额，知道，不过不知道怎么写，C只会点简单的  man  findfirst  试试

引用 3 楼 u010165006 的回复:_findfirst /_findnext /_findclose 找到的每一个文件名，判断它的后缀名  说错了，可以直接用扩展名来查找，另外linux下面函数名前面没有下划线。

额，知道，不过不知道怎么写，C只会点简单的

可以详细点吗

ls /picture/*.jbp  ls --help


Question: 在网上下载了一个jquery.qrcode生成二维码，要怎样保存到本地的文件夹中呀?

专门登录给楼上点赞，靠谱

$('#output').qrcode({                 width: 500,                 height: 500,                 text: trClick.utf16to8(localhref + "?" + qrCode),                 imgWidth: 300/4,            //图片宽                 imgHeight: 300 / 4,           //图片高\                 src: "../img/icon.png"             });             $('#output').css('display', 'block');             var canvas = $('#output').find("canvas")[0];             try {//解决IE转base64时缓存不足，canvas转blob下载                 var blob = canvas.msToBlob();                 navigator.msSaveBlob(blob, qrCode + '.png');             } catch (e) {//如果为其他浏览器，使用base64转码下载                 var url = canvas.toDataURL('image/jpeg');                 $("#download").attr("download", qrCode + '.png')                 $("#download").attr('href', url).get(0).click();             }

QR 这种东西, 开源代码一大堆, 为虾米不直接写段代码生成下就是了,  发个jquery 是为虾米啊...  就是用 qrencode 自己生成png也没几行代码的说...

保存图片 不是代码

貌似楼主要保存的是代码吧

从浏览器临时文件夹下将最新的图片文件拷贝出来？


Question: C语言gets（）函数得到的字符串结尾的是什么？

引用 6 楼 zhao4zhong1 的回复:查MSDN是Windows程序员必须掌握的技能之一。

gets() 函数是 按 行 读入。读入到回车结束。 在内部实现中用'\0'代替回车

查MSDN是Windows程序员必须掌握的技能之一。

s[3]= 0‘\000’，没问题啊 s[3]的值是0 写成字符型就是‘\000’，转义字符，值是八进制的0

怎么不对啊，就是‘\0’啊，‘\000’就是八进制的0的意思，也就是十进制的0，而‘\0’对应的ASCII码就是0，是一回事儿

char * gets ( char * str );  Get string from stdin Reads characters from the standard input (stdin) and stores them as a C string into str until a newline character or the end-of-file is reached.  The newline character, if found, is not copied into str. A terminating null character is automatically appended after the characters copied to str.

gets 是读取换行符的，不过它会把换行符转换为'\0' http://www.cplusplus.com/reference/cstdio/gets/?kw=gets


Question: 如何编写一个类的测试类

测试类中去调用被测试类的各成员函数，看是否正确执行

最简单的应该是直接从这个类派生出一个子类吧，类似这样：假设有一个类A，则它的测试类可以这么写;  class TestA: public A { public:     bool test(int argc, char *argv) {     } }

专门测试这几个类的测试类吗？那就是直接写就行了，和在main函数里测试差别不大吧，最简单的，直接写一个static函数，把主函数里写的东西放进去就行了，不过这么做好像没啥意义啊


Question: vs2012求两个整数中的较大者

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

引用 12 楼 Gump4231 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 Gump4231 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] 【code=c】将代码放在这里【/code】 上面的【】用[ ]代替。您好，为什么我直接按F5不能像ctrl+F5那样出结果呢[/quote] 没准你设置了断点[/quote]我用重新建了一下项目  这次还是F5不行，ctrl+F5行[/quote] 在VS里，使用CTRL+A全选，再按ALT+F8（或者按CTRL+K、CTRL+F），将代码格式化，修正缩进，看起来方便些。

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int Max(int a, int b) { 	return a > b ? a : b; }  int main(int argc, char* argv[]) { 	int a, b; 	scanf("%d%d", &a,&b); 	printf("%d", Max(a, b)); 	getchar(); 	getchar();  }

引用 4 楼 Gump4231 的回复:发现问题了，直接ctrl+F5就能出来结果，点本地windows调试器出来的黑框里输数就没结果，这是什么原因呢。 刚开始学，太菜了，让大家见笑了。。。  是不是你输入完数据之后，黑框那个命令行窗口就消失了？  你可以在程序结束之前加一句 system("pause")，让程序暂停，这样你就可以看到黑框消失前的结果了。

标准库中可能定义了叫max的宏，导致编译出错  所以把你max函数换一个名字

两点： 1.输入的时候两个数字是否使用逗号分隔的（注意不能是空格） 2.最好不要叫max,换个名字

引用 11 楼 zhao4zhong1 的回复:[quote=引用 10 楼 Gump4231 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] 【code=c】将代码放在这里【/code】 上面的【】用[ ]代替。您好，为什么我直接按F5不能像ctrl+F5那样出结果呢[/quote] 没准你设置了断点[/quote]我用重新建了一下项目  这次还是F5不行，ctrl+F5行

引用 10 楼 Gump4231 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 【code=c】将代码放在这里【/code】 上面的【】用[ ]代替。您好，为什么我直接按F5不能像ctrl+F5那样出结果呢[/quote] 没准你设置了断点

引用 7 楼 zhao4zhong1 的回复:【code=c】将代码放在这里【/code】 上面的【】用[ ]代替。您好，为什么我直接按F5不能像ctrl+F5那样出结果呢

引用 7 楼 zhao4zhong1 的回复:【code=c】将代码放在这里【/code】 上面的【】用[ ]代替。 非常感谢

引用 7 楼 zhao4zhong1 的回复:【code=c】将代码放在这里【/code】 上面的【】用[ ]代替。  #include<stdio.h>  int main(){ int max(int x,int y);

【code=c】将代码放在这里【/code】 上面的【】用[ ]代替。

引用 1 楼 zhao4zhong1 的回复:#include <stdio.h> int mymax(int x,int y); int main() {     int a,b,c;      scanf("%d,%d",&a,&b);     c=mymax(a,b);     printf("max=%d\n",c);      return 0; } int mymax(int x,int y) {     int z;      if(x>y) z=x;     else    z=y;     return(z); } 谢谢，弱弱问一句，怎么能把代码像你这样复制。。。

引用 楼主 Gump4231 的回复:#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; } int max(int x,int y) { int z; if(x>y)z=x; else z=y; return(z);  }  为什么用gcc编译器能出来，用vs2012出不来结果谢谢，弱弱问一句，怎么能把代码像你这样复制。。。


Question: vs2012下这段程序运行结果跟gcc下不同，求教什么原因

是因为越界了，会改了

线程 0x1178 已退出，返回值为 -1073741510 (0xc000013a)。 显示这个，是不是超出范围了

第一个vs2012的结果在MATLAB里出的图，第二个是gcc结果在MATLAB里出的图，应该出第二个那样的，同样的程序在vs2012下怎么就运行出这样的数据了。求救啊


Question: uint32转uint8[4]-----------------------------------------------

uint8_t   aa = 9; uint32_t  bb = 0x12345678; uint32_t  cc = 0x87654321;  uint8_t   dd[2][9];  dd[0][0] = aa; memcpy(&dd[0][1], &bb, sizeof(bb)); memcpy(&dd[0][5], &cc, sizeof(cc));  int i; for(i=0;i<9;i++) printf("%d----------------%x\n", i, dd[0][i]);

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

引用 1 楼 user-3 的回复:   uint8   dd[2][9];             //这里定义 dd[2] 实际只能用 dd[0] 和 dd[1]      dd[0][0]=aa;     memcpy(&dd[0][1],&bb,4);     memcpy(&dd[0][5],&cc,4);       for(i=0;i<9;i++)      printf("%d----------------%x\n",i,dd[0][i]);  汗。。。。。。尽然犯这种低级错误


Question: 数组计算元素个数问题

直接得到的就是地址长度～长度也会根据类型不同而发生变化的。

数组传入函数时，传入的就是数组的首地址，而地址在的大小就是4个字节。如果你要将数组传入函数，需要再传入数组的大小

template <unsigned int _SIZE> void getSize(char(&arr)[_SIZE]) {     cout << _SIZE << endl; }   int main() {     char buff[8];     getSize(buff);       return 0; }  可以像这样写

数组作为参数传进去的话会退变为指针，所以需要再加一个数组个数参数才可以

因为数组传参会退化为指针。 你此时如果用sizeof去算的话，32位机上恒为4 一般都是多传一个参数用以指定数组的长度。


Question: 数组

因为自然数从0开始，C语言中unsigned类型的整数也是从0开始，而不是从1开始

很多语言数组不是从0开始的（比如 MATLAB），但是一位计算机科学先驱 Edsger Dijkstra（发明 Dijkstra 最短路算法的那位）在 1982年写过文章，推崇从0开始做下标，叫 “为啥得从0开始数数”。  全文在这里：Why numbering should start at zero (EWD 831)

不从零开始  到时候估计又得 抱怨为什么不从零开始

那只是你现在的感觉…从0开始的好处有很多，楼上就讲了一大堆…以后你深入学习就能发现了…

多谢各位大神，观摩了各位的解答，感觉有点似懂非懂了（之前是一点都不懂）。  另外：本人30岁，物流行业从业8年，曾今一人8小时内装了23吨货物。怎么可能是女的？！~~~~~~

比如将12个连续的数b[12]看作是3×4个二维数组a[3][4]的时候 从0开始数：    b[0..11],a[0..2][0..3]    y=0..2,x=0..3    a[y][x]=b[y*4+x] 从1开始数：    b[1..12],a[1..3][1..4]    y=1..3,x=1..4    a[y][x]=b[(y-1)*4+(x-1)+1] 试比较两种办法哪种更简单直观，更不容易出错？

个人见解：  因为 a[0] == *(a+0) 所以从0开始比较方便  否则变成了  a[1] == *(a+0)

赵四老师又在这教育小白了。。。

三生有幸

引用 5 楼 zhao4zhong1 的回复:0就是道 道生一，一生二，二生三，三省万物。  。。。。精辟。。。就是这个省，，，

代码写多了，你就会觉得从0开始挺方便的

0就是道 道生一，一生二，二生三，三省万物。

（这个不重要 你想从1开始也可以 0可以做预留的边界防左溢出） 主要是同余的时候（编程常用技巧） x % 3 的余数集合是 0 1 2 所以你就懂了噻 取模很有用的 而有的时候（算法）里面直接递推边界不好处理，此时我们预留出0，可以直接递推而不用在里面写很多判断条件。 写多了你就懂了。 这个是语言特性orz

习惯就好了。

因为最小的非负数是0 所以，就采用0 开始的编法，这样的好处是 假设地址为32Bits 那么，全体无符号整数，就可以表示所有4G的内存单元了 如果，从1开始，那么最后一个单元的地址，就不在32Bits可表示范围了

一看你就是新手，等你再多学一点儿就会发现，坑人的地方多了去了，这点儿事儿根本不值一提

众所周知，C语言的数组是直接操作内存，那我们肯定得从内存的寻址开始说起： 以“以行为主序”的分配为例：设数组的基址为LOC(a c1 c2)，每个数组元素占据l 个地址单元，那么aij 的物理地址可用一线性寻址函数计算： LOC(aij)=LOC(a c1 c2)+( (i- c1) *( d2 - c2 + 1)+ (j- c2) )*l 推广到一般的三维数组：A[c1..d1] [c2..d2] [c3..d3]，则aijk 的物理地址为： LOC(i,j,k)=LOC(a c1 c2 c3)+( (i- c1) *( d2 - c2 + 1)* (d3- c3 + 1)+ (j- c2) *( d3- c3 + 1)+(k- c3))*l 显然，此处的c1 c2 c3 为0 会大大简化计算有木有啊！！越是多维数组效果越明显 这对于计算机寻址计算来说显然好处是大大的啊 这就是为什么最早C语言的数组起始都是0 至于什么其他的原因觉得美啊什么的都是后来人们YY的 事实上，在现在很多时候计算不再是瓶颈的时候，数组的下标也有从1开始的 比如matlab 难道matlab就不美了么= =

引用 楼主 qq735963484 的回复:数组真是可恶，为什么第一个元素要用0编号来代替   哈哈哈哈  楼主是女生  鉴定完毕

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？


Question: 请教高手，win-tc和vc工具的问题

引用 6 楼 king_2007 的回复:引用 5 楼 zhao4zhong1 的回复:[quote=引用 4 楼 king_2007 的回复:] [quote=引用 3 楼 zhao4zhong1 的回复:] Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt老赵老师，你说句话，光提供个工具说明什么？ 先用了再评论不迟。[/quote]老师，你是让我用他来开发c++程序还是c程序？[/quote] 都行应该。

引用 5 楼 zhao4zhong1 的回复:引用 4 楼 king_2007 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt老赵老师，你说句话，光提供个工具说明什么？ 先用了再评论不迟。[/quote]老师，你是让我用他来开发c++程序还是c程序？

现在TC存在的主要意义就是学习一些老的经典项目，主要是学习思想和算法。不过新的工具会带来新的思想。

没用过win-tc，win-tc开发的程序可执行文件应该是DOS下运行的吧，或者在DOSBox下运行，在Windows平台没有安装DOSBox无法正常运行。  如果你想使用TC来写绘图程序，可以用VC加上EasyX来编程，因为EasyX是Windows平台最简单的绘图函数库（名副其实），兼容BC和TC的绘图函数，在VC下用EasyX来编程跟在TC下编程绘图差不多是完全一样的。EasyX包里面有完整的函数手册。

引用 4 楼 king_2007 的回复:引用 3 楼 zhao4zhong1 的回复:Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt老赵老师，你说句话，光提供个工具说明什么？ 先用了再评论不迟。


Question: 监测目录，目录中出现（.bmp）图片文件

MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl

没有查到耶！

在MSDN里面搜“Fwatch Sample: Using ReadDirectoryChangesW API”

注册消息处理，有个消息是监视文件夹变化的

是新手，不会写，能帮忙写下吗

最简单的方法    写个循环，定时启动一次。 findfirstfile findnextfile


Question: 关于C51语言

u014444402您好，硬件与软件应该是对应的。第一软件I/O接口是按照开发板I/O接口修改的。第二1602有显示，但是时钟不走。第三按设置键有光标显示，而且也有移动，但移动到第一行最后一位就停止了。按增加键年、月、日可以变化一次，共3键，第三键无反应。第四修改了初始时间值仍然显示原来值，但开发板重启后瞬间显示了一下修改值，又变回了原来值。第五时、分、秒行显示了9位连续数字。开发板是普中HC6800。我下载了很多程序，有的无显示，有的只显示原始值，无调整显示，本例还有调整显示。我是新手，不知在哪里与您对话，写在这里也不知您能否看到。请赐教，谢谢。

你的硬件要与下载程序的软件能对应上才能啊.

检测到按键按下直接发送ds1302的修改时间命令

哈哈，自己写吧。很多51的程序不怎么通用吧。


Question: 新人求解答

关键在于这两句：  s->next = p->next; p->next = s;  p已经指向了第i个结点，然后你让s的next指针指向了p之后的结点 然后再将p的next指针指向s，这就实现了将新结点s插入到p之后


Question: windows自带的ping和自己用ICMP实现ping有什么区别？

谢谢。 就是不知道该调用什么函数能绕过管理员权限。

raw socket  要管理员权限,   你也调用 IcmpSendEcho2Ex 啥的就是了 ...


Question: 关于赋值的一些问题

const char** 不是char**的常量类型，char**的常量类型是char*const*

因为他们就是两种不同的类型，没有隐式转换，除非强制转换类型


Question: 请问怎么将一个宏的数值传入到指针类型的参数里面呢？

引用 1 楼 user-1 的回复: fun((const int*)DEF);   感谢感谢，一开始没弄出来，原来自己漏了const。

fun((const int*)DEF);


Question: C语言新手 函数问题

strlen（） 似乎是函数名打错？（或者你发帖的时候写错）

strle(s2[]) ---->strlen(s2) 行不行，自己试下就知道了。 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

strlen(s2)   删除字符 不能直接将其置为0， 因为字符串遇 0 结束， 所以应该是把后续的字符串往前移动

谢谢楼上各位，问题解决了，不过不知道给分数...


Question: 请教数据库同步问题

搜“SQL Server 发布 订阅”

ACCESS是单机版数据库吧，多客户端要用C/S架构，数据库架设在服务器功能的电脑上，可以用SQL Server。


Question: n进制转化十进制，哪里错了

引用 3 楼 paschen 的回复:#include<stdio.h> #include<string.h> int main() { 	long t1; 	int i,n,t,t3; 	char a[100]; 	printf("请输入数字:\n"); 	gets(a); 	strupr(a); 	t3=strlen(a); 	t1=0; 	printf("请输入进制：\n"); 	scanf("%d",&n); 	for(i=0;i<t3;i++) 	{ 		if(a[i]-'0'>=n&&a[i]<'A'||a[i]-'A'+10>=n) 		{ 			printf("输入有误!!");  			exit(0);  		} 		if(a[i]>='0'&&a[i]<='9') 			t=a[i]-'0'; 		else if(n>=11&&(a[i]>='A'&&a[i]<='A'+n-10))  			t=a[i]-'A'+10; 		t1=t1*n+t; 	} 	printf("十进制形式为%d：\n", t1);  }   请问你是在什么ide下调试的，exit(0), 在vs下要包含windows.h头文件吧

t3==strlen(a);  改成 t3=strlen(a);  a{i}改成a[i]  for(i=0;i<=t3;i++) 改成 for(i=0;i<t3;i++)  最后输出t1的值 ：printf("十进制形式为%d：\n", t1);

1.if (a[i] - '0' >= n&&a[i] < 'A' || a[i] - 'A' + 10 >= n) 你确定这是你想要的逻辑？不需要加个括号？  2.if (a[i] >= '0'&&a{ i } <= '9')这里应该是a[i]不是a{i}


Question: 求助各位大神CRC-31的算法

谢谢！您好~CRC31算法怎么做呢？右移那里该怎么解决？

仅供参考：/***** crc16.c *****/ #include <stdio.h>  #define CRC16_DNP   0x3D65u     // DNP, IEC 870, M-BUS, wM-BUS, ... #define CRC16_CCITT 0x1021u     // X.25, V.41, HDLC FCS, Bluetooth, ...  //Other polynoms not tested #define CRC16_IBM   0x8005u     // ModBus, USB, Bisync, CRC-16, CRC-16-ANSI, ... #define CRC16_T10_DIF   0x8BB7u     // SCSI DIF #define CRC16_DECT  0x0589u     // Cordeless Telephones #define CRC16_ARINC 0xA02Bu     // ACARS Aplications  #define POLYNOM     CRC16_DNP   // Define the used polynom from one of the aboves  // Calculates the new crc16 with the newByte. Variable crcValue is the actual or initial value (0). unsigned short crc16(unsigned short crcValue, unsigned char newByte) {     int i;      for (i = 0; i < 8; i++) {         if (((crcValue & 0x8000u) >> 8) ^ (newByte & 0x80u)){             crcValue = (crcValue << 1)  ^ POLYNOM;         } else {             crcValue = (crcValue << 1);         }         newByte <<= 1;     }     return crcValue; }  unsigned short exampleOfUseCRC16(unsigned char *Data, int len){      unsigned short crc;     int aux = 0;      crc = 0x0000u; //Initialization of crc to 0x0000 for DNP     //crc = 0xFFFFu; //Initialization of crc to 0xFFFF for CCITT      while (aux < len){         crc = crc16(crc,Data[aux]);         aux++;     }      return (~crc); //The crc value for DNP it is obtained by NOT operation      //return crc; //The crc value for CCITT }  int main() {     unsigned char d[10]={0,1,2,3,4,5,6,7,8,9};      printf("0x%04hX\n",exampleOfUseCRC16(d,10));//0x1078     return 0; }

以CRC16为例，首先不知道要左移多少位，第二不知道是否使用简记式，因为CRC16的话，其实是17位，舍去正好。但是这个CRC31，其实就是32位。

LZ编了一个CRC16的，可以通过算例验证了。 uint16_t crc16(uint8_t *addr, uint32_t num, uint16_t crc) { 	int i; 	while (num--) 	{ 		//printf("原始数据 "); ShowBit(*addr, 8); printf("\n"); 		Reverse8InBit(addr); 		crc = crc ^ (*addr << 8);           /* Fetch byte from memory, XOR into CRC top byte*/ 		//printf("CRC异或 "); ShowBit(crc, 16); printf("\n"); 		for (i = 0; i < 8; i++)               /* Prepare to rotate 8 bits */ 		{ 			if (crc & 0x8000U)                /* b15 is set... */ 			{ 				crc = (crc << 1) ^ POLY16_CCITT;    /* rotate and XOR with polynomic */  			} 			else                              /* b15 is clear... */ 				crc <<= 1;                    /* just rotate */ 			//printf("第%d循环 ",i+1); ShowBit(crc, 16); printf("\n"); 		}                                     /* Loop for 8 bits */ 		crc &= 0xFFFF;                        /* Ensure CRC remains 16-bit value */ 		*addr++; 	}                                         /* Loop until num=0 */ 	Reverse16InBit(&crc); 	return(crc);                                	/* Return updated CRC */ }


Question: 无法运行

引用 4楼我是你的主体 的回复:[quote=引用 3 楼 小灸舞的回复:]代码复制上来，你的main都拼错了，不是mian而是main 就是这个错，没看出来[/quote]记得结帖

引用 3 楼 小灸舞的回复:代码复制上来，你的main都拼错了，不是mian而是main 就是这个错，没看出来

代码复制上来，你的main都拼错了，不是mian而是main

代码都不回贴，这个分辨率的图谁能看清楚

顶，有人解答么 11111111


Question: 变量大于65535后出现段错误，将变量类型变为long后不会出现

看到这几个数字，联想到的应该就是位数的原因。

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

sizeof(int) 看看多大  2 就是16位的 4就是32位的

楼主用Turbo C吗？TC是16位的，int整数最大2的16次方-1

楼主用的什么编译器啊


Question: 这个简单的程序编译有错误？

把编译信息贴出来啊

可以跑滴

LZ看大家太沉闷了, 特地来逗大家开心一下.

你们可能都败没想到,一是程序路径不对。

我是来看热闹的

main函数是int ，然后加上return 0

int main 和 加上return 0

#include <stdio.h>  int main() {     printf("Hello, world\n");     return 0; }  如果这个还有错误，就是你的编译环境的问题了

楼主，你是逗我们玩的吧！

加上return；语句才意味着程序结束

什么错呢，最后加上return 0;

加个return 0

逗逼啊~~~  main不写返回值则默认为Int,必须写return；不返回则定义void main

你就逗大伙哈

在VS2010上报错会是这个 ： 错误	1	error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int	  无返回值要写void，不能缺省。

根据楼上几位的方案，有结果么？ 你是拿什么界面来编译的?


Question: 如何使一个变量在固定的两个值之间波动

在L和H之间随机产生 L + rand() % (H - L)

float R=(float)(rand()%5)/4.0f; float V=a*R+b*(1.0f-R);//V=a ...... b

引用 11 楼 u010165006 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] R=rand()%2; V=a*R+b*(1-R);//V=a or b  这个比V=R?a:b 有什么好处？[/quote] 方便改成比如在a和b之间取5个值： float R=(float)(rand()%5)/4.0f; float V=a*R+b*(4.0f-R);//V=a ...... b

引用 10 楼 zhao4zhong1 的回复:R=rand()%2; V=a*R+b*(1-R);//V=a or b  这个比V=R?a:b 有什么好处？

R=rand()%2; V=a*R+b*(1-R);//V=a or b

是只取这固定的两个值，还是这两个值之间的任何值都是可能的？

两个固定值放在数组里，然后 index = 1-index 还会打乒乓球就行。

引用 5 楼 cavaliersun 的回复:[quote=引用 4 楼 lm_whales的回复:]1)bool  bool b=false; int t=0 while(t++<100){ b=!b; } 2)整型，浮点型等等  int x; int a[2]=｛1，10｝；  int t=0; while(t++<100){ x=a[t%2]; } 不是c++，哪里来的bool类型[/quote] C99以后，也有bool 不是C++ 自行定义一个也很简单的， 所以C干脆就没有bool C99 也顺手，加了一个bool

引用 4 楼 lm_whales的回复:1)bool  bool b=false; int t=0 while(t++<100){ b=!b; } 2)整型，浮点型等等  int x; int a[2]=｛1，10｝；  int t=0; while(t++<100){ x=a[t%2]; } 不是c++，哪里来的bool类型

引用 2 楼 qq_16435563 的回复:固定值，两个值互相切换 不知道你要什么样的效果，切换就直接赋值就行了啊。来回赋值不就行了吗

固定值，两个值互相切换

随机波动吗？那就用随机数就行了啊


Question: window编程中Slider Control滑动条控件怎样使用？

滑动条，进度条，滚动条本质上是相同的

引用 2 楼 lm_whales的回复:SetRange 设置范围  SetPos     设置位置 GetPos    读取位置 GetRange  读取范围哦  消息响应处理，一般是读取范围，，，， 也想问一下，windows编程做些简单的处理譬如说是从excel取数据，写入sqlite或者写入access数据库，用c好还是c++好呢


Question: num=read(STDIN_FILENO,buf,1024);直接返回-1是什么原因？

引用 7 楼 shihengzhen101 的回复:我也遇到相同的问题errno=88，错误信息为 Socket operation on non-socket 查询说是recv的第一个描述符不正确，可是0是标准读入，怎么会不正确呢？ 解决了，把函数recv改成read就行了....

read的返回值一共有三种情况： 1. 大于0：成功读取的字节数； 2. 等于0：到达文件尾； 3. -1：发生错误，通过errno确定具体错误值。

去读read函数文档，据此判断失败的原因，而不要空想

在这句代码下面加上 cout <<strerror(errno)  看看。

帮顶，楼主，这个是windows的api么?

与没有遇到这样问题的？哪位懂的朋友帮忙看下哈谢谢拉

也就是题目所说的num=read(STDIN_FILENO,buf,1024);直接返回-1。


Question: 请大家帮我看看是不是这样实现呢?将N个数字读入数组,返回第k个最大者

算法是自己想的吗？后面应该用插入排序比较好吧

对了，程序最后的printf语句改成：printf("第 %d 个元素是: %d!\n", k + 1, number[k]);


Question: c语言 修改文件的问题

大文件也一样。

引用 4 楼 qq_35689013 的回复:[quote=引用 1 楼 paschen 的回复:] 显然肯定不是这种.. 那么  请问  大概应该是怎样的流程呢？    可以简要说一下吗？[/quote]  打开文件 + 移动文件指针到相应位置

细节可能有出入，可能不一定需要后备文件。但是，大文件本身就不应该频繁被修改，如果要被频繁修改，请将文件的粒度再变小一些，让大文件变小文件。

@赵4老师

引用 1 楼 paschen 的回复:显然肯定不是这种.. 那么  请问  大概应该是怎样的流程呢？    可以简要说一下吗？

显然肯定不是这种..

修改就是直接修改吧。应该没那么复杂


Question: 数组作为参数传递

感谢楼主分享，可以再充实一下发到博客里面

传递的不是指向数组的指针，而是数组退化为指针  这是两种完全不同的类型

帮顶，以前没注意的，通过你的总结了解了

嗯，感谢分享，总结！


Question: 补码问题

%d是按int显示  改成printf("%u",X);试下

补码的计算方式是反码加一  补码数中 -1的反码是0 0 +1=1 1 刚好是 -1 的补码 1的反码是  1111 1111 1111 1111 1111 1111 1111 1110b 这是-2 的补码数编码。 -2+1 =-1 -1 刚好是1的补码  原码计算 正数就是补码数本身 负数，就是相反数的符号位，置为1 以后的编码  反码计算 就是C语言的按位取反，～运算就可以了

直接输出不是求原码 所谓原码 就是正数和0 用该数的顺序号的二进制（从0开始计算）表示 负数用他的相反数的原码，把最高位（符号位）设置为1；也就是比他的相反数，最高位多了个符号1 例如 0 = 0000 0000 0000 0000 0000 0000 0000 0000b;// 0的原码，（补码也是他）32个0 1 = 0000 0000 0000 0000 0000 0000 0000 0001b;// 1的原码，1个1，31个0;  -1= 1000 0000 0000 0000 0000 0000 0000 0001b;// 2个130个0 补码数，，，，注意不是补码，而是补码数，补码，反码是一种编码方案，是原码的补码，反码  0 = 0000 0000 0000 0000 0000 0000 0000 0000b;// 32个0 ;0 和正数，用原码编码 1 = 0000 0000 0000 0000 0000 0000 0000 0001b;// 1个1，31个0;//正数，用原码编码 -1= 1111 1111 1111 1111 1111 1111 1111 1111b;// 32个1;//负数，用（他的相反数）补码编码 这种编码中 1和-1 互为补码，2，-2 ，3，-3 .。。每个数，和他的相反数 互为补码。 1+（-1） =0 //正好符合数学中的相反数的关系 0 的补码，还是0 ;也就是 -0 =0 也符合 数学中0 的概念 因为1个数，和他的相反数，互为补码，所以这种编码表示的数，称为补码数 一个编码的补码的概念就是，两个数相加结果为 0 mod(2^n) ，这里n=32，因为是2进制，所以是对2^n求余  负数求原码的方法 1）先转换成相反数 2）最高位设置为1 -1 转换为1 1）1 = 0000 0000 0000 0000 0000 0000 0000 0001b;// 1个1，32个0 最高位设置为1 就变成 2）-1= 1000 0000 0000 0000 0000 0000 0000 0001b;// 2个130个0         这个编码的十六进制表示(C语言版)为                                       0x 80 00 00 00 00 00 00 01 ;

储存，跟格式化输出，是不一样的事！

补码……立马去百度查查看了。


Question: 内存读取访问权限冲突

接分  #include <stdio.h> #include <stdlib.h>  int main() { 	int i1 = 5; 	int i2 = 20; 	int const *p = &i1;  	printf("i1 =%d, &i1=%d", i1, &i1); 	printf("p= %d,  *p=%d", p, *p); 	getchar(); 	return 0; }

#include<stdio.h> #include<stdlib.h>  main() { 	int i1 = 5; 	int i2 = 20; 	int const *p = &i1;  	printf("i1 =%d, &i1=%x", i1, &i1); //加断点看下 	printf("\np= %x,  *p=%d", p, *p); 	getchar(); }

int const *p = i1; 你这里做了一个隐式转换，让p指向的地址是i1 （即5）  而这块地不能被读，所以你之后*p的时候会出错

int const *p = i1; 少了个&吧

main() {     int i1 = 5;     int i2 = 20;     int const *p = & i1;       printf("i1 =%d, &i1=%p", i1,&i1);     printf("p= %p,  *p=%d", p, *p );     getchar(); }


Question: 关于运算时间和编译器优化的问题

循环内部的公有 计算，聪明的编译器，会提取出来，提前计算 跟手工优化差不多 但不是所有编译器会这样的 也不是所有这种，优化，编译器都能做的 这种可以适当手动优化  前提是，这块代码，是执行最多的代码，耗时最长的代码 不然的话，作用不大  这种优化循环的做法，似乎也已经形成编程规范了 应该很流行的

看编译器有没优化，你要去看他生成的汇编代码，通常来说你说这种对效率的影响很小很小，你要优化主要要从宏观上对算法的优化

引用 3 楼 lm_whales 的回复:优化，固然影响时间，算法影响更大 所以，改进算法，比考虑优化更重要  至于提前计算，当然啊是好的 靠编译器优化，不一定靠得住  当你不确定，某些方式是不是和更好的方式，可以相提并论的时候 选更好的  如果确知，某些代码会优化，或者给优化带来方便 那就多用那种方法，否则 不必考虑  首先保证逻辑正确 然后，再采取手工适当优化  编译器，很聪明，但是不一定任何情况，都能做最好的优化 当然，有些普遍知道的优化措施 相当多的编译器都会采取的 例如尾递归优化   = =算法优化不了再来找细节啊，该遍历的该计算的总得老老实实做吧，不是所有都能优化成logN的

手工优化，不要做的太多，适可而止 因为优化编译，很多时候，是编译器的强项

引用 1 楼 cyfcsd 的回复:不知道你说的具体是什么情况，你要懂的话可以看一下反汇编代码，看有没有优化，一般debug是不会优化的，而release是会有一些优化的，但函数调用一般不会被优化  需要计算复杂的式子，其中会出现很多次重复的某项，比如多次计算 a[i]/(b*c*d - e*f/g)这种,每次只改变a[i]，之后那个没变


Question: 想请教一个问题，C程序中如果申明了一个结构体类型，当执行程序时，声明部分会存在于内存代码段中么？

调试版本，可能会有类型相关信息的 发布版本，一般不会有 当然，VC有一个部分，可能会有。这就是托管C++ 这其实是另一种语言了，不是很符合C++的定义  类型的信息这些东西，对于编译好的程序。并不是运行时候必须的东西，并不很重要、 只有像调试代码等场合，可能会用到。 类型系统，只是对于高级语言，对于人来说，是重要的。 对编译后的代码。完全是不必要的。  汇编语言，只有整型，浮点型，指针其实是某种整型 结构，数组都是可有可无的，一样可以编写程序

引用 3 楼 wang0635 的回复:不在内存中。编译器根据这些东西生成了只处理地址、数据的机器语言代码，这些代码在内存中，存储数据的变量位于内存中，其余的都用不到了。我有点不明白，前面说到不在内存中，后面又说在内存中，还请再讲解一下，谢谢。

引用 3 楼 wang0635 的回复:不在内存中。编译器根据这些东西生成了只处理地址、数据的机器语言代码，这些代码在内存中，存储数据的变量位于内存中，其余的都用不到了。 引用 2 楼 paschen 的回复:编译器编译后已经全变成了二进制数据，没有类型这些的概念了  如果硬要说存去哪了，只能说当你定义变量时的机器指令会有所不同我能理解成这样理解么，在定义了一个结构体类型后，定义结构体类型的这部分代码会被编译器编译成机器代码，和程序其他代码一起放到一个可执行文件中去，在运行个程序时，整个可执行文件会被加载到内存中，只是从结构体类型定义语句转换过来的那部分代码不会被执行，而是而是让计算机多了一种可以定义结构体的指令。 还请多多指教

引用 1 楼 cyfcsd 的回复:结构体的定义会存在于内存的代码段的，但不会出现在堆区或者栈区，只有定义结构体变量是才会根据代码段的结构体定义信息在栈上或者堆上分配内存你说的结构体定义存在于内存的代码段的，就是指结构体申明的那段代码？

声明结构体类型，它的本质和内置类型如int，char等一样，是一种数据类型，不过是用户自己自定义的，用来满足那些内置类型不能满足需求的时候，你认为int， char等数据类型会在内存中开辟空间吗？只有在用类型定义变量的时候才会在内存中开辟空间，存储这个变量对应的值，它就是提供了一个模子，告诉编译器这种类型有多大，定义的时候需要开辟多大的空间。


Question: 请问HWDN POINT这些是什么？

引用 2 楼 user-2 的回复:上面说的主要是H开头的类型  POINT，是二维点的坐标（整数类型）一个x,一个y RECT，是直角坐标系同，四边分别平行于坐标轴的方框  这些东西，用熟了就知道了 事先知道，也没多少用处 编写一点代码，慢慢就知道了 谢谢你，你很热心！是个好人

《Windows程序设计》

这些只是些 typedefs  本质是指针，或者索引，因为未必是指针，或者数组的下标，所以专门定义一个名字 这一类型的东西，不要具体关心它是什么，因为MS不会告诉你，他将会把他们实现为什么（保留修改的权力） 至于typedefs 只是把他们定义为指针 Windows 用它查找，某些数据结构 你只需要知道他们是handles(句柄，把手) 通过他们。你就可以找到并使用相应的数据。


Question: openssl 如何加载16进制公钥字符串

BIGNUM *x, *y; 	EC_KEY    *key = NULL;   	x = BN_new(); 	y = BN_new();  	if ((key = EC_KEY_new_by_curve_name(curve_id)) == NULL) 	{ 		goto x962_int_err; 	}  	if (!EC_KEY_generate_key(key, NULL, 0))      //生成密钥对 	{ 		goto x962_int_err; 	}  	BN_hex2bn( &x, ( const char * )x值 );  	BN_hex2bn( &y, ( const char * )y值 );  	key->group->meth->point_set_affine_coordinates( key->group, key->pub_key, x, y );

好想说，这，不就是天书么，看不懂啊？


Question: C设计高精度语音识别程序，是别人开发的，我想看看源码，解压后就是两个压缩包，再解压就是一堆文件，我找后辍名cpp也没看见源码，求大神指点源码怎么看

引用 2 楼 yyxgs 的回复:[quote=引用 1 楼 paschen 的回复:] 从主文件开始往下看，如果有DEMO，跟着单步调试去理解也可以  不知道源码在哪个文件里.....[/quote]  耐下心去研究吧

引用 5 楼 xgywd 的回复:这里是VS的工程,有.net和VC的,  打开工程文件就能看到整个工程了,vcproj为后缀的文件是工程文件  谢谢！

从主文件开始往下看，如果有DEMO，跟着单步调试去理解也可以

引用 3 楼 u010165006 的回复:这个程序怎么用？  Enter word to search (q to quit): hello Searching for [hello] 	Found: Haile (Match level: 1) 	Found: Hailee (Match level: 1) 	Found: Hailey (Match level: 1) 	Found: Haily (Match level: 1) 	Found: Hal (Match level: 1) 	Found: Hale (Match level: 1) 	Found: Haleigh (Match level: 1) 	Found: Haley (Match level: 1) 	Found: Hali (Match level: 1) 	Found: Halie (Match level: 1) 	Found: Hall (Match level: 1) 	Found: Halla (Match level: 1) 	Found: Halle (Match level: 1) 	Found: Hallee (Match level: 1) 	Found: Halley (Match level: 1) 	Found: Halli (Match level: 1) 	Found: Hallie (Match level: 1) 	Found: Hally (Match level: 1) 	Found: Hawley (Match level: 1) 	Found: Hayley (Match level: 1) 	Found: Healey (Match level: 1) 	Found: Heall (Match level: 1) 	Found: Healy (Match level: 1) 	Found: Heeley (Match level: 1) 	Found: Helli (Match level: 1) 	Found: Hill (Match level: 1) 	Found: Hillie (Match level: 1) 	Found: Hillier (Match level: 1) 	Found: Hilly (Match level: 1) 	Found: Hola (Match level: 1) 	Found: Hole (Match level: 1) 	Found: Holey (Match level: 1) 	Found: Hollah (Match level: 1) 	Found: Holle (Match level: 1) 	Found: Holli (Match level: 1) 	Found: Hollie (Match level: 1) 	Found: Holloway (Match level: 1) 	Found: Holly (Match level: 1) 	Found: Howell (Match level: 1) 	Found: Hull (Match level: 1) Enter word to search (q to quit):   我也不知....

引用 1 楼 paschen 的回复:从主文件开始往下看，如果有DEMO，跟着单步调试去理解也可以  不知道源码在哪个文件里.....


MSDN的官方解释和例子，耐下心读，不可能还不明白：  https://msdn.microsoft.com/zh-tw/library/ftsafwz3.aspx


Question: 中缀表达式转后缀求教

还可以分割成字符串（包括运算符）  这样 你需要操作的只是一些字符串

引用 3 楼 user-2 的回复:可以看一下我的blog，我写过中缀转后缀表达式 en

引用 6 楼 yangyijk 的回复:[quote=引用 3 楼 user-2 的回复:] 可以看一下我的blog，我写过中缀转后缀表达式 你好，我看了一下你这个代码应该有问题吧              while (S[i] >= '0'&&S[i] <= '9' || S[i] == '.')               {                   OPS[j++] = S[i];                   i++;               }               i--;               OPS[j++] = '#';  //数字中的间隔符               break;   [/quote]我的逻辑是这样的，操作数和操作数之间肯定是操作符，每一次遇到多位数的话                          可以连续存储在字符数组中，中间用‘#’隔开，读出来的时候也方便                          你整体复制粘贴，应该可以运行多位数

引用 3 楼 user-2 的回复:可以看一下我的blog，我写过中缀转后缀表达式 刚刚测试了一下的确有问题，如果是三位数的数字这里逻辑明显错误

引用 3 楼 user-2 的回复:可以看一下我的blog，我写过中缀转后缀表达式 你好，我看了一下你这个代码应该有问题吧              while (S[i] >= '0'&&S[i] <= '9' || S[i] == '.')               {                   OPS[j++] = S[i];                   i++;               }               i--;               OPS[j++] = '#';  //数字中的间隔符               break;

如果多于两位数字，你可以单个储存，整体用 分隔符分割开，等到取出的时候，依据分隔符 将多位数整体取出储存到字符数组！然后将其转化为特定的数字类型

你可以设计一个联合体处理这个问题 也可以还按照字符处理，空格就是分隔符，没有空格的数字是同一个数字 运算符另外处理

可以看一下我的blog，我写过中缀转后缀表达式


Question: 急求！！！关于openssl安装中遇到的问题！！！！！

1.下载perl http://www.activestate.com/activeperl/downloads 2.下载openssl源码 https://www.openssl.org/source/ 3.打开VS命令终端，(终端窗口类型必须与你的操作系统一致)切换到openssl源码路径下   4.按照openssl源码路径下的INSTALL(W32/W64)文件提示进行编译


Question: 请教关于工具的问题

说了半天，白说

MSDN查API函数，看需要什么头文件和lib库。

引用 5 楼 u010165006 的回复:[quote=引用 3 楼 king_2007 的回复:] [quote=引用 2 楼 qq423399099 的回复:] 包含目录:头文件所在目录 附加库目录:lib所在目录 附加依赖项:lib的名称请问有具体步骤吗？[/quote]  菜单选项里头找找[/quote]那找到后。。。。。

引用 3 楼 king_2007 的回复:[quote=引用 2 楼 qq423399099 的回复:] 包含目录:头文件所在目录 附加库目录:lib所在目录 附加依赖项:lib的名称请问有具体步骤吗？[/quote]  菜单选项里头找找

[quote=引用 1 楼 u010165006 的回复:] 有的API函数需要添加lib才能用。[/quote请问下具体如何操作？？]

引用 2 楼 qq423399099 的回复:包含目录:头文件所在目录 附加库目录:lib所在目录 附加依赖项:lib的名称请问有具体步骤吗？

有的API函数需要添加lib才能用。

包含目录:头文件所在目录 附加库目录:lib所在目录 附加依赖项:lib的名称


Question: 数组转字符串-------------------

int main () { 	unsigned int tmp ; 	sscanf_s ("8048770" ,"%x" ,&tmp) ; 	void *p = (void *) (__int64) tmp ; 	return 0 ; }

是我没表达清楚啊，是这样：  现有一个字符串8048770； 把它组装成一个地址形式0x8048770； 然后把指针p指向这个地址0x8048770；  请问大神，怎么实现？ 我已经在这耗了三天时间了

写个循环，数组中一个元素一个元素去转  转换的函数有挺多

uint8是自己定义的类型？原始类型是啥啊

uint 转char，就不会自己转？


引用 2 楼 fefe82 的回复:5.2.4.2.1 Sizes of integer types <limits.h> 1 The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, the following shall be replaced by expressions that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.  标准只是给了一个范围限制而已，并没有规定一定是这个值。  至于为什么是 -32767 而不是 -32768 ，因为标准对有符号数允许三种不同的表示方式，原码、反码、补码（最常用的）。 16bit 原码与反码都无法表示 -32768。 6.2.6.2 Integer types 2 ............................ If the sign bit is one, the value shall be modified in one of the following ways: — the corresponding value with sign bit 0 is negated (sign and magnitude);     // 原码 — the sign bit has the value −(2^N) (two’s complement);                                         // 补码 — the sign bit has the value −(2^N − 1) (one’s complement).                                 // 反码  另外，标准允许在在有符号数中，用某一个值表示异常：(原码和补码的 10000000 ，反码的 1111111111) .... is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for one’s complement), is a trap representation or a normal value.  如果使用异常值的话，三种编码都无法表示 -32768 。 谢谢回复，很容易钻牛角尖

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

因为 -32768 这个数，对应的编码比较特殊 不是很符合有符号数的定义 首先， -32768  的绝对值是 32768，但是32768 不在 16 Bits有符号数的编码范围，因此也只能用， -32768  的编码表示 但是 32768 是个正数， -32768  的编码 最高位是（符号位）1，是个负数 这不符号绝对值的定义  其次，这个编码除了符号位，每一位都是0 他其实是-0 的编码，不符合 ，补码表示的有符号数的的含义 补码数中，负数 是他的相反数（一个正数）的补码，也就是相反数的反码+1  -32768这个数，他的相反数不在 16 Bits有符号数的编码范围，因而，也不是很符合这个相反数的补码关系 它是它自己的补码，这是只有0 才具有的性质，因为 0 = +0 = -0 从这些方面看， -32768  是个很尴尬的数值 因此，标准里就把有符号数的编码范围 缩小了，16Bits 中，把 -32768排除出去了 不同位数的类似的编码，也是一样处理的。

标准是一方面，编译器的实现是另一回事儿 C语言的标准规定int的范围最小是-32767到32767，但具体到编译器实现就不一定了，16位机时，大部分实现都是-32768到32767


Question: 指针与数组指针的区别

假设我定义了一个 int (*p)[10]; 那么这个p是一个二级指针， 假设有数组 a[4][10], 那么可以 p = a; *p也就相当于a[0], *p是一级指针。

好深奥呀，学习，学习！

p是数组首地址的地址，*p是数组首地址，**p是数组第一个元素。

p是数组指针，*p当然指向数组， 但是数组不能整体读取或者赋值。 因此*p就是第一个元素的地址了

推荐楼主看下 数组指针和指针数组的区别。https://blog.csdn.net/szullc/article/details/84900643

因为p是数组指针，所以*p指向第一行数组的地址。

指针的本质是地址，确切的是代表数组的首地址

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素 http://edu.csdn.net/course/detail/2455 C语言指针与汇编内存地址-二.函数 http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组 http://edu.csdn.net/course/detail/2517 C语言指针与汇编内存地址-四.三维数组

我理解p就是指向数组的首地址a

定义：     数组指针：指向数组首地址的指针， 那么*p只是将p降一级，仍然是地址啊

很多教材讲过，指针指向（即存储）的是数组的首地址，不能理解为元素~

引用 48 楼 chen2qu 的回复:"既然数组指针是指向数组的指针，指针内存放的是所对应的数组的地址，那么*p为什么不是元素而是地址呢？"  你说的中间那一段，其实已经很好的回答了你的问题。 但是你的问题，也是伪的，这里的元素，就是数组的地址，在这个问题中，是同一个东西。  他的意思是为什么*p指向的不是数组元素就是a[0]  我自己也搞不懂既然p是存放数组的地址，那数组的地址又是什么？ 如果数组的地址是数组的首地址那么*p不就是a【0】啊？

不错，过来好好学习一下

引用 8 楼 zhao4zhong1 的回复:电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……666

引用 45 楼 zhao4zhong1 的回复:没我这个中间层，上层就不会直接调用底层API了？ 没有API，我就没办法编程了

引用 43 楼 xiaoyuanyuan2009 的回复:[quote=引用 42 楼 zhao4zhong1 的回复:] 您老现在有没有时间学习了，有时间的话学一下Delphi XE 10，然后教教我们[/quote] 没我这个中间层，上层就不会直接调用底层API了？

引用 37 楼 qq_24861595 的回复:[quote=引用 14 楼 fefe82 的回复:] 数组类型的对象出现在表达式中的时候，绝大部分情况会自动转化为指向数组第一个元素的指针（array-to-pointer conversion）。  如果 p 是指向数组的指针，那么 *p 就是数组，然后它将在绝大多数情况下被转化为指向数组第一个元素的指针。  这种转化在 sizeof（） 里并不会发生。  =================== 注：数组不是指针。数组和指针是完全不同的类型。数组名可以当指针用，只是由于上面所说的转换的存在。  我想请问，如果此时对于p和*p分别加1操作，那么，他们移动的长度相等么[/quote] 不相等。 p+1 移动一个数组的长度 (*p) + 1 移动一个元素的长度

引用 14 楼 fefe82 的回复:数组类型的对象出现在表达式中的时候，绝大部分情况会自动转化为指向数组第一个元素的指针（array-to-pointer conversion）。  如果 p 是指向数组的指针，那么 *p 就是数组，然后它将在绝大多数情况下被转化为指向数组第一个元素的指针。  这种转化在 sizeof（） 里并不会发生。  =================== 注：数组不是指针。数组和指针是完全不同的类型。数组名可以当指针用，只是由于上面所说的转换的存在。  我想请问，如果此时对于p和*p分别加1操作，那么，他们移动的长度相等么

引用 42 楼 zhao4zhong1 的回复: 您老现在有没有时间学习了，有时间的话学一下Delphi XE 10，然后教教我们


Question: gcc 编译报错

引用 2 楼 Gump4231 的回复:弱弱问一句，怎么能把代码复制成这样。。。  调整一下代码缩进，使用语法着色，让大家看起来方便些。  语法着色，在论坛的编辑框里，有一排按钮，左数第12个，可以使用各种语言的语法着色。

引用 楼主 hzgmm 的回复:编译工程时，在下面这句报错 *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;  错误信息： error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] .... cc1: some warnings being treated as errors 弱弱问一句，怎么能把代码复制成这样。。。

弱弱问一句，怎么能把代码复制成这样。。。

编译时有 -fstrict-aliasing 参数或者 -O2等优化参数 就会启用严格对齐。 你使用了参数[-Werror=strict-aliasing]，这意味着你设置了编译器将strict-aliasing的warning编程error  严格对齐 简单来说就是 编译器希望不同类型的对象不会指向同一个地址，你只能使用对应类型去访问对应的地址。 比如说你代码中的buffer[SHA256_SHORT_BLOCK_LENGTH]是 char型的数组， 那么只能使用 char / unsigned char 类型去访问buffer，其他类型(sha2_word64)就会报这个错误。


Question: 请问Windows多线程中，怎么在线程里修改主函数的值呢?比如下例程序中，我要在print线程中修改主函数i的值怎么做呢，修改print函数参数会报错，求帮助！

DWORD WINAPI print(void *p) {  	*(int*)p  = 1; //这里修改主函数i  	for (;;) {  		printf("按Enter键终止运行\n"); 	}  	return 0; }  int main(int argc, char *argv[]) { 	int i = 0;  	HANDLE p = CreateThread(NULL, 0, print, &i, 0, NULL);  	for (;;) {  		getchar(); 		TerminateThread(p, 0); 	}  	return 0; }

线程启动的地方，那个函数中，局部变量的地址 可以传递给子线程 前提是，子线程要比这个函数结束的早 函数结束后，子线程中操作这个地址中的数据，就变成 对野指针进行操作了 还有一个办法是  函数中，动态分配数据，并初始化 而在在子线程中释放内存，不过，这样就不能改动主线程的函数中的数据了 除非二者共享动态分配数据的数据 共享数据，通常需要同步

要在线程中修改变量i的值，可以把i的指针传递到线程函数中，CreateThread的第四个参数就是用来传递东西的

将该值指针作为线程函数参数传递给线程函数，多看看msdn


选 x86版（32Bits）  输出long,long long 是不同的 x64（64Bits）输出 long,long long 都可以用 %lld

引用 1 楼 qq423399099 的回复:为何不用%ld输出呢 我知道是用%ld输出，但是%lld输出也是对的啊

为何不用%ld输出呢


Question: 关于SEH的一个问题，为什么反复触发异常呢？

引用 4 楼 paschen 的回复:看完这篇你就明白了：  http://www.xuebuyuan.com/1618519.html   1) __except(EXCEPTION_CONTINUE_EXECUTION)是让thread回到发生exception的机器指令，不是回到发生exception的C/C++语句； 2) 没有多少适合用__except(EXCEPTION_CONTINUE_EXECUTION)的场合，除非__try部分是用汇编写的。 我在看高端调试时作者反汇编的结果和我的明显不一样，就是我标记的那条指令，我不知道为什么我的这里竟是直接操作寄存器的。 非常感谢提供的地址。

话说，对于整型数 1/0 你希望产生什么结果 这结果，数学上合理吗？ 可以用int 类型表示吗？ 恢复后该怎样执行？ 修改寄存器？把被除数 0 改成1？  没有很好的办法，恢复执行1/0 这种异常，必须捕捉后，跳过现场，代码的执行。

异常的处理方式，有两种，一种是返回现场 一种是不返回现场，不返回现场的异常抛出后，中断程序的执行直至捕捉 捕捉后处理完异常，程序向后执行，异常相关的东西，就成为过去了。 返回现场的，一般是资源不足类型的异常，属于可恢复异常， 例如缺页中断，缺页中断的处理程序，是内存调度程序 内存调度后，页面就在内存中了，此后读写就不再出现异常了。 这种异常，通常只是提供给操作系统的资源管理手段 而，除法错误，属于不可恢复异常，不能返回现场继续执行。  异常处理后，不应该继续执行，因为除0中断，恢复后依然是错误，不能继续执行 这种异常出现，就应该退出现场，执行后面不再会导致异常的程序， 而不是重新执行被异常中断的程序。  举例：如果是整型 除法错误，整个表达式求值过程完全没法子处理这个异常 那么最好的处理方式是捕获异常，并退出程序，或者至少退出这个表达式序列的执行 如果是浮点除法错误，可以设置为产生异常。也可以设置为不产生异常 产生异常，由异常处理程序处理，可以退出执行 也可以直接把表达式结果置为无穷大，继续执行 不产生异常。计算结果直接就是无穷大。  总之，不能返回现场，再次执行 除法语句。 否则，就会出现异常一直在触发，捕捉中，构成死循环了

反汇编代码如下： 00161803 f7f9            idiv    eax,ecx     ///这里出的问题，如果是idiv eax, dword ptr [ebp-20h]  就正常了， 00161805 8945d4          mov     dword ptr [ebp-2Ch],eax 00161808 8b45d4          mov     eax,dword ptr [ebp-2Ch] 0016180b 50              push    eax 0016180c 68d86c1600      push    offset ConsoleApplication1!`string' (00166cd8) 00161811 e80ffbffff      call    ConsoleApplication1!ILT+800(_printf) (00161325) 00161816 83c408          add     esp,8 00161819 c745fcfeffffff  mov     dword ptr [ebp-4],0FFFFFFFEh 00161820 eb22            jmp     ConsoleApplication1!main+0xb4 (00161844) 00161822 c745e043000000  mov     dword ptr [ebp-20h],43h  使用的VS2015 编译


Question: 关于vc++6.0使用出现的问题

使用mingw，比VS小巧多了。推荐一款基于mingw的IDE：C Free

FileTool.exe 替换打开和添加到项目中 Visual C++ 的新功能 http://support.microsoft.com/kb/241396/zh-cn

看看是否兼容，有时它会有兼容性的问题！！

谭浩强赶紧出本新书吧，把过去的bug修补下，最主要的是要引导大家使用新版本的vs，都什么年代了，还在用上个世纪的东西。

解决方法：  http://blog.sina.com.cn/s/blog_4b650d650100qilj.html

换掉VC6 WIN7以上兼容就不是太好了 换成VS http://blog.csdn.net/cometnet/article/details/19551125

汉化版本的问题，具体说是VC的文件位置没有正确配置  解决： 1、手工调整到正确配置（百度上有配置教程） 2、换一个安装包

VC++6.0不标准，如果楼主准备长期学习，建议gcc,vs2015

干脆装visual studio 2015吧。community版免费的。


Question: C语言语句运行时间的问题

假设完全没有优化，x++ 的时间跟循环的时间相比也可以忽略了。由于各种随机误差都能导致第二个比第一个短。  有优化的话，你得先看看优化成啥样子了 ....

我帮你测试是第一个快  这种+运算是很快的，一个时钟周期就可以执行很多次  且同一段代码你在不同时候执行时间也不会完全一样  所以你这个没太大可比性  其次在debug下测试，不然会被优化了

可以解释的，因为第一个循环，可能堆栈，或者其他内存，还没有实际分配物理内存 需要运行的时候，才会分配（内存调度），而第二个循环，已经是物理内存了，因此，没有内存调度 时间短些，也很正常 这个例子说明，现代操作系统，不很适宜，简单的测量， 程序或者算法的运行时间 尤其是调试的时候

整型变量能到这么大的数么