Question: 这是什么意思！！！从调用函数来看，函数传递的是数组，所以函数的形参应为指针

在同一个文件中　对一维数组来说　数组和指针是等价的　所以没有问题　你写成s[100]没有问题

you can also write void fun(char s[], char t[])

数组的传递，其实就是地址的传递！

对于void fun(char s[100], char t[100]); 编译器也会转换为 void fun(char *, char *);

两种方式一样的，只不过根据个人的习惯吧了

在作为函数的参数时，数组和指针是等价的。 所以两种写法没有区别。

可是我写void fun(char s[100], char t[100]); 答案说我是错的，我装的计算机二级考试系统


Question: 求高手详解一下设备环境句柄的含义 困扰很多天了

DC句柄，对应一个DC对象，对象内部是一个数据结构。 包含该DC的驱动程序相关的一些数据结构，比如驱动的函数指针，硬件相关的数据结构等等。  设备环境指的是，对应的硬件参数和驱动程序软件参数。 是对设备硬件的一种抽象。  比如GDI 有屏幕DC和打印机DC等至少两种DC。 都是和图形输出相关的。  需要详细了解的话，请看《Windows 图形编程》，和Window驱动开发方面的书籍。

检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！

引用 2 楼 cyycxz 的回复:引用 1 楼 user-4 的回复:楼主说的是图形么？DC?正是，还有不明白的是为什么获取名柄之后要释放才行。。。 就像申请内存， 你就一直申请，不释放 内存资源是不是就越来越少， 后面再申请就获取不到了吧

Device Contexts Home |  Overview |  How Do I |  Tutorial  A device context is a Windows data structure containing information about the drawing attributes of a device such as a display or a printer. All drawing calls are made through a device-context object, which encapsulates the Windows APIs for drawing lines, shapes, and text. Device contexts allow device-independent drawing in Windows. Device contexts can be used to draw to the screen, to the printer, or to a metafile.  CPaintDC objects encapsulate the common idiom of Windows, calling the BeginPaint function, then drawing in the device context, then calling the EndPaint function. The CPaintDC constructor calls BeginPaint for you, and the destructor calls EndPaint. The simplified process is to create the CDC object, draw, and destroy the CDC object. In the framework, much of even this process is automated. In particular, your OnDraw function is passed a CPaintDC already prepared (via OnPrepareDC), and you simply draw into it. It is destroyed by the framework and the underlying device context is released to Windows upon return from the call to your OnDraw function.  CClientDC objects encapsulate working with a device context that represents only the client area of a window. The CClientDC constructor calls the GetDC function, and the destructor calls the ReleaseDC function. CWindowDC objects encapsulate a device context that represents the whole window, including its frame.   CMetaFileDC objects encapsulate drawing into a Windows metafile. In contrast to the CPaintDC passed to OnDraw, you must in this case call OnPrepareDC yourself.   Mouse Drawing Most drawing in a framework program—and thus most device-context work—is done in the view’s OnDraw member function. However, you can still use device-context objects for other purposes. For example, to provide tracking feedback for mouse movement in a view, you need to draw directly into the view without waiting for OnDraw to be called.   In such a case, you can use a CClientDC device-context object to draw directly into the view.   What do you want to know more about? Device contexts in Win32 documentation   Drawing   Drawing tutorial   Mouse drawing   Mouse drawing tutorial   Lines and curves   Filled shapes   Fonts and text   Colors   Coordinate spaces and transformations

这个应该是引用计数的原因吧，呵呵，我也不是高手 GetDC一次，引用计数+1，ReleaseDC -1，引用计数为0的时候，才会去释放资源。 类似于java和.net的回收机制。

楼主说的是图形么？DC?


Question: 这两个错误提示如何解释呢？

[quote=引用 1 楼 user-2 的回复:] 非常感谢！！！

没有main函数吧

#include <stdio.h>   int f1(int *a){  *a=5;  return 0;}  int main() { return 0; }


Question: 院校的编程大赛，要求设计小型的控制台游戏？（对象：初学编程者半年左右）

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

先去问学长 评分机制


Question: 有趣的 main 函数参数

这个估计只在linux ,unix 上有用，不然早就传开了

受教。不过还是觉得不大可能用到


Question: 求破FFMpeg推送RTMP流至Red5服务器的思路，源文件是本地Flv文件

第一次发帖 就沉了？  时间都去哪了    大神都去哪了。。。。。


Question: 用 n/4 = 1 - 1/3 + 1/5 - 1/7 + ... 公式求n。

#include <stdio.h> #include <math.h> main() { 	int j=1;     double i=1.0, n=0.0;    for(;fabs(1/i)>1e-6;i=+2.0, j++)  {  if(j%2==0)          n=n-1/i;    else      n=n+1/i;    }    n=n*4;    printf("n=%lf\n",n); }

我加了一个fabs（1/i)>1e-6以后还是不行啊

我就是不知道那个语句怎么写，所以空在那里了

晕，你这个循环没有退出条件

double pi=0, f  ,eps = 1e-6; for (i = 5; fabs(  f  = 1.0/ i - 1.0/(i+2)) >eps; i+=4)        pi +=  f;

#include<stdio.h> #include<math.h>  int main(int argc, char *argv[]) {     int i,j;     double n, sum = 0.0, con;      for (i = 1,j = 1; ; i=i+2, ++j) {         if (j % 2 == 0) {                 con = -1.0 / i;         } else {                 con = 1.0 / i;         }         sum = sum + con;          if (fabs(con) < 1e-6) {                 break;         }     }     n = sum * 4;      printf("n=%f\n",n); }


Question: C如何遍历解析xml文件(minixml ).

采用循环吧。你这是看一个读一个的做法。建议使用 TinyXML，那个更简单，方便，实用。


Question: 求推荐几部学习C语言的书籍

看了小谭的书，确实不够。

也可以看看这里 http://blog.csdn.net/thefutureisour/article/details/7598775

看看 都是蛮好的书籍阿

c primer plus 这本书写的非常给力！想学好c，可以买一本好好看看！

看看数据结构方面的吧

C和指针 C语言入门经典

C 和指针不错，可以看下，做下后面的习题，然后学习下数据结构。

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm


Question: 怎样读取TTF字体，把输入的汉字转化成64*64点阵位图，或者生成二维数组也行。

C源代码:显示指定字符在指定字体中对应的由直线段和Bezier曲线段组成的笔划形状的命令行工具FontPath  http://download.csdn.net/detail/zhao4zhong1/6588091


Question: 关于《C语言程序设计：现代方法》第八章第9题编程问题

虽然不是最好的方案，但是我不再纠结这个问题了，还是谢谢楼上兄弟了。

引用 4 楼 zergor 的回复:我看了你的代码，你的思路也是在边界死胡同的时候通过多次尝试来判定出路，不过我运行了你的代码，还是有问题的。 明显还有路可走，只是到了边界而已。 42行改为  if (n>20000) {//钻入死胡同 再试试？

先自己顶一个

仅供参考#include <stdio.h> #include <time.h> #include <stdlib.h> #define MAXX 10 #define MAXY 10 void main() {     char MAP[MAXX][MAXY];     char str;     int x,y,z,f,n;      for (x=0;x<MAXX;x++) {         for (y=0;y<MAXY;y++) {             MAP[x][y]='.';         }     }      for (x=0;x<MAXX;x++) {         printf("\n");         for (y=0;y<MAXY;y++) {             printf("%c",MAP[x][y]);         }     }     printf("\n");      srand((unsigned) time(NULL)); RETRY:     x=0;y=0;str='A';MAP[x][y]=str;      for (str='B';str<='Z';str++) {         n=0;         f=1;         while (1) {             n++;             z=rand()%4;             switch (z) {                 case 0: if (y+1<MAXY && MAP[x  ][y+1]=='.') {y++;MAP[x][y]=str;f=0;} break;                 case 1: if (x+1<MAXX && MAP[x+1][y  ]=='.') {x++;MAP[x][y]=str;f=0;} break;                 case 2: if (y-1>0    && MAP[x  ][y-1]=='.') {y--;MAP[x][y]=str;f=0;} break;                 case 3: if (x-1>0    && MAP[x-1][y  ]=='.') {x--;MAP[x][y]=str;f=0;} break;             }             if (f==0) break;             if (n>20) {//钻入死胡同                 for (x=0;x<MAXX;x++) {                     for (y=0;y<MAXY;y++) {                         MAP[x][y]='.';                     }                 }                 goto RETRY;             }         }//while         if (x==MAXX-1 || y==MAXY-1) break;     }//for      for (x=0;x<MAXX;x++) {         printf("\n");         for (y=0;y<MAXY;y++) {             printf("%c",MAP[x][y]);         }     }     printf("\n"); }

吊死没有那本书


Question: 链表通过文件读写计算两个多项式之积

求大神解答啊=^= 请问有人可以帮忙看看吗

改了一部分供参考 typedef struct polyn {   int coef; //如果要用double,则需要把fscanf和printf中的"%d"改为"%lf"。  double coef;   int e; //double e;   struct polyn *next; }POLYN;  POLYN *creatpolyn(char *file_name); //改 POLYN *creatpolyn();//创建多项式  int main() {    POLYN *ha,*hb,*hc;    ha = creatpolyn("F:\\file1.txt");//改 ha = creatpolyn();   polynout(ha,"ha;");    hb = creatpolyn("F:\\file2.txt");//改 hb = creatpolyn();   polynout(hb,"hb;");    Clearlist(ha);   Clearlist(hb);    return 0; }   POLYN *creatpolyn(char *file_name) //改 POLYN *creatpolyn() {   POLYN *phead = NULL;   POLYN *pnode = NULL;   phead = (struct polyn*)malloc(LEN);   if (NULL== phead)     return NULL;    phead ->coef = 0;   phead->e = -1;   phead->next = NULL;    POLYN polyn;    FILE *fp1;   fopen_s(&fp1,file_name,"rt"); //改 fopen_s(&fp1,"F:\\file1.txt","rt");   if(!fp1)    {     printf("Error!Cannot open file.");      return 0;   }    while(fscanf(fp1,"%d %d\n",&polyn.coef,&polyn.e)==2)   {     //删POLYN *polynmulti = new POLYN;     //删memcpy(polynmulti,&polyn,LEN);     pnode=(struct polyn*)malloc(LEN);     if (NULL == pnode)       break;      pnode->coef = polyn.coef;     pnode->e = polyn.e;     pnode->next = NULL;      InsertPolyn(phead,pnode);//改 InsertPolyn(phead,pnode);     //删printf("coef1:%d,e1:%d\n",*phead,*pnode);     //移下 fclose(fp1);    }   fclose(fp1);//移到此处  /*删. 以下代码将只返回第2个多项式的head. 可以用以上代码完成相同功能.   FILE *fp2;   fopen_s(&fp2,"F:\\file2.txt","rt");   if(!fp2)    {     printf("Error!Cannot open file.");      return 0;   }   while(fscanf(fp2,"%d %d\n",&polyn.coef,&polyn.e)==2)   {     POLYN *polynmulti= new POLYN;     pnode=(struct polyn*)malloc(LEN);     if (NULL == pnode)       break;      pnode->coef = polyn.coef;     pnode->e = polyn.e;     pnode->next = NULL;      InsertPolyn(phead,pnode);     printf("coef2:%d,e2:%d\n",*phead,*pnode);     fclose(fp2);   } */   return phead; }  void InsertPolyn(POLYN *phead, POLYN* s) {   POLYN *p = NULL;   POLYN *q = NULL;   POLYN *r = NULL;   if(NULL == phead||NULL==s)     return;   if(NULL == phead->next)   {     phead->next = s;     return;   }    p = phead->next;   r = phead; //加   q = s;   while(p!= NULL)   {     if(p->e == q->e)     {       p->coef += q->coef;       return;     }     //删p=p->next;    //删}   //删p = p->next;   if(p->e > q->e)   {     q->next = p;      r->next = q;//改 phead->next = p;     return;   }   else   {   //删while(p!=NULL){     //删if(p->e > q->e)     //删  break;     r = p;     p = p->next;   }   //删q->next = r->next;   //删r->next = q;   }   r->next = q;//加 }

add breakpoint


Question: 这个函数有问题吗?

__s32 photo_argb_8bpp(__u8 *srcdata,__u8 * drcdata,__s32 len) {  // unsigned char __u8 	__u8 *date; 	__u32 tmp; 	__u32 cnt; 	__u8  red; 	__u8  gre; 	__u8  blu; 	__u8  alpha;  	tmp = 0; 	red = 0; 	gre = 0; 	blu = 0; 	alpha = 0; 	 	date = srcdata; 	eLIBs_printf("..%s..%d..........+.-....len=%d...\n\n", __FILE__, __LINE__, len); 	GUI_LOCK(); 	for (cnt = 0; cnt < len; cnt++) 	{     		if (cnt<10) 		{ 			eLIBs_printf("..%s..%d......cnt=%d;.%d..%d..%d..%d..\n\n", __FILE__, __LINE__, cnt, red, gre, blu, alpha); 		}  		red     = *(date + tmp + 0); 		if (cnt<10) 		{ 			eLIBs_printf("..%s..%d......cnt=%d;.%d..%d..%d..%d..\n\n", __FILE__, __LINE__, cnt, red, gre, blu, alpha); 		}  		gre     = *(date + tmp + 1); 		if (cnt<10) 		{ 			eLIBs_printf("..%s..%d......cnt=%d;.%d..%d..%d..%d..\n\n", __FILE__, __LINE__, cnt, red, gre, blu, alpha); 		}  		blu     = *(date + tmp + 2);     线程中，这里就出现负数了，不知是何原因。主函数和线程中调用时的参数是一样的.                 if (cnt<10) 		{ 			eLIBs_printf("..%s..%d......cnt=%d;.%d..%d..%d..%d....*drcdata=%d...\n\n", 				__FILE__, __LINE__, cnt, red, gre, blu, alpha, 0.33*red + 0.33*gre +0.33*blu); 		}  		*drcdata++ = 0.33*red + 0.33*gre +0.33*blu; 		if (cnt<10) 		{ 			eLIBs_printf("..%s..%d......cnt=%d;.%d..%d..%d..%d...drcdata=%d.\n\n", 				__FILE__, __LINE__, cnt, red, gre, blu, alpha,*drcdata); 		}  		tmp+= 4; 		if (cnt<10) 		{ 			eLIBs_printf("..%s..%d......cnt=%d;.%d..%d..%d..%d..\n\n", __FILE__, __LINE__, cnt, red, gre, blu, alpha); 		}  	} 	GUI_UNLOCK(); 	return 0; }

串口信息输出难道不是临界资源？

引用 1 楼 zhao4zhong1 的回复:加临界区锁 参考下面//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             Log("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }  不清楚你为什么一上来就说要用锁，LZ给的那个函数内部，全是栈变量，线程私有数据。根本不需要用到锁的知识。

引用 2 楼 huabinsir 的回复:*drcdata++ = 0.33*red + 0.33*gre +0.33*blu;  是这条语句的问题，在线程中，这条语句的值变为了负值;  在主函数中，这条语句的值是正的.  这是什么原因呢? 不知道你两个地方，调用的时候，参数是怎么传的，没办法给你分析，你可以自己调试下，一看就明白。 还有这里多半是用不到锁，因为都是线程私有数据。


Question: C语言能做出如何做出像QQ这种商用软件的界面？

必须很可以 找一个C语言的图形库 比如ＧＴＫ

搜搜看，应该有不少模拟QQ界面的源代码供下载。

UI library

貌似QQ使用MFC吧，你可以百度一下，具体我不清楚（说错勿喷）。不过我看到在 win32平台下，使用duilib库做的仿QQ的界面，几乎和QQ一摸一样。楼主可以尝试一下界面库。

用MFC吧，查下MSDN就可以写窗口程序

腾讯这种大公司一般都会有自己的库 如果想试试，MFC,QT都可以

这个。。C语言据说号称什么软件都能做，你可以看看这个——http://wenku.baidu.com/view/b68727fdc8d376eeaeaa31b6.html 这个看起来好复杂，唉，我是不会


Question: c语言嵌套结构体赋值问题

{ { { 0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0} } }从里往外理解就可以了： { 0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}是对数组s6_addr[16]初始化 { { 0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0} }是对结构体struct in6_addr的初始化(谁让它只有一个成员呢) { { { 0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0} } ......}就是对struct sockaddr_in6 serv1的整体初始化

你说：{ { { 0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0} } }可以表示为结构体？

C 語言中结构体变量 可以直接 互相赋值


Question: 新手求助，c语言随机数组定义问题

引用 2 楼 zhao4zhong1 的回复://定义一个特殊的随机二维数组，比如A[10][10]，其中的元素只有0和1，而且0的个数给定，有50个 #include <stdio.h> #include <stdlib.h> #include <time.h> int d[100]; int i,n,a,b,t; int c,j; int A[10][10]; int main() {     srand(time(NULL));     n=100;     for (i=0;i<n;i++) d[i]=i;/* 填写0～99 */     for (i=n;i>0;i--) {/* 打乱0～99 */         a=i-1;b=rand()%i;         if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}     }      for (i=0;i<10;i++) {         for (j=0;j<10;j++) {             A[i][j]=(d[i*10+j]>=50)?1:0;             printf("%d ",A[i][j]);         }         printf("\n");     }     return 0; } //1 0 0 1 1 0 1 1 0 1 //0 1 0 0 0 0 1 0 1 0 //0 1 1 1 1 0 1 1 0 0 //1 1 0 1 1 1 1 1 0 0 //1 1 1 0 0 0 1 1 0 1 //0 1 0 0 0 0 1 1 1 0 //0 0 1 0 0 1 0 0 1 1 //0 0 0 0 1 1 0 0 0 0 //1 1 0 0 0 1 0 1 0 1 //1 1 1 1 1 0 0 0 1 1 //    回的有点晚了，不过非常感谢您，虽然自己也编了个算法，感觉您的更好！受教了！

回的有点晚了，不过非常感谢您，虽然自己也编了个算法，感觉您的更好！受教了！

自己给自己顶一个，各位大神帮帮忙！


Question: 关于数组增长的一个问题

谢谢大家给的意见，再次谢谢user-5网友的详细描述！我明白了。也多谢zhao4zhong1网友贴的代码！

仅供参考//输出PROG中有但LIST中没有的文本行，即集合PROG-LIST #include <stdio.h> #include <string.h> #include <stdlib.h> #include <search.h> #define MAXCHARS 512 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; char PROG[256]="PROG";//程序Program需要的文件列表 char LIST[256]="LIST";//dir /b /s生成的实际文件列表List FILE *fp,*fl; int i,c,n,L,hh; int ignore_case=0; char ln[MAXCHARS]; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc>1) strcpy(PROG,argv[1]);//命令行参数1覆盖PROG     if (argc>2) strcpy(LIST,argv[2]);//命令行参数2覆盖LIST     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     if ((fl=fopen(LIST,"rt"))==NULL) {         fprintf(stderr,"Can not open %s\n",LIST);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 1;     }     if ((fp=fopen(PROG,"rt"))==NULL) {         fclose(fl);         fprintf(stderr,"Can not open %s\n",PROG);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 2;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(fl);         fclose(fp);         fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 4;     }     n=0;     hh=0;     i=0;     while (1) {         if (fgets(ln,MAXCHARS,fl)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",LIST,hh,MAXCHARS);             while (1) {                 c=fgetc(fl);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     free(buf);                     fclose(fl);                     fclose(fp);                     fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     return 5;                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(fl);     if (ignore_case) qsort(buf,n,MAXCHARS,icompare);     else qsort(buf,n,MAXCHARS,compare);     hh=0;     while (1) {         if (fgets(ln,MAXCHARS,fp)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",PROG,hh,MAXCHARS);             while (1) {                 c=fgetc(fp);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             if (ignore_case) {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);             } else {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);             }         }     }     fclose(fp);     free(buf);     return 0; }

realloc，我在VS2008的使用过程中是做了内存复制动作，但是最好还是自己保障做一次memcpy～

realloc

你这问题我感觉就引发了链表~~~~    或者 比如说int a[10]   如果放满了 你可以int b[20]  把a里面的内容拷给b

补充一点：因为realloc分配的内存区域可能会移动，所以不应当使用任何指针指向该区域。

malloc是分配固定长度的内存，且长度不能变更。分配成功后，将首地址返回 如果需要变更数组长度，可以使用realloc函数。realloc函数可以更改之前分配的内存大小(增加或减少均可)。对于LZ所说的，如果要增加数组长度，且当前内存的大小不足。那么realloc会重新分配另一块足够大的内存块，并将第一次分配的数组内容拷贝到新的内存区域


Question: 在WM_PAINT中使用StretchBlt 刷新不成功

问题已经解决

CreateCompatibleBitmap

可能系统判定你那个区域不需要更新，所以没效果，试试在m_uBtnState改变时主动调用InvalidateRect通知需要更新的区域...

自己顶顶，求解答


Question: Linux下C语言获得系统时间的方法

#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中


Question: 【急】新人求教，文件读写出现错误的指针

谢啦~已经ok了~  引用 2 楼 user-1 的回复:楼主你改写这段代码然后重新编译下 while(fscanf(fp1,"%d %d\n",coef,e)==2)           //把这句代码改为while(fscanf(fp1,"%d %d\n",&coef,&e)!=EOF)

文件里面输入了  1 1 ，希望能读出来系数和指数，但是为什么根本不能读=A=


Question: 求解释程序是干什么用的

《操作系统》 《Windows核心编程》

我想知道这是从哪儿来的代码

程序是为了实现想要的算法用的


Question: 关于printf的问题

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

引用 6 楼 angel_su 的回复:每个分支都要return，不要拼人品... if (mid*mid - y < -0.001 ) {         return mysqrt (mid, end, y);     } else if (mid*mid - y > 0.001) {         return mysqrt (start, mid, y);     } else {... 果然是return的问题导致的，可是为什么会这样呢？那样调用的话最终还是到最后一个“return mid”啊？

重复打印了，把mysqrt（）里面的printf去掉

引用 2 楼 JiMoKuangXiangQu 的回复:[quote=引用 1 楼 user-5 的回复:] %f和double类型不匹配 这是种可能，如果是这样，只需修改成%lf即可。 但也有可能函数mysqrt的计算方法有问题。[/quote] 不是lf的问题。。。

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

引用 1 楼 user-5 的回复:%f和double类型不匹配 这是种可能，如果是这样，只需修改成%lf即可。 但也有可能函数mysqrt的计算方法有问题。

%f和double类型不匹配


Question: 写了一个类似atol的函数，不出结果

引用 5 楼 qingtianjushi 的回复:[quote=引用 3 楼 starytx 的回复:] 为啥要用int*来返回，不是什么时候都要动态开辟空间的，这是我的代码示例，仅供参考 int char_TO_int(char * st) { 	//printf("i am in char to int \n"); 	if (st == NULL || strlen(st) == 0) 	{ 		return 0; 	}  	char *p = st + strlen(st) - 1;  // p指向最后一个有效字符 	int nIndex = 0;    	int nResult = 0; 	while (p >= st) 	{ 		if (*p > '0' && *p <'9') // 是数字字符 		{ 			nResult += (*p - '0') * pow(10.0 ,nIndex); 			nIndex++; 		} 		else	// 如果有非数字字符，重置标记，这样的效果就是只转换最左边的数字字符，如果遇到非数字则丢弃随后的字符,也可以做其他处理（比如直接终止，返回0） 		{ 			nResult = 0; 			nIndex = 0; //			return 0;     		} 		p--; 	}  	return nResult; }  您写的这个好像和我要的结果不一致。我的意思是，char m[]={"3458976120"};     这些数据是Char类型的吧，我们是不能直接用来做数值运算的，因为3的ASCII值不是3.所以需要转换成 数值3 。  实现  atol()    的功能。不过非常感谢您的回复[/quote]没明白你的意思。你不是想把字符串“123”转换成int值为123吗？

引用 3 楼 starytx 的回复:为啥要用int*来返回，不是什么时候都要动态开辟空间的，这是我的代码示例，仅供参考 int char_TO_int(char * st) { 	//printf("i am in char to int \n"); 	if (st == NULL || strlen(st) == 0) 	{ 		return 0; 	}  	char *p = st + strlen(st) - 1;  // p指向最后一个有效字符 	int nIndex = 0;    	int nResult = 0; 	while (p >= st) 	{ 		if (*p > '0' && *p <'9') // 是数字字符 		{ 			nResult += (*p - '0') * pow(10.0 ,nIndex); 			nIndex++; 		} 		else	// 如果有非数字字符，重置标记，这样的效果就是只转换最左边的数字字符，如果遇到非数字则丢弃随后的字符,也可以做其他处理（比如直接终止，返回0） 		{ 			nResult = 0; 			nIndex = 0; //			return 0;     		} 		p--; 	}  	return nResult; }  您写的这个好像和我要的结果不一致。我的意思是，char m[]={"3458976120"};     这些数据是Char类型的吧，我们是不能直接用来做数值运算的，因为3的ASCII值不是3.所以需要转换成 数值3 。  实现  atol()    的功能。不过非常感谢您的回复

引用 2 楼 gongheguoyingpai11 的回复:这个程序有很多的问题 细节问题暂不讨论 就int *p2=(int *)malloc(10);    这个语句你分配十个字节的空间 但是p2并定义为了int型指针 这样 for(i=0;i<10;i++) {  printf("num is %d \n",*p2++); } 这里p2++每次以int类型为4个字节为准的话 这样p2每次相当于移动4个字节  而你总共只分配10个字节 一定会发生内存错误  如果想分配一块可以容纳10个整形数的空间 应该是(int*)malloc(sizeof(int) * 10)  我把分配地址的语句改为(int*)malloc(sizeof(int) * 10)，这个后。程序就运行正常了。您用上面用的For，我感觉不如用malloc，因为到时候可以释放。用For分配得先初始化地址，又长期占用。

这个代码我只看得冒汗，还是没看懂


Question: 不知道为什么这个程序无法调试？

貌似还是搞不定，蛋蛋的忧桑。

不清楚，唉，http://blog.csdn.net/milkcu/article/details/8856768 http://hi.baidu.com/lwpping/item/320da61970fcd1653e87ce31

add break point in the first line in main

引用 2 楼 u014082409 的回复:我明白，我的意思是这个程序编译通过后，输入build excute，一点显示都没有。这是为什么？应该不要输入啥的吧？貌似也没有输入函数之类的。 while((c = getchar())!=EOF){

重建所有 或者安装SP 或者重装VS

确认编译链接通过，按F11键


Question: 这个问题没想明白，大家帮帮忙

引用 1 楼 user-3 的回复:scanf("%s",string1); 改成 gets(string1);  记得scanf遇到空格时会结束 引用 1 楼 user-3 的回复:scanf("%s",string1); 改成 gets(string1);  记得scanf遇到空格时会结束 +1 但是最好使用fgets()可以防止溢出


Question: C 函数入参地址 为何都相同？

mark一下，下班在看

引用 8 楼 leslietuang 的回复:[quote=引用 5 楼 mujiok2003 的回复:]  va_list ap未必是一个地址， 所以不能%p  这 是否说明  不同平台对va_list相关内容  有不同的实现？[/quote]  肯定

引用 5 楼 mujiok2003 的回复:va_list ap未必是一个地址， 所以不能%p  这 是否说明  不同平台对va_list相关内容  有不同的实现？

这 是否说明  不同平台对va_list相关内容  有不同的实现？

va_list ap未必是一个地址， 所以不能%p

引用 3 楼 baipv008 的回复:ap不会依次指向每个参数的地址，而是始终指向起始变参的起始地址吧。  求解释， 这个va_list 的实现细节 是怎样的？

ap不会依次指向每个参数的地址，而是始终指向起始变参的起始地址吧。

引用 1 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）


Question: [SWU]关于指针的问题

对于打开文件是否成功是需要测试的，办法是检测fopen的返回值是否为NULL（参见fopen的手册）。

fscanf, fwscanf Read formatted data from a stream.  int fscanf( FILE *stream, const char *format [, argument ]... );  int fwscanf( FILE *stream, const wchar_t *format [, argument ]... );  Function Required Header Compatibility  fscanf <stdio.h> ANSI, Win 95, Win NT  fwscanf <stdio.h> or <wchar.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. If an error occurs, or if the end of the file stream is reached before the first conversion, the return value is EOF for fscanf or WEOF for fwscanf.  Parameters  stream  Pointer to FILE structure  format  Format-control string  argument  Optional arguments  Remarks  The fscanf function reads data from the current position of stream into the locations given by argument (if any). Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format. format controls the interpretation of the input fields and has the same form and function as the format argument for scanf; see scanf for a description of format. If copying takes place between strings that overlap, the behavior is undefined.  fwscanf is a wide-character version of fscanf; the format argument to fwscanf is a wide-character string. These functions behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _ftscanf fscanf fscanf fwscanf    For more information, see Format Specification Fields – scanf functions and wscanf Functions.  Example  /* FSCANF.C: This program writes formatted  * data to a file. It then uses fscanf to  * read the various data back from the file.  */  #include <stdio.h>  FILE *stream;  void main( void ) {    long l;    float fp;    char s[81];    char c;     stream = fopen( "fscanf.out", "w+" );    if( stream == NULL )       printf( "The file fscanf.out was not opened\n" );    else    {       fprintf( stream, "%s %ld %f%c", "a-string",                 65000, 3.14159, 'x' );        /* Set pointer to beginning of file: */       fseek( stream, 0L, SEEK_SET );        /* Read data back from file: */       fscanf( stream, "%s", s );       fscanf( stream, "%ld", &l );        fscanf( stream, "%f", &fp );       fscanf( stream, "%c", &c );        /* Output data read: */       printf( "%s\n", s );       printf( "%ld\n", l );       printf( "%f\n", fp );       printf( "%c\n", c );        fclose( stream );    } }   Output  a-string 65000 3.141590 x   Stream I/O Routines  See Also   _cscanf, fprintf, scanf, sscanf


Question: 关于hook遇到任务管理器后出现的问题

是不是因为任务管理器的类名也是IE开头的呀，他的名字是iexp。。。什么的吧

在http://www.codeproject.com搜“hook”

引用 1 楼 zhao4zhong1 的回复:MessageBox(NULL,"IE启动","提示",MB_OK); 改为  MessageBox(NULL,text,"提示",MB_OK);//看看text到底是什么内容  text里面是类名呀，IE浏览器开头两个字母是IE，跟这个没什么关系的，如果改成你那样也会崩，会出现很多对话框，上面写着#22305


Question: 关于数组增长的奇怪的问题！

各位网友，问题的答案已经找到了。 问题所处：SIZE=SIZE*2; pp=(int *)realloc(e_a->arr,SIZE); 问题：realloc(e_a->arr,SIZE)中的SIZE应该是SIZE*sizeof(int); ps:...终于找到了。。这一上午再加上晚上2个小时。。只能说自己活该了。。

realloc函数先检查ptr指向的内存块的大小，如果size比原来的小，那么realloc修改内存块头信息，缩短这块内存。剩下的部分就释放了。如果size比原来的大，那么看这块之后的空闲区域是否足够让原块扩展。够的话就修改内存块头信息。 不够就另外分配一块区域，复制原块内容然后释放原块的空间。 无论是否分配了新的空间，返回地址是真正有效的那块空间的地址。也就是只有在需要分配新空间时，才返回与ptr不同的地址。   我的理解是：realloc函数返回的是一个有效的头地址。tuzhutuzhu网友，你的意思是：realloc函数返回的新增部分的地址？

多谢各位网友的指教，其实我并不是一遇到BUG就贴上来的，我从9点开始调试，但是因为自己时初学者，用了一个上午也没什么进展，所以觉得虽然问题要靠自己解决，但是闭门造车也是不对的，所以就发了上来看看大家有没有什么指教。再次多谢大家的指教。

realloc函数返回的是指向追加分配的内存空间的地址，LZ的代码中这行不合适吧 e_a->arr=pp;

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。+1


Question: [SWU]用字符指针作为参数来传递字符串

函数可以返回指针，但要弄明白的是，函数中声明的变量将在函数返回时失效，我是指内存分配。 使用函数时，只需填入变量作为参数，调用时将复制这些变量的值，这就是所谓的传值。

仅仅是输出来，可以改代码： num     = strlen(str2); 为 num     = sizeof(str2)/sizeof(str2[0])

恩，楼上正解！

#include <stdio.h>  //库函数 strcpy 大概就是这么实现的 char *stringcopy(char *from, char *to)  {         char *dst  = to;                     while(*from!='\0'){                   *to     = *from;                   from++;                   to++;           }           *to     = '\0';          return dst;// 把to没有改动的原值，传回去就可以了   } int main(){ char a[]="From "； char b[80]= "To "; printf("a =%s,b = %s\n",a,b); printf("%s",stringcopy(a,b+3));); printf("a =%s,b = %s\n",a,b); return 0; }

你可以想：让函数返回值是字符串的地址。

第二个问题已经解决   我需要但是对于第一个问题，我还需要多研究一下。


Question: makefile  公共源文件指针链接

搜“跟我一起写makefile”

但9楼内容中无Tab字符。

引用 10 楼 zhao4zhong1 的回复:提醒：makefile里面的Tab字符必须是真的TAb字符而不能用空格代替。 这个我是真知道

提醒：makefile里面的Tab字符必须是真的TAb字符而不能用空格代替。

引用 3 楼 zhao4zhong1 的回复:会建立目录链接吗？ OBJS:= foo.o bar.o main.o SRC := foo.c bar.c main.c TARGET:=ok.exe $(TARGET):$(OBJS) 	gcc -Wall -o $@ $^ main.o:main.c foo.h bar.h 	gcc -Wall -g-O2 -c $< -o $@  foo.o:foo.h foo.c 	gcc -Wall -g-O2 -c $< -o $@ bar.o:bar.c bar.h 	gcc -Wall -g-O2 -c $< -o $@  .PHONY :all all: $(TARGET)  您看我的makefile有问题吗？总是报错 gcc -Wall -o ok.exe foo.o bar.o main.o foo.o: file not recognized: File format not recognized collect2: ld returned 1 exit status make: *** [ok.exe] Error 1

includes和/include不是一回事！  关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”

引用 13 楼 zhao4zhong1 的回复:搜“跟我一起写makefile” INC :=-I./../../includes/ FLAGS := -W -Wall -ggdb #OBJS:= main.o  bar.o  SRC := foo.c bar.c main.c #SRC :=  bar.c main.c TARGET:=ok.exe $(TARGET):$(OBJS) 	gcc -W -Wall -ggdb $(INC)  $^ -o $@ main.o:main.c bar.h foo.h 	gcc -c -W -Wall -ggdb  $(INC)  $<  -o $@  我的这个INC有问题吗？为什么 总是找不到源文件呢

会建立目录链接吗？

引用 1 楼 nanali2088 的回复:|-->Include-->|-->*.h |                     |-->…… |-->Commom-->|-->C1.c |                          |-->C2.c |             |-->H-->|-->CR-->|-->main.c                              |-->Commom-->|-->C1.c  红色部分代码并不是实际存在的，而是通过链接到上一级的common文件夹得到的。怎么实现呢？

引用 7 楼 nanali2088 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] C:\>linkd /? Links an NTFS directory to a target valid object name in Windows 2000.  LINKD Source [/D] Destination    Source             - Displays the Windows 2000 name targeted by Source    Source Destination - Links source directory to Destination directory or a                        Windows 2000 device or any valid Windows 2000 name    Source /D          - Deletes Source, regardless of whether a link exists at                        source    /?                 - Prints this help message  LINKD grafts (links) the target name directly into the name space at Source, so that Source subsequently acts as a name space junction. The Source directory must reside on a disk formatted with NTFS in Windows 2000. The destination (the target of the link) can be any valid directory name or device name or valid object name in Windows 2000. When the target name does not resolve to a directory or a device, open calls fail.  All characters in both the Source and Destination names must be in the ASCII character set. Usage of arbitrary Unicode characters is not supported.  Type "LINKD /? | more" if you need to see all the help text  C:\>junction /?  Junction v1.06 - Windows junction creator and reparse point viewer Copyright (C) 2000-2010 Mark Russinovich Sysinternals - www.sysinternals.com  The first usage is for displaying reparse point information, the second usage is for creating a junction point, and the last for deleting a junction point: usage: junction [-s] [-q] <file or directory>        -q     Don't print error messages (quiet)        -s     Recurse subdirectories  usage: junction <junction directory> <junction target>        example: junction d:\link c:\windows  usage: junction -d <junction directory>  我用了一个软连接  不知道可不可以 [/quote] 一回事

引用 6 楼 zhao4zhong1 的回复:C:\>linkd /? Links an NTFS directory to a target valid object name in Windows 2000.  LINKD Source [/D] Destination    Source             - Displays the Windows 2000 name targeted by Source    Source Destination - Links source directory to Destination directory or a                        Windows 2000 device or any valid Windows 2000 name    Source /D          - Deletes Source, regardless of whether a link exists at                        source    /?                 - Prints this help message  LINKD grafts (links) the target name directly into the name space at Source, so that Source subsequently acts as a name space junction. The Source directory must reside on a disk formatted with NTFS in Windows 2000. The destination (the target of the link) can be any valid directory name or device name or valid object name in Windows 2000. When the target name does not resolve to a directory or a device, open calls fail.  All characters in both the Source and Destination names must be in the ASCII character set. Usage of arbitrary Unicode characters is not supported.  Type "LINKD /? | more" if you need to see all the help text  C:\>junction /?  Junction v1.06 - Windows junction creator and reparse point viewer Copyright (C) 2000-2010 Mark Russinovich Sysinternals - www.sysinternals.com  The first usage is for displaying reparse point information, the second usage is for creating a junction point, and the last for deleting a junction point: usage: junction [-s] [-q] <file or directory>        -q     Don't print error messages (quiet)        -s     Recurse subdirectories  usage: junction <junction directory> <junction target>        example: junction d:\link c:\windows  usage: junction -d <junction directory>  我用了一个软连接  不知道可不可以

没看懂你的意思。common是公共代码，编译成一个库不就完了

引用 3 楼 zhao4zhong1 的回复:会建立目录链接吗？ 我没能明白意义啊？可否详细一点？


Question: 新手，求各位大神帮忙

#include <stdio.h>  int main() { 	int a; 	scanf("%d",&a); 	 	while(a>0) 	{ 		printf("%d",a%10); 		a=a/10; 	} 	return 0; } 没考虑任何特殊情况～

把數分解，還有沒有別的辦法哦？

把數分解，還有沒有別的辦法哦？

编程能力都是在自己思考调试程序和查找资料中慢慢积累起来的 不自己思考，练习代码，永远都学不会编程滴。


Question: 七年之痒——我还适合编程吗？

有钱难买“我乐意”！

引用 38 楼 beiye90 的回复:引用 34 楼 my_live_123 的回复:同岁同一个专业，我没有你搞那么花，一直坚持C/C++，一直在路上C/C++就业方向好像很渺茫啊！ 往“地狱”走的，没有往“天堂”去！还好吧，底层竞争者相对上层来说要少的多，就业要看自己的功力！

我27岁开始编程

感觉LZ支教呗耽误了4年！

干这一行，个人喜欢是最好。

我都30多快40了，都在写程序，怕毛啊。  如果你家庭经济允许，做做自己想做的事情就是，何必怕前怕后的。

这个社会估计需要一点：看谁能坚持的跑下去！哪怕起初是错误的方向，一直走下去，到最后，即使社会不认可，也是自己的成功！正如你说的那样：不后悔自己的一千个日日夜夜！come on，选择目的地，背上背包，启程吧，骚年！

同岁同一个专业，我没有你搞那么花，一直坚持C/C++，一直在路上

引用 26 楼 aa573915483 的回复:[quote=引用 24 楼 linux_hsylar 的回复:] 本人88年，有些C/C++基础，现在在北京培训C/C++的，只要对编程感兴趣，其他一切都不是问题， 楼主，加油！[/quote]哈哈，有什么问题麽？

年龄不是问题，关键是有没有决心。楼主确定自己想做程序吗？因为这是要投入不少时间和精力的。

能做连连看，还可以。

引用 24 楼 linux_hsylar 的回复:本人88年，有些C/C++基础，现在在北京培训C/C++的，只要对编程感兴趣，其他一切都不是问题， 楼主，加油！

嗯，只要你不放弃梦想，什么都有可能。

耐心，坚持，在自己认为合适的领域持续投入几年，绝对有所收获。 本人搞C++，从2002年在学校看C语言和C++语言程序设计算起，现在已经十来个年头了。至今虽然可以对c++的大部分领域都通晓，但是还是觉得很多地方不懂，还需要继续积累。 任何一门技术和语言，只要深入了解，你就会发现自己懂的越来越少，学习的兴致也会被提起。但是最怕的就是浅尝辄止，总是认为自己学某个技术已经掌握了很多东西了，应该没啥问题了，此时危险，犹如井底之蛙。。

老实说楼主目前的水平很菜，不过没什么，我当年水平更菜。编程之路很漫长，需要时间积累。

楼主现在做什么工作？

楼主有天赋,性格却不适合 程序能写得倍儿棒的,大多有点偏执狂  浅尝则止怕是不行哦

精诚所至，金石为开。兴趣是最好的老师，当然每学一样东西时都得专一才好。我完全是出于兴趣，没有任何功利心，所以也就没有什么压力，当然动力也就不会太大。愿与楼主共勉！


Question: 问个的问题,请各位拯救我这个白痴吧

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

2楼已经把该说的都说了。把另外一个for循环也贴出来应该更明了一些

lz这话问的。。。多个等号，那就是里边的循环多执行了一次，所以肯定会多输出一个 * ，至于为啥输到那儿了，那就是你其他的代码（应该是嵌套for循环方面）的问题了


Question: sscanf如何获得扫描的剩余部分？

引用 楼主 RunApp 的回复:rt，例如在网络通信里，需要做数据包拼接，而且有的时候数据一起来。这时用sscanf扫描，不知道应该怎么获得它的结束位置，以便下一次调用sscanf使用。  比较乱不知说清楚没有。 引用 1 楼 zhao4zhong1 的回复:#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.   长见识了，正解～

引用 楼主 RunApp 的回复:rt，例如在网络通信里，需要做数据包拼接，而且有的时候数据一起来。这时用sscanf扫描，不知道应该怎么获得它的结束位置，以便下一次调用sscanf使用。  比较乱不知说清楚没有。  长见识了，正解～～

int sscanf(const char *buffer,const char *format,[argument ]...); 这个函数原型可以看出，无法满足你的要求，因为无法改变const buffer，也无法知道究竟是吃了buffer多少个字符  个人愚见：这两种方案你看看 1.封包的时候，sprintf("%ns")来固定长度，不够则填充，解包时用%ns扫描 2.采用RTSP协议处理方式，商定每个可识别串都用 CR LF结束


Question: 数据结构    创建单链表问题

仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #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: 编程挑战题，求最大公倍数的那个题，输出为空值，在vc6.0上没有问题

引用 4 楼 logiciel 的回复:printf("Case %d: %d\n\n",i+1,y[i]); 以上语句将多输出一行空行。如果题目没有要求有空行，试改为： printf("Case %d: %d\n",i+1,y[i]);题目有这个，昨天测试了下好像是f赋值的那句有问题，根本没有执行。

为什么in t  nu m[]是整型的却给它赋值为浮点数呢，你可以把用到／的地方定义为double试一试

求最大公约数何必那么麻烦

引用 2 楼 liutao_12345 的回复:int ys( int a, int b) {     int s,temp;     if (b > a)     {         temp=a;         a=b;         b=temp;     }      s = a % b;  	if(s == 0) 		return b; 	else 		ys(b,s); } 不是这个原因。


Question: 用vs运行从程序，用了double型想输出的答案是1.6但是还是不一样

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

引用 8 楼 mujiok2003 的回复:[quote=引用 7 楼 u012421456 的回复:] [quote=引用 6 楼 mujiok2003 的回复:] [quote=引用 4 楼 u012421456 的回复:] double就是改用该用%lf，如果是%f会有警告，可能会造成数据丢失  %f是正确的。 [/quote] 这话怎么说[/quote]  1. printf:  %f ---- > double (因为float会转换double) %Lf ---> long double 2. scanf:  %f --- float* %lf .... double*  %Lf ... long double*  不要弄混了。 具体可以看看标准[/quote]  哦，你说的对，我简单试了试，发现这里用%f 和%lf都行，都没有警告   谢谢指点啊

printf("total is %g\n", d);  使用 %g 可以显示得好看点

引用 7 楼 u012421456 的回复:[quote=引用 6 楼 mujiok2003 的回复:] [quote=引用 4 楼 u012421456 的回复:] double就是改用该用%lf，如果是%f会有警告，可能会造成数据丢失  %f是正确的。 [/quote] 这话怎么说[/quote]  1. printf:  %f ---- > double (因为float会转换double) %Lf ---> long double 2. scanf:  %f --- float* %lf .... double*  %Lf ... long double*  不要弄混了。 具体可以看看标准

引用 6 楼 mujiok2003 的回复:[quote=引用 4 楼 u012421456 的回复:] double就是改用该用%lf，如果是%f会有警告，可能会造成数据丢失  %f是正确的。 [/quote] 这话怎么说

引用 4 楼 u012421456 的回复:double就是改用该用%lf，如果是%f会有警告，可能会造成数据丢失  %f是正确的。

lz以后还是仔细检查后再上论坛问吧

double就是改用该用%lf，如果是%f会有警告，可能会造成数据丢失

# include <stdio.h> # include <windows.h> void main() { 	double a = 1.0; 	double d = 0.2*a + 0.4*a + a; 	printf("totall is %lf\n",d);  //最好是%lf 	system("pause"); }

%d是整数，double应该是%f

printf("totall is %f\n",d);// %d---->%f输出格式弄错了吧


Question: 啊哈C语言（坐在马桶上都能读懂的编程入门书）pdf最新版

很不错的入门教程。

最好不要这么学，呵呵呵

刚学C语言，支持一下。

看截图好像不错，虽然不一定会用得到，但先留个名，有需要了再看

恩，很有特点！

说是一物即不中。  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “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

马桶编程专用

很有特点，非常不错！  引用 楼主 ahalei 的回复:分享一个超萌超简单的C语言入门。 http://download.csdn.net/detail/ahalei/7017315

分享一个超萌超简单的C语言入门。 http://download.csdn.net/detail/ahalei/7017315  先来截个图给大家看看


Question: 数据结构问题，，两动态链表合并问题

可是我的是创建3个链表呢，，，还是不明白呀，能解释下吗

3个head节点，3个数节点，共6个


Question: 控件背景设置   WIN32

Codejock.Xtreme.Suite.Pro.ActiveX

OnPaint中加图


Question: 什么时候用宏，什么时候用函数？

引用 1 楼 user-13 的回复:在你能力强大到来csdn仅为娱乐之后才考虑是否该使用函数型的宏。 支持大侠 我是能用函数时最好不用宏，具体也还没理解

能用函数时最好不用宏， 不利理解也不利调试。

编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E

其实两种方法都能达到目的，用宏的好处在于程序某个值需要修改，只要把宏定义改了就行了

给几个宏的例子， 1） 当你需要定义C++那样使用引用的时候       如果使用指针，可能显得很不好理解       而C有没有引用，这样的数据类型，此时可以使用宏。       比如 DSP定义寄存器宏        #define register_xxx  (*(DWORD*)  0xXXXXXXXXXXXX）  2） 当你需要定义通用代码的时候 ，C没有模板，直接定义通用函数比较麻烦        比如      #define  abs(x)  ((x)<0)? - (x) : (x)) 3) 另外，如果需要，可以定义宏来精简代码      比如，曾经看到有人这么写代码      #define for_inc(i,start,end)  for((i) =(start);(i)<(end);(i)++)      #define for_dec(i,start,end)  for((i) =(start);(i)>(end);(i)--)      #define swap(type,a,b) do{ type t  = a; a = b; b = t;}while(0)   PS： 一般简短的，逻辑不复杂，但是经常使用的代码，可以定义为宏 宏调用，生成的代码，比较长，但是速度较快，效果等同于C++inline----- inline 就是C++ 用来替换宏的 函数调用代码，生成的代码比较短，但是运行速度，不如宏，这点其实就是C++inline和非 inline的区别

我是这样理解的：首先他们是有区别的，第一函数可以没有返还值，而宏则必须要有返回值，第二编译时的过程是不同的，函数是通过函数调用实现的，而宏是在.o文件连接时把代码粘上去的（替换宏的引用）。举个例子： #define FUN 2+2 ,main()函数中有如下代码--printf("%d",FUN-FUN)，结果是4而不是0，因为它的执行过程是这样的FUN-FUN相当于2+2-2+2=4。从第二点可以看出用宏代替函数时会有很多的不确定性。具体什么时候用宏什么时候用函数，我不能给出明确的答案，但是我建议定义别名时用宏，需要用到某种操作时用函数。        希望能帮到你，不用谢。

一般都可以用函数替换function alike macro

宏定义不占运行时间，只占编译时间。而函数调用则占运行时间。 问：1.处理相同事件，谁的效率高？2.运行与编译是什么？有何区别？ 答：把函数定义成宏形式，原理和内联函数一样，如果函数体内代码短小，又经常调用，宏效率高，反之使用函数调用。

宏更多的用于维护一些常量 这样便于维护 因为对一般人来说用宏替代函数 那一般不是新手就是大牛

虽然很多经典名著都说宏不好 但是很多经典库中都使用很多宏

功能简单，调用次数较多的情况下，或者处于一个循环中时，用的就比较好

1.当你的程序中出现大量有意义的常数的时候，例如0x0312,0x0313，这个时候你可以把它们定义为宏 2.当你的程序需要一个开关量用来控制是否开启某个功能，你要定义一个宏 3.一些简单的小功能，比如，两个数比较大小，取某个数中第n位的值等等，你需要定义一个宏 等等

在你能力强大到来csdn仅为娱乐之后才考虑是否该使用函数型的宏。


Question: w

我好像搞错了 不行你看了以后不行我再看看

# include<stdio.h> # include <windows.h> int m, k; double n; int main() { 	float a; 	scanf("%lf %d %d", &n, &m, &k);  	float f(int m); 	a = f(m); 	printf("%.2f\n", a); 	system("pause"); 	return 0; } float f(int m) {	 	double y;  //这里还是也用double吧 	if(m == 1) 		y = k / (1+12*n); 	else 		y = (f(m-1)+k) / (1+12*n); 	return y; }  /*楼主你8行三个数据类型最好用空格分开，  还有，你已经在上面定义了n是double，怎么这里又用%ld输入啊？改成%lf试试*/ 看看行不行


Question: POJ1328 贪心算法

过了→_→ 乃白赚了20分~

瓦擦   ········哇擦擦擦擦擦擦擦·······································

注意要输出“Case”而不是“case"。        printf("case %d: %d\n",x,num);       printf("case %d: -1\n",x); 改为：       printf("Case %d: %d\n",x,num);       printf("Case %d: -1\n",x); 即可AC。


Question: 关于C语言中switch与exit问题

引用 3 楼 zhccl 的回复:fork调用一次，返回两次。fork成功之后会增加一个进程，并且在子进程调用exe系列函数之前，两个进程运行同一样代码。 因为，在两个进程中的返回不一样～父进程里返回子进程的PID，子进程返回0，等于现在两个进程都准备运行switch代码了，子进程进case0，调用了execl（...）之后，子进程和父进程运行的代码就不一样了；父进程switch，进default。。。明白了。

那是两个进程啊，你断点在一个进程里，另一个进程还是在运行的。

case0是子进程，default是父进程。fork之后，父子进程各自执行的


Question: 求教

在判断是否等于EOF的时候就不行！

怎么可能，占的内存大小都不一样


Question: 关于mfc 获取编辑框中的数字问题

引用 2 楼 u010517717 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] f=e;这句还没执行呢亲！ 噗。。。犯傻了。。。。[/quote] 没关系！我也傻过。

引用 1 楼 zhao4zhong1 的回复:f=e;这句还没执行呢亲！ 噗。。。犯傻了。。。。

f=e;这句还没执行呢亲！


Question: 8583协议求解答

楼主,是否已经解决,小弟也在处理8583的问题.

还有扩展域 65-128

// typedef struct  { // short bit_flag;			 /*0-该域不存在,1-该域存在*/    // char  data_name[37];     /*域名*/  // short length;            /*数据域长度*/  // short attribute;         /*0-ascii,1-bcd,2-长度是bcd,数据是ascii 3-bcd,跟1有所不同,可参考24域 4-长度是bcd码,数据也是bcd码* // short variable_flag;     /*0-定长,1-1位变长,2-2位变长,3位变长*/  // short length_in_byte;    /*实际长度*/ // char *data;				 /*存放具体值*/  //  // }ISO8583; */ ISO8583 market_8583[FIELD_NUM]=                                                       {                																					  //																					        0-ascii,1-bcd, //						0-该域不存在														2-长度是bcd, //						1-该域存在             域名                          数据域长度     数据是ascii 		/* FIELD  0 */ {0            ,"MESSAGE TYPE                        ",      4     ,          1          ,      0      ,      0     ,NULL}, 		/* FIELD  1 */ {0            ,"BIT MAP,EXTENDED                    ",      8     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD  2 */ {0            ,"PRIMARY ACCOUNT NUMBER              ",     19     ,          4          ,      2      ,      0     ,NULL}, 		/* FIELD  3 */ {0            ,"PROCESSING CODE                     ",      6     ,          1          ,      0      ,      0     ,NULL}, 		/* FIELD  4 */ {0            ,"AMOUNT OF TRANSACTIONS              ",     12     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD  5 */ {0            ,"AMOUNT, SETTLEMENT                  ",     12     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD  6 */ {0            ,"AMOUNT, CARDHOLDER BILLING          ",     12     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD  7 */ {0            ,"TRANSACTION DATE AND TIME           ",     10     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD  8 */ {0            ,"AMOUNT, CARDHOLDER BILLING FEE      ",      8     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD  9 */ {0            ,"CONVERSION RATE,SETTLEMENT          ",      8     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 10 */ {0            ,"CONVERSION RATE,CARDHOLDER BILLING  ",      8     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 11 */ {0            ,"System Trace Audit Number           ",      6     ,          1          ,      0      ,      0     ,NULL}, 		/* FIELD 12 */ {0            ,"Time, Local Transaction             ",      6     ,          1          ,      0      ,      0     ,NULL}, 		/* FIELD 13 */ {0            ,"Date, Local Transaction             ",      4     ,          1          ,      0      ,      0     ,NULL}, 		/* FIELD 14 */ {0            ,"Expired Date                        ",      4     ,          1          ,      0      ,      0     ,NULL}, 		/* FIELD 15 */ {0            ,"DATE, SETTLEMENT                    ",      4     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 16 */ {0            ,"DATE, CONVERSION                    ",      4     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 17 */ {0            ,"DATE, CAPTURE                       ",      4     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 18 */ {0            ,"MERCHANT'S TYPE                     ",      4     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 19 */ {0            ,"ACQUIRING INSTITUTION COUNTRY CODE  ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 20 */ {0            ,"PRIM. ACCNT. NO. EXT.,COUNTRY CODE  ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 21 */ {0            ,"FORWARDING INSTITUTION COUNTRY CODE ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 22 */ {0            ,"POINT OF SERVICE ENTRY MODE         ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 23 */ {0            ,"CARD SEQUENCE NUMBER                ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 24 */ {0            ,"Network Management Information Code ",      3     ,          3          ,      0      ,      0     ,NULL}, 		/* FIELD 25 */ {0            ,"POINT OF SERVICE CONDITION CODE     ",      2     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 26 */ {0            ,"POINT OF SERVICE PIN CAPTURE CODE   ",      2     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 27 */ {0            ,"AUTH IDENTIFICATION RESPONSE LENGTH ",      1     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 28 */ {0            ,"AMOUNT,TRANSACTION FEE              ",      9     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 29 */ {0            ,"AMOUNT,SETTLEMENT FEE               ",      9     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 30 */ {0            ,"AMOUNT,TRANSACTION PROCESSING FEE   ",      9     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 31 */ {0            ,"AMOUNT,SETTLEMENT PROCESSING FEE    ",      9     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 32 */ {0            ,"ACOUIRING INSTITUTION ID. CODE      ",     11     ,          0          ,      2      ,      0     ,NULL}, 		/* FIELD 33 */ {0            ,"FORWARDING INSTITUTION ID. CODE     ",     11     ,          0          ,      2      ,      0     ,NULL}, 		/* FIELD 34 */ {0            ,"PRIMARY ACCOUNT NUMBER,EXTENDED     ",     28     ,          0          ,      2      ,      0     ,NULL}, 		/* FIELD 35 */ {0            ,"TRACK 2 DATA                        ",     37     ,          0          ,      2      ,      0     ,NULL}, 		/* FIELD 36 */ {0            ,"TRACK 3 DATA                        ",    104     ,          0          ,      3      ,      0     ,NULL}, 		/* FIELD 37 */ {0            ,"Refrence Number                     ",     12     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 38 */ {0            ,"AUTH. IDENTIFICATION RESPONSE       ",      6     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 39 */ {0            ,"RESPONSE CODE                       ",      2     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 40 */ {0            ,"SERVICE RESTRICTION CODE            ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 41 */ {0            ,"Card Acceptor Terminal ID           ",      8     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 42 */ {0            ,"Card Acceptor Institute ID          ",     15     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 43 */ {0            ,"CARD ACCEPTOR NAME/LOCATION         ",     40     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 44 */ {0            ,"ADDITIONAL RESPONSE DATA            ",     25     ,          0          ,      2      ,      0     ,NULL}, 		/* FIELD 45 */ {0            ,"                                    ",     1      ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 46 */ {0            ,"                                    ",     1      ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 47 */ {0            ,"                                    ",     1      ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 48 */ {0            ,"ADDITIONAL DATA PRIVATE             ",    512     ,          2          ,      3      ,      0     ,NULL}, 		/* FIELD 49 */ {0            ,"ORIGINAL RRN                        ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 50 */ {0            ,"MONTH TO BATCH ENQUIRE              ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 51 */ {0            ,"CURRENCY CODE,CARDHOLDER BILLING    ",      3     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 52 */ {0            ,"PERSONAL IDENTIFICATION NUMBER DATA ",      8     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 53 */ {0            ,"SECURITY RELATED CONTROL INFORMATION",     16     ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 54 */ {0            ,"ADDITIONAL AMOUNTS                  ",    40      ,          0          ,      2      ,      0     ,NULL}, 		/* FIELD 55 */ {0            ,"                                    ",    1       ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 56 */ {0            ,"                                    ",    1       ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 57 */ {0            ,"                                    ",    1       ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 58 */ {0            ,"                                    ",    1       ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 59 */ {0            ,"                                    ",    1       ,          0          ,      0      ,      0     ,NULL}, 		/* FIELD 60 */ {0            ,"Details-Parameter-Data              ",    999     ,          2          ,      3      ,      0     ,NULL}, 		/* FIELD 61 */ {0            ,"RESERVED --- PRIVATE                ",     26     ,          0          ,      3      ,      0     ,NULL}, 		/* FIELD 62 */ {0            ,"Slip Memo                           ",    200     ,          2          ,      3      ,      0     ,NULL}, 		/* FIELD 63 */ {0            ,"RESERVED --- PRIVATE                ",     12     ,          0          ,      3      ,      0     ,NULL}, 		/* FIELD 64 */ {0            ,"Message Authentication Code         ",     8      ,          0          ,      0      ,      0     ,NULL}  };                                                                                这不是银联标准，自己参考。  记得当初我弄明白的时候就没人告诉我这些

里面有变长和定长 还有bsd编码  卡号变长所以家长度  交易类型 定长 bsd编码  得知道每个域的定义与说明

标准的ISO8583格式， TPDU + MTI + bitmap + field data 如果银联的稍微有点不通 UnionPay TPDU+ Header + MTI + field data BitMap: [ 2 ] [ 3 ] [ 4 ] [ 7 ] [ 35 ] [ 36 ] [ 41 ] 不懂你为什么将第七域放时间，标准的格式是在12域才发送的交易时间。

接下来我们按照域信息生成位图 因为有第2域，所以第二个位置是1，由第三域，所以第三个位置 是1，。。。 依此类推得到一串数字 0111 0010 0000 0000 0000 0000 0000 0000 0011 0000 1000 0000 0000 0000 0000 0000 转换过来，就是 72 00 00 00 30 80 00 00 这个就是BITMAP了 然后把上面的数据按照BITMAP+每个域的内容，依次排列 就得到这个包的内容了 7200000030800000165309987876545342900000000000000100 20030802063132333435360009123456001083938373635343332 前头再加上TPDU和MSGID就是最后的数据包  还有解包能不能解释一下。。。。


Question: 一段程序,32位windows下执行可以,64位下总会出错

看来的确是DEP的事

引用 11 楼 xuch318 的回复:自己解决了,用VirtualAlloc ,具体的原理还不怎么明白,不过可以运行了,楼上的各位,谢谢了,不过请你们下次回答问题时看清我主要问的是什么.下面顺带的把我上面提问的代码完善些,不过没有最终完善 #include <stdio.h>  int ss(int a, int b, int c) { return a+b+c; }  int main() {   long a;   const unsigned char t[] =  #if defined(WIN32) #if defined(__x86_64)  {0x55, 0x48, 0x89, 0xe5, 0x89, 0x4d, 0x10, 0x89, 0x55, 0x18, 0x44, 0x89, 0x45, 0x20, 0x8b, 0x45, 0x18, 0x8b, 0x55, 0x10, 0x01, 0xc2, 0x8b, 0x45, 0x20, 0x01, 0xd0, 0x5d, 0xc3}; #else   {0x55, 0x89, 0xe5, 0x8b, 0x45, 0x0c, 0x8b, 0x55, 0x08, 0x01, 0xd0, 0x03, 0x45, 0x10, 0x5d, 0xc3}; #endif #endif   printf("%s\n", t);  // 1   int (*x)(int, int ,int );   x = (int(*)(int,int,int))t;   a = x(1,2,8);  // 2   printf("%ld\n", a);   return 1; }   这么看不会再有人说我的t是32位或者64位汇编了吧?还有,我主要提问是在 "// 2"那句会出错,不再上面"// 1",即使说编译器没在最后加0x00,但那么大内存肯定有,到时候结束就是了,我写这句是说内存可以访问,但不可执行的 你说的是用VirtualAlloc来分配t数组？还是怎么的？

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）

引用 8 楼 bigbaldy 的回复:t里面是32位汇编，64bit下肯定执行不了 你觉得我在后面说转成32位编译器要改下t的值是什么意思？

t里面是32位汇编，64bit下肯定执行不了

引用 3 楼 xuch318 的回复:[quote=引用 1 楼 xiejianjun417 的回复:] 首先printf("%s\n", t);这一句就已经导致错误了，你采用%s格式来打印，就已经非法访问了。%s会打印直到发现‘\0'的结束符，t是一个字符数组，但是不是一个字符串。 再者x = (int(*)(int,int,int))t;怎么能直接将一个数组强制转换成函数指针呢？这样调用，肯定出问题呀  语言允许,请不要用正常思维来想这段程序,知道溢出怎么回事就不会对这段程序感觉奇怪了 这段程序从语法来说没什么问题,我打印那段字符也不是为了看printf的对错,只是看t所在的内存能否访问,而且我这么初始化内存,最后一个位编译器会加上'\0'字符的[/quote] 真是高端，还有这样的编译器

引用 5 楼 zhao4zhong1 的回复:t的值只对应32位汇编指令码而不对应64位汇编指令码。 能说的详细点吗?怎么不对应64位的汇编指令呢?

t的值只对应32位汇编指令码而不对应64位汇编指令码。

引用 楼主 xuch318 的回复:程序如下,win764位下执行到a=x(1,2,8)时就会出错,该程序在32位能够执行(t值已经更新,表示的是ss编译后的二进制),编译器用的是64位的gcc 程序执行到 "// 1"处是没问题的,看来内存是可以访问的,只是到"// 2"处就出错,看来该段内存有读的权限,但好像没运行的权限 前段时间在64位linux上也碰到类似问题,后来高人指点mprotect来解决,windows 64位下是不是问题类似?请问需要调用什么函数?  t后的数值没错,请有怀疑的看官试试自己生成.  #include <stdio.h>  int ss(int a, int b, int c) { return a+b+c; }  int main() {   long a;   unsigned char t[] = {0x55, 0x48, 0x89, 0xe5, 0x89, 0x4d, 0x10, 0x89, 0x55, 0x18, 0x44, 0x89, 0x45, 0x20, 0x8b, 0x45, 0x18, 0x8b, 0x55, 0x10, 0x01, 0xc2, 0x8b, 0x45, 0x20, 0x01, 0xd0, 0x5d, 0xc3};   printf("%s\n", t);  // 1   int (*x)(int, int ,int );   x = (int(*)(int,int,int))t;   a = x(1,2,8);  // 2   printf("%ld\n", a);   return 1; }   相信大家好多人没有64位的mingw,我用的是TDM-GCC-64,sourceforge的一个项目,大家可以下下来看看帮我分析下  这段程序32位windows下可以执行,不过要t[] = {0x55, 0x89, 0xe5, 0x8b, 0x45, 0x0c, 0x8b, 0x55, 0x08, 0x01, 0xd0, 0x03, 0x45, 0x10, 0x5d, 0xc3}, gcc -o x x.c编译(x是你所起的文件名)

引用 1 楼 xiejianjun417 的回复:首先printf("%s\n", t);这一句就已经导致错误了，你采用%s格式来打印，就已经非法访问了。%s会打印直到发现‘\0'的结束符，t是一个字符数组，但是不是一个字符串。 再者x = (int(*)(int,int,int))t;怎么能直接将一个数组强制转换成函数指针呢？这样调用，肯定出问题呀  语言允许,请不要用正常思维来想这段程序,知道溢出怎么回事就不会对这段程序感觉奇怪了 这段程序从语法来说没什么问题,我打印那段字符也不是为了看printf的对错,只是看t所在的内存能否访问,而且我这么初始化内存,最后一个位编译器会加上'\0'字符的

引用 1 楼 xiejianjun417 的回复:首先printf("%s\n", t);这一句就已经导致错误了，你采用%s格式来打印，就已经非法访问了。%s会打印直到发现‘\0'的结束符，t是一个字符数组，但是不是一个字符串。 再者x = (int(*)(int,int,int))t;怎么能直接将一个数组强制转换成函数指针呢？这样调用，肯定出问题呀  很明白了....


Question: 調用system（）問題

詩下用英文文件名來作為參數

#include<stdio.h> #include<stdlib.h>       int main()    {       char gbkcmdstr[256]="md5sum 证书.txt > 证书.txt.md5";       char utf8cmdstr[1024];        //TODO:调用iconv将gbkcmdstr转换为utf8cmdstr           system(utf8cmdstr);        return ;    }  //iconv_linux下字符集编码转换轻松实现 (1) iconv_t iconv_open(const char *tocode, const char *fromcode); //此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。 (2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft); //此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。 (3) int iconv_close(iconv_t cd); //此函数用于关闭转换句柄,释放资源。  //例子1: 用C语言实现的转换示例程序  /* f.c : 代码转换示例C程序 */ #include <iconv.h> #define OUTLEN 255 main() { char *in_utf8 = "姝ｅ?ㄥ??瑁?"; char *in_gb2312 = "正在安装"; char out[OUTLEN];  /*unicode码转为gb2312码*/ rc = u2g(in_utf8,strlen(in_utf8),out,OUTLEN); printf("unicode-->gb2312 out=%sn",out); //gb2312码转为unicode码  rc = g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN); printf("gb2312-->unicode out=%sn",out); } /*代码转换:从一种编码转为另一种编码*/ int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen) { iconv_t cd; int rc; char **pin = &inbuf; char **pout = &outbuf;  cd = iconv_open(to_charset,from_charset); if (cd==0) return -1; memset(outbuf,0,outlen); if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1; iconv_close(cd); return 0; } /*UNICODE码转为GB2312码*/ int u2g(char *inbuf,int inlen,char *outbuf,int outlen) { return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen); } /*GB2312码转为UNICODE码*/ int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen) { return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen); }  //例子2: 用C++语言实现的转换示例程序  /* f.cpp : 代码转换示例C++程序 */ #include <iconv.h> #include <iostream>  #define OUTLEN 255  using namespace std;  // 代码转换操作类  class CodeConverter {  private: iconv_t cd; public:  // 构造 CodeConverter(const char *from_charset,const char *to_charset) { cd = iconv_open(to_charset,from_charset); }   // 析构 ~CodeConverter() { iconv_close(cd); }   // 转换输出 int convert(char *inbuf,int inlen,char *outbuf,int outlen) { char **pin = &inbuf; char **pout = &outbuf;  memset(outbuf,0,outlen); return iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen); } };  int main(int argc, char **argv) { char *in_utf8 = "姝ｅ?ㄥ??瑁?"; char *in_gb2312 = "正在安装"; char out[OUTLEN];  // utf-8-->gb2312 CodeConverter cc = CodeConverter("utf-8","gb2312"); cc.convert(in_utf8,strlen(in_utf8),out,OUTLEN); cout << "utf-8-->gb2312 in=" << in_utf8 << ",out=" << out << endl;  // gb2312-->utf-8 CodeConverter cc2 = CodeConverter("gb2312","utf-8"); cc2.convert(in_gb2312,strlen(in_gb2312),out,OUTLEN); cout << "gb2312-->utf-8 in=" << in_gb2312 << ",out=" << out << endl; }    二、利用iconv命令进行编码转换  iconv命令用于转换指定文件的编码,默认输出到标准输出设备,亦可指定输出文件。  用法： iconv [选项...] [文件...]  有如下选项可用:  输入/输出格式规范： -f, --from-code=名称 原始文本编码 -t, --to-code=名称 输出编码  信息： -l, --list 列举所有已知的字符集  输出控制： -c 从输出中忽略无效的字符 -o, --output=FILE 输出文件 -s, --silent 关闭警告 --verbose 打印进度信息  -?, --help 给出该系统求助列表 --usage 给出简要的用法信息 -V, --version 打印程序版本号  例子: iconv -f utf-8 -t gb2312 aaa.txt >bbb.txt 这个命令读取aaa.txt文件，从utf-8编码转换为gb2312编码,其输出定向到bbb.txt文件。  小结: Linux为我们提供了强大的编码转换工具,给我们带来了方便。

我把    “证书”   換成 “你們”   就能正常生成 你們.txt.md5

应该是源代码与SHELL的编码不一致而导致的，你可以试试GBK看看。  引用 4 楼 u012293844 的回复:[quote=引用 2 楼 turingo 的回复:] 查看一下源代码中“证书”是什么样的编码格式？  [quote=引用 楼主 u012293844 的回复:] #include<stdio.h>    #include<stdlib.h>        int main()    {        system("md5sum 证书.txt > 证书.txt.md5");        return ;    }  目的是生成 证书.txt 的md5 文件，運行結果生成的文件卻是   ??书.txt.md5 。 請問問題出在哪？？？[/quote]事ubuntu下用我用touch 生成的一個測試文件內容是空的。漢字 用的是iUSBpinyin拼寫的  應該是utf-8 [/quote]

引用 2 楼 turingo 的回复:查看一下源代码中“证书”是什么样的编码格式？  [quote=引用 楼主 u012293844 的回复:] #include<stdio.h>    #include<stdlib.h>        int main()    {        system("md5sum 证书.txt > 证书.txt.md5");        return ;    }  目的是生成 证书.txt 的md5 文件，運行結果生成的文件卻是   ??书.txt.md5 。 請問問題出在哪？？？[/quote]事ubuntu下用我用touch 生成的一個測試文件內容是空的。漢字 用的是iUSBpinyin拼寫的  應該是utf-8

引用 1 楼 zhao4zhong1 的回复: system("md5sum \"证书.txt\" > \"证书.txt.md5\"");試了一下 不行

查看一下源代码中“证书”是什么样的编码格式？  引用 楼主 u012293844 的回复:#include<stdio.h>    #include<stdlib.h>        int main()    {        system("md5sum 证书.txt > 证书.txt.md5");        return ;    }  目的是生成 证书.txt 的md5 文件，運行結果生成的文件卻是   ??书.txt.md5 。 請問問題出在哪？？？


Question: Windows 平台 eslipse+CDT+MinGW  环境配置问题 求教！

引用 2 楼 flowersthese 的回复:[quote=引用 1 楼 user-1 的回复:] 是不是只写了个.h文件,貌似得有个.c或者.cpp文件才能开始编译 我hello world就是一个 cpp hello world.cpp[/quote]  hello world.cpp有空格的话在命令行下不行吧,你要文件名是这个的话怕是不行,"hello world.cpp"才行 另外我搜了一下,出问题的貌似也是文件名上的问题,全文复制给你,你看看变通下 先试试不仅eclipse能不能编译,确定编译器能用先,要是在命令行下输入gcc没反应,建议你把gcc所在目录加进windows的path里  "记录一下，装完eclipse和cdt后helloworld编译出现nothing to build for project helloworld。google了一把，发现我的main文件后面没有加.cpp，rename成main.cpp后成功编译。"

引用 1 楼 user-1 的回复:是不是只写了个.h文件,貌似得有个.c或者.cpp文件才能开始编译 我hello world就是一个 cpp hello world.cpp

是不是只写了个.h文件,貌似得有个.c或者.cpp文件才能开始编译


Question: 一个关于段错误的问题  大神求助啊~！~！~！~！~！~

struct ofp_action_header actions[0]    这种结构该怎么给他开辟空间啊

我又修改了一下    主函数加上了两个开辟内存的语句    但是执行最后一句printf的时候还是会报段错误   不执行printf就不报错   这是为什么呢 void main() { 	struct sine_sw_flow *f; 	 	struct sine_sw_flow_actions *sf;	 	struct ofp_action_output *oa; 	int i;						 	f = calloc(1, sizeof (struct sine_sw_flow));	 	sf = f->sf_acts;	 	oa = (struct ofp_action_output *)sf->actions; 	sf = calloc(1, sizeof (struct sine_sw_flow_actions)); 	oa = calloc(1, sizeof (struct ofp_action_output));  	oa->type = 1; 	oa->len = 8; 	oa->port = 1; 	oa->max_len = 32768; 	sf->actions_len = sizeof(struct ofp_action_output); 	f->cookie = 0; 	f->priority = 1; 	f->idle_timeout = 32768; 	f->hard_timeout = 32768; 	f->used = 1; 	f->created = 1; 	f->byte_count = 0; 	f->packet_count = 0; 	for(i = 0; i < 10; i++) 		f->key.flow.sid[i]=0xffff; 	for(i = 0; i < 8; i++) 		f->key.flow.nid_src[i]=0xffff; 	for(i = 0; i < 8; i++) 		f->key.flow.nid_dst[i]=0xeeee; 	printf("%d",f->sf_acts->actions_len); }

sizeof *f 错了吗？我改成了 sizeof(struct sine_sw_flow)还是不行    我定位错误发生在 oa = (struct ofp_action_output *)sf->actions; oa->type = 1; oa->len = 8; oa->port = 1; oa->max_len = 32768; sf->actions_len = sizeof(struct ofp_action_output); 这几句    把这几句注释掉就没有段错误了    可是这几句为什么错了呢？？？？

sf = f->sf_acts;	sf_acts这个是NULL，都没分配内存

Windows： 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 Linux： 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

sizeof *f，这个错了，你得到的是一个指针的size


Question: 动态数组。。求帮助

m = (int *)malloc(sizeof(int)*1)才分配一个int单元，m[j++]都越界了。  引用 楼主 yuanwei285 的回复:/* *输入一个数，求出它所有质因数并存到数组中，并打印 */ #include <stdio.h> #include <stdlib.h>   void main() { 	int mm,i,j;  	int *m; 	printf("Please input one number :"); 	scanf("%d",&mm);   	 	while(mm>0) 	{ 		for(i=1,j=0;i<=mm;i++) 		{ 			if((mm%i) == 0){ 				m = (int *)malloc(sizeof(int)*1);  // 找到一个质因数分配一个数组长度 				m[j++]=i ; 			} 		} 		break; 	}	 	         for(i=0;i<sizeof(m);i++) 	  printf("%d",m[i]);    打印的结果为什么是一个随机数啊？新手。。


Question: 请教一个关于VC数据库语句的问题

自己顶一下，大家帮帮忙呀

自己顶一下，大家帮帮忙呀

楼上的，还不是行呀，按你说的，m_FieldsPtr = &(kk.ID_Record->Fields); 出现错误了，你看看图片，

&m_FieldsPtr = kk.ID_Record->Fields; 改为 m_FieldsPtr = &(kk.ID_Record->Fields);

error C2440: '=' : cannot convert from 'FieldsPtr' to 'Fields **'  很明显是等号两边的数据类型不一致，不能赋值导致的错误 &m_FieldsPtr = kk.ID_Record->Fields;  m_FieldsPtr本来就是指针类型，再取地址就成了二级指针，即就是'Fields **‘，你把一个一级指针和一个二级指针相互赋值肯定会出错啊

不行呀，如果要是向你那样写的话，运行到m_FieldsPtr = kk.ID_Record->Fields;句子后，会出现错误，就是附件的。

//&m_FieldsPtr = kk.ID_Record->Fields; m_FieldsPtr = kk.ID_Record->Fields;   ??


Question: 数据结构C语言版怎样自学？

引用先说明不是为了考试，已经工作了，对编程很感兴趣，所以想看书深入了解和操作  编程的“编”就是要动手的意思， 不能只看书。

程序＝算法＋数据结构 《数据结构（C语言版）》 《算法精解（C语言实现）》

引用 2 楼 zhao4zhong1 的回复:为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 明白大概意思了，但有一个疑问，请确认这样理解对不对，数据结构是固定的？算法是活的？ 要想灵活运用算法必先掌握数据的固定结构？还是说数据结构是不断变化的，算法也是活的？

多练习多画结构和逻辑图。  引用 楼主 u013933163 的回复:先说明不是为了考试，已经工作了，对编程很感兴趣，所以想看书深入了解和操作。  之前看过C语言和汇编，然后看2小时严蔚敏的数据结构C语言版，晕晕乎乎的完全不懂，求助能帮指点下如何能学好数据结构？


Question: 编写一个程序读入一行输入，然后反向打印该行

引用 1 楼 piaobotudou 的回复:LENGTH = 20 输入回车了，但是循环没有退出来。所以还在等待输入d对奥，我说怎么回事。明白了，谢谢。

LENGTH = 20 输入回车了，但是循环没有退出来。所以还在等待输入


Question: C语言挑战题目！求大神挑战！编写产生210个2.300到1.800范围内的随机数的程序,并且以降序排序

what a big challenge!

#include<stdio.h> #include<stdlib.h> void BubbleSort(int arr[], int n) {      int i = 0, j =0;           for(i = 0; i < n; i++)        for(j = 0; j < n - 1 - i; j++)        {              if(arr[j] <arr[j + 1])              {                        arr[j] = arr[j] ^ arr[j+1];                        arr[j+1] = arr[j] ^ arr[j+1];                        arr[j] = arr[j] ^ arr[j+1];              }                     }      }  void main() { 	float a[210]={0}; 	int i=0; 	for(i=0;i<210;i++) 	{ 		a[i]=1.800+0.500*rand()/(RAND_MAX+1.0); 	} 	BubbleSort(a,210); 	for(i=0;i<210;i++)printf("%4.3f\n",a[i]); } 应该是楼主的作业吧。。。

1l有点问题，代码示例，仅供参考 int cmp(const void *a ,const void *b) { 	return (*((float*)b) - *((float*)a))*1000; }   int _tmain(int argc, _TCHAR* argv[]) {  	srand(time_t(0)); 	float n[210]; 	for(int i =0; i != 210; i++) 	{ 		n[i] = (rand()%(2300 - 1800) + 1800 + 1)/1000.0f;  // 随机产生1.800~2.300之间的一个数 	}   	qsort(n ,210 ,sizeof(float) ,cmp);  	return 0; }

简单写下思路： float n[210]; for(int i =0; i != 210; i++) n[i] = rand()%(2300 - 1800) + 1800 + 1;  // 随机产生1800~2300之间的一个整数  然后对n进行降序排序（冒泡或其他，随便），最后每个元素除以100.0即可


Question: 不用库函数，用C语言写一个函数，完成内存之间的拷贝

引用 1 楼 caozhy 的回复:不考虑效率，循环赋值就是了。 两块内存如有重叠部分得考虑下吧

不考虑效率，循环赋值就是了。

check source code of memcpy

如果有重叠，不可能实现拷贝，只能实现移动。

assert条件写反了。


Question: 关于C中全局变量的疑问

执行在main函数之前

分配在可执行文件中了.........

全局变量和静态变量都是静态存贮方式，存放在静态存储区，在main函数运行前编译器完成内存分配。程序结束后操作系统回收。

引用 14 楼 mymtom 的回复:int i = 10; 已经初始化的数据段,  由编译器(compiler)和链接器(linker)生成数据段，运行时由加载器(loader)从可执行程序的数据段加载到内存中。 对于C++来说，有所不同，对于class的话，还要执行类的构造函数  /**  * @file    hello.cpp  * @brief     */  #include <iostream> using namespace std;  class CHello { public:     CHello()     {         cout << __FILE__ << ":" <<__LINE__ << endl;     } };  CHello hello;  int main(int argc, char *argv[]) {     ;      return 0; }   $ g++ -g -o hello hello.cpp   $ gdb hello GNU gdb Fedora (6.8-37.el5) Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  Type "show copying" and "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"... (gdb) break hello.cpp:13 Breakpoint 1 at 0x8048722: file hello.cpp, line 13. (gdb) run Starting program: /home/smgview/priv/zhn/src/hello   Breakpoint 1, CHello (this=0x8049ad4) at hello.cpp:13 13                      cout << __FILE__ << ":" <<__LINE__ << endl; (gdb) bt #0  CHello (this=0x8049ad4) at hello.cpp:13 #1  0x080486ed in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at hello.cpp:17 #2  0x08048705 in global constructors keyed to hello () at hello.cpp:25 #3  0x0804880b in __do_global_ctors_aux () #4  0x080484f9 in _init () #5  0x08048799 in __libc_csu_init () #6  0x00a1fe41 in __libc_start_main () from /lib/libc.so.6 #7  0x080485d1 in _start ()

个人觉得是编译器做的

《Windows PE权威指南》

准确的说，编译器把你的代码翻译成机器规则，在执行的时候，按照这个规则进行空间创建和赋值。

全部变量是在main函数调用之前就已经分配了内存。MFC中的app对象就是这样做到的。如果你懂C++可以自己测试，在cpp中声明一个类对象，此类的构造函数会先于main函数被调用

由操作系统来做？精确的说是编译器做的

我觉得是过程式运行的，在main运行之前分配

main之前，看编译原理和操作系统

参考Linux源代码相关片断。

在main函数之前的启动代码中。  引用 楼主 RJGCSS 的回复:我想问一下，如果在C语言中定义了一个全局变量并且赋值了，请问什么时候给变量分配一个全局的内存和赋初值？  在程序加载的时候？？ 由操作系统来做？？？

在main函数之前就已经分配好内存空间了

main之前，属于数据段

如果是C语言,其实编译器就完成了这个操作,为全局变量分配了虚拟地址并赋初值. 程序加载时, OS为每个虚地址页匹配一个物理地址页

是的！执行在main函数之前


Question: 求学长学姐大神指教一个归并排序算法

1 递归树画起来不对，每次都是两分的 2 你参数中的temp是做什么的，不是用来存放中间结果吗

二路归并：http://blog.csdn.net/zhangxiangdavaid/article/details/34463409 有图，有分析

数组只有一个元素也是一个有序数组

谢谢，但我还是不理解，每次执行mergesort(a, first, mid, temp)到不满足条件后，比如第一次到{3}它存放在a数组里面吗？

你的图上，{3,5}进行mergesort，{4}进行mergesort之后并没有进行合并操作。 {3,5}应该和{4}进行mergearray变成{3,4,5}然后再与{7,9}进行mergearray变成{3,4,5,7,9} http://blog.csdn.net/zhccl/article/details/7964164


Question: 想了解下各种计算机语言的用途

你手机里的一些好玩的好用的APP，电脑上的软件游戏，还有一些智能的工具怎么来的呢？

引用 8 楼 zhao4zhong1 的回复:建议下载研究eMule源代码。 赵老师今天心情很不错，多谢指点一二！

面向对象只是一种编程思想。 再抽象的编程语言，最后不都变成汇编代码了吗？我们完全可以说汇编语言是面向对象、脚本化、动态化、泛函化、并行化、分布化的语言。

建议下载研究eMule源代码。

引用 6 楼 zhao4zhong1 的回复:[quote=引用 5 楼 u013933163 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 有几个疑问，1是汇编语言是不是window汇编？2是按照上面箭头顺序，看完C语言是不是应该看数据结构、编译原理、操作系统了？？[/quote] 不一定是Windows汇编，只要是X86系列的汇编即可。 不要只停留在看的层面，要动手单步调试或设断点调试。[/quote] 还想问问，C语言是面向过程的，那么写好的程序如何让它面向对象？ 比如说怎样才能把一个写好的程序包装一下，做成一个软件界面实现该程序的功能呢？

引用 5 楼 u013933163 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 有几个疑问，1是汇编语言是不是window汇编？2是按照上面箭头顺序，看完C语言是不是应该看数据结构、编译原理、操作系统了？？[/quote] 不一定是Windows汇编，只要是X86系列的汇编即可。 不要只停留在看的层面，要动手单步调试或设断点调试。

引用 4 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 有几个疑问，1是汇编语言是不是window汇编？2是按照上面箭头顺序，看完C语言是不是应该看数据结构、编译原理、操作系统了？？

引用 1 楼 starytx 的回复:你这个话题太大了，可以先找一本c语言基础书，数据结构等看看，特别是序言部分多看看  只能给你几个传送门了——http://www.ruanyifeng.com/blog/2010/03/programming_language_evaluations_revised.html  http://zh.wikipedia.org/wiki/编程语言  http://wenda.so.com/q/1375398910068449?src=110  http://wenku.baidu.com/view/d060eb176c175f0e7cd137f6.html  http://www.docin.com/p-259815231.html


Question: 汉字转换拼音

#include <stdio.h> #include <string.h> #define MAXLEN 1000 char ln[MAXLEN]; FILE *f; int i,z; int b,n,L; int main(int argc,char **argv) {     if (argc<2) {         printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);         return 1;     }     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     z=0;     b=0;     n=0;     L=0;     while (1) {         if (NULL==fgets(ln,MAXLEN,f)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) {             if (0==z) {                 for (i=0;i<L-1;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L-1) z=1;//当前行不是空行             }             if (0==z) b++; else n++;             z=0;         } else {             if (0==z) {                 for (i=0;i<L;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L) z=1;//当前行不是空行             }         }     }     fclose(f);     if (L>0 && '\n'!=ln[L-1]) {         if (0==z) b++; else n++;//最后一行末尾无'\n'也计算     }     printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);     return 0; }

fgets, fgetws Get a string from a stream.  char *fgets( char *string, int n, FILE *stream );  wchar_t *fgetws( wchar_t *string, int n, FILE *stream );  Function Required Header Compatibility  fgets <stdio.h> ANSI, Win 95, Win NT  fgetws <stdio.h> or <wchar.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns string. NULL is returned to indicate an error or an end-of-file condition. Use feof or ferror to determine whether an error occurred.  Parameters  string  Storage location for data  n  Maximum number of characters to read  stream  Pointer to FILE structure  Remarks  The fgets function reads a string from the input stream argument and stores it in string. fgets reads characters from the current stream position to and including the first newline character, to the end of the stream, or until the number of characters read is equal to n – 1, whichever comes first. The result stored in string is appended with a null character. The newline character, if read, is included in the string.   fgets is similar to the gets function; however, gets replaces the newline character with NULL. fgetws is a wide-character version of fgets.   fgetws reads the wide-character argument string as a multibyte-character string or a wide-character string according to whether stream is opened in text mode or binary mode, respectively. For more information about using text and binary modes in Unicode and multibyte stream-I/O, see Text and Binary Mode File I/O and Unicode Stream I/O in Text and Binary Modes.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _fgetts fgets fgets fgetws    Example  /* FGETS.C: This program uses fgets to display  * a line from a file on the screen.  */  #include <stdio.h>  void main( void ) {    FILE *stream;    char line[100];     if( (stream = fopen( "fgets.c", "r" )) != NULL )    {       if( fgets( line, 100, stream ) == NULL)          printf( "fgets error\n" );       else          printf( "%s", line);       fclose( stream );    } }   Output  /* FGETS.C: This program uses fgets to display     Stream I/O Routines  See Also   fputs, gets, puts

如果我要是用字符串数组做呢   是不是在Fgets读取时在后面自动加上了'\0'

引用 5 楼 beiye90 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:]     char a[7000][100];     char b[1000];      if ((cp=fopen("常用汉字拼音对照表.txt","r"))==NULL) {         printf("\n\n\t\t    没有对照表！\n\n");         return;     }     while (1) {         if (NULL==fgets(a[i],100,cp)) break;         if ('\n'==a[i][strlen(a[i])-1]) a[i][strlen(a[i])-1]=0;         i++;         if (i>=7000) break;     }  我做时 把这个a[i][strlen(a[i])-1]=0;写成了a[i][strlen(a[i])-1]='\0'; 为什么不行？[/quote] 你前面少条件if ('\n'==a[i][strlen(a[i])-1]) 啊。

引用 3 楼 zhao4zhong1 的回复:    char a[7000][100];     char b[1000];      if ((cp=fopen("常用汉字拼音对照表.txt","r"))==NULL) {         printf("\n\n\t\t    没有对照表！\n\n");         return;     }     while (1) {         if (NULL==fgets(a[i],100,cp)) break;         if ('\n'==a[i][strlen(a[i])-1]) a[i][strlen(a[i])-1]=0;         i++;         if (i>=7000) break;     }  我做时 把这个a[i][strlen(a[i])-1]=0;写成了a[i][strlen(a[i])-1]='\0'; 为什么不行？

还是换行啊！

char a[7000][100];     char b[1000];     if((cp=fopen("常用汉字拼音对照表.txt","r"))==NULL)     printf("\n\n\t\t    没有对照表！\n\n");     while (!feof(cp))     {         fgets(a[i++],100,cp);


Question: 【SWU} 如何判断一个数是质数？

格式不对，应该是【】

你的循环体没有包括 i++;所以死循环了。加一个大括号，扩住while开始到i++;


Question: 一个关于内存和程序加载的问题，求助

参考Linux源代码中加载可执行程序相关片断。

可以预定的，然后厂家给你做缺货处理，然后补货

first, you should know windows memory management

你的程序（text)和数据（data)会被OS 内存管理模块按需映射到物理存储（内存+ 磁盘（虚拟内存））

引用 1 楼 user-6 的回复:实际运行到需要的时候才会动态加载进去的！ 不会一下子全部加载的！ 扛不住的！ 你好，这是我原先的理解，不知道哪些地方有错  比如F盘有个A.exe,C盘有个PageFile.sys交换文件  运行A.exe的时候就把他的全部地址空间的内容读入内存一小部分，并将其余大部分装入PageFile.sys  当A.exe访问某个不在物理内存的虚拟地址时发生缺页中断，并从PageFile.sys寻找缺页 ......

有一种机制叫缺页处理。

实际运行到需要的时候才会动态加载进去的！ 不会一下子全部加载的！ 扛不住的！


Question: [SWU]c语言 16进制转换为10进制

if (s[i] == 0){         ++i;         if (s[i] == 'x' || s[i] == 'X')             ++i;     } 这里就错了。改为if (s[i] =='0'){         ++i;         if (s[i] == 'x' || s[i] == 'X')             ++i;     }[/code]