Question: gdb调试和正常运行结果不一致。

将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施”： //带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

先自己顶顶

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

我大概知道说的意思了，但是长类型输出结果不会比短类型的还要小啊(都是无符号的)。

首先谢谢楼上赵老师的瞬间判断给出的结论。 以及举一反三的指针例句。 谢谢！  但是这里不存在scanf的%变量以及&问题。也不存在printf和输出格式不对问题。 可能是个人学历能力原因，还是不能从老师的例句启发中找到问题答案，麻烦有遇到类似问题的大大们再看看啦。


Question: 不使用 “+” 号，实现加法

lz这做法的主要意义是修改一下以后就能应付会溢出的平均数了。这个做法的出处估计其实就是从那里来的。

int Add(int x,int y) {     int i;     if(y==0) return x;     else     {         for(i=1;i<=y;i++)         {             x++;         }         return x;     } }

a + b  --->  a - (-b)

引用 18 楼 u013163178 的回复:能解释下printf函数里面的东西吗 return printf("%*c%*c", a, '\r', b, '\r');  * 就是后面a的值，a = 3 的话，就是printf("%3c", '\r');  这位大神果然牛人！

茴香豆的‘茴’有几种写法

记得看过一个写HelloWorld的乱码大赛

这...个...有...意...思...么...？考发散性思维？

add( x ^ y, (x & y) << 1); 楼主这代码能解释下吗？不理解啊！

不错，很好的例子。

/*************************************************************************     > File Name: sum.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年10月25日 星期六 14时57分38秒  ************************************************************************/  #include<stdio.h> int * add(int a, int b) { 	int *const p=(unsigned int *)a; 	return &p[b]; }  int main() { 	printf("%d\n",(int)add(2,3));  	return 0; } 算出来是错的

引用 2 楼 wushishuihuo 的回复:两个减号，num1-（-num2）+1

_asm{     ADD AX,CX; }

引用 8 楼 slx_391987 的回复:自增 ++ 算不？   自增输入特例吧～而且这玩意俩加号～

引用 5 楼 u010375827 的回复:计算机最底层都是用补码进行加法计算。 知道是补码有什么用，怎么在代码中把这个思想利用起来

引用 2 楼 wushishuihuo 的回复:两个减号，num1-（-num2） 也是一个好方法啊，学习了

引用 9 楼 max_min_ 的回复:位于 位或   | & ^  都可以啊 版主大大能不能给个C/C++语言的例子，学习一下

位于 位或   | & ^  都可以啊

自增 ++ 算不？

法子真多。。。

2个减号


Question: c语言

应该 还真是你代码问题！ 一切的不可思议都是在情理之中，这就是编码的乐趣。

绝对？ 不要这么肯定， 同一楼， 无码无真相

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

无码无真相


Question: 关于3D中的vertex normals 和 theta与phi的关系


Question: 关于小写字符转大写字符的问题，请教指点！

自己实现库函数就行啦  #include <stdio.h>  int my_isupper(char c) {     return (c >= 'A' && c <= 'Z'); }  int my_islower(char c) {     return (c >= 'a' && c <= 'z'); }  int my_toupper(char c) {     if (my_islower(c))         return 'A' + (c - 'a');     else         return c; }  int my_tolower(char c) {     if (my_isupper(c))         return 'a' + (c - 'A');     else         return c; }  char *strupper(char *s) {     char *p;      for (p = s; *p; ++p)         *p = my_toupper(*p);     return s; }  char *strlower(char *s) {     char *p;      for (p = s; *p; ++p)         *p = my_tolower(*p);     return s; }  int main(int argc, char *argv[]) {     char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcd-1234";      printf("%s\n", strupper(s));     printf("%s\n", strlower(s));      return 0; }

引用 1 楼 user-4 的回复:void uppers(const char *str,char *dest){ assert((str!=NULL)&&(dest!=NULL)); while(*str!='\0'){ *dest=*str; if( (*str>='a') && (*str<='z') ) { *dest=*str-32; } str++; dest++; } *dest='\0'; }  谢谢回复！对于不用处理的字符应该给赋值，我写程序的时候没考虑。

引用 2 楼 u013163178 的回复:从语言标准库里面有这个函数，看我代码 /*************************************************************************     > File Name: toupper.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年10月23日 星期四 10时33分57秒  ************************************************************************/  #include<stdio.h> #include<ctype.h>  int main() { 	char s[] = "hello world!"; 	printf("before toupper is: %s\n",s); 	for(int i=0; i< sizeof(s); i++) 		s[i] = toupper(s[i]); 	printf("after toupper is: %s\n",s);  	return 0; } 详情可登陆www.gfsoso.com  这是一道笔试题：编写一个函数实现将字符串的小写字母转换为大写字母，不能调用C/C++库函数。 函数原型为void uppers(const char *src,char *dest) 其中src是输入字符串的地址，dest是输出字符串的地址。


Question: 求大神指教，我想从键盘输入一段字符串，然后从屏幕上显示出来。。。

找本基础的资料看看呗，入门级的

printf("%s\n", text);这一句放进while循环中才是输出你当前输入的字符串

# include <stdio.h> # include <string.h>  # define TEXTLEN 10   int main (void) {	 	char endstr[] = "*\n"; 	char text[TEXTLEN]; 	int i = 0;  	printf("请输入任意字符串\n"); 	while(1) 	{ 		fgets(text, TEXTLEN, stdin);    ///为什么不直接写gets( text ) ? 		i = strcmp(text, endstr);  ////看看i的值是多少  		if( !i )    ///当你输完一句话能执行到break吗？ 			break;  		if(strlen(text) > TEXTLEN) 		{ 			printf("超过容量，请重新开始输入\n"); 			return 1; 		} 	}  	printf("%s\n", text);  	return 0; }

这两行顺序错了吧，对调一下试试 } printf("%s\n", text);


Question: 链表遍历疑问

代码太乱 没看 不过 建议你create的时候 都memset 0 一下

单步跟踪，多加打印，自已动手，丰衣足食 在你觉得有问题的地方加打印，看输出是怎么样得出来的，然后相应的调整 祝你成功

llist_node_st{  char data[0]; struct llist_node_st *prv; struct llist_node_st *next;	 };  char data[0]; 是什么意思阿？


Question: 程序入口main函数，main文件？

引用 4 楼 zhao4zhong1 的回复:对任何开发环境，熟悉这个开发环境下的调试器是大前提。  这里的RUN TO main，没有说明是main.c还是main(),不过从汇编那个看来，是main：。 但是在工程中找不到main：后面init_all的C代码

对任何开发环境，熟悉这个开发环境下的调试器是大前提。

引用 2 楼 zmlovelx 的回复:入口函数是可以指定的。  工程里找不到 init_all 这个函数

入口函数是可以指定的。

嵌入式的东西有点特殊。


Question: 指向函数的指针

int (*k)(int,int)或者是f得转换成int (*)(int, int)吧。

对于函数指针，f等同于*f，所以D和A是一样的


Question: 有关外部函数调用的问题

Thank U!

引用 4 楼 u014592447 的回复:[quote=引用 2 楼 Bigbalana 的回复:] VS2013上将这个函数定义为不安全函数，有些病毒利用这类获取输入函数，大量的输入内容达到覆盖内存的效果。像这样的还有gets_S(),以及很多的字符串处理函数都被VS2013定义为不安全 但是如果我想在上面的函数中使用scanf_s这个函数，那要进行什么样的操作呢？[/quote]  如果说你是用它来获取字符串  scanf_s("%s",aa,20)  aa是字符型指针 或者数组名  20是你希望获取字符串的最多字符数，除了这种情况外 其他的使用方法与scanf() 相同

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

引用 2 楼 Bigbalana 的回复:VS2013上将这个函数定义为不安全函数，有些病毒利用这类获取输入函数，大量的输入内容达到覆盖内存的效果。像这样的还有gets_S(),以及很多的字符串处理函数都被VS2013定义为不安全 但是如果我想在上面的函数中使用scanf_s这个函数，那要进行什么样的操作呢？

这个问题许多人都问过了——http://bbs.csdn.net/topics/370236436

发现问题所在 我用的VS2013 其中我将scanf_s("%c",c) 换成了 scanf("%c",c)虽然提出安全警告 但是结果却显示正确。 请问大神们，这里scanf 和 scanf_s的区别体现在什么地方


Question: codebolcks+gcc编译器怎么运行多线程程序？

哦，对，是因为我的主线程结束了，所以子线程也死了，一语惊醒。WaitForMultipleObjects函数太复杂了，容易出错，为了先看到效果，就先用system("PAUSE")试了一下，找到了原因，谢谢！

在主线程使用WaitForMultipleObjects等待子线程的创建。

windows下使用CreateThread好像也是可以的啊，你的程序没有出现你想要的情况，是因为你的主进程结束了，所以你创建两个线程也跟着结束了。

贴上代码：  #include <stdio.h> #include <stdlib.h> #include <windows.h>   DWORD WINAPI driverWork(LPVOID lpParameter); DWORD WINAPI sellerWork(LPVOID lpParameter);  HANDLE dEvent,tEvent;   //事件对象，相当于司机和售票员的私有信号量  int main() {     DWORD driverID,ticke_sellerID;   //司机线程和售票员线程的id     HANDLE driver,ticket_seller;    //司机线程和售票员线程的句柄      //创建事件对象     //dEvent = CreateEvent(NULL,FALSE,FALSE,NULL);     //tEvent = CreateEvent(NULL,FALSE,FALSE,NULL);     //printf("创建事件完毕！\n");     //创建线程     driver = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)driverWork,NULL,0,&driverID);     ticket_seller = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sellerWork,NULL,0,&ticke_sellerID);     if(driver && ticket_seller) {         printf("创建线程完毕！\n");     }     //关闭线程     //printf("开始关闭线程！\n");     //CloseHandle(driver);     //CloseHandle(ticket_seller);     return 0; }  //司机线程 DWORD WINAPI driverWork(LPVOID lpParameter) {     int i = 0;     while(i < 10)     {         printf("正常行车，到站，停车\n");         i++;     }     return 0; }  DWORD WINAPI sellerWork(LPVOID lpParameter) {     int i = 0;     while(i < 10)     {         printf("售票\n");         i++;     }     return 0; }  运行结构如下，有两种情况，但都不是想要的情况：


Question: #define 宏定义空值 对程序有多大影响

很感谢大家给予及时回复

宏不能定义宏。  就像 #define define    将define定义为空  你觉得它下面的所有define 是不是就是空了呢？  这是鸡生蛋，蛋生鸡的问题

简单的讲，就是编译预处理，宏替换的问题，对于""中出现的宏名不做替换。 仅此而已，详细内容就去看预处理的细节。

#define和#include都是预处理命令，两者是并列关系，不存在相互调用关系。我猜。

引用 3 楼 zhao4zhong1 的回复:研究一下gcc源代码中处理#define和#include相关部分。  呵呵，不是我不求甚解。我非计算机专业，只是在自己的编程中发现了这个问题，只想做个简单的了解。望大师给指点一下即可。简明扼要

引用 1 楼 ForestDB 的回复:你试试 # include <stdio.h>  已知""内的内容不做宏替换。  没有什么影响，哪儿有讲这方面理论的吗？我在书上和网上都没找到

研究一下gcc源代码中处理#define和#include相关部分。

没有什么影响，哪儿有讲这方面理论的吗？我在书上和网上都没找到

你试试 # include <stdio.h>  已知""内的内容不做宏替换。


Question: [求助]：winTC编译环境下如何透过winIO读取底层CMOS数值

winio.h #ifndef WINIO_H #define WINIO_H  #ifdef WINIO_DLL #define WINIO_API _declspec(dllexport) #else #define WINIO_API _declspec(dllimport) #endif  extern "C" {   WINIO_API bool _stdcall InitializeWinIo();   WINIO_API void _stdcall ShutdownWinIo();   WINIO_API PBYTE _stdcall MapPhysToLin(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle);   WINIO_API bool _stdcall UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr);   WINIO_API bool _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal);   WINIO_API bool _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal);   WINIO_API bool _stdcall GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);   WINIO_API bool _stdcall SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);   WINIO_API bool _stdcall InstallWinIoDriver(PSTR pszWinIoDriverPath, bool IsDemandLoaded = false);   WINIO_API bool _stdcall RemoveWinIoDriver(); }  extern bool IsNT; extern HANDLE hDriver; extern bool IsWinIoInitialized;  bool _stdcall StartWinIoDriver(); bool _stdcall StopWinIoDriver();  #endif  winiotest.cpp #include <windows.h> #include <stdio.h> #include "winio.h"  void main() {   DWORD dwPortVal;   DWORD dwMemVal;   bool bResult;   HANDLE hPhysicalMemory;   PBYTE pbLinAddr;    // Call InitializeWinIo to initialize the WinIo library.    bResult = InitializeWinIo();    if (bResult)   {     // Under Windows NT/2000/XP, after calling InitializeWinIo,     // you can call _inp/_outp instead of using GetPortVal/SetPortVal      GetPortVal(0x378, &dwPortVal, 4);      SetPortVal(0x378, 10, 4);      // Map physical addresses 0xA0000 - 0xAFFFF into the linear address space     // of the application. The value returned from the call to MapPhysToLin is     // a linear address corresponding to physical address 0xA0000. In case of     // an error, the return value is NULL.      pbLinAddr = MapPhysToLin((PBYTE)0xA0000, 65536, &hPhysicalMemory);      if (pbLinAddr)     {       // Now we can use pbLinAddr to access physical address 0xA0000        *pbLinAddr = 10;        // When you're done with pbLinAddr, call UnmapPhysicalMemory        UnmapPhysicalMemory(hPhysicalMemory, pbLinAddr);     }      // Instead of using MapPhysToLin, we can use GetPhysLong/SetPhysLong      GetPhysLong((PBYTE)0xA0000, &dwMemVal);      SetPhysLong((PBYTE)0xA0000, 10);      // When you're done using WinIo, call ShutdownWinIo      ShutdownWinIo();   }   else   {     printf("Error during initialization of WinIo.\n");     exit(1);   } }

Win-TC天生和WinIO不兼容。 VC+WinIO才行。


Question: 解析html网页图片链接下载却没反应？？？？？？？？？？？？？？？

引用 9 楼 mymtom 的回复:GET 请求格式不对呀     sprintf(str,             "GET /www/images/qq2012/guide_k_04.png HTTP/1.1\r\n"             "Host: mat1.gtimg.com\r\n"             "Connection: close\r\n"             "\r\n"             ); 请求格式也改了  也确实接收到数据 可是我接收数据创建图片 却0字节  sprintf(str_get,"GET %s  HTTP/1.0\r\nHost:%s\r\nContent-Type=images/x-icon\r\nConnection:C    lose\r\n\r\n",url_get, url_host);  90                 //sprintf(str_get,"GET %s HTTP/1.1\r\nHost:%s\r\nContent-Type=images/x-icon\r\nConnection:    keep-alive\r\n\r\n",filename, "http://mat1.gtimg.com");  91                 ret1 = send(sockfd, (void *)str_get, strlen(str_get), 0);  92                 if(ret1 < 0){  93                     printf("resend error %d,%s", errno, strerror(errno));  94                     exit(0);  95                 }else  96                     printf("resend success, total is:%d\n", ret1);  97                 memset(buf, 0, 4095);  98                 while(1){  99                     i = recv(sockfd, (void *)buf, 50, 0); 100                     if(i == 0){ 101                         close(sockfd); 102                         printf("read picture end\n"); 103                         return; 104                     } 105                     else{ 106                         fp = fopen(filename,"a"); 107                         fwrite(buf, 1, i, fp); 108                     } 109                 }

引用 8 楼 rui___ 的回复:引用 5 楼 r_Jimy 的回复:另外，你这个SOCKET连接是连接到哪个服务器哪个端口这个要考虑好，一般情况下是要连网关的网关/》？？？试试

引用 4 楼 r_Jimy 的回复:你是靠主动轮循去接收吗？具体的recv是系统函数还是你自己写的，你写的socket其它通讯是OK的吗？这个是连接qq.com的 解析出来的图片地址

引用 3 楼 rui___ 的回复:难不成，发送的请求有点问题请他的都ok  第一次写有点乱    你看下 #include "downpicture.h"   void down_picture(char * url, const char * filename){  	FILE * fp; 	int sockfd; 	int ret; 	int ret1; 	int i; 	int h;  	struct hostent * host; 	struct sockaddr_in servaddr;  	char str1[4096]; 	char buf[BUFSIZE]; 	char *str; 	char str_get[4096]; 	socklen_t len;  	fd_set t_set1; 	struct timeval tv; 	host = gethostbyname("www.qq.com");	 	if(fp < 0) 	{ 		printf("open file fail...\n"); 		return; 	}else 		printf("file create success\n");  	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )  	{  		printf("socket error!\n");  		exit(0); 	}   	bzero(&servaddr, sizeof(servaddr));  	servaddr.sin_family = AF_INET;  	servaddr.sin_port = htons(PORT); 	servaddr.sin_addr = *((struct in_addr*)host->h_addr);  	if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)  	{      		printf("connect error!\n");  		exit(0);  	}  	printf("connect success \n");   	memset(str1, 0, 4096);  	sprintf(str1,"GET / HTTP/1.0\r\nHost:%s\r\nContent-Type=text/plain\r\nConnection:keep-alive\r\n\r\n","www.qq.com");	 	ret = send(sockfd,(void *)str1,strlen(str1),0);  	if (ret < 0)  	{  		printf("send error %d，Error message'%s'\n",errno, strerror(errno));  		exit(0);  	} 	else 	{  		printf("send success ,total send %d \n", ret);  	}  	while(1) 	{  		tv.tv_sec= 0;  		tv.tv_usec= 0;  		h= 0;  		FD_ZERO(&t_set1);  		FD_SET(sockfd, &t_set1);  		h= select(sockfd +1, &t_set1, NULL, NULL, &tv);  		if (h == 0) continue;  		if (h < 0)  		{  			close(sockfd);  			printf("some thing read error！\n");  			return;  		}  		if (h > 0) 		{  			memset(buf, 0, 4095);  			i= recv(sockfd, (void *)buf, 4092,0);  			if (i==0) 			{  				memset(str_get, 0, 4096); 				sprintf(str_get,"GET / HTTP/1.1\r\nHost:%s\r\nContent-Type=images/x-icon\r\nConnection:Close\r\n\r\n",url); 				//sprintf(str_get,"GET %s HTTP/1.1\r\nHost:%s\r\nContent-Type=images/x-icon\r\nConnection:keep-alive\r\n\r\n",filename, "http://mat1.gtimg.com"); 				ret1 = send(sockfd, (void *)str_get, strlen(str_get), 0); 				if(ret1 < 0){ 					printf("resend error %d,%s", errno, strerror(errno)); 					exit(0); 				}else 					printf("resend success, total is:%d\n", ret1); 				memset(buf, 0, 4095); 				while(1){ 					i = recv(sockfd, (void *)buf, 50, 0); 					if(i == 0){ 						close(sockfd); 						printf("read picture end\n"); 						return; 					} 					else{ 						fp = fopen(filename,"a"); 						fwrite(buf, 1, i, fp); 					} 				}  				 			}  		}  	}  	fclose(fp); 	close(sockfd);  }

自己解决啦  哈哈

引用 15 楼 mymtom 的回复:这里只有fopen没有fclose呀？#include "downpicture.h"   void down_picture(char * url, const char * filename){  	FILE * fp; 	int sockfd; 	int ret; 	int ret1; 	int i; 	int h;  	char url_get[50] = {0}; 	char url_host[100] = {0}; 	struct hostent * host; 	struct sockaddr_in servaddr;  	char str1[4096]; 	char buf[BUFSIZE]; 	char *str; 	char str_get[4096]; 	socklen_t len;  	fd_set t_set1; 	struct timeval tv; 	host = gethostbyname("www.qq.com");	 	fp = fopen(filename,"a"); 	if(fp < 0) 	{ 		printf("open file fail...\n"); 		return; 	}else 		printf("file create success\n");  	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )  	{  		printf("socket error!\n");  		exit(0); 	}   	bzero(&servaddr, sizeof(servaddr));  	servaddr.sin_family = AF_INET;  	servaddr.sin_port = htons(PORT); 	servaddr.sin_addr = *((struct in_addr*)host->h_addr);  	if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)  	{      		printf("connect error!\n");  		exit(0);  	}  	printf("connect success \n");   	memset(str1, 0, 4096);  	sprintf(str1,"GET / HTTP/1.1\r\nHost:%s\r\nContent-Type=text/plain\r\nConnection:keep-alive\r\n\r\n","www.qq.com");	 	ret = send(sockfd,(void *)str1,strlen(str1),0);  	if (ret < 0)  	{  		printf("send error %d，Error message'%s'\n",errno, strerror(errno));  		exit(0);  	} 	else 	{  		printf("send success ,total send %d \n", ret);  	}  	while(1) 	{  		tv.tv_sec= 0;  		tv.tv_usec= 0;  		h= 0;  		FD_ZERO(&t_set1);  		FD_SET(sockfd, &t_set1);  		h= select(sockfd +1, &t_set1, NULL, NULL, &tv);  		if (h == 0) continue;  		if (h < 0)  		{  			close(sockfd);  			printf("some thing read error！\n");  			return;  		}  		if (h > 0) 		{  			memset(buf, 0, 4095);  			i= recv(sockfd, (void *)buf, 4092,0);  			if (i==0) 			{  				strncpy(url_host, url, 21); 				strcpy(url_get, &url[22]);   				printf("%s\n%s\n\n", url_host, url_get);  				memset(str_get, 0, 4096); 				sprintf(str_get,"GET %s  HTTP/1.0\r\nHost:%s\r\nContent-Type=images/x-icon\r\nConnection:Close\r\n\r\n",url_get, "www.qq.com"); 				//sprintf(str_get,"GET %s HTTP/1.1\r\nHost:%s\r\nContent-Type=images/x-icon\r\nConnection:keep-alive\r\n\r\n",filename, "http://mat1.gtimg.com"); 				ret1 = send(sockfd, (void *)str_get, strlen(str_get), 0); 				if(ret1 < 0){ 					printf("resend error %d,%s", errno, strerror(errno)); 					exit(0); 				}else 					printf("resend success, total is:%d\nsockfd is %d\n\n", ret1, sockfd); 				memset(buf, 0, 4095); 				while(1){ 					i = recv(sockfd, (void *)buf, 50, 0); 					if(i == 0){ 						close(sockfd); 						printf("read picture end\n"); 						return; 					} 					else{ 						printf("%d\n\n", i); 						fwrite(buf, 1, i, fp); 					} 				}  				 			}  		}  	}  	fclose(fp); 	close(sockfd);  }            完整的代码   我还解析了 www.qq.com中新闻等url   可是发送请求不能下载 给我段错误   看来协议还得好好看看

这里只有fopen没有fclose呀？

引用 12 楼 rui___ 的回复:引用 8 楼 rui___ 的回复:引用 5 楼 r_Jimy 的回复:另外，你这个SOCKET连接是连接到哪个服务器哪个端口这个要考虑好，一般情况下是要连网关的网关/》？？？发送了  i = 0   没有接收到数据 i = recv(sockfd, (void *)buf, 50, 0); 100                     if(i == 0){ 101                         close(sockfd); 102                         printf("read picture end\n"); 103                         return; 104                     } 105                     else{ 106                         fp = fopen(filename,"a"); 107                         fwrite(buf, 1, i, fp);  我直接接收然后保存到文件的  不对么？？初学者捣鼓的  怎么做的？？？？请指教

返回的HTTP报文你解析对了没有： Content-Length: 13704 HTTP 头之后跟的 13704 字节就是PNG文件的内容。  HTTP/1.1 200 OK Server: cws/3.8.3 Date: Thu, 23 Oct 2014 02:34:21 GMT Content-Type: image/png Content-Length: 13704 Connection: close Last-Modified: Wed, 14 May 2014 02:03:23 GMT ETag: "5372ceeb-3588" Accept-Ranges: bytes Expires: Fri, 23 Oct 2015 02:34:21 GMT Cache-Control: max-age=31536000 X-Cache: MISS from shenzhen.gtimg.com

难不成，发送的请求有点问题

人呢？？

没人么   给自己顶！！


Question: 自己写的一个strncpy（）函数。

总是编译不通过，我按照提示错误，看不出来有问题啊 /*************************************************************************     > File Name: mystrcpy.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年10月23日 星期四 10时53分07秒  ************************************************************************/ #include<stdlib.h> #include<stdio.h> #include<string.h>  void mystrncpy(char *str1, char * str2, int n) { 	int i; 	if((n < strlen(str1) && strlen(str1) < strlen(str2)) ||( n < strlen(str2) && strlen(str2) < strlen(str1)) 	{ 		for(i=0; i < n; ++i) 			str1[i] = str2[i]; 		str1[i] ='\0'; 	} 	else if((strlen(str2) < n &&  n < strlen(str1)) || (strlen(str2) < strlen(str1) && strlen(str1) < n) 	{ 		for(i=0; i< strlen(str2); ++i) 			str1[i] = str2[i]; 		str1[i] = '\0'; 	} 	else if((strlen(str1) < strlen(str2) && strlen(str2)  < n ) || (strlen(str1) <  n && n < strlen(str2)) 	{ 		for(i=0; i< strlen(str1)-1; ++i) 			str1[i] = str2[i]; 		str1[i] = '\0'; 	} } int main() { 	char *str1 = (char *) malloc(10); 	char str2[] = "hello world"; 	mystrncpy(str1,str2, 5); 	printf("%s\n",str1); 	return 0; }

C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\STRNCPY.C /*** *strncpy.c - copy at most n characters of string * *       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. * *Purpose: *       defines strncpy() - copy at most n characters of string * *******************************************************************************/  #include <cruntime.h> #include <string.h>  /*** *char *strncpy(dest, source, count) - copy at most n characters * *Purpose: *       Copies count characters from the source string to the *       destination.  If count is less than the length of source, *       NO NULL CHARACTER is put onto the end of the copied string. *       If count is greater than the length of sources, dest is padded *       with null characters to length count. * * *Entry: *       char *dest - pointer to destination *       char *source - source string for copy *       unsigned count - max number of characters to copy * *Exit: *       returns dest * *Exceptions: * *******************************************************************************/  char * __cdecl strncpy (         char * dest,         const char * source,         size_t count         ) {         char *start = dest;          while (count && (*dest++ = *source++))    /* copy string */                 count--;          if (count)                              /* pad out with zeroes */                 while (--count)                         *dest++ = '\0';          return(start); }

//字符串拷贝 char *StrCpy(char *pDes, const char *pSrc) { 	char *pTemp = pDes; 	while('\0' != *pSrc) 	{ 		*pTemp++ = *pSrc++; 	} 	*pTemp = '\0';  	return pDes; }  //指定长度字符串拷贝 char *StrnCpy(char *pDes, const char *pSrc, int nNums) { 	char *pTemp = pDes; 	int nTemp = nNums; 	while('\0' != *pSrc && nNums > 0) 	{ 		*pTemp++ = *pSrc++; 		nNums--; 	} 	*pTemp = '\0';  	return pDes; }

ch1[j] = '\0'; 数组越界了

#include<stdio.h> #include<string.h> void strncpy(char s1[],char s2[],int n) {   int lens2=strlen(s2);   int i=0,j;   if(lens2>=n)     {       while(i<n) 	{ 	  s1[i]=s2[i]; 	  i++; 	}       s1[i]=0;     }   else     {       i=0;       while(i<lens2) 	{ 	  s1[i]=s2[i]; 	  i++; 	}       s1[i]=0;      }    } int main() {   char str1[20],str2[20];   int n;   scanf("%s  %d",str2,&n);   strncpy(str1,str2,n);   printf("%s\n",str1);   return 0; }

‘gets’ is deprecated in linux!  liam@ubuntu:~/practice$ ./a.out  dgdfgdfgdfgdfg 5 dgdfgdfgd Next one. sdfsdf3 3 sdf Next one. sdfgdfgdf4 4 sdfg Next one.  没看见有啥问题。不过真心难用。


以管理员身份运行 以XP兼容模式运行


Question: c语言的空格问题

找到，http://msdn.microsoft.com/zh-cn/aa246404    多谢！  结贴

引用 2 楼 shenwansan_gz 的回复:学习了，多谢！ btw：@zhao4zhong1  这些资料科已在哪里找到？ MSDN98

学习了，多谢！ btw：@zhao4zhong1  这些资料科已在哪里找到？

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.


Question: c快学完了，有点茫然，请大家指教

引用 26 楼 u010913001 的回复:引用 25 楼 aa5566f4 的回复:我覺得要學彙編語言最近看了一点，但我觉得汇编挺深的，只能结合c反汇编理解，你是台湾人？  是阿 我是中國台灣人

顶一个吧……话说我大三的时候C语言有没有写到500行都是个问题……我觉得大学还是尽量打好基础吧。 如果对软件架构、大型软件之类的有兴趣，以后想当架构师什么的，学好C++，了解设计模式，多看些经典书籍，多用一些现有的框架MFC、QT、ACE之类，有时间也可以研究下代码，培养自己面向对象的设计思想……这样一步步来，而且这些都是基础……路很长。 如果对驱动有兴趣，学下相关驱动的知识（linux的系统原理啊、内核的部分知识啥的），从一些简单的驱动开始（串口啊、USB啊之类的），嵌入式的话很多都是linux。 如果自认为数学不错，可以试着弄下算法。  最最重点的，能找到一个项目去做，或者自己鼓捣一个开源项目（比如丢个HTTP协议到网上什么的给大家用）。 计算机是门实践性学科，做项目是最为有效和快捷的提高方式。

编程语言仅仅是一个形式，“内功课”也很重要：计算机操作系统、计算机网路、数据库、编译原理等，如果语言功底足够好，你的内功也练到家了，那么应该多练习一些项目。

引用 30 楼 aa5566f4 的回复:引用 26 楼 u010913001 的回复:[quote=引用 25 楼 aa5566f4 的回复:] 我覺得要學彙編語言最近看了一点，但我觉得汇编挺深的，只能结合c反汇编理解，你是台湾人？  是阿 我是中國台灣人 [/quote] 看头像有点象香港人。

我覺得要學彙編語言

引用 22 楼 u010913001 的回复:[quote=引用 20 楼 lovesmiles 的回复:] 楼主看的书还是太少了。多看书吧。 侯捷的　STL源码剖析 Effective c++ ,  more Effective c++ 《Effective STL》 《Essential C++ 中文版》 《More Exceptional C++ 中文版》 深度探索 C++ 对象模型 <<UNIX环境高级编程>>  C++反汇编与逆向分析技术揭秘 一入STL深似海。。[/quote] stl就是个library而已

引用更快速更高效的获取信息，像黑客一样纵横网络世界。可现在并没有实现一点，所以并不知道下一步怎么办  勤奋之外，还得有点天分，探索linux 内核吧。

引用 20 楼 lovesmiles 的回复:楼主看的书还是太少了。多看书吧。 侯捷的　STL源码剖析 Effective c++ ,  more Effective c++ 《Effective STL》 《Essential C++ 中文版》 《More Exceptional C++ 中文版》 深度探索 C++ 对象模型 <<UNIX环境高级编程>>  C++反汇编与逆向分析技术揭秘 一入STL深似海。。

引用 9 楼 zhao4zhong1 的回复:《Linux C编程一站式学习》 引用 9 楼 zhao4zhong1 的回复:《Linux C编程一站式学习》 我看到第三章，我想是 学C++的STL 还是学linux系统 ？windows系统编程？求教 我有C++标准库看了看难度挺大，看了mfc反而是vc++的封装比较简单，linux是网络方向的很多书 请指导

同感！给你我的大学学习计划，做个参考： 1、《离散数学》 2、《数据结构与算法》  3、《操作系统》、《汇编》 4、《编译原理》 5、《计算机网络》

引用 4 楼 hust_123 的回复:大三写了2W行代码，不错了，大学本科还是好好学好基础高三写了1w行代码怎么破？

linux，一直在吃Windows这个饭碗想从事后台，，，，，再说一句，天下之大何苦做码农

lz 我没有其他意思哈 只是激励你一下 如果想要搞CC++的话，大三 500行的项目 太小了些  加油吧

楼主学嵌入式，赶脚买个板子来学习吧，从单片机->带操作系统->wince linux大系统

引用 6 楼 N_sev7 的回复:不过有两门课必须学好 一、数学。可能你听过很多遍，我上大学的时候也听过，但是想着写代码的和数学有多大关系，但是现在我知道我多幼稚了。 二、英语。可能你还是听过很多遍，我上大学的时候....。当你遇到一个技术难题时，你百谷到有用的都是外国人发的帖子的时候你就后悔英语没学好了。。。《The Intel 64 and IA-32 Architectures Software Developer's Manual》全英文的... 数学很重要，但跟方向很有关系，线性代数，微积分相关的算法，非专涉及相关领域基本用不到，到是一些排序，堆域概念，或数据校验，加解密等算法用得较多（专心学好《数据结构与算法》吧） 英语很重要，但是学校课本里的课文背得再熟，第一次看DATASHEET，规格书，库说明文档等，依然会头大，所以有方向后，专业的英语文档下些来学比过6级8级来得重要

引用 2 楼 u013163178 的回复:linux 就是数据哗哗的在终端里面滚 欢迎你使用linux学习哦 linux涉及 嵌入式，嵌入式万一又是做手机，这不是不归路啊

引用 9 楼 zhao4zhong1 的回复:《Linux C编程一站式学习》 好 看看，我决定还是学校选方向 选嵌入式，这些东西学学了解，还是主要写自己的程序

个人认为：学习Linux，在更底层开发，更有趣，特别是使用很多命令，一个命令进去，就哗啦啦的一堆数据出来了，我自己学完的一本书，推荐下，人民邮电出版社《Linux C编程实战》


Question: nvidia  cuda toolkit和 cuda sdk

为什么中文的网站只有2.3版本，而英文版有6.5版本 http://www.nvidia.cn/object/cuda_get_cn_old.html  https://developer.nvidia.com/cuda-toolkit

有些答案说要安装cuda driver，官网找不到呢


Question: c语言数组问题

int a,b,c=0; 这种方式只初始化了c.

#include<stdio.h>  #include<conio.h>  #include <stdlib.h> int haha(char *p) { 	int a,b,c; 	a=b=c=0;//b没有初始化 	for(a=0;*(p+a)!='\0';a++) 	{ 		if(*(p+a)=='O') 		{ 			c++; 			b+=c; 		} 		else 		{ 			c=0;                              		} 	} 	return b;  }  int main() { 	int a,b,c,d=0; 	char p[100][100]; 	int sum[100]; 	scanf("%d",&a); 	for(b=0;b<a;b++){ 		getchar(); 		scanf(" %s",&p[b]); 	} 	for(b=0;b<a;b++){ 		sum[b]=haha(p[b]); 		printf("%s-->",p[b]); 		printf("%d\n",sum[b]);          	} 	getch();     	return 0; }


Question: 为什么用fwrite写入。然后读取TXT文件里面的内容显示乱码

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

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

引用 3 楼 x_i_aofeng 的回复:没有。不过自己已经解决了。嘻嘻 。。谢谢了啊你是什么问题，又是怎么解决的呢，可否分享下经验

没有。不过自己已经解决了。嘻嘻 。。谢谢了啊

你是不是输入的数字和中文啊


Question: gcc环境下的月经贴：core dumped. 但确实非常奇怪，请高手给看看

理解和讨论之前请先学会如何观察！  学会使用GDB单步调试才是楼主的当务之急！

我不会emacs，可惜。 http://bbs.csdn.net/topics/390306165

a[n]  与  *（a+n）  是等价的，然后你照搬就能明白为什么会那样输出了

引用 11 楼 zhao4zhong1 的回复:[quote=引用 10 楼 javashit 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] 理解和讨论之前请先学会如何观察！  学会使用GDB单步调试才是楼主的当务之急！  我完全同意你说的 在VC环境下，通常需要Alt+8, Alt+6, Alt+5 分别打开汇编、内存、寄存器窗口 那么，在GDB下如何做呢？ [/quote] GDB常用命令 调用gdb编译需要在cc后面加 -g参数再加-o； [root@redhat home]#gdb 调试文件：启动gdb (gdb) l ：（字母l）从第一行开始列出源码 (gdb) break n :在第n行处设置断点 (gdb) break func：在函数func()的入口处设置断点 (gdb) info break： 查看断点信息 (gdb) r：运行程序 (gdb) n：单步执行 (gdb) c：继续运行 (gdb) p 变量 ：打印变量的值 (gdb) bt：查看函数堆栈 (gdb) finish：退出函数 (gdb) shell 命令行：执行shell命令行 (gdb) set args 参数:指定运行时的参数 (gdb) show args：查看设置好的参数 (gdb) show paths:查看程序运行路径；            set environment varname [=value] 设置环境变量。如：set env USER=hchen；             show environment [varname] 查看环境变量； (gdb) cd 相当于shell的cd; (gdb)pwd ：显示当前所在目录 (gdb)info program： 来查看程序的是否在运行，进程号，被暂停的原因。 (gdb)clear 行号n：清除第n行的断点 (gdb)delete 断点号n：删除第n个断点 (gdb)disable 断点号n：暂停第n个断点 (gdb)enable 断点号n：开启第n个断点 (gdb)step：单步调试如果有函数调用，则进入函数；与命令n不同，n是不进入调用的函数的 list ：简记为 l ，其作用就是列出程序的源代码，默认每次显示10行。 list 行号：将显示当前文件以“行号”为中心的前后10行代码，如：list 12 list 函数名：将显示“函数名”所在函数的源代码，如：list main list ：不带参数，将接着上一次 list 命令的，输出下边的内容。 注意 ：如果运行list 命令得到类似如下的打印，那是因为在编译程序时没有加入 -g 选项： (gdb) list 1       ../sysdeps/i386/elf/start.S: No such file or directory.         in ../sysdeps/i386/elf/start.S run：简记为 r ，其作用是运行程序，当遇到断点后，程序会在断点处停止运行，等待用户输入下一步的命令。 回车：重复上一条命令。 set args：设置运行程序时的命令行参数，如：set args 33 55 show args：显示命令行参数 continue：简讯为 c ，其作用是继续运行被断点中断的程序。 break：为程序设置断点。 break 行号：在当前文件的“行号”处设置断点，如：break  33 break 函数名：在用户定义的函数“函数名”处设置断点，如：break cb_button info breakpoints：显示当前程序的断点设置情况 disable breakpoints Num：关闭断点“Num”，使其无效，其中“Num”为 info breakpoints 中显示的对应值 enable breakpoints Num：打开断点“Num”，使其重新生效 step：简记为 s ，单步跟踪程序，当遇到函数调用时，则进入此函数体（一般只进入用户自定义函数）。 next：简记为 n，单步跟踪程序，当遇到函数调用时，也不进入此函数体；此命令同 step 的主要区别是，step 遇到用户自定义的函数，将步进到函数中去运行，而 next 则直接调用函数，不会进入到函数体内。 until：当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。 finish： 运行程序，直到当前函数完成返回，并打印函数返回时的堆栈地址和返回值及参数值等信息。 stepi或nexti：单步跟踪一些机器指令。 print 表达式：简记为 p ，其中“表达式”可以是任何当前正在被测试程序的有效表达式，比如当前正在调试C语言的程序，那么“表达式”可以是任何C语言的有效表达式，包括数字，变量甚至是函数调用。 print a：将显示整数 a 的值 print ++a：将把 a 中的值加1,并显示出来 print name：将显示字符串 name 的值 print gdb_test(22)：将以整数22作为参数调用 gdb_test() 函数 print gdb_test(a)：将以变量 a 作为参数调用 gdb_test() 函数 bt：显示当前程序的函数调用堆栈。 display 表达式：在单步运行时将非常有用，使用display命令设置一个表达式后，它将在每次单步进行指令后，紧接着输出被设置的表达式及值。如： display a watch 表达式：设置一个监视点，一旦被监视的“表达式”的值改变，gdb将强行终止正在被调试的程序。如： watch a kill：将强行终止当前正在调试的程序 help 命令：help 命令将显示“命令”的常用帮助信息 call 函数(参数)：调用“函数”，并传递“参数”，如：call  gdb_test(55) layout：用于分割窗口，可以一边查看代码，一边测试： layout src：显示源代码窗口 layout asm：显示反汇编窗口 layout regs：显示源代码/反汇编和CPU寄存器窗口 layout split：显示源代码和反汇编窗口 Ctrl + L：刷新窗口 quit：简记为 q ，退出gdb 当然，gdb的功能远不止这些，包括多进程/多线程/信号/远程调试等功能在这里均没有提及，有需要的读者可以参考其它信息 本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/pizi0475/archive/2011/03/08/6232749.aspx 用gdb查看内存 格式: x /nfu <addr> 说明 x 是 examine 的缩写 n表示要显示的内存单元的个数 f表示显示方式, 可取如下值 x 按十六进制格式显示变量。 d 按十进制格式显示变量。 u 按十进制格式显示无符号整型。 o 按八进制格式显示变量。 t 按二进制格式显示变量。 a 按十六进制格式显示变量。 i 指令地址格式 c 按字符格式显示变量。 f 按浮点数格式显示变量。 u表示一个地址单元的长度 b表示单字节， h表示双字节， w表示四字节， g表示八字节 Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal), t(binary), f(float), a(address), i(instruction), c(char) and s(string). Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes) 举例 x/3uh buf 表示从内存地址buf读取内容， h表示以双字节为一个单位， 3表示三个单位， u表示按十六进制显示 例子： n是个局部变量 Breakpoint 1, main (argc=1, argv=0xbffff3a4) at calc.c:7 7        int n = atoi(argv[1]); (gdb) print &n $1 = (int *) 0xbffff2ec (gdb) x 0xbffff2ec 0xbffff2ec:    0x00282ff4 (gdb) print * (int *) 0xbffff2ec $2 = 2633716 (gdb) x /4xw 0xbffff2ec 0xbffff2ec:    0x00282ff4    0x080484e0    0x00000000    0xbffff378 (gdb) x /4dw 0xbffff2ec 0xbffff2ec:    2633716    134513888    0    -1073745032 (gdb) 本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/cgipro/archive/2010/12/01/6047504.aspx  比较详细的GDB用法说明http://blog.csdn.net/eroswang/article/details/2425242  gdb主要调试的是C/C++的程序。要调试C/C++的程序，首先在编译时，必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数即可。如： [david@DAVID david]$ gcc -g hello.c -o hello [david@DAVID david]$ g++ -g hello.cpp -o hello 如果没有-g，将看不见程序的函数名和变量名，代替它们的全是运行时的内存地址。当用-g把调试信息加入，并成功编译目标代码以后，看看如何用gdb来调试。 启动gdb的方法有以下几种： 1. gdb <program> program也就是执行文件，一般在当前目录下。 2. gdb <program> core 用gdb同时调试一个运行程序和core文件，core是程序非法执行后，core dump后产生的文件。 3. gdb <program> <PID> 如果程序是一个服务程序，那么可以指定这个服务程序运行时的进程ID。gdb会自动attach上去，并调试它。program应该在PATH环境变量中搜索得到。 gdb启动时，可以加上一些gdb的启动开关，详细的开关可以用gdb -help查看。下面只列举一些比较常用的参数： -symbols <file> -s <file> 从指定文件中读取符号表。 -se file 从指定文件中读取符号表信息，并把它用在可执行文件中。 -core <file> -c <file> 调试时core dump的core文件。 -directory <directory> -d <directory> 加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。 [/quote]  救人救到底 送佛送到西  求emacs+gdb配置全餐文档！！！

建议重新理一理“地址和值”

引用char *p;   *p =  ... p是野指针，不能修改

引用问题1：此时为何会core dump? 因为p的值是一个char‘l’， 不是一个有效地址， 属于野指针。

引用 10 楼 javashit 的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] 理解和讨论之前请先学会如何观察！  学会使用GDB单步调试才是楼主的当务之急！  我完全同意你说的 在VC环境下，通常需要Alt+8, Alt+6, Alt+5 分别打开汇编、内存、寄存器窗口 那么，在GDB下如何做呢？ [/quote] GDB常用命令 调用gdb编译需要在cc后面加 -g参数再加-o； [root@redhat home]#gdb 调试文件：启动gdb (gdb) l ：（字母l）从第一行开始列出源码 (gdb) break n :在第n行处设置断点 (gdb) break func：在函数func()的入口处设置断点 (gdb) info break： 查看断点信息 (gdb) r：运行程序 (gdb) n：单步执行 (gdb) c：继续运行 (gdb) p 变量 ：打印变量的值 (gdb) bt：查看函数堆栈 (gdb) finish：退出函数 (gdb) shell 命令行：执行shell命令行 (gdb) set args 参数:指定运行时的参数 (gdb) show args：查看设置好的参数 (gdb) show paths:查看程序运行路径；            set environment varname [=value] 设置环境变量。如：set env USER=hchen；             show environment [varname] 查看环境变量； (gdb) cd 相当于shell的cd; (gdb)pwd ：显示当前所在目录 (gdb)info program： 来查看程序的是否在运行，进程号，被暂停的原因。 (gdb)clear 行号n：清除第n行的断点 (gdb)delete 断点号n：删除第n个断点 (gdb)disable 断点号n：暂停第n个断点 (gdb)enable 断点号n：开启第n个断点 (gdb)step：单步调试如果有函数调用，则进入函数；与命令n不同，n是不进入调用的函数的 list ：简记为 l ，其作用就是列出程序的源代码，默认每次显示10行。 list 行号：将显示当前文件以“行号”为中心的前后10行代码，如：list 12 list 函数名：将显示“函数名”所在函数的源代码，如：list main list ：不带参数，将接着上一次 list 命令的，输出下边的内容。 注意 ：如果运行list 命令得到类似如下的打印，那是因为在编译程序时没有加入 -g 选项： (gdb) list 1       ../sysdeps/i386/elf/start.S: No such file or directory.         in ../sysdeps/i386/elf/start.S run：简记为 r ，其作用是运行程序，当遇到断点后，程序会在断点处停止运行，等待用户输入下一步的命令。 回车：重复上一条命令。 set args：设置运行程序时的命令行参数，如：set args 33 55 show args：显示命令行参数 continue：简讯为 c ，其作用是继续运行被断点中断的程序。 break：为程序设置断点。 break 行号：在当前文件的“行号”处设置断点，如：break  33 break 函数名：在用户定义的函数“函数名”处设置断点，如：break cb_button info breakpoints：显示当前程序的断点设置情况 disable breakpoints Num：关闭断点“Num”，使其无效，其中“Num”为 info breakpoints 中显示的对应值 enable breakpoints Num：打开断点“Num”，使其重新生效 step：简记为 s ，单步跟踪程序，当遇到函数调用时，则进入此函数体（一般只进入用户自定义函数）。 next：简记为 n，单步跟踪程序，当遇到函数调用时，也不进入此函数体；此命令同 step 的主要区别是，step 遇到用户自定义的函数，将步进到函数中去运行，而 next 则直接调用函数，不会进入到函数体内。 until：当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。 finish： 运行程序，直到当前函数完成返回，并打印函数返回时的堆栈地址和返回值及参数值等信息。 stepi或nexti：单步跟踪一些机器指令。 print 表达式：简记为 p ，其中“表达式”可以是任何当前正在被测试程序的有效表达式，比如当前正在调试C语言的程序，那么“表达式”可以是任何C语言的有效表达式，包括数字，变量甚至是函数调用。 print a：将显示整数 a 的值 print ++a：将把 a 中的值加1,并显示出来 print name：将显示字符串 name 的值 print gdb_test(22)：将以整数22作为参数调用 gdb_test() 函数 print gdb_test(a)：将以变量 a 作为参数调用 gdb_test() 函数 bt：显示当前程序的函数调用堆栈。 display 表达式：在单步运行时将非常有用，使用display命令设置一个表达式后，它将在每次单步进行指令后，紧接着输出被设置的表达式及值。如： display a watch 表达式：设置一个监视点，一旦被监视的“表达式”的值改变，gdb将强行终止正在被调试的程序。如： watch a kill：将强行终止当前正在调试的程序 help 命令：help 命令将显示“命令”的常用帮助信息 call 函数(参数)：调用“函数”，并传递“参数”，如：call  gdb_test(55) layout：用于分割窗口，可以一边查看代码，一边测试： layout src：显示源代码窗口 layout asm：显示反汇编窗口 layout regs：显示源代码/反汇编和CPU寄存器窗口 layout split：显示源代码和反汇编窗口 Ctrl + L：刷新窗口 quit：简记为 q ，退出gdb 当然，gdb的功能远不止这些，包括多进程/多线程/信号/远程调试等功能在这里均没有提及，有需要的读者可以参考其它信息 本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/pizi0475/archive/2011/03/08/6232749.aspx 用gdb查看内存 格式: x /nfu <addr> 说明 x 是 examine 的缩写 n表示要显示的内存单元的个数 f表示显示方式, 可取如下值 x 按十六进制格式显示变量。 d 按十进制格式显示变量。 u 按十进制格式显示无符号整型。 o 按八进制格式显示变量。 t 按二进制格式显示变量。 a 按十六进制格式显示变量。 i 指令地址格式 c 按字符格式显示变量。 f 按浮点数格式显示变量。 u表示一个地址单元的长度 b表示单字节， h表示双字节， w表示四字节， g表示八字节 Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal), t(binary), f(float), a(address), i(instruction), c(char) and s(string). Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes) 举例 x/3uh buf 表示从内存地址buf读取内容， h表示以双字节为一个单位， 3表示三个单位， u表示按十六进制显示 例子： n是个局部变量 Breakpoint 1, main (argc=1, argv=0xbffff3a4) at calc.c:7 7        int n = atoi(argv[1]); (gdb) print &n $1 = (int *) 0xbffff2ec (gdb) x 0xbffff2ec 0xbffff2ec:    0x00282ff4 (gdb) print * (int *) 0xbffff2ec $2 = 2633716 (gdb) x /4xw 0xbffff2ec 0xbffff2ec:    0x00282ff4    0x080484e0    0x00000000    0xbffff378 (gdb) x /4dw 0xbffff2ec 0xbffff2ec:    2633716    134513888    0    -1073745032 (gdb) 本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/cgipro/archive/2010/12/01/6047504.aspx  比较详细的GDB用法说明http://blog.csdn.net/eroswang/article/details/2425242  gdb主要调试的是C/C++的程序。要调试C/C++的程序，首先在编译时，必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数即可。如： [david@DAVID david]$ gcc -g hello.c -o hello [david@DAVID david]$ g++ -g hello.cpp -o hello 如果没有-g，将看不见程序的函数名和变量名，代替它们的全是运行时的内存地址。当用-g把调试信息加入，并成功编译目标代码以后，看看如何用gdb来调试。 启动gdb的方法有以下几种： 1. gdb <program> program也就是执行文件，一般在当前目录下。 2. gdb <program> core 用gdb同时调试一个运行程序和core文件，core是程序非法执行后，core dump后产生的文件。 3. gdb <program> <PID> 如果程序是一个服务程序，那么可以指定这个服务程序运行时的进程ID。gdb会自动attach上去，并调试它。program应该在PATH环境变量中搜索得到。 gdb启动时，可以加上一些gdb的启动开关，详细的开关可以用gdb -help查看。下面只列举一些比较常用的参数： -symbols <file> -s <file> 从指定文件中读取符号表。 -se file 从指定文件中读取符号表信息，并把它用在可执行文件中。 -core <file> -c <file> 调试时core dump的core文件。 -directory <directory> -d <directory> 加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。

引用 9 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！  学会使用GDB单步调试才是楼主的当务之急！  我完全同意你说的 在VC环境下，通常需要Alt+8, Alt+6, Alt+5 分别打开汇编、内存、寄存器窗口 那么，在GDB下如何做呢？

跟coredump无关，就printf而言，格式说明符和提供的参数要配套，否则就是错误； 比如%s，你就得提供一个指向null结尾的char指针。

我不太同意3楼，因为他认为每个例子的"Hello World"在常量存储区中。

/*************************************************************************     > File Name: p.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年10月21日 星期二 18时07分32秒  ************************************************************************/ #include<stdlib.h> #include<stdio.h> int main() { 	char *p；     p = (char *)malloc(sizeof (char));     *p ="Hello World"[3]; 	printf("%c\n",p); 	return 0; } 这个没问题，不过在我的机器上显示不出来，也不报错

第一个问题是因为类型不一致. 后面的问题是p还没指向任何东西,你就上*p,能不出问题吗?  两种方案: char A; char *p = &A; *p = "hello world"[3]; ... or char *p = &"hello world"[3];

#include <stdio.h> int main() {   char *p;   *p = "hello world"[3];//悬挂指针啊   printf("%c\n", "hello"[3]);   return 0; }

幸亏我有耐心，你还是不懂C指针啊！！！  #include <stdio.h>  int main(int argc ,char *argv[]) {   /********************************/   // (block 1) is equal to (block 2)   { // block 1     char *p = &"Hello World"[3];     printf("%s\n", p);   }    { // block 2     char const *arr = "Hello World";     char *p =  &arr[3];     printf("%s\n", p);   }   /********************************/    /********************************/   {     char const *arr = "Hello World";     char *p = arr[3]; // shit, what the f..k!     printf("%s\n", p); // coredump!   }   /********************************/    /********************************/   {     char const *arr = "Hello World";     char *p;     *p = arr[3]; // shit, is `p' a valid pointer!     printf("%s\n", p); // coredump!     printf("%c\n", *p); // coredump!   }   /********************************/    return 0;   }

你要想引用"Helloe World"这个常量的地址，首先你就要将他保存在内存里面。 再看你的代码 #include <stdio.h> int main() { //下2行有问题，这里的"Hello World"只是一个临时存在的常量而已，只是一个字面值，这两条语句结束他的生存期就结束了。 //就像a=1一样，1 更本就不存在啊，只是a存在   char *p;   p = &"hello world"[3];   printf("%s\n", p);   return 0; }

你看这个代码 /*************************************************************************     > File Name: p.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年10月21日 星期二 18时07分32秒  ************************************************************************/  #include<stdio.h> int main() { 	char p = "hello world"[3]; 	printf("%c\n",p); 	return 0; }


Question: 【求助】TC编译环境下window函数如何突破25行80列限制

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

textmode                         <CONIO.H>  Changes screen mode (in text mode)   Declaration:  void textmode(int newmode);   Remarks: textmode selects a specific text mode.  You can give the text mode (the argument newmode) by using a symbolic constant from the enumeration type text_modes (defined in CONIO.H).  If you use these constants, you must include CONIO.H.  When textmode is called, the current window is reset to the entire screen, and the current text attributes are reset to normal, corresponding to a call to normvideo.  Specifying LASTMODE to textmode causes the most recently selected text mode to be reselected.  textmode should be used only when the screen is in text mode (presumably to change to a different text mode).  When the screen is in graphics mode, use restorecrtmode to escape temporarily to text mode.   Return Value:  None   See Also:   gettextinfo   window   Example:   #include <conio.h>   int main(void)  {     textmode(BW40);     cprintf("ABC");     getch();      textmode(C40);     cprintf("ABC");     getch();      textmode(BW80);     cprintf("ABC");     getch();      textmode(C80);     cprintf("ABC");     getch();      textmode(MONO);     cprintf("ABC");     getch();      return 0;  }   text_modes                        <CONIO.H>  Enum: Standard video modes   Constant |Value| Text Mode  LASTMODE | -1  | Previous text mode  BW40     |  0  | Black and white       40 columns  C40      |  1  | Color                 40 columns  BW80     |  2  | Black and white       80 columns  C80      |  3  | Color                 80 columns  MONO     |  7  | Monochrome            80 columns  C4350    | 64  | EGA and               43-line           |     | VGA                   50-line

搜“Native Application 开发详解”

好的，我试试用VGA。VGA之前也搜索过做过，主要没找到实例，所以学它的进展缓慢。

http://www.columbia.edu/~em36/wpdos/videomodes.txt 这个也许TC本身做不到了，要改VGA的设置，也许？

用TC的原因在于写DOS界面的时候比较方便，可以加菜单窗口颜色等等。VC可以有这些功能吗？我要做的是类似一个叫spfdisk的tool，多数情况下是要在开机进F9进DOS界面执行的。

http://www.devtrends.com/index.php/linux-console-modes-80x25-really/ 还是自行搜搜vga相关的知识吧，搜索也是种学习。

看七楼。TC换VC

引用 6 楼 zhao4zhong1 的回复: textmode                         <CONIO.H>   #include <conio.h>   int main(void)  {     textmode(BW40);     cprintf("ABC");     getch();      textmode(C40);     cprintf("ABC");     getch();      textmode(BW80);     cprintf("ABC");     getch();      textmode(C80);     cprintf("ABC");     getch();      textmode(MONO);     cprintf("ABC");     getch();      return 0;  }    textmode(BW80); textmode(c80);textmode(MONO);三种模式在执行的时候还是只能输出80列数据，我希望有100列甚至更多。

引用 5 楼 ForestDB 的回复:纯字符的显示器的分辨率不就是80 * 25，133 * 40？这么几种么？ 可以看看vga相关的知识。我的现在是80*25，有什么办法可以换成133*40吗？

珍惜下生命，不要浪费在TC上。

研究一下INT 10h

你该换个思路，我记得以前玩DOS游戏的时候画面很好看啊，应该是一个像素一个像素画出来的，你看看有没有描绘像素点的函数，这样就不需要考虑80*25的限制了。

这是计算题，和编译器有关系么？ 分辨率，可以缩放，应该问题不大吧


Question: 请教个很水的问题，谢谢。。。

引用 14 楼 xihu1364 的回复:不能通过 因为dest[1000] 没初始化  所以join中 必须加上 dest[nStrLen] = '\0'; 引用 15 楼 Saleayas 的回复:void join(char* strs[], int strNum, char *dest) {     int i; if (strNum > 0) strcpy(dest, strs[i]);     for(i=1;i<strNum;i++)         strcat(dest,strs[i]); }   确实是初始化问题，改过后可以通过了，谢谢你们，初始化这个问题应该引起重视的。。。

引用 11 楼 xihu1364 的回复:评判??   void join(char* strs[], int strNum, char *dest) { 	int i; 	for(i=0;i<strNum;i++) 		strcat(dest,strs[i]); }  void main() { 	char* ss[] = {"hello,","welcome to ","C context!"}; 	char dest[1000] = {0}; 	join(ss,3,dest); 	printf("%s\n",dest);  	while (1) 	{ 		Sleep(100); 	} }   正常编译，运行结果正常  #Include <string.h> void join(char const* strs[], int strNum, char *dest) { 	int i;         strcpy(dest, strs[0]); 	for(i=1;i < strNum;i++) 		strcat(dest,strs[i]); }  int main(void) { 	char const* ss[] = {"hello,","welcome to ","C context!"}; 	char dest[1000];//= {0}; 	join(ss, sizeof(ss)/sizeof(char const*),dest); 	printf("%s\n",dest);  	//while (1) 	//{ 	//	Sleep(100); 	//}         return 0; }

看到上面的回复了   void join(char* strs[], int strNum, char *dest) { 	int nStrLen = 0;  	for(int i=0;i<strNum;i++) 	{ 		nStrLen += strlen(strs[i]);  		strcat(dest,strs[i]); 	} 	dest[nStrLen] = '\0'; }  void main() { 	char* ss[] = {"hello,","welcome to ","C context!"}; 	char dest[1000]; 	join(ss,3,dest); 	printf("%s\n",dest); }

引用 11 楼 xihu1364 的回复:评判??   void join(char* strs[], int strNum, char *dest) { 	int i; 	for(i=0;i<strNum;i++) 		strcat(dest,strs[i]); }  void main() { 	char* ss[] = {"hello,","welcome to ","C context!"}; 	char dest[1000] = {0}; 	join(ss,3,dest); 	printf("%s\n",dest);  	while (1) 	{ 		Sleep(100); 	} }   正常编译，运行结果正常 我也是觉得奇怪，应该是这个判题的系统问题吧，哎。。

引用 8 楼 march0912 的回复:[quote=引用 7 楼 march0912 的回复:] strcat(dest,str[i]); str[i]是什么？ 当i = 0的时候，str[0] = "hello",它只是这个字符串的首地址，你strcat这个首地址是个什么意思  看错了[/quote]那个评判系统是这样提示的：编译成功，但无法通过评判。

引用 6 楼 starytx 的回复:void join(char* strs[], int strNum, char *dest){  int i;  for(i=0;i<strNum;i++)  strcat(dest,strs[i]);  难道是这个原因？ 不是，这个应该是我发帖时打错的，不好意思。

引用 7 楼 march0912 的回复:strcat(dest,str[i]); str[i]是什么？ 当i = 0的时候，str[0] = "hello",它只是这个字符串的首地址，你strcat这个首地址是个什么意思  看错了

引用 4 楼 Saleayas 的回复:正确的写法应该是： char dest[1000]; // 这里需要清零。  但是如果使用者没有清零。 那么 join 中，你也可以清零。 因为 strcat 需要 dest 有字符串的终止符。 但是这个题目是在一个考试的判断系统，题目应该是只需要我们书写join（）函数的实现，main（）函数是题目系统给定的，我也不知道是怎么样的，只要join函数写对了，题目就通过。。

引用 1 楼 Saleayas 的回复:dest  需要初始化。怎么初始化。这个是传进来的值，不是应该在main（）里面初始化的吗。题目的意思是只要写join这个函数，系统会自动判断你写得对还是错，结果显示：编译通过，但没有核实正确。

然后呢？？？

dest  需要初始化。


Question: 关于位运算，请教一个问题

仅供参考#include <stdio.h>  #define WIRTE_UINT(des ,x ,pos ,len)  (                                   \     (des)                                                                 \     &                                                                     \        ~(                                /* 除要修改的位为0，其余都为1 */ \             (                                                             \                 (1<<(len))-1             /* 长度为len位的1             */ \             )                                                             \             <<(32-(pos)-(len))           /* 左移32-(pos)-(len)位       */ \         )                                                                 \     |                                                                     \         (                                                                 \             (x)                                                           \             <<(32-(pos)-(len))                                            \         )                                                                 \ ) #define READ_UINT(src ,pos ,len)      (                                   \     (                                                                     \         (                                                                 \             (unsigned)(src)                                               \         )                                                                 \         >>(32-(pos)-(len))               /* 逻辑右移32-(pos)-(len)位   */ \     )                                                                     \     &                                                                     \     (                                                                     \         (1<<(len))-1                     /* 长度为len位的1             */ \     )                                                                     \ )  int main()                              //                1111111111222222222233 {                                       //bit   01234567890123456789012345678901     unsigned int des = 0x661;           //      00000000000000000000011001100001     unsigned int r;      des = WIRTE_UINT(des ,3 ,28 ,2);    //      00000000000000000000011001101101     printf("des==0x%08X\n",des);     r = READ_UINT(des ,28 ,2);     printf("r==%d\n",r);     return 0; } //des==0x0000066D //r==3

引用 17 楼 u013163178 的回复:楼主看下面，找到灵感没有 00100100&1 ->00000000; 00100100& 10 -> 00000000; 00100100& 100 ->00000100; 00100100& 1000 ->00000000; 00100100& 10000 ->00000000; 00100100& 100000 ->0010000;//就是这个把， 00100000<<1    -> 01000000 00100100& 1000000 ->00000000; 00100100& 00000000 -> 00000000; 是啊，因为不知道左边的第一个1在哪一位，所以用循环

这种事情还是参考hacker's delight靠谱一点。 印象里msb不像lsb有x&-x这种不需要循环/分治的做法的。

引用 17 楼 u013163178 的回复:楼主看下面，找到灵感没有 00100100&1 ->00000000; 00100100& 10 -> 00000000; 00100100& 100 ->00000100; 00100100& 1000 ->00000000; 00100100& 10000 ->00000000; 00100100& 100000 ->0010000;//就是这个把， 00100000<<1    -> 01000000 00100100& 1000000 ->00000000; 00100100& 00000000 -> 00000000;  貌似要循环才能搞定啊

引用 12 楼 xydp1987108 的回复:1楼是对的   应该是00010100 &00010000 = 0001 0000  而不是00010100 & 00001010  00010000 怎么得到的，原始数据是00001010

引用 6 楼 u013163178 的回复:你的意思是永远保存左边的第一个1吗，不管他在第几位  是这个意思，只保存最左边一个1，且最左边的要左移一位

死循环了，搞不不懂，谁能告诉为什么 /*************************************************************************     > File Name: hello.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年10月22日 星期三 18时10分02秒  ************************************************************************/  #include<stdio.h> int main() { 	unsigned char fun(unsigned char val); 	unsigned char n = 0X1; 	printf("%x\n",fun(n)); 	return 0; }  unsigned char fun(unsigned char val) { 	unsigned char tmp = 0X1; 	unsigned char a; 	while(tmp != 0); 	{ 		if(tmp & val) 		{ 			a = tmp & val; 			tmp = tmp<<1; 		} 		else 			tmp = tmp<<1; 	} 	return a; }

#include <stdio.h> unsigned char setfirstzero(unsigned char num) {     int len=0;     while(num!=0x01)     {         len++;         num=num>>1;     }     num=num<<len;     return num; }  int main() {     unsigned char num=0x11;     printf("%x\n",setfirstzero(num));     return 0; }

引用 5 楼 xuhb95083023 的回复:[quote=引用 3 楼 lovesmiles 的回复:] [quote=引用 2 楼 xuhb95083023 的回复:] [quote=引用 1 楼 lovesmiles 的回复:] 	short Data =0x0a;//定义 	Data = Data<<1; //左移 	Data = Data & 0x10;//只取最高位，其它位置0  这个和我原先想法一样，不过是错误的[/quote] 何解是错的？愿闻其详[/quote]  00001010 左移1位变成 00010100  00010100 & 00001010 = 00000000  你这红色 的是移位后的结果data,绿色的是什么东西？我的并运算是0x10，也就是00010000.和你的不一样。   答案错！[/quote]  看清楚了，你为什么还会和00001010做运算？

错了 没看清移动一位

Data  = (Data <<4)&0x80

引用 4 楼 user-7 的回复: unsigned func(unsigned val) { 	unsigned ret; 	val <<= 1; 	while (val) 	{ 		ret = val; 		val &= (val - 1); 	} 	 	return ret; }   修改下：  unsigned func(unsigned val) { 	unsigned ret = 0; 	val <<= 1; 	while (val) 	{ 		ret = val; 		val &= (val - 1); 	} 	 	return ret; }

你的意思是永远保存左边的第一个1吗，不管他在第几位

引用 3 楼 lovesmiles 的回复:[quote=引用 2 楼 xuhb95083023 的回复:] [quote=引用 1 楼 lovesmiles 的回复:] 	short Data =0x0a;//定义 	Data = Data<<1; //左移 	Data = Data & 0x10;//只取最高位，其它位置0  这个和我原先想法一样，不过是错误的[/quote] 何解是错的？愿闻其详[/quote]  00001010 左移1位变成 00010100  00010100 & 00001010 = 00000000   答案错！

引用 2 楼 xuhb95083023 的回复:[quote=引用 1 楼 lovesmiles 的回复:] 	short Data =0x0a;//定义 	Data = Data<<1; //左移 	Data = Data & 0x10;//只取最高位，其它位置0  这个和我原先想法一样，不过是错误的[/quote] 何解是错的？愿闻其详

引用 1 楼 lovesmiles 的回复:short Data =0x0a;//定义 	Data = Data<<1; //左移 	Data = Data & 0x10;//只取最高位，其它位置0  这个和我原先想法一样，不过是错误的


Question: C语言初学者问题在线测试过不去 求教

我才刚刚开始学 这章的内容就只有循环嵌套.能给点有用的思路行不行  我到现在连数组都没学 我编的'\b'又不给用  能不能只用循环  说一下这题的算法

建议楼主学习或复习《编译原理》词法分析中的有限状态自动机。

输入输出要完全和题目的一样，而且不能有多余的printf语句，输入和输出一般都是一次性完成的

我现在只想知道如何编写在 '(' 到 ')' 不输出字符且不输出括号,而在 '(' 到 '\n' 输出字符且输出左括号

引用 8 楼 u012061345 的回复:[quote=引用 6 楼 lovesmiles 的回复:] [quote=引用 5 楼 u012061345 的回复:] [quote=引用 1 楼 lovesmiles 的回复:] 错得离谱，题目是要求输入一行字符，你只能输入一个个字符。肯定通不过。  在线判题，这不是问题。不考虑效率的话。[/quote]  在线系统这才是关键问题，实现的功能必须和描术的一致，在线系统的测试数据就是一行一行输入。你处理不了就说明你不符号答案。  你有玩过这些在线系统没有？[/quote]  你可以做一个实验。[/quote] 只能呵呵了

引用 6 楼 lovesmiles 的回复:[quote=引用 5 楼 u012061345 的回复:] [quote=引用 1 楼 lovesmiles 的回复:] 错得离谱，题目是要求输入一行字符，你只能输入一个个字符。肯定通不过。  在线判题，这不是问题。不考虑效率的话。[/quote]  在线系统这才是关键问题，实现的功能必须和描术的一致，在线系统的测试数据就是一行一行输入。你处理不了就说明你不符号答案。  你有玩过这些在线系统没有？[/quote]  你可以做一个实验。

#include <stdio.h> int main() { 	char str[1000]; 	int i=0,j; 	char ch; 	gets(str); 	while(str[i]) 	{ 		if (str[i]!='(') 		printf("%c",str[i]); 		else 		{ 			j=i+1; 			while(str[j++]!=')'); 			i=j-1; 		} 		i++; 		 	} 	return 0; }

引用 5 楼 u012061345 的回复:[quote=引用 1 楼 lovesmiles 的回复:] 错得离谱，题目是要求输入一行字符，你只能输入一个个字符。肯定通不过。  在线判题，这不是问题。不考虑效率的话。[/quote]  在线系统这才是关键问题，实现的功能必须和描术的一致，在线系统的测试数据就是一行一行输入。你处理不了就说明你不符号答案。  你有玩过这些在线系统没有？

引用 1 楼 lovesmiles 的回复:错得离谱，题目是要求输入一行字符，你只能输入一个个字符。肯定通不过。  在线判题，这不是问题。不考虑效率的话。

括号嵌套的情况考虑过吗？

引用 2 楼 wax14111205058 的回复:那怎么输入一行字符？cin.getline

那怎么输入一行字符？

错得离谱，题目是要求输入一行字符，你只能输入一个个字符。肯定通不过。


Question: 这种定义函数的方法没见过,有没有人知道这是什么写法?

引用 1 楼 lovesmiles 的回复:这是c语言的K&R 定义方式，在C语言早期是用这种方式的，后来才变成我们常用的这种。  http://blog.chinaunix.net/uid-7426920-id-2627743.html   你的代码应该是很古老的代码了。  正解，原来 是这样的。。。

我表示没有见过，长见识了

C Function Definitions A function definition specifies the name of the function, the types and number of parameters it expects to receive, and its return type. A function definition also includes a function body with the declarations of its local variables, and the statements that determine what the function does.   Syntax  translation-unit :  external-declaration translation-unit external-declaration  external-declaration : /* Allowed only at external (file) scope */  function-definition declaration  function-definition : /* Declarator here is the function declarator */  declaration-specifiersopt attribute-seqopt declarator declaration-listopt compound-statement  /* attribute-seq is Microsoft Specific */  Prototype parameters are:  declaration-specifiers :  storage-class-specifier declaration-specifiers opt  type-specifier declaration-specifiers opt type-qualifier declaration-specifiers opt  declaration-list :  declaration declaration-list declaration  declarator :  pointeropt direct-declarator  direct-declarator : /* A function declarator */   direct-declarator ( parameter-type-list ) /* New-style declarator */ direct-declarator ( identifier-list opt ) /* Obsolete-style declarator */  The parameter list in a definition uses this syntax:   parameter-type-list : /* The parameter list */  parameter-list parameter-list , ...  parameter-list :  parameter-declaration parameter-list , parameter-declaration  parameter-declaration :  declaration-specifiers declarator declaration-specifiers abstract-declarator opt  The parameter list in an old-style function definition uses this syntax:  identifier-list : /* Used in obsolete-style function definitions and declarations */  identifier identifier-list , identifier  The syntax for the function body is:  compound-statement : /* The function body */   { declaration-list opt statement-list opt }  The only storage-class specifiers that can modify a function declaration are extern and static. The extern specifier signifies that the function can be referenced from other files; that is, the function name is exported to the linker. The static specifier signifies that the function cannot be referenced from other files; that is, the name is not exported by the linker. If no storage class appears in a function definition, extern is assumed. In any case, the function is always visible from the definition point to the end of the file.   The optional declaration-specifiers and mandatory declarator together specify the function’s return type and name. The declarator is a combination of the identifier that names the function and the parentheses following the function name. The optional attribute-seq nonterminal is a Microsoft-specific feature defined in Function Attributes.   The direct-declarator (in the declarator syntax) specifies the name of the function being defined and the identifiers of its parameters. If the direct-declarator includes a parameter-type-list, the list specifies the types of all the parameters. Such a declarator also serves as a function prototype for later calls to the function.   A declaration in the declaration-list in function definitions cannot contain a storage-class-specifier other than register. The type-specifier in the declaration-specifiers syntax can be omitted only if the register storage class is specified for a value of int type.   The compound-statement is the function body containing local variable declarations, references to externally declared items, and statements.   The sections Function Attributes, Storage Class, Return Type, Parameters, and Function Body describe the components of the function definition in detail.


Question: 二维数组作参数问题

引用 8 楼 gzvincentlee 的回复:[quote=引用 6 楼 r_Jimy 的回复:] [quote=引用 5 楼 gzvincentlee 的回复:] [quote=引用 3 楼 r_Jimy 的回复:]  bool find(int array[MAXLEN][MAXLEN],int number,int x,int y,int nlen) {     if(x > nlen-1 || y < 0)         return false;      if(array[x][y] == number)     {         printf("the number %d is found!\n",number);         printf("x = %d ; y = %d\n",x,y);	         return true;	     }     else if(array[x][y] > number)     {         //return find(array[MAXLEN][MAXLEN],number,x,y-1,nlen);你直接传入array[10][10]越界了，下同         return find(array,number,x,y-1,nlen);     }     else if(array[x][y] < number)     {         //return find(array[MAXLEN][MAXLEN],number,x+1,y,nlen);         return find(array,number,x+1,y,nlen;     } }  谢谢你。你说的是对的。但是我想知道为什么find函数定义的时候形参又可以是array[10][10]呢？[/quote] 形参只用于指示参数类型，定义成int array[][]也可以，具体指定是10可以方便知道数组只有10个元素，这里的参数是数组 名，即指向二维数组首地址的指针，通过这个指针可以访问整个数组 而函数调用传入的参数也应是一个地址，你这时传入一个array[3][5]，它的实际上是数组里的元素，假设数组初始化array[3][5]=0;那么函数里面会把这个0作为地址参数来访问，即使刚好这里的值可以被程序访问，读到的值也不会是array数组的内容 假设函数声明为void  fun(int arr[]); 此时外面定义数组 int arr1[5]; int arr2[6] 这时都可以这样调用这个函数 fun(arr1); fun(arr2); 传入的数组地址不同，就能访问不同的数组了 [/quote] 谢谢，你说的大概意思我明白。但是定义成int array[][]编译是会出错的。要定义成int array[][10]，或者int array[10][10]。但是我想知道这个10有什么作用？我定义成int array[3][3]的时候我输入的时候输入二维数组的时候元素为4*4也可以运行。[/quote]   int array[3][3]会被编译器理解成int array[][3]，还是一个数组指针。上前面一样。 你还可以这样。int (&array)[10][10];这个就是真正的int array[10][10]了。数组的引用。

引用 6 楼 r_Jimy 的回复:[quote=引用 5 楼 gzvincentlee 的回复:] [quote=引用 3 楼 r_Jimy 的回复:]  bool find(int array[MAXLEN][MAXLEN],int number,int x,int y,int nlen) {     if(x > nlen-1 || y < 0)         return false;      if(array[x][y] == number)     {         printf("the number %d is found!\n",number);         printf("x = %d ; y = %d\n",x,y);	         return true;	     }     else if(array[x][y] > number)     {         //return find(array[MAXLEN][MAXLEN],number,x,y-1,nlen);你直接传入array[10][10]越界了，下同         return find(array,number,x,y-1,nlen);     }     else if(array[x][y] < number)     {         //return find(array[MAXLEN][MAXLEN],number,x+1,y,nlen);         return find(array,number,x+1,y,nlen;     } }  谢谢你。你说的是对的。但是我想知道为什么find函数定义的时候形参又可以是array[10][10]呢？[/quote] 形参只用于指示参数类型，定义成int array[][]也可以，具体指定是10可以方便知道数组只有10个元素，这里的参数是数组 名，即指向二维数组首地址的指针，通过这个指针可以访问整个数组 而函数调用传入的参数也应是一个地址，你这时传入一个array[3][5]，它的实际上是数组里的元素，假设数组初始化array[3][5]=0;那么函数里面会把这个0作为地址参数来访问，即使刚好这里的值可以被程序访问，读到的值也不会是array数组的内容 假设函数声明为void  fun(int arr[]); 此时外面定义数组 int arr1[5]; int arr2[6] 这时都可以这样调用这个函数 fun(arr1); fun(arr2); 传入的数组地址不同，就能访问不同的数组了 [/quote] 谢谢，你说的大概意思我明白。但是定义成int array[][]编译是会出错的。要定义成int array[][10]，或者int array[10][10]。但是我想知道这个10有什么作用？我定义成int array[3][3]的时候我输入的时候输入二维数组的时候元素为4*4也可以运行。

其实二维数组像 char array[2][3]; 就是连续的6个字节的内存，传一个指针，一个总长度就可以了。

引用 5 楼 gzvincentlee 的回复:[quote=引用 3 楼 r_Jimy 的回复:]  bool find(int array[MAXLEN][MAXLEN],int number,int x,int y,int nlen) {     if(x > nlen-1 || y < 0)         return false;      if(array[x][y] == number)     {         printf("the number %d is found!\n",number);         printf("x = %d ; y = %d\n",x,y);	         return true;	     }     else if(array[x][y] > number)     {         //return find(array[MAXLEN][MAXLEN],number,x,y-1,nlen);你直接传入array[10][10]越界了，下同         return find(array,number,x,y-1,nlen);     }     else if(array[x][y] < number)     {         //return find(array[MAXLEN][MAXLEN],number,x+1,y,nlen);         return find(array,number,x+1,y,nlen;     } }  谢谢你。你说的是对的。但是我想知道为什么find函数定义的时候形参又可以是array[10][10]呢？[/quote] 形参只用于指示参数类型，定义成int array[][]也可以，具体指定是10可以方便知道数组只有10个元素，这里的参数是数组 名，即指向二维数组首地址的指针，通过这个指针可以访问整个数组 而函数调用传入的参数也应是一个地址，你这时传入一个array[3][5]，它的实际上是数组里的元素，假设数组初始化array[3][5]=0;那么函数里面会把这个0作为地址参数来访问，即使刚好这里的值可以被程序访问，读到的值也不会是array数组的内容 假设函数声明为void  fun(int arr[]); 此时外面定义数组 int arr1[5]; int arr2[6] 这时都可以这样调用这个函数 fun(arr1); fun(arr2); 传入的数组地址不同，就能访问不同的数组了

引用 3 楼 r_Jimy 的回复: bool find(int array[MAXLEN][MAXLEN],int number,int x,int y,int nlen) {     if(x > nlen-1 || y < 0)         return false;      if(array[x][y] == number)     {         printf("the number %d is found!\n",number);         printf("x = %d ; y = %d\n",x,y);	         return true;	     }     else if(array[x][y] > number)     {         //return find(array[MAXLEN][MAXLEN],number,x,y-1,nlen);你直接传入array[10][10]越界了，下同         return find(array,number,x,y-1,nlen);     }     else if(array[x][y] < number)     {         //return find(array[MAXLEN][MAXLEN],number,x+1,y,nlen);         return find(array,number,x+1,y,nlen;     } }  谢谢你。你说的是对的。但是我想知道为什么find函数定义的时候形参又可以是array[10][10]呢？

引用 1 楼 zhao4zhong1 的回复:思考一下为什么没人把整个互联网内容当函数参数传来传去呢？噗

find函数写的有问题

思考一下为什么没人把整个互联网内容当函数参数传来传去呢？


Question: 请教数据结构的两个问题

编译器都要使用词法分析器。


Question: 已知两个链表head1 和head2 各自有序，请把它们合并成一个链表依然有序

node *Merge(node *head1,node *head2) { 	node *p1,*p2,*head; 	if (head1->next->data<head2->next->data) 	{ 		head = head1; 		p1 = head1->next; 		p2 = head2->next; 	} 	else 	{ 		head = head2; 		p1 = head1->next; 		p2 = head2->next; 	} 	node *pcur = head; 	while(p1!=NULL&&p2!=NULL) 	{ 		if (p1->data<=p2->data) 		{ 			pcur->next = p1; 			pcur = p1; 			p1 = p1->next; 		} 		else 		{ 			pcur->next = p2; 			pcur = p2; 			p2 = p2->next; 		} 		if (p1!=NULL) 		{ 			pcur->next = p1; 		} 		if (p2!=NULL) 		{ 			pcur->next = p2; 		} 	} 	return head; }

递归就更简单了  node *func(node *head1, node *head2) { 	node *head; 	node **pnode; 	if (NULL == head1) 	{ 		return head2; 	} 	if (NULL == head2) 	{ 		return head1; 	} 	pnode = head1->data < head2->data ? &head1 : &head2; 	head = *pnode; 	*pnode = (*pnode)->next; 	head->next = func(head1, head2); 	return head; }

引用 4 楼 hello_world000 的回复:随手写了一个，没测试  node *func(node *head1, node *head2) { 	node *head, *cur; 	node **pnode; 	if (NULL == head1) 	{ 		return head2; 	} 	if (NULL == head2) 	{ 		return head1; 	} 	pnode = head1->data < head2->data ? &head1 : &head2; 	head = *pnode; 	*pnode = (*pnode)->next; 	for (cur = head; head1 && head2; cur = cur->next, *pnode = (*pnode)->next) 	{ 		pnode = head1->data < head2->data ? &head1 : &head2; 		cur->next = *pnode; 	}     cur->next = head1 ? head1 : head2; 	return head; } 随手引用一个，没测试

太简单了，合并二有序链表，一搜一大把。

假如从小到大排序，先比较head1和head2，将小的存入目标链表，并取出他的next，然后将next继续和较大的比较，以此类推


Question: linux下c的udp获得广播返回的ip地址的问题

接收到了数据

判断下recvfrom的返回值，看看是不是没有接收到数据


Question: C语言阶乘递归调用，这个怎么解释？

引用 4 楼 gold615 的回复:想起来了，这个有个执行顺序的问题，栈是后进先出，因此是先执行--n，然后才是 n*fun（--n）。  这个说法有问题。  支持1、2楼。

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

参考置顶帖   C,C++表达式求值顺序

return n*fun(--n);  编译器有可能先处理--n，改变了n的值，结果就变成了(n-1) * fun(n-1)


Question: C通过popen模拟shell命令遇到的问题

引用 2 楼 slx_391987 的回复:看下pclose函数有没有报错？  没报错，返回0

引用 1 楼 r_Jimy 的回复:你用ls命令怎么删除呢？ rm?  xargs

看下pclose函数有没有报错？

你用ls命令怎么删除呢？ rm?

问题已解决！

引用 5 楼 mymtom 的回复: int iRet = asprintf(&cmd, "ls -lh /root/Project/programing/bak/ |grep a.out  | awk -F'->' '{print $1}' | awk -F' ' '{print $9}' | xargs rm -f "); /* 改为 */ int iRet = asprintf(&cmd, “%s", "ls -lh /root/Project/programing/bak/ |grep a.out  | awk -F'->' '{print $1}' | awk -F' ' '{print $9}' | xargs rm -f ");   问题已解决，不是串拼接的问题，是rm删除的路径不对


Question: 在windows系统中用c语言创建子进程的函数是什么，包含在哪个头文件中？

http://blog.csdn.net/vah101/article/details/5774654 #include <windows.h>


Question: C语言中关于调和级数代码哪步错了？

你的所有变量都是整数，所以运算结果也全都是整数。比如，1/i会得到0 是不是要把H改成double，然后H=H+1.0/i ;输出用%lf代替%d

for (i==2;i<n;i++)  // 多了个等号


Question: 一组正整数数字，求这组数字能组成的最大数？有没有好解法？

引用 29 楼 liuxie99 的回复:我也觉得应该是a515360208说的 “要把每个数的高位到低位都分开了进行排序，最高位相同的比较次高位，依次类推，”次高位没有比如，121和12谁大

引用 28 楼 nice_cxf 的回复:[quote=引用 27 楼 shfodhifdhiauh 的回复:] [quote=引用 26 楼 nice_cxf 的回复:] [quote=引 用 25 楼 shfodhifdhiauh 的回复:] 这个板块没有版主大神吗？怎么召唤他？ 其实就是自己写个比较函数排序就是，函数也简单，假定两个数为a和b那么如果字符串ab>字符串ba,则a>b,反之则小即可，最后按排序顺序就可以了[/quote]你有么有看前面他们举得例子[/quote] 1,10，100，由于110>101,10100〉10010因此1〉10〉100 1，12，122，由于112<121,12122<12212,因此122〉12〉2 [/quote]1，12，121呢？如果位数不同，怎么比较大小？比如12，121？

引用 27 楼 shfodhifdhiauh 的回复:[quote=引用 26 楼 nice_cxf 的回复:] [quote=引 用 25 楼 shfodhifdhiauh 的回复:] 这个板块没有版主大神吗？怎么召唤他？ 其实就是自己写个比较函数排序就是，函数也简单，假定两个数为a和b那么如果字符串ab>字符串ba,则a>b,反之则小即可，最后按排序顺序就可以了[/quote]你有么有看前面他们举得例子[/quote] 1,10，100，由于110>101,10100〉10010因此1〉10〉100 1，12，122，由于112<121,12122<12212,因此122〉12〉2

引用 26 楼 nice_cxf 的回复:[quote=引用 25 楼 shfodhifdhiauh 的回复:] 这个板块没有版主大神吗？怎么召唤他？ 其实就是自己写个比较函数排序就是，函数也简单，假定两个数为a和b那么如果字符串ab>字符串ba,则a>b,反之则小即可，最后按排序顺序就可以了[/quote]你有么有看前面他们举得例子

引用 25 楼 shfodhifdhiauh 的回复:这个板块没有版主大神吗？怎么召唤他？ 其实就是自己写个比较函数排序就是，函数也简单，假定两个数为a和b那么如果字符串ab>字符串ba,则a>b,反之则小即可，最后按排序顺序就可以了

这个板块没有版主大神吗？怎么召唤他？

引用 23 楼 hust_123 的回复:果断从大到小排序，简单明了看看前面的回答，，，

引用 39 楼 zhao4zhong1 的回复:[quote=引用 38 楼 shfodhifdhiauh 的回复:] [quote=引用 37 楼 boliang319 的回复:] 第一步：遍历这n个正整数，找出位数最多的一个的位数m 第二步：再遍历n个正整数，把不足m位的数以右边补0的方式都补到m位 第三部：对补过位的n个数做排序，比方说快速排序 第四部：从大到小的一次取出n个数，去掉补的零，从左到右排列得到结果。 94  9  4  14  1 94  90  40 14 10 94 9 4 14 1 9 94 4 14 1[/quote]   引用 33 楼 zhao4zhong1 的回复://一组正整数，求用这组正整数对应的数字字符串连在一起能组成的最大数 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 20 #define MAXL MAXN*(10+1) char ln[MAXL],*p; unsigned int uis[MAXN]; int i,n,r; int compare(const void *a,const void *b) {     char da[11],db[11],dab[21],dba[21];      sprintf(da,"%u",*(unsigned int *)a);     sprintf(db,"%u",*(unsigned int *)b);     sprintf(dab,"%s%s",da,db);     sprintf(dba,"%s%s",db,da);     return strcmp(dba,dab); } int main() {     fgets(ln,MAXL,stdin);     p=ln;     i=0;     while (1) {         r=sscanf(p,"%u%n",&uis[i],&n);         if (1==r) {             i++;             if (i>=MAXN) {                 printf(">%d number is ignored.\n",MAXN);                 break;             }             p+=n;         } else if (0==r) {             p++;         } else break;     }     n=i;     qsort(uis,n,sizeof(unsigned int),compare);     ln[0]=0;     for (i=0;i<n;i++) sprintf(ln,"%s%u",ln,uis[i]);     printf("%s\n",ln);     return 0; }  C:\test>test 94  9  4  14  1 9944141  C:\test>test 94  90  40 14 10 9490401410  C:\test>test 94 9 4 14 1 9944141 [/quote]谢谢，写的很好！改变比较大小的规则，ab前后组合谁大放前面最终得到最大数

C:\test>test 9 99 98 8 88 89 97 7 1 10 100 12 121 1212 9999897898887121212121110100

引用 38 楼 shfodhifdhiauh 的回复:[quote=引用 37 楼 boliang319 的回复:] 第一步：遍历这n个正整数，找出位数最多的一个的位数m 第二步：再遍历n个正整数，把不足m位的数以右边补0的方式都补到m位 第三部：对补过位的n个数做排序，比方说快速排序 第四部：从大到小的一次取出n个数，去掉补的零，从左到右排列得到结果。 94  9  4  14  1 94  90  40 14 10 94 9 4 14 1 9 94 4 14 1[/quote]   引用 33 楼 zhao4zhong1 的回复://一组正整数，求用这组正整数对应的数字字符串连在一起能组成的最大数 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 20 #define MAXL MAXN*(10+1) char ln[MAXL],*p; unsigned int uis[MAXN]; int i,n,r; int compare(const void *a,const void *b) {     char da[11],db[11],dab[21],dba[21];      sprintf(da,"%u",*(unsigned int *)a);     sprintf(db,"%u",*(unsigned int *)b);     sprintf(dab,"%s%s",da,db);     sprintf(dba,"%s%s",db,da);     return strcmp(dba,dab); } int main() {     fgets(ln,MAXL,stdin);     p=ln;     i=0;     while (1) {         r=sscanf(p,"%u%n",&uis[i],&n);         if (1==r) {             i++;             if (i>=MAXN) {                 printf(">%d number is ignored.\n",MAXN);                 break;             }             p+=n;         } else if (0==r) {             p++;         } else break;     }     n=i;     qsort(uis,n,sizeof(unsigned int),compare);     ln[0]=0;     for (i=0;i<n;i++) sprintf(ln,"%s%u",ln,uis[i]);     printf("%s\n",ln);     return 0; }  C:\test>test 94  9  4  14  1 9944141  C:\test>test 94  90  40 14 10 9490401410  C:\test>test 94 9 4 14 1 9944141

引用 37 楼 boliang319 的回复:第一步：遍历这n个正整数，找出位数最多的一个的位数m 第二步：再遍历n个正整数，把不足m位的数以右边补0的方式都补到m位 第三部：对补过位的n个数做排序，比方说快速排序 第四部：从大到小的一次取出n个数，去掉补的零，从左到右排列得到结果。 94  9  4  14  1 94  90  40 14 10 94 9 4 14 1 9 94 4 14 1

按字典序逆序。

同#33，把数字当作字符串，字符串比较（字符串比较按照字符位上的大小比较与长度无关）。将大的字符串放在前面，这样得到的整数值就是最大的，得到的整体整数也是最大的。

每个数都分别拆开，再排序，这就没问题了吧。

引用 30 楼 shfodhifdhiauh 的回复:[quote=引用 28 楼 nice_cxf 的回复:] [quote=引用 27 楼 shfodhifdhiauh 的回复:] [quote=引用 26 楼 nice_cxf 的回复:] [quote=引 用 25 楼 shfodhifdhiauh 的回复:] 这个板块没有版主大神吗？怎么召唤他？ 其实就是自己写个比较函数排序就是，函数也简单，假定两个数为a和b那么如果字符串ab>字符串ba,则a>b,反之则小即可，最后按排序顺序就可以了[/quote]你有么有看前面他们举得例子[/quote] 1,10，100，由于110>101,10100〉10010因此1〉10〉100 1，12，122，由于112<121,12122<12212,因此122〉12〉2 [/quote]1，12，121呢？如果位数不同，怎么比较大小？比如12，121？[/quote] 121和12？12112<12121,那么就是12大，两个数只有两种拼法，那个最后结果大，在前边的那个就是大的，如果相同就是相等，比如12=1212，1=11=111等

引用 4 楼 FancyMouse 的回复:[quote=引用 3 楼 nice_cxf 的回复:] 按字符串排序，从大到小就ok了 两组数据 1 12 122 ----- 1 10 100[/quote]有没有好方法？

引用 7 楼 zhao4zhong1 的回复:全排列＋穷举！来个简单点的，，，


Question: 有一个浮点型变量 X,如何判断它是否为 0 ？用除法可以吗？

直接判断他的绝对值是否小于一个很小的数（比如：0.000001），如果成立，就可以认为这个浮点数是0，浮点数没有绝对的值，要考虑精确度问题

fabs(x) < 0.0000001;则为零。后面精度自己控制。

float x  if(x>= -0.000001 && x<= 0.000001)

浮点数还是不要用 == 判断吧

直接判断它是否等于0就行了。另：你的X需要初始化 #include <stdio.h> int main(void) {     float x;     while(scanf("%f",&x)!=EOF) 	(x==0)?printf("X is zero!\n"):printf("X isn't zero!\n");     return 0; }


Question: 数据结构 链表 指针

引用 9 楼 u014794736 的回复:[quote=引用 7 楼 chenhanzhun 的回复:] 楼主，你所说的是动态链表，动态链表的好处是内存分配比较自由，方便管理，删除和插入元素也很方便。动态链表中每个节点包含连个数据项：当前节点数据值data和指向下一个节点的指针next； 你所说的是节点p是当前节点，p->next是指向下一个节点，若当前节点的数据值data=ai，下节点的数据值为ai+1；即p->data=ai；则p->next->data就是下一结点的数据值，所以p->next->data=ai+1；具体可以参考博文：http://blog.csdn.net/chenhanzhun/article/details/19409697谢谢。  多谢了！[/quote] 希望对你有帮助，谢谢

链表的定义就是一个连着一个的结构体指针，画一个图就明白了。对于地址连续的结构（比如数组），可以通过指针+1等来移动数据的指向，对于链表可以通过next节点来遍历数据

引用 7 楼 chenhanzhun 的回复:楼主，你所说的是动态链表，动态链表的好处是内存分配比较自由，方便管理，删除和插入元素也很方便。动态链表中每个节点包含连个数据项：当前节点数据值data和指向下一个节点的指针next； 你所说的是节点p是当前节点，p->next是指向下一个节点，若当前节点的数据值data=ai，下节点的数据值为ai+1；即p->data=ai；则p->next->data就是下一结点的数据值，所以p->next->data=ai+1；具体可以参考博文：http://blog.csdn.net/chenhanzhun/article/details/19409697谢谢。  多谢了！

一句话：该类型的指针+1是移动该类型的大小，自然就到下一个了。

链表的节点在栈中的位置是随机的，所谓的p->next，其实指的就是当前节点包含一个相应类型的指针，指向另一个节点。而next只是一个名字，为了帮助理解，而并不代表它的空间位置

从内存上看，ai,ai[0],ai[0].data这三个元素的地址上相同的 对编译器来说，一个结构指针struct A *a 指向地址0x100; 则a+1指向的是0x100+sizeof(struct A)的地址

链表其实可以用数组表示，这样更好理解  #define MAX_NODES 1000  //根据需要定义 #define INVALID_INDEX 0    //0是第一个结点，非循环链表可将其做为无效index,刚好默认初始化是0 typedef struct {       int data;       int nextIndex;//类比用指针指向下一个单元的地址，作用都是指向下一单元 }NODE; NODE nodes[MAX_NODES]; //初始化 void list_init(void) {       nodes[0].data=32;       nodes[0].nextIndex=2;        nodes[2].data=55;       nodes[2].nextIndex = 1;        nodes[1].data=10;       nodes[1].nextIndex =0; }  上面的初始化函数建立这样一个链表： node0----->node2------>node1---->NULL 所谓next指向的是寻找到下一结点的方式，可为数组索引，指向一下结点的指针等 而data是我们给定的值，也可以包含多个data，看需要

仅供参考//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //


Question: 大神看看我的程序错哪了，判断一个字符数组是否为回文，数据结构

谢谢大家，是我忘了清除键盘缓冲区了

getchar()是当用户输入回车后，它才会开始一个一个的读取字符，但是回车不会被丢弃，会被作为一个字符赋给变量。

我是不明白为什么再输入值的时候，它会给我自己赋一个空值，再让我输入下一个

for(i=0;i<20;i++)  if(p1[i]!=p2[i])  flag=0; 你这个for循环判断，每次都判断够20次，如果你输入的字符串不够20个字符，多出来的不就是未知的值吗？那样p1和p2就不会一样，flag就会等于0. 应该在m=!时，把字符串p1和p2最后一位置'\0',判断的时候使用  for(i=0;p1[i]!='\0';i++)  就行了

输出某一区间的回文数，仅供参考…… #include <iostream>  using namespace std;  int arry[] = {1, 10, 100, 1000, 10000, 100000};	//若还有更大的数，依次直接加10的n次方即可 int func2(int num, int n);  int func (int num) { 	int numtmp = num; 	int count = 0; 	while(numtmp) 	{  		count++;  		numtmp = numtmp /10;		 	} 	 	for(int i = 0; i <count; i++) 	{ 		if ( func2(num, i+1) != func2(num, count--)) 			return -1; 	} 	cout << num << '\t';	 	return 0;	  }  //返回一个数中的第n位是多少 int func2(int num, int n)	//n，要返回的第n位数 { 	if (num / arry[n -1] == 0) 	{ 		printf("error\n"); 		return -1;	 	} 	 	int tmp = num % arry[n]; 	tmp = tmp / arry[n-1];	 	return tmp;		 }  int main(void) { 	int count = 0; 	for (int i = 1; i < 100000; i++) 	{ 		if (func(i) == 0) 		{ 			count++; 		} 	} 	cout << endl << "\nThe range 1 --- " << i << " couunt is: " << count << endl; }

分配的char数组没有清0操作  换成  char p1[20]={0},p2[20]={0};  就可以了

我知道啊 我就是一个一个的把它们输进去，然后调试的的时候就是不对

void panduan(seq *s) { 	int flag=1; 	char p1[20],p2[20]; 	int i=0; 	char m; 	printf("请输入："); 	m=getchar(); 	for(;m!='!';)//输入！号时结束 	{ 		p1[i]=m; 		push(s,m); 		printf("请输入："); 		m=getchar(); 		i++; 	} 	i=0; 	while(s->top!=-1) 	{ 		pop(s,&p2[i]); 		i++; 	} 	for(i=0;i<20;i++) 		if(p1[i]!=p2[i]) 			flag=0; 	if(flag==1) 		printf("该字符串是回文！\n"); 	else 		printf("该字符串不是回文！\n"); }  逻辑太混乱了，你的输入是单个字符。还是好好改一改吧


Question: 在PE编程遇到的问题

突然明白了，数据是重新定位才出现的

这是ollydebug数据区 这是ollydebug代码区 实际只是想取到数据区一个指定地址里（注：0x1000940c）的一行十六进制数据 显示到Data inpretation列


Question: 来位大牛帮看看哪里错了啊~

out_arr[j]=s->pos;//改 out_arr[++j]=s->pos;   for(i=0;i<=j;i++) //改 for(i=0;i<len;i++)     printf("%d ",out_arr[i]); //改 printf("%d",out_arr[i]);    scanf("%d", &m);//改 scanf("%d",m);

是实现链表吧 你下面这句错了 scanf("%d",m); 应该是 scanf("%d",&m); 其他没看，还有问题跟我说下吧

void achieve(int len,int in_arr[],int m,int out_arr[])要实现什么？怎么逻辑那么乱……


Question: 关于《深入理解计算机系统》官方主页如何有效使用？

引用 5 楼 zhao4zhong1 的回复:英语也是一门计算机语言的说。说的极是啊，现在越来越有这种感觉了！！

引用 7 楼 ypzhong 的回复:[quote=引用 4 楼 u013163178 的回复:] [quote=引用 3 楼 u013457146 的回复:] 我买了，已经看了好多了，可以上面的家庭作业有点难度，官方网站上可以下载到解决方案。网站全是英文的还要注册账号，进来问下高手，网站上哪里下载作业答案？？ 建议你还是先看写基础的书，不然对你是一种很大的打击[/quote] 其实这就是基础书籍啦。只需要c语言基础和一点汇编基础，况且汇编里面还有教，以及简单的Linux操作命令。有这些基础啃完完全OK。[/quote] 就是的，我都快看完了感觉都是很基础的东西，内容比较广书有点厚，也没那么吓人的。

引用 3 楼 u013457146 的回复:我买了，已经看了好多了，可以上面的家庭作业有点难度，官方网站上可以下载到解决方案。网站全是英文的还要注册账号，进来问下高手，网站上哪里下载作业答案？？ 建议你还是先看写基础的书，不然对你是一种很大的打击

引用 4 楼 u013163178 的回复:[quote=引用 3 楼 u013457146 的回复:] 我买了，已经看了好多了，可以上面的家庭作业有点难度，官方网站上可以下载到解决方案。网站全是英文的还要注册账号，进来问下高手，网站上哪里下载作业答案？？ 建议你还是先看写基础的书，不然对你是一种很大的打击[/quote] 其实这就是基础书籍啦。只需要c语言基础和一点汇编基础，况且汇编里面还有教，以及简单的Linux操作命令。有这些基础啃完完全OK。

英语

英语也是一门计算机语言的说。

你没有买那本书吗


Question: C语言问题

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

while那里改为 while(1) {  scanf("%d",&num);    switch(num)  {  case 1:limit=17850.0;break;  case 2:limit=23900.0;break;  case 3:limit=29750.0;break;  case 4:limit=14875.0;break;  case 5:printf("Done!\n");  return 0;  default :printf("Please enter a valid figure:\n");  return num;  } } 这样就可以实现输入不在正确数字时一直循环，但是回不到switch， 除了直接continue，这种为何不能实现   2）   if (m <= limit)   tax = m * RATE1;   else  tax = limit * RATE1 + (m - limit) * RATE2; 这种语句为何还需要加大括号 麻烦了

你好，我改了一下，其实我主要疑问有二 一，如果default那里return num为何不起作用，我知道直接continue更好。 二，在if里面第一个语句不加{}就会显示错误，不解，不是只有一句吗

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。

多谢老师回复。。 我也试过设断点处理，但是还是不能理解 if语句里面只有一行为何还提示以下 error C2181: illegal else without matching if warning C4552: '*' : operator has no effect; expected operator with side-effect  代码 	 	if (m <= limit)  		tax = m * RATE1;	 	 	else 		tax = limit * RATE1 + (m - limit) * RATE2; 	 	printf("tax is %.2lf\n",tax); 再怎么想也想不通

把while去掉就行了。 改成scanf("%d",&num)；

输入1，2，3，4 一直在while里面循环吧。


Question: 浮点数在内存中的存储

引用 4 楼 zhao4zhong1 的回复:http://bbs.csdn.net/topics/390676437 正解！

引用 3 楼 yanzi150207348 的回复:好的 我试试  谢谢！ 也就是说实际的十六进制数就是IEEE754标准表示的吗？ 当然是呀！

好的 我试试  谢谢！ 也就是说实际的十六进制数就是IEEE754标准表示的吗？

浮点数进printf会提升到double。你如果需要它原本的值的话那要*(int*)(&tempV)

没有人遇到这样问题吗？

#include <stdio.h>  typedef union fu_s {     float f;     unsigned int u; } fu_t;  int main(int argc, char *argv[]) {     fu_t fu;      fu.f = 0.700012;     printf("%.24f\n", fu.f);     printf("%08X\n", fu.u);       return 0; } /* 输出为 0.700012028217315673828125 3F3333FD  说明: S-符号 E-阶码 F-尾数 3F        33        33        FD 0011 1111 0011 0011 0011 0011 1111 1101  0 01111110 011 0011 0011 0011 1111 1101 S E        F  S = 0 E = 126 - 127 = -1 F = 1 + 2^-2 + 2^-3    + 2^-6 + 2^-7   + 2^-10 + 2^-11   + 2^-14 + 2^-15    + 2^-16 + 2^-17 + 2^-18 + 2^-19   + 2^-20 + 2^-21 + 2^-23   = 1.40002405643463134765625 V = 1.40002405643463134765625 * 2^-1   = 0.700012028217315673828125 */


Question: void * 指针的问题，和网上的一致说法不一样

引用 3 楼 wangjun403 的回复:[quote=引用 1 楼 CKRGD 的回复:] 不知楼主听说过自动类型转换没有 数字的自动类型转换（当数字范围变化时）都会有warning [/quote]  这个范围应该是变大了吧

引用 1 楼 CKRGD 的回复:不知楼主听说过自动类型转换没有 数字的自动类型转换（当数字范围变化时）都会有warning

.c和.cpp不是一回事！

不知楼主听说过自动类型转换没有


Question: 一个字符串处理程序，core dump了，请帮忙看看是哪里出问题了

感谢各位时间，本帖将会和http://bbs.csdn.net/topics/390911755一起结贴给分 还请各位版友继续耐心关注，本人定当按时给分结贴

引用 10 楼 u013163178 的回复:你看这代码 /*************************************************************************     > File Name: p.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年10月21日 星期二 18时07分32秒  ************************************************************************/  #include<stdio.h> int main() { 	char *p=&"Hello World"[3]; 	printf("%s\n",p);  	return 0; }   您的回答，非常重要，我已经反复试验了您的回答 另开一贴专门讨论，还请帮助看一下这个帖子： http://bbs.csdn.net/topics/390911755

do {           tmp_value = value;           value /= base;           *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];       } while ( value );   明显你就抄漏了别人的东西。既然不是自己写的，copy也要认真copy.

引用 8 楼 lovesmiles 的回复:[quote=引用 5 楼 cinnik 的回复:] 因为35 + (tmp_value - value * base)这个表达式越界了。  而且，while循环无法结束。   } while (value);  是的，你这是那里的代码，是不是少了什么东西？ 自己单步调试一下。[/quote]  代码源自于此： http://blog.csdn.net/zougangx/article/details/6187713 看起来是个很成熟的牛人写出来的啊

引用 5 楼 cinnik 的回复:因为35 + (tmp_value - value * base)这个表达式越界了。  而且，while循环无法结束。   } while (value);  是的，你这是那里的代码，是不是少了什么东西？ 自己单步调试一下。

再请问，这一行是什么意思：  *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"       [35 + (tmp_value - value * base)];   这里的中括号是什么意思？ "[ ]"??  求大神指导

#include <stdio.h> #include <stdlib.h>   char* itoa(int, char*, int);   int main(void) {   int num = 698;   char str[25];     itoa(num, str, 10);   printf("The number 'num' is %d and the string 'str' is %s. \n", num, str); }   char* itoa(int value, char* result, int base) {     char* ptr = result, *ptr1 = result, tmp_char;   int tmp_value;     //check that the base if valid   if (base < 2 || base > 36) {     *result = '\0';     return result;   }    do {     tmp_value = value;     *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"       [35 + (tmp_value - (value / base * base))];     value = tmp_value / base;   } while (value);     //apply negative sign   if (tmp_value < 0) *ptr++ = '-';   *ptr-- = '\0';     while (ptr1 < ptr)   {     tmp_char = *ptr;     *ptr-- = *ptr1;     *ptr1++ = tmp_char;   }       return result; }

另外，您说的产生core.xxx是当进程崩溃时发生的吧？ 至于"Segmentation fault (core dumped)"，应该是程序操作了某些OS保护的区段吧？是不会产生core.xxx吧？  当前这个程序之所以发生core dump，应该是ptr最初赋值"zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz". ptr指向了只读数据区 而当再次进去do while循环后，ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" 其实是想改动这个只读数据区，所以发生了core dump。。。。 这是我的推测，请指导是否正确？

真是感谢您的解答  再请问，这一行是什么意思：  *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"       [35 + (tmp_value - value * base)];

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令


Question: 怎样把多个大小各部相同的txt文件分为几个大小相等的组？

linux系统下，可以使用opendir，readdir 遍历文件夹下所有文件，用struct stat结构体获取文件大小。然后排序分组即可。

仅供参考//给出12个随机数,分成三组求和,每组的个数不定,要求求出来的三个数之间相差最小,最完美的情况是三个数相等. #include <stdlib.h> #include <stdio.h> #include <time.h> #include <math.h> #include <limits.h> int i,j,k; int g[12][3]={//可能的分组大小     { 1, 1,10},     { 1, 2, 9},     { 1, 3, 8},     { 1, 4, 7},     { 1, 5, 6},     { 2, 2, 8},     { 2, 3, 7},     { 2, 4, 6},     { 2, 5, 5},     { 3, 3, 6},     { 3, 4, 5},     { 4, 4, 4}, }; int n[12]; int m[12]; int f[12];//当前最小时各数 int g1,g2,g3;//1,2,3组可分配的个数 int n1,n2,n3;//1,2,3组已分配的个数 int f1,f2;//当前最小时1,2组的个数 int s1,s2,s3;//123组的和 int d;//1-2,2-3,3-1组中各数和之间差的绝对值之和 int dmin=INT_MAX;//保存当前d的最小值 void swap(int *pi1,int *pi2) {     int t;     t=*pi1;*pi1=*pi2;*pi2=t; } void test() {     s1=0;     for (i=0;i<g1;i++) s1=s1+n[i];     s2=0;     for (i=g1;i<g1+g2;i++) s2=s2+n[i];     s3=0;     for (i=g1+g2;i<12;i++) s3=s3+n[i];     d=abs(s1-s2)+abs(s2-s3)+abs(s3-s1);     if (d<dmin) {         dmin=d;         f1=g1;         f2=g2;         for (i=0;i<12;i++) f[i]=n[i];         printf("(");         for (i=0;i<g1;i++) printf("%2d,",n[i]);         printf(")  (");         for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);         printf(")  (");         for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);         printf(") %4d\n",dmin);     } else {         printf("(");         for (i=0;i<g1;i++) printf("%2d,",n[i]);         printf(")  (");         for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);         printf(")  (");         for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);         printf(") %4d\n",d);     } } void main() {     srand(time(NULL));     for (i=0;i<12;i++) m[i]=rand()%100;     for (i=0;i<12;i++) printf("%2d,",m[i]);     printf("\n");     for (i=1;i<12;i++) {         for (j=0;j<i;j++) {             if (m[i]>m[j]) swap(&m[i],&m[j]);//冒泡排序从大到小         }     }     for (i=0;i<12;i++) printf("%2d,",m[i]);     printf("\n");     for (k=0;k<12;k++) {//在12种分组方法中         //取第i种分组方法         g1=g[k][0];         g2=g[k][1];         g3=g[k][2];         printf("%2d-%2d,%2d,%2d\n",k,g1,g2,g3);         //将从大到小12个数双向轮流分配到三个组中         n1=0;         n2=0;         n3=0;         for (j=0;j<12;j++) {             switch (j%6) {             case 0:         redo:                 if (n1<g1) {                     n[n1]=m[j];                     n1++;                     break;                 }             case 1:                 if (n2<g2) {                     n[g1+n2]=m[j];                     n2++;                     break;                 }             case 2:                 if (n3<g3) {                     n[g1+g2+n3]=m[j];                     n3++;                     break;                 }             case 3:                 if (n3<g3) {                     n[g1+g2+n3]=m[j];                     n3++;                     break;                 }             case 4:                 if (n2<g2) {                     n[g1+n2]=m[j];                     n2++;                     break;                 }             case 5:                 if (n1<g1) {                     n[n1]=m[j];                     n1++;                     break;                 }             default:goto redo;             }         }         test();     }     printf("---------------------------------------------------\n");     g1=f1;     g2=f2;     for (i=0;i<12;i++) n[i]=f[i];     printf("(");     for (i=0;i<g1;i++) printf("%2d,",n[i]);     printf(")  (");     for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);     printf(")  (");     for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);     printf(") %4d\n",dmin); }

不改变文件？  总大小/5，，然后从大文件开始组合，往这个大小上去去凑。


Question: 关于strcpy

楼主看下面代码,发现错误了吗#include<stdio.h> int main() {  int *p=NULL;  *p=3;//error } #incolude<stdio.h> int main() { int a=9; int *p=&a; *p=10; return 0; }

你悬挂指针了，你s指针没有指向任何地址，怎么可能作为buufer呢 在main函数里面加一句,s指针应该改名为buf，这样看起来直观一点点， s =(char *)malloc(20); #include <string.h>  void Strcpy(char *to, char *from) { strcpy(to, from); }  int main() { char *s=NULL; s= (char *)malloc(20); Strcpy(s,"abcdefg"); return(0); }

strcpy的实质是对一个一个字符的拷贝，你把一个字符串拷贝到一个没有内存空间的NULL指针上，不出错才怪！

strcpy(char* to, const char * from) {   whille(to++ = from++); }  strcpy的c语言实现就上面一句代码。你的to 指向了null，对它的写操作肯定会出错。

C语言实际上建立在一个抽象的层次上，它没有涉及某一个具体的硬件结构（C语言的宗旨之一就是通用－－通用于任何计算机），对NULL而言，只是表示地址范围中的一个特殊点，它不可访问－－表示无效地址。 至于它是不是0，0地址处是什么？这就要涉及到具体的计算机硬件结构了，这是另一个层次的问题了。 一个具体的编译器负责NULL与一个具体硬件结构地址的关联。没有记错的话，看看“C的495个问题” 摘自——http://bbs.csdn.net/topics/380080326?page=1  为啥要这么用strcpy呢？

操作NULL指针

编译不会出错，因为函数里传进去的是形参，不会改变s在main里的值


Question: C语言新手求解

return 8000不是返回值咩

用了楼上的还是不对啊....

整个程序怎么一个提示性质的语句都没有，也不知道输入的都是什么 而且没有消除非法输入的语句啊

没有返回值。。。 #include <stdio.h>  int yideng(int a,int c) {     if(a>80&&c>1)         return 8000 ;     return 0; } int erdeng(int a,int b) {     if(a>85&&b>80)         return 4000 ;     return 0; } int sandeng(int a) {     if(a>90)         return 2000 ;     return 0; } int sideng(int a,char b) {     if(a>85&&b=='Y')         return 1000 ;     return 0; } int wudeng(int a,char b) {     if(a>80&&b=='Y')         return 850 ;     return 0; }  int main() {     char p[100][20];     int h[100][3];     char y[100][3];     int sum[100];     int a,b,c,d,m,n ;     scanf("%d",&b);     for(a=0;a<b;a++)     {         scanf("%s",p[a]);         scanf("%d%d%d",&h[a][0],&h[a][1],&h[a][2]);         scanf("%c%c",&y[a][0],&y[a][1]);     }     for(a=0;a<b;a++)     {         sum[a]+=yideng(h[a][0],h[a][2]);         sum[a]+=erdeng(h[a][0],h[a][1]);         sum[a]+=sandeng(h[a][0]);         sum[a]+=sideng(h[a][0],y[a][1]);         sum[a]+=wudeng(h[a][0],y[a][0]);     }     d=0 ;     m=0 ;     n=0 ;     for(c=0;c<b;c++)         if(sum[c]>d)         {             m=c ;             n=sum[c];         }     printf("%s\%d",p[m],n);     return 0 ; }

哪里错了 出来一些垃圾值