Question: 求1到1000加起来结果，四种算法有两种不理解求指导

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

转成数学很容易看懂

引用 1 楼 user-7 的回复:/*第二种算法*/ // 第一个for循环先算出1+2+...+100的和，第二个for循环算出1+2+...1000的和 #include <stdio.h> int main() {     int a,b=0,sum=0;      for(a=1; a<=100; a++)         b += a;     //b就是1~100     sum = b;        // sum是1+2+...100的和      for(a=1; a<=9; a++)     {          b = b+10000;    // 101+102+...+200 的和比 1+2+...+100 的和大 10000，以此类推，应该懂了吧         sum = sum+b;     }     printf("%d\n", sum);      return 0; }   /*第三种算法*/ #include <stdio.h> int main() {     int s=0, low=1, high=1000;      //  for(; low<high; s+=(low+high), low++,high--) //      ; //  将上面的for写成这样 //  将1到1000依次首尾相加。应该很容易看懂的。     for (; low<high; low++, high++)     {         s += (low+high);     }     printf("%d",s);          return 0; }  记得结贴啊 +1

引用 1 楼 user-7 的回复:/*第二种算法*/ // 第一个for循环先算出1+2+...+100的和，第二个for循环算出1+2+...1000的和 #include <stdio.h> int main() {     int a,b=0,sum=0;      for(a=1; a<=100; a++)         b += a;     //b就是1~100     sum = b;        // sum是1+2+...100的和      for(a=1; a<=9; a++)     {          b = b+10000;    // 101+102+...+200 的和比 1+2+...+100 的和大 10000，以此类推，应该懂了吧         sum = sum+b;     }     printf("%d\n", sum);      return 0; }   /*第三种算法*/ #include <stdio.h> int main() {     int s=0, low=1, high=1000;      //  for(; low<high; s+=(low+high), low++,high--) //      ; //  将上面的for写成这样 //  将1到1000依次首尾相加。应该很容易看懂的。     for (; low<high; low++, high++)     {         s += (low+high);     }     printf("%d",s);          return 0; }  记得结贴啊正解

引用 2 楼 afire22 的回复:楼上正解，再加一种递归算法 int sum(int a) { 	if(a == 0) 		return 0; 	return sum(--a)+a; }   int main(int argc, char* argv[]) { 	int s = sum(1000); 	printf("%d\n",s); 	return 0; } 这个递归不对，return sum(--a)+a;第一次a的值只有999 #include <stdio.h>  int sum(int a) { if(a == 0) return 0; int b = a; return b + sum(--a); } int main(int argc, char* argv[]) { int s = sum(1000); printf("%d\n",s); return 0; } 这样才对


Question: typedef   结构体  指针

引用 4 楼 u011577666 的回复:[quote=引用 1 楼 shimachao 的回复:] 表示一个指针。以后你可以用LinkList p来定义指针p；  意思是LNode *p;和*LinkList p是等价的  就是说 LinkList p; 和 LNode *p;效果一样？[/quote] 是的，你已领悟了精髓

引用 6 楼 mcmay 的回复:敲错了，以上我写的内容中Node应为LNode。 相当于 struct LNode{ ElemType data; struct LNode *next; }; typedef struct LNode LNode; //这里LNode就相当于struct LNode typedef struct LNode * LinkList; //同理，LinkList就相当于struct LNode * （一个struct LNode类型的指针）  声明一个LinkList a就相当于声明一个struct LNode * a。LinkList就是一个struct LNode类型的指针。谢谢哈，终于知道怎么用了

引用 楼主 u011577666 的回复:typedef struct LNode{ 	ElemType data; 	struct LNode *next; }LNode,*LinkList;  *LinkList 这个怎么理解，就教~ 相当于 struct LNode{ 	ElemType data; 	struct LNode *next; }; typedef struct Node LNode; //这里LNode就相当于struct Node typedef struct Node * LinkList; //同理，LinkList就相当于struct Node * （一个struct Node类型的指针）  声明一个LinkList a就相当于声明一个struct Node * a。LinkList就是一个struct Node类型的指针。

引用 1 楼 shimachao 的回复:表示一个指针。以后你可以用LinkList p来定义指针p；  意思是LNode *p;和*LinkList p是等价的  就是说 LinkList p; 和 LNode *p;效果一样？

我上一个的回答应该有点不精确，用typedef将LinkList定义为一个类型，该类型是指向结构体的指针类型，以后可以用LinkList来直接定义指向该结构体指针的对象

LinkList就是指向该结构体的指针，该结构体应该定义了一个链表。


Question: 4参数拟合算法 C语言

自己顶一下!!!


Question: 发送GET命令给服务器获取资源recv接收的内容怎么解析？

谢谢 ，已经解决了 thank you....

这是HTTP的协议头部分，略过不存即可。


Question: C语言：文件中字符串的查找与替换

这个 或许能解决你的问题 http://blog.csdn.net/gsx_xiaoxia/article/details/51835425

所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。

首先，要先把源文件内容读到内存中，然后直接判断下支付传内容是否满足条件，如果满足则读取头文件中的内容到内存中，并且把源文件中的内容清空（清空方法很多，可以直接杂文件头位置写入新数据或者直接删除源文件再创建个），这个时候，把头文件中的内容写到源文件中就OK了

文件读写是否会？


Question: 可以这样初始化结构吗

引用 2 楼 braveboyny 的回复:你还不如把发帖的时间用来自己用编译器试一试。 这个可以有

引用 17 楼 xiaohuh421 的回复:1楼的做法已经是标准做法了.    [quote=引用 16 楼 yangyunzhao 的回复:] [quote=引用 1 楼 xianzq888 的回复:] DATA B = { 0 }; 这个效率比memset高[/quote]  这个不一定比memset高, 要看结构体大小, 结体比较大时, 它也是使用memset. 你可以看反汇编代码, 看它是怎么实现={0}的.[/quote]  这个好像是的。 不过还是建议用=，大体来说比memset高

1楼的做法已经是标准做法了.    引用 16 楼 yangyunzhao 的回复:[quote=引用 1 楼 xianzq888 的回复:] DATA B = { 0 }; 这个效率比memset高[/quote]  这个不一定比memset高, 要看结构体大小, 结体比较大时, 它也是使用memset. 你可以看反汇编代码, 看它是怎么实现={0}的.

引用 1 楼 xianzq888 的回复:DATA B = { 0 };  这个效率比memset高

引用 10 楼 u011362822 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  ++[/quote] ++

引用 8 楼 u013523101 的回复:你要声明DATA结构体的话直接用 DATA B;就可以声明了。为何你还有DATA B=DATA{}? C#用多了？ DATA D = {xxoo}  C本来就支持 如果直接DATA D  d的各个域的数据就有许多乱数据在上面

引用 2 楼 braveboyny 的回复:你还不如把发帖的时间用来自己用编译器试一试。 +1

你在编译器里面试试啊

引用 6 楼 zhao4zhong1 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  ++

嗯嗯

好像不行

引用 2 楼 braveboyny 的回复:你还不如把发帖的时间用来自己用编译器试一试。  顶啊，这种问题自己试一下就可以了。把所有成员都打印一下就知道了

引用 2 楼 braveboyny 的回复:你还不如把发帖的时间用来自己用编译器试一试。 这个建议可以有

你还不如把发帖的时间用来自己用编译器试一试。

DATA B = { 0 };


Question: DS:如何获取鼠标选中的文件路径

仅供参考，尽管是VB6： VERSION 5.00 Begin VB.Form Form1    BorderStyle     =   1  'Fixed Single    Caption         =   "ShowFilesOnClipboard - Double-click to refresh."    ClientHeight    =   3135    ClientLeft      =   45    ClientTop       =   330    ClientWidth     =   7560    Icon            =   "ShowFilesOnClipboard.frx":0000    LinkTopic       =   "Form1"    MaxButton       =   0   'False    MinButton       =   0   'False    ScaleHeight     =   3135    ScaleWidth      =   7560    StartUpPosition =   2  '屏幕中心    Begin VB.TextBox Text1       Height          =   2895       Left            =   120       Locked          =   -1  'True       MultiLine       =   -1  'True       ScrollBars      =   3  'Both       TabIndex        =   0       Text            =   "ShowFilesOnClipboard.frx":030A       Top             =   120       Width           =   7335    End End Attribute VB_Name = "Form1" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Option Explicit Private Const CF_HDROP = 15 Private Type POINT     x As Long     y As Long End Type Private Type DROPFILES     pFiles As Long     pt As POINT     fNC As Long     fWide As Long End Type Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long Private Declare Function CloseClipboard Lib "user32" () As Long Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Sub ShowFilesOnClipboard()    Dim lHandle As Long    Dim lpResults As Long    Dim lRet As Long    Dim df As DROPFILES    Dim strDest As String    Dim lBufferSize As Long    Dim arBuffer() As Byte    Dim vNames As Variant    Dim i As Long    Dim txt As String    Dim fn As String    Dim fs As Object     Set fs = CreateObject("Scripting.FileSystemObject")    If OpenClipboard(0) Then       lHandle = GetClipboardData(CF_HDROP)       ' If you don't find a CF_HDROP, you don't want to process anything       If lHandle > 0 Then          lpResults = GlobalLock(lHandle)           lBufferSize = GlobalSize(lpResults)          ReDim arBuffer(0 To lBufferSize)           CopyMemory df, ByVal lpResults, Len(df)          Call CopyMemory(arBuffer(0), ByVal lpResults + df.pFiles, (lBufferSize - Len(df)))           If df.fWide = 1 Then             ' it is wide chars--unicode             strDest = arBuffer          Else             strDest = StrConv(arBuffer, vbUnicode)          End If          GlobalUnlock lHandle          vNames = Split(strDest, vbNullChar)          i = 0          txt = ""          Do             fn = vNames(i)             If Len(fn) <= 0 Then Exit Do             If fs.FolderExists(fn) Then fn = fn + "\"             If InStr(fn, " ") > 0 Then                 txt = txt + Chr(34) + fn + Chr(34) + vbCrLf             Else                 txt = txt + fn + vbCrLf             End If             i = i + 1          Loop       Else          txt = "No files on clipboard. Double-click to refresh."       End If    Else       txt = "Can not open clipboard. Double-click to retry."    End If    CloseClipboard    Set fs = Nothing    Text1.Text = txt End Sub  Private Sub Form_DblClick()    Call ShowFilesOnClipboard End Sub  Private Sub Form_Load()    Call ShowFilesOnClipboard End Sub  Private Sub Text1_DblClick()    Call ShowFilesOnClipboard End Sub  Private Sub Text1_KeyPress(KeyAscii As Integer)     If KeyAscii = 1 Then 'ctrl a         Text1.SelStart = 0         Text1.SelLength = Len(Text1.Text)     ElseIf KeyAscii = 3 Then 'ctrl c         Text1.SelLength = 0         Clipboard.SetText Text1.Text     End If End Sub

学习了

谁知道的麻烦告之下

引用 楼主 yirancpp 的回复:英语不上不知道怎么在那个网站上搜

我搜索一下IShellWindows 接口，涉及到windows shell编程，你这是获取选中文件的路径。 另外到http://www.codeproject.com或http://www.sourceforge.net中搜索一下，应该有很多这样的示例。

引用 3 楼 zhao4zhong1 的回复:搜“Shell extension” [/quote]只找到一个复制文件名的但是已经很老了

搜“Shell extension”


Question: 求一个C语言子函数

，fwrite

楼主，连百度贴“C语言”吧都鄙视这种伸手行为！所以，你去百度吧，不然后面的大神要来喷你了！

何必学这个专业。

课本上都有啊，fopen + fputs

fprintf

引用 5 楼 maomaodelaogong 的回复:引用 楼主 BULLrule 的回复:老师要我们做一个任务，我负责其中一个子函数的编程，因为不是考试范围，所以不想花时间学，求大神赐一个，具体要求是实现C语言的数据保存到磁盘文件中，只要一个子函数，求大神！！很简单的……呵呵，不是考试范围？不想花时间？既然不打算靠编程混饭，接的什么任务？学的什么计算机？改行吧……我估计就凭你这句话就没人想帮你，帮你的都是傻子……我看楼下谁还帮…… 看过之后我有股想骂人的冲动，自己做吧，少年！

fopen，fwrite？

不想学就不要接受任务。 显然你没搞清楚输入数据。什么叫C语言数据 所以只能给你些通用方法： fwrite ofstream

论坛上很多,楼主可以找找

fwrite


Question: C语言分析网页源文件

引用 1 楼 user-3 的回复:听说过硕鼠么，下面是它的网址 http://www.flvcd.com/ 收藏了。

用脚本语言比较适合干这个事

引用 1 楼 user-3 的回复:听说过硕鼠么，下面是它的网址 http://www.flvcd.com/谢谢诶，很好用的软件啊

听说过硕鼠么，下面是它的网址 http://www.flvcd.com/


Question: socket通信中可以用select函数来解决单线程问题吗？

多谢各位啦~

引用 10 楼 yulihua49 的回复:[quote=引用 9 楼 q191201771 的回复:] 看需求咯 如果是linux一般一个epoll线程够了 无论select或epoll，在一个线程时，都可以理解为一个线程的线程池。 多线程时，epoll比较方便实现，select比较麻烦，而且低效。[/quote] 撇开效率，上层写代码，epoll和select其实差不多，都是每个socket都是由一且唯一的epoll（select）管理 你说的一个线程相当于线程池中的一个线程，其实还是有差别的，你可以考虑下多对多通信的情况，就要跨线程了。 另外，如果计算比较密集，把计算和io线程分离也行。 这里我写的一个epoll库 https://code.csdn.net/q191201771/chef

可以系统的看看APUE

看需求咯 如果是linux一般一个epoll线程够了

参考MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\IOCTL.C /******************************************************************************\ * ioctl.c - TCP server * *       This is a part of the Microsoft Source Code Samples. *       Copyright 1996-1997 Microsoft Corporation. *       All rights reserved. *       This source code is only intended as a supplement to *       Microsoft Development Tools and/or WinHelp documentation. *       See these sources for detailed information regarding the *       Microsoft samples programs. \******************************************************************************/    #define WIN32_LEAN_AND_MEAN #include <winsock2.h> #include <stdlib.h> #include <stdio.h> #include <string.h>  #define DEFAULT_PORT 5001  int ReadAndEcho(SOCKET , char *,int ) ; int WriteMessage(SOCKET , char *,int ) ;  void Usage(char *progname) {     fprintf(stderr,"Usage\n%s -e [endpoint] -i [interface]\n",         progname);     fprintf(stderr,"Where:\n");     fprintf(stderr,"\tendpoint is the port to listen on\n");     fprintf(stderr,"\tinterface is the ipaddr (in dotted decimal notation)");     fprintf(stderr," to bind to\n");     fprintf(stderr,"Defaults are 5001 and INADDR_ANY\n");     WSACleanup();     exit(1); } int main(int argc, char **argv) {      char Buffer[128];     char *interface= NULL;     unsigned short port=DEFAULT_PORT;     int fromlen;     int i, ioctl_opt =1;     struct sockaddr_in local, from;     WSADATA wsaData;     SOCKET listen_socket, msgsock;     fd_set readfds, writefds, exceptfds;      /* Parse arguments */     if (argc >1) {         for(i=1;i <argc;i++) {             if ( (argv[i][0] == '-') || (argv[i][0] == '/') ) {                 switch(tolower(argv[i][1])) {                     case 'i':                         interface = argv[++i];                         break;                     case 'e':                         port = atoi(argv[++i]);                         break;                     default:                         Usage(argv[0]);                         break;                 }             }             else                 Usage(argv[0]);         }     }      if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) {         fprintf(stderr,"WSAStartup failed with error %d\n",WSAGetLastError());         WSACleanup();         return -1;     }      if (port == 0){         Usage(argv[0]);     }      //     // The fd sets should be zeroed out before using them to prevent errors.     FD_ZERO(&readfds);     FD_ZERO(&writefds);     FD_ZERO(&exceptfds);     memset(Buffer,0,sizeof(Buffer));      local.sin_family = AF_INET;      //     // bind to specific interface if desired.      local.sin_addr.s_addr = (!interface)?INADDR_ANY:inet_addr(interface);      /*      * Port MUST be in Network Byte Order      */     local.sin_port = htons(port);      listen_socket = socket(AF_INET, SOCK_STREAM,0); // TCP socket     if (listen_socket == INVALID_SOCKET){         fprintf(stderr,"socket() failed with error %d\n",WSAGetLastError());         WSACleanup();         return -1;     }     //     // bind() associates a local address and port combination with the     // socket just created.      if (bind(listen_socket,(struct sockaddr*)&local,sizeof(local) )         == SOCKET_ERROR) {         fprintf(stderr,"bind() failed with error %d\n",WSAGetLastError());         WSACleanup();         return -1;     }      //     // start listening on the socket for incoming connections     //     if (listen(listen_socket,5) == SOCKET_ERROR) {         fprintf(stderr,"listen() failed with error %d\n",WSAGetLastError());         WSACleanup();         return -1;     }     printf("%s: Listening on port %d\n",argv[0],port);      //     // Set the socket to non-blocking mode.     //     if (ioctlsocket(listen_socket,FIONBIO,&ioctl_opt) == SOCKET_ERROR) {         fprintf(stderr,"ioctlsocket failed %d\n",WSAGetLastError());         WSACleanup();         return -1;     }     //     // The structure of the loop below is very simple. We only accept one     // connection at a time. As soon as another client connects, we     // disconnect the first one, and start talking to the new client.     // All this server does is to echo the data received on the socket     // back to the client.     //     // This is not a very realistic server, but it does serve to show that     // select() does not scale very well on win32. If we were dealing     // with more than one client, we would have to have a list of sockets     // that are in each fdset to be able to check them when select()     // returns.     //     while(1) {          //         // A socket in the listen() state becomes ready to read when a         // client connects to it. An accept() will complete without         // blocking.         // Since select sets the sockets that are ready to be read from or         // written to, we have to include listen_socket in the fdset each time         // through the loop.         //          FD_SET(listen_socket,&readfds);          i = select(0,&readfds,&writefds,&exceptfds,NULL);         if (i == SOCKET_ERROR) {             fprintf(stderr,"select failed %d\n",WSAGetLastError());         }         if (i==0){             fprintf(stderr,"Select returned no fds ready\n");         }          if (FD_ISSET(listen_socket, &readfds)){             //             // close the previous client socket.             // We must also clear it from the fdset to prevent select()             // from failing.             //             closesocket(msgsock);             FD_CLR(msgsock,&readfds);             FD_CLR(msgsock,&writefds);             fromlen = sizeof(from);             msgsock= accept(listen_socket,(struct sockaddr*)&from,&fromlen);             if (msgsock == INVALID_SOCKET) {                 fprintf(stderr,"accept failed %d\n",WSAGetLastError());                 WSACleanup();                 return -1;             }             FD_SET(msgsock,&writefds);             FD_SET(msgsock,&readfds);             continue;         }         if (FD_ISSET(msgsock,&readfds) ) {             //             // socket is ready to read, i.e., there is data on the socket.             //             if (ReadAndEcho(msgsock,Buffer,sizeof(Buffer))<0) {                 fprintf(stderr,"terminating connection\n");                 FD_CLR(msgsock,&readfds);                 FD_CLR(msgsock,&writefds);                 closesocket(msgsock);                 continue;             }         }         if (FD_ISSET(msgsock,&writefds) ){             if (WriteMessage(msgsock,Buffer,sizeof(Buffer)) <=0) {                 fprintf(stderr,"terminating connection\n");                 FD_CLR(msgsock,&readfds);                 FD_CLR(msgsock,&writefds);                 closesocket(msgsock);                 continue;             }         }         FD_SET(msgsock,&writefds);         FD_SET(msgsock,&readfds);     } } int ReadAndEcho(SOCKET insock, char *Buffer,int size) {     int rc;      rc = recv(insock,Buffer,size,0);      if (rc == SOCKET_ERROR) {         fprintf(stderr,"recv() failed with error %d\n",WSAGetLastError());         return -1;     }     if (rc ==0) {         fprintf(stderr,"Connection closed by client\n");         return 0;     }     printf("Received [%s] from client\n",Buffer);     return rc; } int WriteMessage(SOCKET outsock, char *Buffer,int size) {     int rc;     int lasterr;      printf("Sending [%s] to client\n",Buffer);     rc = send(outsock,Buffer,size, 0);      if (rc == SOCKET_ERROR) {       lasterr = WSAGetLastError();       if (lasterr == WSAEWOULDBLOCK)         return 0;       else {         fprintf(stderr,"send() failed with error %d\n",lasterr);         return -1;       }     }     if (rc ==0) {         fprintf(stderr,"Connection closed by client\n");     }     return rc; }  http://bbs.csdn.net/topics/390374955

只是不阻塞而已！客户端的请求处理还是得排队。。

可以实现，UNP V1 149页里面有具体的实现方法。但是通常我不会这么做。

引用 2 楼 user-11 的回复:单线程用select可以实现多链接，可是和多线程比，有毛优势呢。 没啥优势，只是select实现多线程很麻烦，一般就不费那个劲了。

引用 9 楼 q191201771 的回复:看需求咯 如果是linux一般一个epoll线程够了 无论select或epoll，在一个线程时，都可以理解为一个线程的线程池。 多线程时，epoll比较方便实现，select比较麻烦，而且低效。

select函数只能解决小连接数量的socket连接，一般默认定义小于64个。多的还是使用多线程比较好。参考《windows网络和通信程序设计》第一章

引用 6 楼 sd530842780 的回复:这个只是一种方法吧，相当于做了一个小玩具 同意

这个只是一种方法吧，相当于做了一个小玩具

引用 3 楼 galileo_chan 的回复:引用 2 楼 user-11 的回复:单线程用select可以实现多链接，可是和多线程比，有毛优势呢。确实没有什么优势，只能说是在单线程下一种实现方法吧。。 select函数的例子可以看《UNIX网络编程（卷1）》。 有没有优势看具体的需求。考虑一下IO密集型和CPU密集型两种需求

单线程用select可以实现多链接，可是和多线程比，有毛优势呢。

#define MAX_SOCK_FD  FD_SETSIZE #define BUFFER_SIZE  1024  #include"MyMsg.h"  #define PORT 6000									//服务器端口地址 #define MAX_MANY_CLIENT  255			//最多可接收的客户端数 #define IP	"127.0.0.1"		    		//服务器IP地址  int serverSocketFd = 0;			    	//服务器的socket的文件描述符 int clientSocketFd = 0;  struct sockaddr_in server_addr = {0} ;	//用于聆听客户端的socket描述符，并放于等待队列中 struct sockaddr_in client_addr = {0} ; socklen_t  socklen = sizeof(struct sockaddr_in);  void startCommunication(FILE*fp,char*fm,manInfolinkT*p1 ,onLineManInfolinkT *p2) { 	int fd	; 	 	int  i = 0;    //用于循环 	int  j = 0;	   //存放某个字符所在的位置 	int  m = 0;    //用于循环计数 	int bai = 0;   //暂存fd的百位 	int shi = 0;   //暂存fd的个十位 	int ge  = 0;   //暂存fd的个位 	int flag = 0;  //用存储数据包标志 	int privateCode = 0 ;//存放要发送给谁的fd 	 	manInfoT  manInfo = { 0 };// 存放已经报文中解析的数据 	onLineManInfoT  onLineManInfo = {0} ; //暂存登录报文中在线人员的信息 	onLineManNodeT  *pOnLineManNodeTemp = NULL;  // 用于遍历在线人员 	char *passWordTemp;	      //暂存找到的找到该昵称所对应的密码 	int recSize = 0;          //接收的字节数 	 	int result = 0;		        //函数返回值，用户判断函数是否成功被调用 	char buf[BUFFER_SIZE];		 	fd_set inset, temp_inset;  	 	signal(SIGPIPE, SIG_IGN);  	createSocket(&serverSocketFd )	; 	 	bindSocket();  	listenSocket(); 	 	FD_ZERO(&inset); 	FD_SET(serverSocketFd, &inset); 	while(1) 	{ 		temp_inset = inset;  		selectSocket(MAX_SOCK_FD,&temp_inset);// 		 		for(fd = 3; fd < MAX_SOCK_FD; fd++) 		{ 			if(FD_ISSET(fd, &temp_inset) != 0) 			{ 				if(fd == serverSocketFd) 				{ 					clientSocketFd = accept_socket()	; 					FD_SET(clientSocketFd, &inset)	; 					printf("New connection from %d(socket)\n", clientSocketFd); 				}  				else  				{		 					memset(buf, 0, sizeof(buf)); 					result = recv(fd, buf, BUFFER_SIZE, 0);                                         。。。。。。。。                                         。。。。。。。。                                         。。。。。。。。


Question: 单向动态链表的问题

删除的时候应该得到它的前驱才好删除……

if (h->xh==x)/*删除相应的结点*/ { h=s1->xg; s1->xg=NULL; free(s1); return 0; } while (1) { n++; s2=s2->xg; if (s2->xh==x) { s1->xg=s2->xg; s2->xg=NULL; free(s2); break; } s1=s2; if (n>=10) { printf("查无此数\n"); break;  } }


Question: linux网络编程 求解中文字符串转换问题

我刚刚接触网络编程，目前的水准估计就是基本的c编程水准了，别的方面的确不清楚。问下针对这个程序，怎么调库，库又是什么？

传说，这个东西不是有现成的库可以用么？


Question: 字符串赋值函数

char str[6] = "hello";  char reverse_str[7] = {0};   printf("%s\n", str);  for (i = 0; i < 5;i++)  {  reverse_str[4-i] = str[i];  }  printf("%s\n", reverse_str);

你应该打印不出来吧，你循环条件i<5，这样的话reverse_str的第一位你是没有赋值的，这样你还能打印出来？

// copystr.cpp : 定义控制台应用程序的入口点。 // #include <stdio.h> #include <stdlib.h>  int main() {     char str[6] = "Hello";     char copystr[7];    // printf("%s\n",str);     int i = 0;     for(;i<5;i++)         copystr[4-i] = str[i];     copystr[5] ='\0';     printf("%s\n",copystr);     return 0; }


Question: c语言开发工具

eclipse  + 虚拟机

这些是标准函数，你的感觉有问题。

引用 楼主 mingren00 的回复:我现在用的开发软件是VC++，但是我感觉这个环境对于getchar()、putchar()等函数支持不好，再编辑的时候总是报错，求大神推荐一个小巧好用的开发环境。谢了  那一定是你编错了。因为VC再差，getchar这种功能是不会错的

楼主就不能不用getchar、putchar吗？ #include <stdio.h> int main() {     int IP[4];     int i;     char c;      printf("请输入一个ip地址:");fflush(stdout);     while (1) {         rewind(stdin);         if (5==scanf("%d.%d.%d.%d%c",&IP[0],&IP[1],&IP[2],&IP[3],&c)) {             if (0<=IP[0] && IP[0]<=255              && 0<=IP[1] && IP[1]<=255              && 0<=IP[2] && IP[2]<=255              && 0<=IP[3] && IP[3]<=255              && '\n'==c) {                 break;             } else printf("输入的ip地址格式不对!\n请重新输入:\n");         } else printf("输入的ip地址格式不对!\n请重新输入:\n");     }     for (i=0;i<4;i++) {         printf("IP[%d]=%d\n",i,IP[i]);     }     return 0; }  #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.

用DEV-C++吧

CodeBlock

我现在主要使用C-Free，感觉还可以

有个钟家民的编译软件感觉不错

谢谢各位大神

Code::Blocks 13.12   这个版本用的是MinGW-gcc-4.7.1 http://sourceforge.net/projects/codeblocks/files/Binaries/13.12/Windows/codeblocks-13.12mingw-setup.exe Dev-C++ 5.6.3  这个版本用的是MinGW-gcc-4.8.1 http://jaist.dl.sourceforge.net/project/orwelldevcpp/Setup%20Releases/Dev-Cpp%205.6.3%20MinGW%204.8.1%20Setup.exe

C/C++程序设计学习与实验系统

Pelles C for Windows，这个小巧好用。主页：http://www.christian-heffner.de/

CodeBlocks, 百度就有


Question: 这个哪里写错了 求指点 感谢

晕死 我找到错在哪里了啊 多了一个&


Question: C语言猜数字游戏

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>   #define OK         0 #define SHORT      1 #define DUPLICATE  2 #define NONNUMERIC 3   #define SIZE 5     /*定义变量及函数*/ void c_input(char *str, int size) {     int i, j, flag, len;     /*检测输入是否合法*/     do{         flag = OK;         scanf("%s", str);         rewind(stdin);         len = strlen(str);         if(len < size) {             printf("长度不足，请重新输入：\n");             flag = SHORT;             continue;         }           for(i=0; i<size && flag==OK; i++) {             if(str[i]<'0' || str[i]>'9') {                 printf("含非数字字符，请重新输入：\n");                 flag = NONNUMERIC;                 break;             }             for(j=0; j<size; j++) {                 if(str[i] == str[j] && i != j) {                     printf("含重复字符，请重新输入：\n");                     flag = DUPLICATE;                     break;                 }             }         }     }while(flag != OK);     str[size] = '\0';     return; }   /*显示帮助信息*/ void c_help() {     system("cls");     printf("\t\t\t\t※游戏帮助※");     printf("\n    本游戏由电脑自动生成五个不重复数字，由玩家来猜；游戏开始后，");     printf("\n    玩家输入五个不重复的数字，输入后会有提示XAYB， X表示有几个");     printf("\n    数字与答案数字相同且位置相同。 Y表示有几个数字与答案数字相");     printf("\n    同但位置不正确。例如：答案数字是3792，如果输入9786，则会提");     printf("\n    示1A1B。玩家总共有十次机会来猜数字。");     printf("\n\n\n\t\t\t\t\t\t祝您游戏愉快!");     printf("\n\n请按任意键返回主菜单……");     getchar();     return; }     /*游戏部分*/ /*定义变量及函数*/ void c_game(const char *temp) {     int i, j, ci; 	char nickname; 	printf("请输入你的昵称:"); 	nickname=getchar();     static score = 0;     char in[SIZE + 1];     char out[5]="0A0B";     for(ci=0; ci<10; ci++) {         printf("第 %d 次输入，你总共有10次机会：",ci + 1);         c_input(in, SIZE);         if(strcmp(in, temp) == 0) {             score += 100;             printf("恭喜您，加一百分!\n您的总分为%5d", score);             printf("\n请按任意键返回主菜单…");             getchar();             return;         }         for(i=0; i<SIZE; i++) {             if(in[i] == temp[i])                 out[0]++;             else                 for(j=0; j<SIZE; j++)                     if(in[i] == temp[j])                         out[2]++;         }         printf("%s\n",out);                   out[0] = '0';         out[2] = '0';     }     printf("很遗憾，您的机会用完了，再接再厉哦!");     printf("\n请按任意键返回主菜单……");     getchar();     return; }       void c_rand(char *str) {     int i, j;     char data[] = "0123456789";     system("cls");     srand(time(NULL));     printf("\t\t\t\t※猜数字游戏中※\n\n");     /*电脑自动生成5个不重复数字*/     for(i=0; i<SIZE; i++) {         j = rand() % (10 - i);         str[i] = data[j];         data[j] = data[10 - i - 1];     }     c_game(str);     return; }      void c_jifenbang(char *str){ 	//查看积分榜//     char F; 	system("cls"); 	printf("\t\t\t\t※查看积分榜※\n\n"); 	printf("用户%c的积分为%5d,nickname,score"); 	printf("\n\n\n按F返回菜单"); 	scanf("%c",&F); 	if F=F, 	return 0 	 }    void c_test(char *str) {     /*用户自己设置数字来测试游戏*/     system("cls");     printf("\t\t\t\t※测试模式※\n\n");     printf("请输入测试数据：");     /*检测用户输入的数据是否符合要求*/     c_input(str, SIZE);     /*系统根据玩家设定的数据展开游戏测试*/     system("cls");     printf("\t\t\t\t※测试模式※\n\n");     c_game(str);     return; }       int main() {     char str[80];     char ch;     char choice;     while(1) {                system("cls");         printf("\n          猜数字游戏         ");         printf("\n\t\t1、【进入游戏】");         printf("\n\t\t2、【测试模式】");         printf("\n\t\t3、【游戏帮助】");         printf("\n\t\t4、【查看积分】");         printf("\n\t\t5、【退出游戏】");         printf("\n请选择（1-5） : ");         choice = getchar();         fflush(stdin);         system("cls");         switch(choice)         {         case '1':             printf("***游戏模式***\n");             c_rand(str);             break;         case '2':             printf("***测试模式***\n");             c_test(str);             break;         case '3':             printf("***帮助***\n");             c_help(); 			break;         		case '4':             printf("***查看积分榜***\n");             c_jifenbang(); 			break;         case '5':             printf("你确定要退出吗？(y/n):");             ch = getchar();             if(ch == 'y' || ch == 'Y')                 exit(0);         }     }     return 0; }     帮忙修改一下这个版本

求散分！ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>  #define OK         0 #define SHORT      1 #define DUPLICATE  2 #define NONNUMERIC 3  #define SIZE 5   /*定义变量及函数*/ void c_input(char *str, int size) { 	int i, j, flag, len; 	/*检测输入是否合法*/ 	do{ 		flag = OK; 		scanf("%s", str); 		rewind(stdin); 		len = strlen(str); 		if(len < size) { 			printf("长度不足，请重新输入：\n"); 			flag = SHORT; 			continue; 		}  		for(i=0; i<size && flag==OK; i++) { 			if(str[i]<'0' || str[i]>'9') { 				printf("含非数字字符，请重新输入：\n"); 				flag = NONNUMERIC; 				break; 			} 			for(j=0; j<size; j++) { 				if(str[i] == str[j] && i != j) { 					printf("含重复字符，请重新输入：\n"); 					flag = DUPLICATE; 					break; 				} 			} 		} 	}while(flag != OK); 	str[size] = '\0'; 	return; }  /*显示帮助信息*/ void c_help() { 	system("cls"); 	printf("\t\t\t\t※游戏帮助※"); 	printf("\n    本游戏由电脑自动生成五个不重复数字，由玩家来猜；游戏开始后，"); 	printf("\n    玩家输入五个不重复的数字，输入后会有提示XAYB， X表示有几个"); 	printf("\n    数字与答案数字相同且位置相同。 Y表示有几个数字与答案数字相"); 	printf("\n    同但位置不正确。例如：答案数字是3792，如果输入9786，则会提"); 	printf("\n    示1A1B。玩家总共有十次机会来猜数字。"); 	printf("\n\n\n\t\t\t\t\t\t祝您游戏愉快!"); 	printf("\n\n请按任意键返回主菜单……"); 	getchar();     return; }   /*游戏部分*/ /*定义变量及函数*/ void c_game(const char *temp) { 	int i, j, ci; 	static score = 0; 	char in[SIZE + 1]; 	char out[5]="0A0B"; 	for(ci=0; ci<10; ci++) { 		printf("第 %d 次输入，你总共有10次机会：",ci + 1); 		c_input(in, SIZE); 		if(strcmp(in, temp) == 0) { 			score += 100; 			printf("恭喜您，加一百分!\n您的总分为%5d", score); 			printf("\n请按任意键返回主菜单…"); 			getchar(); 			return; 		} 		for(i=0; i<SIZE; i++) { 			if(in[i] == temp[i]) 				out[0]++; 			else 				for(j=0; j<SIZE; j++) 					if(in[i] == temp[j]) 						out[2]++; 		} 		printf("%s\n",out); 		 		out[0] = '0'; 		out[2] = '0'; 	} 	printf("很遗憾，您的机会用完了，再接再厉哦!"); 	printf("\n请按任意键返回主菜单……"); 	getchar(); 	return; }   void c_rand(char *str) { 	int i, j; 	char data[] = "0123456789"; 	system("cls"); 	srand(time(NULL)); 	printf("\t\t\t\t※猜数字游戏中※\n\n"); 	/*电脑自动生成5个不重复数字*/ 	for(i=0; i<SIZE; i++) { 		j = rand() % (10 - i); 		str[i] = data[j]; 		data[j] = data[10 - i - 1]; 	} 	c_game(str); 	return; }   void c_test(char *str) { 	/*用户自己设置数字来测试游戏*/ 	system("cls"); 	printf("\t\t\t\t※测试模式※\n\n"); 	printf("请输入测试数据："); 	/*检测用户输入的数据是否符合要求*/ 	c_input(str, SIZE); 	/*系统根据玩家设定的数据展开游戏测试*/ 	system("cls"); 	printf("\t\t\t\t※测试模式※\n\n"); 	c_game(str); 	return; }   int main() { 	char str[80]; 	char ch; 	char choice; 	while(1) {		 		system("cls"); 		printf("\n          猜数字游戏         "); 		printf("\n\t\t1、【进入游戏】"); 		printf("\n\t\t2、【测试模式】"); 		printf("\n\t\t3、【游戏帮助】"); 		printf("\n\t\t4、【退出游戏】"); 		printf("\n请选择（1-4） : "); 		choice = getchar(); 		fflush(stdin); 		system("cls"); 		switch(choice) 		{ 		case '1': 			printf("***游戏模式***\n"); 			c_rand(str); 			break; 		case '2': 			printf("***测试模式***\n"); 			c_test(str); 			break; 		case '3': 			printf("***帮助***\n"); 			c_help(); break; 		case '4': 			printf("你确定要退出吗？(y/n):"); 			ch = getchar(); 			if(ch == 'y' || ch == 'Y') 				exit(0); 		} 	} 	return 0; }

给我做做呗，多多感谢啊


Question: 猜数字游戏C程序设计

多少钱。。。

貌似不好玩……

谁挖的坟？

题，收下了。

可以自己慢慢写啊，一个功能一个功能的实现，这样总能写出来的，求人不如求己

你要的代码有点复杂，建议去找一些类似的开源代码

怎么没人回复呢？？


Question: LinkList *L这个是不是表示一个二重指针

就是二重指针，建议楼主看一看传值和传地址的资料，不然以后会不清楚什么时候该用二重指针，什么时候可以不用二重指针

是二重指针   楼主在学数据结构吧   C语言版的数据结构有很多typedef，这样看着方便，但写程序的还是需要知道各个宏之间的关系。

可以认为是二重指针

typedef struct Node *LinkList; 你这样子写的话很容易误解的  typedef struct Node* LinkList;  这样子书写会比较容易理解， LinkList 就是struct Node*，LinkList *L 就是 (struct Node*) *L 也就是 struct Node** L 所以是二级指针。

对的，LinkList 就是struct node* 类型，LinkList * 就等同于 struct node**

计算机组成原理→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

对，是二级指针

是的，为了修改Listlist的值就必须使用它的地址形式作为参数传给函数。

是的，就是这样

LinkList *L 等同于 struct Node **L


Question: 菜鸟求助！文件指针和文件内部指针的区别

/***       *FILE   *_openfile(filename,   mode,   shflag,   stream)   -   open   a   file   with   string       *               mode   and   file   sharing   flag.       *       *Purpose:       *               parse   the   string,   looking   for   exactly   one   of   {rwa},   at   most   one   '+',       *               at   most   one   of   {tb},   at   most   one   of   {cn},   at   most   one   of   {SR},   at   most       *               one   'T',   and   at   most   one   'D'.   pass   the   result   on   as   an   int   containing       *               flags   of   what   was   found.   open   a   file   with   proper   mode   if   permissions       *               allow.   buffer   not   allocated   until   first   i/o   call   is   issued.   intended       *               for   use   inside   library   only       *       *Entry:       *               char   *filename   -   file   to   open       *               char   *mode   -   mode   to   use   (see   above)       *               int   shflag   -   file   sharing   flag       *               FILE   *stream   -   stream   to   use   for   file       *       *Exit:       *               set   stream's   fields,   and   causes   system   file   management   by   system   calls       *               returns   stream   or   NULL   if   fails       *       *Exceptions:       *       *******************************************************************************/  FILE   *   __cdecl   _openfile   (                       const   char   *filename,                       REG3   const   char   *mode,                       int   shflag,                       FILE   *str                       )       {                       REG2   int   modeflag;                       int   streamflag   =   _commode;                       int   commodeset   =   0;                       int   whileflag;                       int   filedes;                       REG1   FILE   *stream;                             _ASSERTE(filename   !=   NULL);                       _ASSERTE(mode   !=   NULL);                       _ASSERTE(str   !=   NULL);                             /*   Parse   the   user's   specification   string   as   set   flags   in                                     (1)   modeflag   -   system   call   flags   word                                     (2)   streamflag   -   stream   handle   flags   word.   */                             /*   First   mode   character   must   be   'r',   'w',   or   'a'.   */                             switch   (*mode)   {                       case   'r':                                       modeflag   =   _O_RDONLY;                                       streamflag    ¦=   _IOREAD;                                       break;                       case   'w':                                       modeflag   =   _O_WRONLY    ¦   _O_CREAT    ¦   _O_TRUNC;                                       streamflag    ¦=   _IOWRT;                                       break;                       case   'a':                                       modeflag   =   _O_WRONLY    ¦   _O_CREAT    ¦   _O_APPEND;                                       streamflag    ¦=   _IOWRT;                                       break;                       default:                                       return(NULL);                                       break;                       }                             /*   There   can   be   up   to   three   more   optional   mode   characters:                             (1)   A   single   '+'   character,                             (2)   One   of   't'   and   'b'   and                             (3)   One   of   'c'   and   'n'.                       */                             whileflag=1;                             while(*++mode   &&   whileflag)                                       switch(*mode)   {                                             case   '+':                                                       if   (modeflag   &   _O_RDWR)                                                                       whileflag=0;                                                       else   {                                                                       modeflag    ¦=   _O_RDWR;                                                                       modeflag   &=   ~(_O_RDONLY    ¦   _O_WRONLY);                                                                       streamflag    ¦=   _IORW;                                                                       streamflag   &=   ~(_IOREAD    ¦   _IOWRT);                                                       }                                                       break;                                       case   't':                                                       if   (modeflag   &   (_O_TEXT    ¦   _O_BINARY))                                                                       whileflag=0;                                                       else                                                                       modeflag    ¦=   _O_TEXT;                                                       break;                                             case   'b':                                                       if   (modeflag   &   (_O_TEXT    ¦   _O_BINARY))                                                                       whileflag=0;                                                       else                                                                       modeflag    ¦=   _O_BINARY;                                                       break;                                       case   'c':                                                       if   (commodeset)                                                                       whileflag=0;                                                       else   {                                                                       commodeset   =   1;                                                                       streamflag    ¦=   _IOCOMMIT;                                                       }                                                       break;                                             case   'n':                                                       if   (commodeset)                                                                       whileflag=0;                                                       else   {                                                                       commodeset   =   1;                                                                       streamflag   &=   ~_IOCOMMIT;                                                       }                                                       break;                                       default:                                                       whileflag=0;                                                       break;                                       }                             /*   Try   to   open   the   file.     Note   that   if   neither   't'   nor   'b'   is                             specified,   _sopen   will   use   the   default.   */                             if   ((filedes   =   _sopen(filename,   modeflag,   shflag,   CMASK))    <   0)                                       return(NULL);                             /*   Set   up   the   stream   data   base.   */             #ifndef   CRTDLL                       /*   force   library   pre-termination   procedure   */                       _cflush++;       #endif     /*   CRTDLL   */                             /*   Init   pointers   */                       stream   =   str;                             stream->_flag   =   streamflag;                       stream->_cnt   =   0;                       stream->_tmpfname   =   stream->_base   =   stream->_ptr   =   NULL;                       stream->_file   =   filedes;                             return(stream);       }

引用 7 楼 su_787910081 的回复:[quote=引用 5 楼 shenchenman 的回复:] 文件指针指向文件，自增没有意义； 内部指针指向文件的数据，对其自增就能不断读文件内容 真心有点扯 [/quote]  搞笑 请问哪里扯？   Return Value    --------------------------------------------------------------------------------      Each of these functions returns a pointer to the open file. A null pointer value indicates an error. If filename or mode is NULL or an empty string, these functions trigger the invalid parameter handler, which is described in Parameter Validation. If execution is allowed to continue, these functions return NULL and set errno to EINVAL. 返回一个FILE*，也就是文件指针，指向一个文件，你要是做偏移了，能close掉？  文件内部指针，本身对调用fopen的人来说不可见的，CFILE类内部管理的一个指针变量，读取内容时，会做处理。什么叫扯？求解释 另附一个CFILE重载函数的实现： /***       *FILE   *_fsopen(file,   mode,   shflag)   -   open   a   file       *       *Purpose:       *               Opens   the   file   specified   as   a   stream.     mode   determines   file   mode:       *               "r":   read               "w":   write             "a":   append       *               "r+":   read/write                                 "w+":   open   empty   for   read/write       *               "a+":   read/append       *               Append   "t"   or   "b"   for   text   and   binary   mode.   shflag   determines   the       *               sharing   mode.   Values   are   the   same   as   for   sopen().       *       *Entry:       *               char   *file   -   file   name   to   open       *               char   *mode   -   mode   of   file   access       *       *Exit:       *               returns   pointer   to   stream       *               returns   NULL   if   fails       *       *Exceptions:       *       *******************************************************************************/             FILE   *   __cdecl   _tfsopen   (                       const   _TSCHAR   *file,                       const   _TSCHAR   *mode                       ,int   shflag                       )       {                       REG1   FILE   *stream;                       REG2   FILE   *retval;                             _ASSERTE(file   !=   NULL);                       _ASSERTE(*file   !=   _T('/0'));                       _ASSERTE(mode   !=   NULL);                       _ASSERTE(*mode   !=   _T('/0'));                             /*   Get   a   free   stream   */                       /*   [NOTE:   _getstream()   returns   a   locked   stream.]   */                             if   ((stream   =   _getstream())   ==   NULL)                                       return(NULL);                             /*   open   the   stream   */       #ifdef   _UNICODE                       retval   =   _wopenfile(file,mode,shflag,stream);       #else     /*   _UNICODE   */                       retval   =   _openfile(file,mode,shflag,stream);       #endif     /*   _UNICODE   */                             /*   unlock   stream   and   return.   */                       _unlock_str(stream);                       return(retval);       }

FILE 是C流，是一种带缓冲的，表示文件的数据结构。 FILE* fp 是流指针，是C，C++语言的指针概念中的指针，指向的数据类型是FILE。  内部指针，是文件读写的当前位置指针，其实就是个位置； 文件读写的当前位置，不是C，C++语言的指针。  流数据结构中有一个域，表示这个当前位置。 所以，可以通过流指针，改变文件读写的当前位置。  fseek就是专门做这个的，fwrite,fread 也会改变它，，， 另外，fgetc,fgets,fputc,fputs,fscanf,fprintf 也会改变它 ftell 可以获取这个当前位置。

引用 5 楼 shenchenman 的回复:文件指针指向文件，自增没有意义； 内部指针指向文件的数据，对其自增就能不断读文件内容 真心有点扯

引用 5 楼 shenchenman 的回复:文件指针指向文件，自增没有意义； 内部指针指向文件的数据，对其自增就能不断读文件内容 扯

FILE *是地址 ftell()的返回值是代表文件字节偏移量的一个数。

fp没有移动。  你要操作一个文件就用文字指针指向这个文件。实际上文件指针指向的是一个数据结构，这个数据结构中有各种成员用来管理这个打开的文件。而文件内部指针只是这些成员中的一个，用来管理文件偏移量。还有管理读写模式之类的成员等等。

两者的区别在于 fp说白了标识你要操作哪个文件，所谓的‘文件指针’ 另一个文件内部指针是说你对这个文件的操作位置 比如fopen打开后，你fread是从该文件开头读起 但是你调用fseek后fread，就能从该文件的特定位置读数据，就是所谓的‘文件内部指针’


Question: C#动态库调用时提示： 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

引用 6 楼 dailongzhen 的回复:[quote=引用 2 楼 user-1 的回复:] [quote=引用 1 楼 user-1 的回复:] byte 的范围可能不够 然后超出了 就读取别的地方的内存 于是就： 尝试读取或写入受保护的内存。这通常指示其他内存已损坏  尝试换一个类型吧  好像搞错了.... 你少写参数了。 GetString（byte[] bytes）这个版本是不公开的， Unicode类公开的只有下面这个。 GetString(byte[] bytes, int index, int count)[/quote] 没有啊，编辑器提示的只有Encoding.Unicode .GetString(byte[] bytes);[/quote]  先调试一下 看string中是什么  编译器有问题... 你改一下试一试

引用 5 楼 user-1 的回复:[quote=引用 3 楼 dailongzhen 的回复:] [quote=引用 1 楼 user-1 的回复:] byte 的范围可能不够 然后超出了 就读取别的地方的内存 于是就： 尝试读取或写入受保护的内存。这通常指示其他内存已损坏  尝试换一个类型吧 报错是出在”mibdecode(array);“，传的是string，与byte有什么关系呢？[/quote]  转换时出错 未接受到值[/quote] 那该怎么解决呢？

引用 2 楼 user-1 的回复:[quote=引用 1 楼 user-1 的回复:] byte 的范围可能不够 然后超出了 就读取别的地方的内存 于是就： 尝试读取或写入受保护的内存。这通常指示其他内存已损坏  尝试换一个类型吧  好像搞错了.... 你少写参数了。 GetString（byte[] bytes）这个版本是不公开的， Unicode类公开的只有下面这个。 GetString(byte[] bytes, int index, int count)[/quote] 没有啊，编辑器提示的只有Encoding.Unicode .GetString(byte[] bytes);

引用 3 楼 dailongzhen 的回复:[quote=引用 1 楼 user-1 的回复:] byte 的范围可能不够 然后超出了 就读取别的地方的内存 于是就： 尝试读取或写入受保护的内存。这通常指示其他内存已损坏  尝试换一个类型吧 报错是出在”mibdecode(array);“，传的是string，与byte有什么关系呢？[/quote]  转换时出错 未接受到值

引用 2 楼 user-1 的回复:[quote=引用 1 楼 user-1 的回复:] byte 的范围可能不够 然后超出了 就读取别的地方的内存 于是就： 尝试读取或写入受保护的内存。这通常指示其他内存已损坏  尝试换一个类型吧  好像搞错了.... 你少写参数了。 GetString（byte[] bytes）这个版本是不公开的， Unicode类公开的只有下面这个。 GetString(byte[] bytes, int index, int count)[/quote] index 或 count 小于零。 - 或 - index 和 count 不表示 bytes 中的有效范围。 抛出异常 ArgumentOutOfRangeException

引用 1 楼 user-1 的回复:byte 的范围可能不够 然后超出了 就读取别的地方的内存 于是就： 尝试读取或写入受保护的内存。这通常指示其他内存已损坏  尝试换一个类型吧 报错是出在”mibdecode(array);“，传的是string，与byte有什么关系呢？

引用 1 楼 user-1 的回复:byte 的范围可能不够 然后超出了 就读取别的地方的内存 于是就： 尝试读取或写入受保护的内存。这通常指示其他内存已损坏  尝试换一个类型吧  好像搞错了.... 你少写参数了。 GetString（byte[] bytes）这个版本是不公开的， Unicode类公开的只有下面这个。 GetString(byte[] bytes, int index, int count)


Question: 我发送一个HTTP请求到服务器，服务器返回响应报文，报文主体是源源不断的音频流，怎么接收？

你接受到的东西，要么存下来，要么即时处理掉。

这好像应该是传输层处理的问题，不是应用层问题

revc（）

请先学会使用抓包软件比如wireshark


Question: 高手多，c怎么实现去除采样数据的衰减直流分量

高手门，来吧！！！这个问题应该不难

增加窗口宽度


Question: %f格式和%e格式的输出

引用 8 楼 zhao4zhong1 的回复:英语也是一门计算机语言的说。你还是说汉语吧，我看不懂你写的文字

long double能用%f输出？

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

引用 6 楼 zhao4zhong1 的回复:e  double Signed value having the form [ – ]d.dddd e [sign]ddd where d is a single decimal digit, dddd is one or more decimal digits, ddd is exactly three decimal digits, and sign is + or –.  E double Identical to the e format except that E rather than e introduces the exponent.  f double Signed value having the form [ – ]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision.  g double Signed value printed in f or e format, whichever is more compact for the given value and precision. The e format is used only when the exponent of the value is less than –4 or greater than or equal to the precision argument. Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.  G double Identical to the g format, except that E, rather than e, introduces the exponent (where appropriate).您还是说汉语吧。。。。。

引用 4 楼 wxf54318 的回复:感觉最后一行%f 是溢出了，程序是没问题的 printf的%f说明符的确既可以输出float型又可以输出double型。根据“默认参数提升”规则（在printf这样的函数的可变参数列表中，不论作用域内有没有原型，都适用这一规则）float型会被提升为double型。因此printf()只会看到双精度数。 double型的精度至少是10位有效数字，5.32e-5，这能溢出吗？

编译环境的问题吧，最后一行用VS我这编译没问题。

double    %lf float         %f


Question: 角度周期变化存在360度处跳变到0，现在需要做平滑滤波，有什么简单的方法能解决这个问题？

采集每次都%360,然后再拿去用,怎么可能跳变嘛 多开个变量你会死吗?

忽略360、720、1080、……、n*360度对应的数据。（n为正整数）

楼主问的是编程思路？如果超出360想把这个n处理为平滑的。那就把y值处理为360-（n%360)，即以这个360最大值为起点，向下偏移。因为考虑n可能大于720，所以使用取模运算来得到离360整倍数的差额。

这种东西，只能在采集的时候做区分，到底是一开始的0度，还是转完一圈之后的0度  就是比如转过一圈之后的1度，采集的时候记录为361度 或者单独再记录一个转动的圈数，比如是0圈50度，1圈20度，2圈10度


Question: 循环如何优化

最简单的优化方法是用一个二维数组比如int PV[Width][Height]记住LCD屏上每个像素在本次PutPixel之前的值。 如果该值和本次PutPixel的值一样，跳过本次PutPixel；否则PutPixel并在数组中记住新值。

引用 2 楼 ychongx 的回复:[quote=引用 1 楼 user-4 的回复:] 减少/去掉分支机构和函数调用。 如果不是清屏时画圆环而且圆环颜色不止一种，怎么办，代码需要通用  /*   * 绘制同心圆  */ void Mire(void) {     UINT32 x,y;     UINT32 color;     UINT8 red,green,blue,alpha;      for (y = 0; y < ysize; y++)         for (x = 0; x < xsize; x++){             color = ((x-xsize/2)*(x-xsize/2) + (y-ysize/2)*(y-ysize/2))/64;             red   = (color/8) % 256;             green = (color/4) % 256;             blue  = (color/2) % 256;             alpha = (color*2) % 256;              color |= ((UINT32)alpha << 24);             color |= ((UINT32)red   << 16);             color |= ((UINT32)green << 8 );             color |= ((UINT32)blue       );              PutPixel(x,y,color);         } }  麻烦详细点说，大神[/quote]  性能 和 你所谓的通用，都是矛盾体。   你这个所谓的通用，每处理一个像素点，都要调用一次函数。 以8bpp为例，  你就是为了给地址赋值颜色。 却执行了一个函数。  当你对整个图像做完处理之后，处理图像的时间假设为1， 那么调用函数的开销可能就是3~5.  这是多么大的性能浪费啊。  在C/C++预研内的描述， 感觉有如下优化可能。  1、 看看 ClearSCR， 难道一个memset不能搞定？ 2、 Mire 中， color的第1次之后的赋值，用联合体之类的会不会更快。 3、 mire中，  color的第一次赋值，是不是可以更快，例如使用位移。 4、 去掉处理单个像素的函数吧。

引用 1 楼 user-4 的回复:减少/去掉分支机构和函数调用。 根据bpp定义多个PutPixel函数，同时PutPixel并入到ClearScr，在画图的时候先在内存中画好准备要显示图片，在真正要显示的时候直接COPY，就是双缓冲来处理显示延时的问题。

引用 1 楼 user-4 的回复:减少/去掉分支机构和函数调用。 如果不是清屏时画圆环而且圆环颜色不止一种，怎么办，代码需要通用  /*   * 绘制同心圆  */ void Mire(void) {     UINT32 x,y;     UINT32 color;     UINT8 red,green,blue,alpha;      for (y = 0; y < ysize; y++)         for (x = 0; x < xsize; x++){             color = ((x-xsize/2)*(x-xsize/2) + (y-ysize/2)*(y-ysize/2))/64;             red   = (color/8) % 256;             green = (color/4) % 256;             blue  = (color/2) % 256;             alpha = (color*2) % 256;              color |= ((UINT32)alpha << 24);             color |= ((UINT32)red   << 16);             color |= ((UINT32)green << 8 );             color |= ((UINT32)blue       );              PutPixel(x,y,color);         } }  麻烦详细点说，大神

减少/去掉分支机构和函数调用。

引用 4 楼 TheNewIpad 的回复:[quote=引用 2 楼 ychongx 的回复:] [quote=引用 1 楼 user-4 的回复:] 减少/去掉分支机构和函数调用。 如果不是清屏时画圆环而且圆环颜色不止一种，怎么办，代码需要通用  /*   * 绘制同心圆  */ void Mire(void) {     UINT32 x,y;     UINT32 color;     UINT8 red,green,blue,alpha;      for (y = 0; y < ysize; y++)         for (x = 0; x < xsize; x++){             color = ((x-xsize/2)*(x-xsize/2) + (y-ysize/2)*(y-ysize/2))/64;             red   = (color/8) % 256;             green = (color/4) % 256;             blue  = (color/2) % 256;             alpha = (color*2) % 256;              color |= ((UINT32)alpha << 24);             color |= ((UINT32)red   << 16);             color |= ((UINT32)green << 8 );             color |= ((UINT32)blue       );              PutPixel(x,y,color);         } }  麻烦详细点说，大神[/quote]  性能 和 你所谓的通用，都是矛盾体。   你这个所谓的通用，每处理一个像素点，都要调用一次函数。 以8bpp为例，  你就是为了给地址赋值颜色。 却执行了一个函数。  当你对整个图像做完处理之后，处理图像的时间假设为1， 那么调用函数的开销可能就是3~5.  这是多么大的性能浪费啊。  在C/C++预研内的描述， 感觉有如下优化可能。  1、 看看 ClearSCR， 难道一个memset不能搞定？ 2、 Mire 中， color的第1次之后的赋值，用联合体之类的会不会更快。 3、 mire中，  color的第一次赋值，是不是可以更快，例如使用位移。 4、 去掉处理单个像素的函数吧。[/quote] 你说的蛮对的，帖子居然不能编辑，没权限，坑爹啊


Question: 用同一个pthread_t创建若干线程和用不同的pthread_t创建不同的线程有什么区别？


Question: c语言求大神帮助，我是菜鸟，谢谢

5、 输入一英文句子，将其中所有单词首字符转换成大写后输出。（C语言） #include <stdio.h> int main(int argc, const char * argv[]) {      char str[100]; //申明一个字符数组 	 int i=0;      int word=0;//标识是否为单词 0表示为单词，1表示不是单词      int count=0;//统计单词个数     printf("请输入一句英文:\n");        //从键盘输入英文单词     gets(str);     printf("当前输入的英文句子是：");     puts(str);     //循环遍历     while (str[i] != '\0') {         if(str[i] == ' '){             //设置为单词             word=0;         }else if (word == 0){             count++;             //将单词字母大写             str[i]=str[i]-32;             word=1;         }         i++;     }     printf("所有单词首字符转换成大写后输出后的英文句子是：");     puts(str);     return 0; } 6、 在一个已知的字符串中查找最长单词，假定字符串中只含字母和空格，空格用来分隔不同单词。（C语言） #include<stdio.h> int main(){     char str[100]="it is necessary for us all to make efforts to cultivate good manners"; 	int length=0;//定义计算单词长度计数器 	int maxLength=0;//定义单词最大长度 	int index=0;//定义单词最后一位字符的下标 	int i=0; 	//循环查找最大单词的多字母的下标     for(i=0;str[i] != '\0';i++){ 		if(str[i] !=' '){ 			length++; 		    if(length>maxLength){             index=i;             maxLength=length; 			} 		}else{ 			length=0; 		} 	}     printf("当前英文句子:\n%s\n",str); 	printf("最长单词:\n"); 	//循环打出最长单词 	for(i=maxLength;i != 0;i--){ 		printf("%c",str[index-i+1]); 	} 	printf("\n"); } 7、 输入两个数，打印（printf）这两个数的和、差、积、商、以及余数。（C语言编程题） #include<stdio.h> int main(){ 	int a=0,b=0; 	int sum=0;//和 	int cha=0;//差 	int cj=0;//乘积 	int shang=0;//商值 	int ys=0;//余数 	printf("请输入两个数并且以','号隔开："); 	scanf("%d,%d",&a,&b); //	scanf("%d",&b); 	sum=a+b; 	cha=a-b; 	cj=a*b; 	if(b != 0){      	shang=a/b; 		ys=a%b; 	}else{ 		printf("b不能为0\n"); 	} 	printf("两数之和为%d\n",sum); 	printf("两数之差为%d\n",cha); 	printf("两数之积为%d\n",cj); 	printf("两数之商为%d\n",shang); 	printf("两数之余为%d\n",ys); } 8、 编写一个int string_len(char *s)，返回字符串s的字符长度(不包括\0)  （C语言编程题） #include<stdio.h> //求字符串的长度 int string_len(char *s){ 	int length=0; 	int i; 	for(i=0;s[i] != '\0';i++){ 		length++; 	}     return length; } int main(){    char str[100];    int len=0;    printf("请输入字符串\n");    gets(str);    len= string_len(str);   printf("字符串的字符长度是%d\n",len); } 9、 从键盘输入6个字符串（仅仅包含英文字母和数字），对这6个字符串从小到大排列并输出结果。（C语言） #include<stdio.h> #include<string.h> int main(){     int i=0,j=0; 	char str[6][50]; 	for(i=0;i<6;i++){ 		printf("请输入第%d个字符串（仅仅包含英文字母和数字）:",i+1); 	    scanf("%s",str[i]); 	} //比较字符串 	for(i=0;i<6;i++){ 		for(j=0;j<5;j++){ 			if(strcmp(str[i],str[j])<0){ 				char tem[50]; 				strcpy(tem,str[i]); 	            strcpy(str[i],str[j]); 				strcpy(str[j],tem); 			} 		} 	} 	printf("这6个字符串从小到大排列并输出结果:\n"); 	for(i=0;i<6;i++){ 		printf("第%d个字符串:%s\n",i+1,str[i]); 	} 	printf("\n"); } 10、 小明从2006年1月1日开始，每三天结识一个美女两天结识一个帅哥，编程实现当输入2006年1月1日之后的任意一天，输出小明那天是结识美女还是帅哥（注意润年问题）（C语言） #include<stdio.h> int sumOfDays(int y,int m,int d); int main(){     int year,month,day; 	do{ 		printf("请输入2006年1月1日以后的某一天:\n"); 		scanf("%d%*c%d%*c%d",&year,&month,&day); 	}while(year<2006 || (month<1 || month>12) || (day<1 || day>31)); 	sumOfDays(year,month,day); } int sumOfDays(int y,int m,int d) {      int i,j; 	 int sumDays=0;//总天数 	 int DaysOfYear=0;//年总天数 	 int DaysOfMonth=0;//月总天数 	 int leapYearMonths[12]={31,29,31,30,31,30,31,31,30,31,30,31}; // 闰年的每月天数 	 int simpleYearMonths[12]={31,28,31,30,31,30,31,31,30,31,30,31}; // 平年每月天数 	 int xcYear=y-2006;//相差的年数 	 int xcMonth=m-1;  	 //求相差年总天数 	 for(i=0;i<xcYear;i++) 	 { 		 if((2006+i)%4==0 && (2006+i)%100 !=0) 		 {             DaysOfYear+=366; 		 }else if((2006+i)%400==0){              DaysOfYear+=366; 		 }else 		 { 			 DaysOfYear+=365; 		 } 	 }  	//求相差月总天数 	 for(i=1;i<xcMonth;i++) 	 { 		 if(y%4==0 && y%100 !=0) 		 {             DaysOfMonth=leapYearMonths[i-1]; 		 }else if(y%400==0) 		 {              DaysOfMonth=leapYearMonths[i-1]; 		 }else 		 { 			 DaysOfMonth=simpleYearMonths[i-1]; 		 } 	 }      //总天数 	 sumDays = DaysOfYear + DaysOfMonth + d;  	 //判断那天认识的人 	 if(sumDays %2 ==0){ 		 printf("小明结识帅哥了\n"); 	 }else if(sumDays %3 == 0){ 	     printf("小明结识了美女\n"); 	 }else{          printf("小明没有结识美女也没有结识帅哥\n"); 	 } }

这都是考黑马的题目上的，你这些都不会，你还考鸡巴什么黑马？？就算混进去了，你也跟不上学习的节奏，，

不要管别人怎么说，自己怎么学就怎么学，相信一定会成功

加油吧少年

大一做过的题目。都很简单的啊～好歹自己先写一下代码，然后又问题再来问，甩一堆问题上来，什么也不说，这总是不好的吧～

看到这样的问题出现，只想说：“真操蛋”

5+5*5+5 = 35

艾玛，又一个伸手党。

5、 从键盘输入一大堆字符串，统计A、B、C、D的出现次数，最后出现次数由高到低输出字母和出现次数。（C语言） #include <stdio.h> int main() {     char str;     int count_a = 0, count_b = 0, count_c = 0, count_d = 0;     for(int i = 0; i <10; i++)     while ((str = getchar()) != '\n')     {         if (str == 'A')         {             count_a++;         }         else if (str == 'B')         {             count_b++;         }         else if (str == 'C')         {             count_c++;         }         else if (str == 'D')         {             count_d++;         }     }     printf("A: %d  B: %d  C: %d  D: %d\n", count_a, count_b, count_c, count_d);     return 0; }

你这么问不行，还是看看这个吧——http://bbs.csdn.net/topics/390623576

好歹你把代码写出来啊，大家帮你该也行啊，你自己都不动手

35  gcc -E


Question: 讨论一种可靠的socket断线重连方法

谢谢回复，结贴了！

不要动态创建、销毁线程。要使用线程池。 重连操作要避免重入，要适当间隔一段时间比如10秒。

通过心跳包+时间戳来判断是否超时

通常判断断线是通过心跳包，或者多长时间之内没有收到数据超时，来判断断线重连 send和recv出错不一定是断线导致的

引用 6 楼 u011828085 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 多线程中的阻塞，别忘了加锁。  加锁？什么意思，锁住什么[/quote] 多线程访问共享资源为避免冲突需要加锁。参考下面： //循环向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; }

引用 5 楼 zhao4zhong1 的回复:多线程中的阻塞，别忘了加锁。  加锁？什么意思，锁住什么

多线程中的阻塞，别忘了加锁。

谢谢各位的指点。  还想问下，socket是阻塞还是非阻塞的好？ 自从设为非阻塞之后，send经常出现“Resource temporarily unavailable”错误， recv经常出现“invalid argument”错误  send那个sleep一小会可以缓解，但recv那个不知道是什么问题。  char serv_msg[300]; recv(tcp_pointer->socket_handle,serv_msg,sizeof(serv_msg),0);   这样参数有问题吗？


Question: 求大神帮助 这个冒泡功能的代码 如何理解

引用 2 楼 pozimxb 的回复:[quote=引用 1 楼 redakira 的回复:] if 的作用就是如果满足大小要求就交换2个元素的位置, 这也是冒泡的根本思想 4个FOR是3个循环其中第二个是2层嵌套 第一个FOR是用来读取输入 第四个是用来输出 第二,三个是用来冒泡的  外层循环次数当然都一样  {x=a[j];a[j]=a[j-1];a[j-1]=x;} 这个我不明白是什么意思啊  x变量除了这里 下面也没有再用到啊 真看不懂是干什么的..  完全不理解啊[/quote] x就是用来交换a[j]和a[j-1]的值的一个暂时变量 我们做个假设, 饮料是变量的值, 而放饮料的杯子是存放变量的地方, 我们称为地址, 那么假如:  你有一个装可乐(a[j]的值)的杯子(a[j]的地址)和一个装雪碧(a[j-1]的值)的杯子(a[j-1]的地址) 如果你要交换这两者, 最直观的做法就是拿第三个杯子x,  然后把可乐(a[j]的值)倒到第三个杯子(x的地址)里 -> x = a[j] 把雪碧(a[j-1]的值)倒到可乐杯子(a[j]的地址)里 -> a[j] = a[j-1] 最后把可乐(x的值)倒到雪碧杯子(a[j-1]的地址)里 -> a[j-1] = x

这就是最基本的冒泡排序，没别的，在你知道冒泡原理的情况下，单步调试程序是理解的最好办法。。。。

引用 1 楼 redakira 的回复:if 的作用就是如果满足大小要求就交换2个元素的位置, 这也是冒泡的根本思想 4个FOR是3个循环其中第二个是2层嵌套 第一个FOR是用来读取输入 第四个是用来输出 第二,三个是用来冒泡的  外层循环次数当然都一样  {x=a[j];a[j]=a[j-1];a[j-1]=x;} 这个我不明白是什么意思啊  x变量除了这里 下面也没有再用到啊 真看不懂是干什么的..  完全不理解啊


Question: 程序员的第一堂课

同志，还要继续努力哦

引用 3 楼 u010165006 的回复:main()写错了。 我说怎么看着就有点不顺眼  再说用vc的话，不是自己帮你生成了main么？居然还写错啦

printf("%d\n", c);

开始的时候，我也是这样，但没问同学，全是自己看书过的。。。

我们都是从小长大的。低级错误不可悲， 止步不前，或学习过慢则是过错了；学技术要快呀，共勉之

谭浩强的书就免了吧, K&R才是經典. 建議LZ買K&R學習.

printf("%d",c); %d是整型的输出格式，逗号后面的c是你要输出的整型变量

表示， 看见比我还笨的了。。 printf（“%d\n”， c）；

#include<stdio.h>  int main (void) { 	int a,b,c; 	a=0; 	b=1; 	c=a+b; 	printf("%d \n", c) }

我开始时也是void main 但现在一直是int main(int argc,char* argv[])

表达式是printf("%d\n",c)

引用 13 楼 hollebab 的回复:不是学生的问题,是老师, 因为我们老师教我们用void main(),我记忆犹新 现在的大学教C语言可以说不是真正的教,只是让你知道世界上有这么个东西而已 唉，谭浩强的书就是这样，我们刚学C时就是他的书，而老师也不纠正，唉，计算机方面还是国外的好书多啊！

提问前先看一下书好点

#include <stdio.h> int main() { 	int a,b,c; 	a=0; 	b=1; 	c=a+b; 	printf("%d\n",c); 	return 0; }

引用 14 楼 braveboyny 的回复:每天回帖即可获得10分可用分！ 支持

lz问这种问题，本人表示惊愕

引用 13 楼 hollebab 的回复:只是让你知道世界上有这么个东西而已我倒觉得这就是大学本应该做的事，剩下的就是学生自己的事了。

printf("%d",c);

输出结果你可以这样写（这是C++的写法） cout<< c <<endl;

这种问题还问啊，估计c语言教材的第一章就会说的。 printf ("%d\n", c);


Question: 突然想到递归包含怎么样预处理？

编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E  理解和讨论之前请先学会如何观察！

禁止相互 #include 。编译不通过的。 使用签名就可以了。

引用 1 楼 user-4 的回复:这没什么实际价值。递归调用倒是有点用，你只需两个都前向声明就行了++

假设编译器，可以正确处理,编译过程如下:   编译 main.cpp //main.cpp 。。。。  #include "a.h" //此时处理对a.h的包含 //===> 嵌入a.h #ifndef _A_H_ // #define _A_H_ //  _A_H_  defined.  #include "b.h"//  此时处理对b.h的包含 //==>嵌入b.h #ifndef _B_H_ #define _B_H_ //  _B_H_  defined.  #include "a.h"//==> 第二次 嵌入a.h  #ifndef _A_H_  //  1)_A_H_  defined. 所以除了配对的#endif ，后面的预编译语句，不执行；代码也不会编译了，所以没有递归。 //#define _A_H_ //........ #endif         // 2) 只有 1)2) 这两个预编译语句会执行，结果是跳过中间所有代码，不编译。   struct B {     struct A *pa;//没有前置声明，struct A不能识别，编译出错，所以struct B不能识别 }// ；这里应该有分号，不然这里或者后面，会报缺少分号错误。  #endif  struct A {     struct B *pb;   //有定义，本来是不会出错的，不过struct B不能识别，所以这里应该还是会编译出错 }// ；这里应该有分号，不然这里或者后面，会报缺少分号错误。  #endif  PS： 交叉引用的类型的头文件里面，不能缺少类型前置声明。

这没什么实际价值。递归调用倒是有点用，你只需两个都前向声明就行了


Question: 如何将读取的中文转为十六进制数啊？

引用 1 楼 user-3 的回复:char buff[1024]; char * s = "变成十六进制"; for(size_t i = 0;i < strlen(s);++i) { 	sprintf(buff + 2 * i,"%02x",s[i]); } printf("%s\n",buff);  用%02x确实能将字符串的二进制编码打印出来，我试了下，读取从windows下保存的unicode编码的文件，读出来的就是每个字对应的unicode码。但是读取在linux下用C语言保存的文件，读出来的编码就不是unicode码，大神，我要怎么把读出来的转成unicode呀？或者用C语言保存的时候能不能保存成unicode编码格式啊？

UTF8转Unicode，仅供参考，尽管是VB6： Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByRef lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByRef lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long '常用的代码页： const cpUTF8   =65001 const cpGB2312 =  936 const cpGB18030=54936 const cpUTF7   =65000 Function MultiByteToUTF16(UTF8() As Byte, CodePage As Long) As String     Dim bufSize As Long     bufSize = MultiByteToWideChar(CodePage, 0&, UTF8(0), UBound(UTF8) + 1, 0, 0)     MultiByteToUTF16 = Space(bufSize)     MultiByteToWideChar CodePage, 0&, UTF8(0), UBound(UTF8) + 1, StrPtr(MultiByteToUTF16), bufSize End Function  Function UTF16ToMultiByte(UTF16 As String, CodePage As Long) As Byte()     Dim bufSize As Long     Dim arr() As Byte     bufSize = WideCharToMultiByte(CodePage, 0&, StrPtr(UTF16), Len(UTF16), 0, 0, 0, 0)     ReDim arr(bufSize - 1)     WideCharToMultiByte CodePage, 0&, StrPtr(UTF16), Len(UTF16), arr(0), bufSize, 0, 0     UTF16ToMultiByte = arr End Function  Private Sub Command1_Click()     MsgBox MultiByteToUTF16(UTF16ToMultiByte("ab中,c", cpUTF8), cpUTF8) End Sub

中文占两字节，首先判断第一字节最高位是否为0，零的话，就只读一字节（ASCII），如果不是，就按两字节读取，读的两个字节根据字符编码集去解释是什么字。

晕，说得不对啊。  转编码，应该是用 使用iconv函数族   #include <iconv.h>         size_t iconv(iconv_t cd, char **restrict inbuf,               size_t *restrict inbytesleft, char **restrict outbuf,               size_t *restrict outbytesleft);


Question: 关于栈的输出

真相以示。。。闪。。。

额 看到了 ……

double转int int再转double

楼主如果要想用小数，参数应该使用浮点数

顶板凳，说的有道理。确实是被强转了。

正解， 浮点型被你转换为整形 引用 1 楼 user-6 的回复:void push(PSTACK ps,int val)//压栈 int啊

void push(PSTACK ps,int val)//压栈 int啊


Question: 谁知道这个怎么改

引用 3 楼 mwp 的回复:楼上英明，#define GERB_MESSAGE（t...）  g_log(NULL, G_LOG_LEVEL_MESSAGE, ##t) 在VS里的确是改成 #define GERB_MESSAGE(...) g_log(NULL, G_LOG_LEVEL_MESSAGE,__VA_ARGS__) 就对了

#define GERB_MESSAGE(...) g_log(NULL, G_LOG_LEVEL_MESSAGE,format, __VA_ARGS__)


Question: 我有一个挺不错的设计，可以做毕设，大创啥的，但是我只懂硬件，不懂软件，所以想找高手一起探讨一下

或者参考这个： Printer Escapes Windows version 3.x supported as many as 64 special functions called printer escapes that applications used to access special device features. An application called these functions by specifying one of 64 predefined values as the second parameter to the Escape function. For example, one of these applications printing on a PostScript printer could draw a PostScript graphic object called a path by calling the Escape function and supplying the BEGIN_PATH and END_PATH values. Most of these escapes are obsolete in the Microsoft® Win32® application programming interface (API) but are provided to simplify the porting of 16-bit Windows-based applications. The Win32 version of GDI supports a complete set of path functions that applications can use instead of the escapes to draw paths on any device. For a list of the Win32 functions that replace some of the escapes, see the Escape function.  Of the 64 original printer escapes, only the QUERYESCSUPPORT and the PASSTHROUGH escapes can be used by Win32-based applications:   Applications written for Windows 3.x can also use QUERYESCSUPPORT and PASSTHROUGH as well as the following 10 escapes. Note that the following escapes are only supported for backwards compatibility with Windows 3.x-based applications. The Escape function may fail if a Win32-based application uses any of these.   ABORTDOC  ENDDOC  GETPHYSPAGESIZE  GETPRINTINGOFFSET  GETSCALINGFACTOR  NEWFRAME  NEXTBAND  SETABORTPROC  SETCOPYCOUNT  STARTDOC  In addition to supporting Escape, the Win32 API provides an extended escape function called ExtEscape. This function allows applications to access capabilities of a particular device not directly available through GDI.

引用 5 楼 zhao4zhong1 的回复:借助WinIO.sys提供的API输出到并口对应端口0x378..0x37F 我去试试，先谢谢你

引用 3 楼 zhao4zhong1 的回复:你到底是纯DOS还是Windows？win xp

你到底是纯DOS还是Windows？

引用 1 楼 zhao4zhong1 的回复:纯DOS环境下用输出到PRN设备或outportb到并口对应端口0x378..0x37F Windows下可以输出到PRN设备或借助WinIO.sys提供的API输出到并口对应端口0x378..0x37F 我昨天把DB25插在计算机上，上面显示THE IO.SYS service is present，but the driver cannot be connected to，然后我试了一下程序，发现输出没有反应啊，这是怎么回事，我设置的地址是basic port是378啊


Question: 求助内存分配

晕。这么低级 。竟然没发现 太不认真啦 。反省反省

#include <stdio.h> #include <string.h> #include <stdlib.h> #define NUM 3 void memtest() {     char *str[NUM];     int t;      for (t=0;t<NUM;t++) {         str[t] = (char *)malloc(20);         if (str[t] == NULL)//这里不能多一个;         {             printf("malloc error\n\r");             exit(1);         }         printf("enter str[%d]:",t);fflush(stdout);         fgets(str[t],19,stdin);         if ('\n'==str[t][strlen(str[t])-1]) str[t][strlen(str[t])-1]=0;     }     for (t=0;t<NUM;t++) printf("str[%d]=\"%s\"\n",t,str[t]);     for (t=0;t<NUM;t++) free(str[t]); } int main() {     memtest();     return 0; } //enter str[0]:000 //enter str[1]:111 //enter str[2]:222 //str[0]="000" //str[1]="111" //str[2]="222" //

if(str[t] == NULL);，这行，多了个;


Question: 请教整型长度问题

引用 3 楼 silenttears 的回复:[quote=引用 1 楼 user-3 的回复:] 有区分正负数阿  int 是 -(2^32)   到    2^31-1  , unsigned int 就是 0到2^32-1了  确定64位是2^61-1?  但是我测试的时候，发现无符号是2^31-1  而不是2^32-1，为什么呢？[/quote]  你有什么证据？

复习整数的二进制表示。

引用 1 楼 user-3 的回复:有区分正负数阿  int 是 -(2^32)   到    2^31-1  , unsigned int 就是 0到2^32-1了  确定64位是2^61-1?  但是我测试的时候，发现无符号是2^31-1  而不是2^32-1，为什么呢？


Question: 关于指针和数组

计算机组成原理→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

估计是印刷错误，不然我也求解释

数组的名字在程序代码中的意义要分场合： 只在很少的场合下表示整个数组，有sizeof(数组名)和&数组名，不常见的就不提了  而在大多数场合，数组名表示它首元素的指针（允许我不用地址这个术语），即“数组名”与"&数组名[0]"同义；从而有一个程序员自己可以“推导”的方法-----若数组名左有&、右有[0]，则同时销掉-----还可以继续推广为“&指针表达式[0]"的左&右[0]同时销掉

指针与地址的概念，现有教程介绍的都存在问题。 “指针就是地址”这句话对编译器设计者说正确，对程序员说就不完全正确。  指针是带有指向对象类型信息的地址，即它的值是地址，但它有对象的类型信息。 而地址是一个不具备类型的量（俗称标量），只有void*指针才等价于地址。 上图，将类型概念抽象并提升----形成层次概念。  可以看出，有四个指针的地址值是一样的，但它们的层次（类型）信息是不一样的

a[0]+n   代表第0行第n个元素的地址 //这里a可以理解为a[0][n], 可以联想到一维的a+n表示第n个元素的地址，a[0]相当于一维时的a   &a[0]代表第0行的首地址    //这里a[0]表示第一行， 后面没有加数值，可以联想到a后面没加数值时是表示首地址

你把二维数组当成数组元素为一维数组的数组看，更有益处。

二维数组a[m][n]，表示m行、n列；也即m行，每行n个元素；也即是有m个一维数组，其中每个一维数组a[i]都有n个元素。 a的值等于a[m][n]整个二维数组的首地址， a[0]表示二维数组中的第1个一维数组，其值也等于第一行的首地址，还等于整个二维数组的首地址，也就等于a. a[0][0]是第1行第1个元素，那么&a[0][0]自然就是整个二维数组的首地址，也是第1行的首地址。 a是二维数组，a[0]是一维数组，可以对数组取地址，即有&a和&a[0]。 终上：a == &a[0] == a[0] == &a[0][0] == &a  虽然以上几个的值相等，但各自的意义还是有区别，如何看出来不一样呢：就是“加1”. a和&a[0]意义是一样的，表示行地址，指向的是一行，因为a+1和&a[0]+1 都比 a本身 大 n*每个元素所占字节，即跳了一行。 a[0]和&a[0][0] 是一样的，指向的是第1行第1个元素，因为a[0]+1和&a[0][0]+1仅仅跳了一个元素的字节数。 而&a则是整个二维数组的首地址，&a+1后跳过了整个二维数组，即增加了m*n*每个元素所占字节数。

就是把数组的地址赋给数组的第一个元素


Question: c语言文件显示问题

引用 楼主 u014203673 的回复:代码如下 #include<stdio.h> #include <stdlib.h> struct student_type { 	char num[6];	 	char sex[2]; 	char name[7]; }stud[3];  void main() { 	int i,x; 	FILE * fp;  	if((fp=fopen("e:\\stud.txt","rb"))==NULL) 	{  		printf("cannot open file\n"); 		exit(0); 	}  	printf("Input No:"); 	scanf("%d",&i); 	i--; 	x=sizeof(struct student_type); //结构体长度 	printf("%d\n",x); 	fseek(fp,i*sizeof(struct student_type),0);  //文件指针位置 	//printf("%d\n",x); 	fread(&stud[i],sizeof(struct student_type),1,fp);	        //显示第i组数据 	printf("%15s%4s%15s\n",stud[i].num,stud[i].sex,stud[i].name); 	printf("%15s\n",stud[i].sex); 	printf("%15s\n",stud[i].name); 	printf("%15s",stud[i].num); 	fclose(fp); } stud文件内容如下  显示结果如下   do not use binary mode to open a text file

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

有什么问题吗？


Question: LinkQueue Q;这个Q分配了空间吗？

LinkQueueNodePtr,* LinkQueuePtr 你这个命名啊~~~~LinkQueueNodePtr这货明明不是ptr么

引用 6 楼 oYinGui1 的回复:[quote=引用 2 楼 u012061345 的回复:] 只是指针而已，链表节点都是这样定义的。 无论什么指针，32位机器上都占4个字节的内存，所以压根不需要知道结构体的细节，只要知道这个名字是个结构体就行了。 如果不定义指针，就不行了。因为不知道结构体的细节，就无法正确分配内存。 成员函数指针就不是指针？成员函数指针就不是4。。。[/quote]  好吧，成员函数指针不是普通的指针。

分配了空间的。

typedef struct LinkQueueNodePtr //这里的LinkQueueNodePtr这个名称和struct这个结构体类型名 {                                                               //共同构成了struct LinkQueueNodePtr这个类型     char  data;     struct LinkQueueNodePtr *next;    //这里的struct LinkQueueNodePtr就是指针* next的类型，见第一行说明 }LinkQueueNodePtr,* LinkQueuePtr

引用 2 楼 u012061345 的回复:只是指针而已，链表节点都是这样定义的。 无论什么指针，32位机器上都占4个字节的内存，所以压根不需要知道结构体的细节，只要知道这个名字是个结构体就行了。 如果不定义指针，就不行了。因为不知道结构体的细节，就无法正确分配内存。 成员函数指针就不是指针？成员函数指针就不是4。。。

这是好习惯。

引用 2 楼 u012061345 的回复:只是指针而已，链表节点都是这样定义的。 无论什么指针，32位机器上都占4个字节的内存，所以压根不需要知道结构体的细节，只要知道这个名字是个结构体就行了。 如果不定义指针，就不行了。因为不知道结构体的细节，就无法正确分配内存。 都是老师教的——》打破砂锅问到底  ，现在有强迫症了

道友吃完饭速来搭救于我


Question: 关于C语言，怎么实现用户可以指定待查找文本的名称与位置，用VC

等用户输入文件名后再进行打开文件，就是将这个输入的字符串指针以参数传入。 用户指定位置，使用fseek函数，来把指针指向用户制定的位置开始进行字符串匹配的搜索。

参考notepad++源代码。


Question: 求解c穷举算法怎么写

密码验证程序，一般做个数字就可以了，太难的时间比较长

关键看你的密码输入以后如何返回? 是会返回给你正确个数还是只告诉你正确与否. 暴力破解密码就是多重for循环嵌套, 个人认为可以先缓存所有可能密码, 然后用数组+下标来进行尝试. 如果能够返回正确的位置, 那问题就简单多了, 可以把不满足密码条件的数组元素都删除了.


Question: 【有趣的C实验】用%c输出char型数组

String Manipulation These routines operate on null-terminated single-byte character, wide-character, and multibyte-character strings. Use the buffer-manipulation routines, described in Buffer Manipulation, to work with character arrays that do not end with a null character.  String-Manipulation Routines  Routine Use  _mbscoll, _mbsicoll, _mbsncoll, _mbsnicoll Compare two multibyte-character strings using multibyte code page information (_mbsicoll and _mbsnicoll are case-insensitive)  _mbsdec, _strdec, _wcsdec Move string pointer back one character  _mbsinc, _strinc, _wcsinc Advance string pointer by one character  _mbslen Get number of multibyte characters in multibyte-character string; dependent upon OEM code page  _mbsnbcat Append, at most, first n bytes of one multibyte-character string to another  _mbsnbcmp Compare first n bytes of two multibyte-character strings  _mbsnbcnt Return number of multibyte-character bytes within supplied character count  _mbsnbcpy Copy n bytes of string  _mbsnbicmp Compare n bytes of two multibyte-character strings, ignoring case  _mbsnbset Set first n bytes of multibyte-character string to specified character  _mbsnccnt Return number of multibyte characters within supplied byte count  _mbsnextc, _strnextc, _wcsnextc Find next character in string  _mbsninc. _strninc, _wcsninc  Advance string pointer by n characters  _mbsspnp, _strspnp, _wcsspnp Return pointer to first character in given string that is not in another given string  _mbstrlen Get number of multibyte characters in multibyte-character string; locale-dependent  sprintf, _stprintf Write formatted data to a string  strcat, wcscat, _mbscat Append one string to another  strchr, wcschr, _mbschr Find first occurrence of specified character in string  strcmp, wcscmp, _mbscmp Compare two strings  strcoll, wcscoll, _stricoll, _wcsicoll, _strncoll, _wcsncoll, _strnicoll, _wcsnicoll Compare two strings using current locale code page information (_stricoll, _wcsicoll, _strnicoll, and _wcsnicoll are case-insensitive)  strcpy, wcscpy, _mbscpy Copy one string to another  strcspn, wcscspn, _mbscspn,  Find first occurrence of character from specified character set in string  _strdup, _wcsdup, _mbsdup Duplicate string  strerror Map error number to message string  _strerror Map user-defined error message to string  strftime, wcsftime Format date-and-time string  _stricmp, _wcsicmp, _mbsicmp Compare two strings without regard to case  strlen, wcslen, _mbslen, _mbstrlen Find length of string  _strlwr, _wcslwr, _mbslwr Convert string to lowercase  strncat, wcsncat, _mbsncat Append characters of string  strncmp, wcsncmp, _mbsncmp Compare characters of two strings  strncpy, wcsncpy, _mbsncpy Copy characters of one string to another  _strnicmp, _wcsnicmp, _mbsnicmp Compare characters of two strings without regard to case  _strnset, _wcsnset, _mbsnset Set first n characters of string to specified character  strpbrk, wcspbrk, _mbspbrk Find first occurrence of character from one string in another string  strrchr, wcsrchr,_mbsrchr Find last occurrence of given character in string  _strrev, _wcsrev,_mbsrev Reverse string  _strset, _wcsset, _mbsset Set all characters of string to specified character  strspn, wcsspn, _mbsspn Find first substring from one string in another string  strstr, wcsstr, _mbsstr Find first occurrence of specified string in another string  strtok, wcstok, _mbstok Find next token in string  _strupr, _wcsupr, _mbsupr Convert string to uppercase  strxfrm, wcsxfrm Transform string into collated form based on locale-specific information  vsprintf, _vstprint Write formatted output using a pointer to a list of arguments

引用 17 楼 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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解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赵老师，您对学习C的字符有什么建议吗？

引用 15 楼 dbzhang800 的回复:引用 12 楼 u013643920 的回复:[quote=引用 10 楼 mujiok2003 的回复:] [quote=引用 9 楼 u013643920 的回复:] [quote=引用 3 楼 user-9 的回复:] 用%c来格式化一个指针。关键是没溢出呢，就可以找规律玩喽~ 在错误的代码找规律，没有意义。 你要想知道真正发生了什么，调试一下就是清楚了(step into printf)。 [/quote]找规律的意思就是了解知道代码运行的原理啦~~~[/quote]  其实，用正常的路径来学习会更快。本身就函数调用那一点点事：调用时，你把一个指针压入了栈(4个字节)，函数内，它从栈中取出一个字符(一个字节)[/quote]取出的那一个字节是从高位还是从低位开始取呢？

引用 12 楼 u013643920 的回复:引用 10 楼 mujiok2003 的回复:[quote=引用 9 楼 u013643920 的回复:] [quote=引用 3 楼 user-9 的回复:] 用%c来格式化一个指针。关键是没溢出呢，就可以找规律玩喽~ 在错误的代码找规律，没有意义。 你要想知道真正发生了什么，调试一下就是清楚了(step into printf)。 [/quote]找规律的意思就是了解知道代码运行的原理啦~~~[/quote]  其实，用正常的路径来学习会更快。本身就函数调用那一点点事：调用时，你把一个指针压入了栈(4个字节)，函数内，它从栈中取出一个字符(一个字节)

引用 3 楼 user-9 的回复:用%c来格式化一个指针。++

Process returned 0 (0x0)   execution time : 0.110 s Press any key to continue.

逗B贴，

引用 12 楼 u013643920 的回复:引用 10 楼 mujiok2003 的回复:[quote=引用 9 楼 u013643920 的回复:] [quote=引用 3 楼 user-9 的回复:] 用%c来格式化一个指针。关键是没溢出呢，就可以找规律玩喽~ 在错误的代码找规律，没有意义。 你要想知道真正发生了什么，调试一下就是清楚了(step into printf)。 [/quote]找规律的意思就是了解知道代码运行的原理啦~~~[/quote] 就是一个强制转型， 调试一下就明白了。

引用 10 楼 mujiok2003 的回复:引用 9 楼 u013643920 的回复:[quote=引用 3 楼 user-9 的回复:] 用%c来格式化一个指针。关键是没溢出呢，就可以找规律玩喽~ 在错误的代码找规律，没有意义。 你要想知道真正发生了什么，调试一下就是清楚了(step into printf)。 [/quote]找规律的意思就是了解知道代码运行的原理啦~~~

引用 8 楼 u013643920 的回复:[quote=引用 7 楼 oYinGui1 的回复:] [quote=引用 5 楼 u013643920 的回复:] [quote=引用 1 楼 oYinGui1 的回复:] test.cpp: 在函数‘int main()’中: test.cpp:14:22: 警告：格式 ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char*’ [-Wformat=]      printf("%c", name);                       ^ 编译都通过不了，GCC4.9.0实测我只VC++6.0，win7下额~[/quote] 强烈建议使用CodeBlocks，带gcc编译器的也就100M左右。功能蛮强大的。[/quote]恩，好的。是IDE环境吗？[/quote] 对，写些简单的代码，学习什么的，VS又太庞大，启动速度慢，CB启动就蛮快的，而且附带的gcc也是比较强大的编译器。

引用 9 楼 u013643920 的回复:引用 3 楼 user-9 的回复:用%c来格式化一个指针。关键是没溢出呢，就可以找规律玩喽~ 在错误的代码找规律，没有意义。 你要想知道真正发生了什么，调试一下就是清楚了(step into printf)。

引用 7 楼 oYinGui1 的回复:[quote=引用 5 楼 u013643920 的回复:] [quote=引用 1 楼 oYinGui1 的回复:] test.cpp: 在函数‘int main()’中: test.cpp:14:22: 警告：格式 ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char*’ [-Wformat=]      printf("%c", name);                       ^ 编译都通过不了，GCC4.9.0实测我只VC++6.0，win7下额~[/quote] 强烈建议使用CodeBlocks，带gcc编译器的也就100M左右。功能蛮强大的。[/quote]恩，好的。是IDE环境吗？

引用 5 楼 u013643920 的回复:[quote=引用 1 楼 oYinGui1 的回复:] test.cpp: 在函数‘int main()’中: test.cpp:14:22: 警告：格式 ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char*’ [-Wformat=]      printf("%c", name);                       ^ 编译都通过不了，GCC4.9.0实测我只VC++6.0，win7下额~[/quote] 强烈建议使用CodeBlocks，带gcc编译器的也就100M左右。功能蛮强大的。

引用 3 楼 user-9 的回复:用%c来格式化一个指针。恩，对的~

引用 1 楼 oYinGui1 的回复:test.cpp: 在函数‘int main()’中: test.cpp:14:22: 警告：格式 ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char*’ [-Wformat=]      printf("%c", name);                       ^ 编译都通过不了，GCC4.9.0实测我只VC++6.0，win7下额~

引用 2 楼 lin5161678 的回复:好好学习  多看书 少YY我真的做出来了！有图的，要看吗？

用%c来格式化一个指针。


Question: 求各位给个意见（c中的小问题）

这是一个很初级的OJ陷阱，因为a*b有可能导致溢出。

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


Question: SOCKET 传输大文件应该怎么做？

谢谢各位大牛的回答，因为最近有事，所以结贴晚了，小弟拜谢！ 另外：代码已经实现了，速度也能达到70+！

引用 20 楼 mujiok2003 的回复:[quote=引用 17 楼 u013093541 的回复:] [quote=引用 13 楼 mujiok2003 的回复:] 个人觉得单线程non-blocking IO+ synchronous I/O multiplexing(select/poll/epoll...) 更好。  牛哥，能说仔细下么？ [/quote]  其实没有必要弄搞那么复杂，直接用send/recv就好了， 只要网络足够通畅， 轻松达到。 我在我的笔记本(10Gbps的网卡）上轻松上90MB/s。 [/quote]  上图：

引用 17 楼 u013093541 的回复:[quote=引用 13 楼 mujiok2003 的回复:] 个人觉得单线程non-blocking IO+ synchronous I/O multiplexing(select/poll/epoll...) 更好。  牛哥，能说仔细下么？ [/quote]  其实没有必要弄搞那么复杂，直接用send/recv就好了， 只要网络足够通畅， 轻松达到。 我在我的笔记本(10Gbps的网卡）上轻松上90MB/s。

引用 11 楼 u013093541 的回复:昨天有去做测试，发现，并不是IO的问题造成整体的传输慢！还会代码存在问题 我按照自己3的思路去完成代码，也就是在Server端，我分了两个线程，一个线程用于读取文件，并将读到的buf加入到一个动态链表尾部，另一个线程从此链表头取数据，进行send操作，并且对send的返回值进行校验，如果send的返回值和预期的发送字节数不同，则采用断点重传的方式，继续传输。在Client端口，也是用类似的服务端的机制，维护一个链表，进行读取。 需要说明的是：我维护的这个链表是由深度的，并通过深度来调节两个线程对链表的操作。  这个思路是可行的的， 注意两个问题： 1. 防止文件IO过快， 导致你的队列(链表）迅速膨胀。 2. 队列(或链表）要有同步机制， 尽量减小临界区。

每秒50M能达到预期效果吗？ 有结果回复下

引用 16 楼 u013093541 的回复:[quote=引用 14 楼 zhao4zhong1 的回复:] 在文件大小相同的前提下：  读刚读过的文件比头次读没读过的文件快  读转速快的硬盘上的文件比读转速慢的硬盘上的文件快  读没有磁盘碎片的文件比读有磁盘碎片的文件快  读文件不处理比边读边处理快  单线程从头到尾一次读文件比多线程分别读文件各部分快（非固态硬盘上）  读固态硬盘上的文件比读普通硬盘上的文件快  赵老师，您说的这句“ 单线程从头到尾一次读文件比多线程分别读文件各部分快（非固态硬盘上）”只是针对的读取文件是么？那在我传输的过程中，采用多线程应该是比单线程传输要快一些吧？ 谢谢指教！[/quote] 是的。

引用 13 楼 mujiok2003 的回复:个人觉得单线程non-blocking IO+ synchronous I/O multiplexing(select/poll/epoll...) 更好。  牛哥，能说仔细下么？

引用 14 楼 zhao4zhong1 的回复:在文件大小相同的前提下：  读刚读过的文件比头次读没读过的文件快  读转速快的硬盘上的文件比读转速慢的硬盘上的文件快  读没有磁盘碎片的文件比读有磁盘碎片的文件快  读文件不处理比边读边处理快  单线程从头到尾一次读文件比多线程分别读文件各部分快（非固态硬盘上）  读固态硬盘上的文件比读普通硬盘上的文件快  赵老师，您说的这句“ 单线程从头到尾一次读文件比多线程分别读文件各部分快（非固态硬盘上）”只是针对的读取文件是么？那在我传输的过程中，采用多线程应该是比单线程传输要快一些吧？ 谢谢指教！

引用 12 楼 mujiok2003 的回复:[quote=引用 11 楼 u013093541 的回复:] 昨天有去做测试，发现，并不是IO的问题造成整体的传输慢！还会代码存在问题 我按照自己3的思路去完成代码，也就是在Server端，我分了两个线程，一个线程用于读取文件，并将读到的buf加入到一个动态链表尾部，另一个线程从此链表头取数据，进行send操作，并且对send的返回值进行校验，如果send的返回值和预期的发送字节数不同，则采用断点重传的方式，继续传输。在Client端口，也是用类似的服务端的机制，维护一个链表，进行读取。 需要说明的是：我维护的这个链表是由深度的，并通过深度来调节两个线程对链表的操作。  这个思路是可行的的， 注意两个问题： 1. 防止文件IO过快， 导致你的队列(链表）迅速膨胀。 2. 队列(或链表）要有同步机制， 尽量减小临界区。 [/quote]  小弟想请问一下，我现在维护一个链表，确实会使得链表的长度在某一个时刻徒增，那么应该如何设置链表的深度（文件200M）同时，发送的块大小是要一个一个的试？还是怎样才能或得更好的传输速度？ 第二个问题，您说的同步机制，我理解，但是说减小临界区是什么意思？是说对临界数据的选择尽量使得其数据量小么？ 谢谢！

引用 4 楼 zhao4zhong1 的回复:不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545好熟悉的回复，我以前发帖子你也是这样的回复

引用 1 楼 zilaishuichina 的回复:文件切块，是没有错的。发送端接受端开缓存，也是没有错的  至于lz说的速度慢，可能不是慢在网络IO上： 1：可能是慢在磁盘IO上，也就是你文件内容可能是一边读一边发的，lz可以尝试把文件内容全部读入内存，然后直接对内存中的文件数据分块发送。或者lz可以先做下测试，把你读取文件的代码先去掉，直接malloc分配50M，随便填点数据，然后发送这块内存。如果不慢了，证明是读文件的问题。如果还慢，只能说是你网络代码效率的问题了，比如可以选择换用IOCP模型在做尝试 2：可能是慢在频繁的申请释放内存上，lz可以考虑使用内存池，给你提供的这个内存池你可以看最后的测试效果，效率相差2个数量级 文件IO速度一般比socket IO快，试试scatter read, gather write, 目的是减少系统调用次数。

引用出现1的问题，是因为发端太快，造成丢包  TCP不会丢包。

引用 6 楼 u013093541 的回复:谢谢，各位大牛，小弟现在就去改代码，今天加个班，明天再向各位求教！ 解决问题要紧，先别关IOCP一类的了，不然干完需要一段时间了

谢谢，各位大牛，小弟现在就去改代码，今天加个班，明天再向各位求教！

千兆网卡直接send recv 应该也不会出问题吧，而且速度也应该不会慢，是不是你忘了处理粘包的问题呢？ 楼上说的文件分块传输也是可以考虑的，通过多线程发送，接收完毕之后再将文件合并， IOCP有一个transmitfile 你可以试一下 希望可以帮到你


Question: 这段C代码是什么意思，为什么可以这样调用

http://bbs.csdn.net/topics/390374955 参考C:\windows_2000_source_code\win2k\private\ntos\w32\ntuser\client\msgbox.c内容节选：      316: /***************************************************************************\     317: * MessageBox (API)     318: *     319: * History:     320: * 11-20-90 DarrinM      Ported from Win 3.0 sources.     321: \***************************************************************************/     322:      323: int MessageBoxA(     324:     HWND hwndOwner,     325:     LPCSTR lpszText,     326:     LPCSTR lpszCaption,     327:     UINT wStyle)     328: {     329:     EMIGETRETURNADDRESS();     330:     return MessageBoxExA(hwndOwner, lpszText, lpszCaption, wStyle, 0);     331: }     332:      333: int MessageBoxW(     334:     HWND hwndOwner,     335:     LPCWSTR lpszText,     336:     LPCWSTR lpszCaption,     337:     UINT wStyle)     338: {     339:     EMIGETRETURNADDRESS();     340:     return MessageBoxExW(hwndOwner, lpszText, lpszCaption, wStyle, 0);     341: }     342:      343:      344: /***************************************************************************\     345: * MessageBoxEx (API)     346: *     347: * History:     348: * 11-20-90 DarrinM      Ported from Win 3.0 sources.     349: \***************************************************************************/     350:      351: int MessageBoxExA(     352:     HWND hwndOwner,     353:     LPCSTR lpszText,     354:     LPCSTR lpszCaption,     355:     UINT wStyle,     356:     WORD wLanguageId)     357: {     358:     int retval;     359:     LPWSTR lpwszText = NULL;     360:     LPWSTR lpwszCaption = NULL;     361:      362:     if (lpszText) {     363:         if (!MBToWCS(lpszText, -1, &lpwszText, -1, TRUE))     364:             return 0;     365:     }     366:      367:     if (lpszCaption) {     368:         if (!MBToWCS(lpszCaption, -1, &lpwszCaption, -1, TRUE)) {     369:             UserLocalFree(lpwszText);     370:             return 0;     371:         }     372:     }     373:      374:     EMIGETRETURNADDRESS();     375:     retval = MessageBoxExW(hwndOwner,     376:                            lpwszText,     377:                            lpwszCaption,     378:                            wStyle,     379:                            wLanguageId);     380:      381:     UserLocalFree(lpwszText);     382:     if (lpwszCaption)     383:         UserLocalFree(lpwszCaption);     384:      385:     return retval;     386: }     387:      388: int MessageBoxExW(     389:     HWND hwndOwner,     390:     LPCWSTR lpszText,     391:     LPCWSTR lpszCaption,     392:     UINT wStyle,     393:     WORD wLanguageId)     394: {     395:     MSGBOXDATA  MsgBoxParams;     396:      397:      398: #if DBG     399:     /*     400:      * MB_USERICON is valid for MessageBoxIndirect only.     401:      * MessageBoxWorker validates the other style bits     402:      */     403:     if (wStyle & MB_USERICON) {     404:         RIPMSG0(RIP_WARNING, "MessageBoxExW: Invalid flag: MB_USERICON");     405:     }     406: #endif     407:      408:     RtlZeroMemory(&MsgBoxParams, sizeof(MsgBoxParams));     409:     MsgBoxParams.cbSize           = sizeof(MSGBOXPARAMS);     410:     MsgBoxParams.hwndOwner        = hwndOwner;     411:     MsgBoxParams.hInstance        = NULL;     412:     MsgBoxParams.lpszText         = lpszText;     413:     MsgBoxParams.lpszCaption      = lpszCaption;     414:     MsgBoxParams.dwStyle          = wStyle;     415:     MsgBoxParams.wLanguageId      = wLanguageId;     416:      417:     EMIGETRETURNADDRESS();     418:     return MessageBoxWorker(&MsgBoxParams);     419: }

我看向伪代码

引用 1 楼 zhao4zhong1 的回复:奇技淫巧帮我看看吧，现在上传了图片。

这是看雪论坛的《加密与解密》书里面介绍Windows内部函数的一段代码，pdf不清晰，但是能看，请大手指导一下，为什么能这么用，我们能这样定义函数吗？ 还是这本来就不是C代码！！！！！！！

看不懂啊，好奇葩的用法

奇技淫巧


Question: 求C语言高手帮改一个程序，才学习这个很多不懂。

这个函数就是根据用户的选择实现添加分数和查询分数的功能，不知道楼主希望的功能是什么？

你要怎么改啊？这需求忒不明确了，亲。

先说说你是哪里不懂吧。还有就是以后贴程序不要这么贴。。格式不好大家都不好看

把别人的一段代码拿出来让别人帮你改？ 好歹你自己写段代码出来，遇到问题解决不了来这里发问，有人可以帮你，你这样谁会帮你改的呢？

不懂还是扎扎实实学吧


Question: 夜深了

引用 30 楼 bug1190 的回复:你光喜欢C有毛用，还要把OS 的API和业务逻辑需求搞到一起，去写出能解决问题的代码才是程序员干的活好不，你还差一大截呢，劳资也喜欢C，简单嘛，大家都喜欢，看见纯C写的代码你是不是有种发春的感觉啊，， 看到你的头像有种发chun的感觉

我是来纯粹支持的。。。。

引用 47 楼 yingzijuntuan 的回复:顶一个，我是来骗分的 好，我被你骗一下吧 引用 48 楼 Purplepower 的回复:嗯，夜是很深了  回复于： 2014-06-02 12:45:22  从你的回复时间看， 你应该身处美国吧...

引用 46 楼 u012421456 的回复:支持楼主，坚强的走下去， 我的 记忆力，好像是有点儿关系吧 顺便问一句，楼主汇编怎么样啊？ 汇编真心不行， 因为并没有真正应用过， 除了学校的课程设计以外...

引用 45 楼 protel99_cz 的回复:充满激情，又满眼迷茫。其实每个人都有过这样的阶段。做了十几年的技术，也收获了不少，但是技术本身带给自己的并不多，更多的是其它方面的提高，比如社交能力，管理能力 其实我也有些彷徨，感觉做技术还是需要一定的智力和耐力，将来才能有所成就，但是真的感觉自己的智力是硬伤 耐力也欠缺，举棋不定的状态有些！！！

嗯，夜是很深了

顶一个，我是来骗分的

跟楼主一样，13年毕业，做软件，工作未满一年 只是，我还不知道前路在何方...

引用 42 楼 TZM_CSDN 的回复:跟楼主一样，13年毕业，做软件，工作未满一年 只是，我还不知道前路在何方...  赶快想好吧   时不我待啊

推荐楼主阅读我的博客文章《参禅与悟道——浅谈人生》。 如果以前读过，请再读一次。

引用 29 楼 zyaiwx 的回复:加油吧，楼主。码农不易，且码且珍惜 说的不错

真是因为楼主在学习，在思考，所以才发现自己很多不足的地方，只有知道了自己的不足，才有改进的方向啊，学习的道路本来就不平坦，很多东西的都是有联系的，所以不单是学习编程，还要学习其他的东西。如果你感觉疲劳，感觉知识不够用，那就对了，说明你在走上坡路，说明你一直在接触一些新的领域或者说是新的知识，而不是固步自封。不断的学习才能不被淘汰，赵老师说的对： 学然后知不足。 活到老学到老。 哈哈，我是一个菜鸟，楼主不要笑我啊

加油吧，楼主。码农不易，且码且珍惜

引用 25 楼 supermegaboy 的回复:[quote=引用 23 楼 N_sev7 的回复:] [quote=引用 22 楼 my_live_123 的回复:] 卤煮，你就坚持做自己喜欢的事情就好了！鄙人觉得，自己玩的high才不枉此生！当然你要定义好这个“玩”字！ 现在“玩”的就很high， 想抽烟就抽， 一天一盒都不够， 可是，青春需要买单的， 总不能玩完了就逃单吧[/quote]  每抽一根烟，寿命短一个月。[/quote]  我觉得我原来可能能活到100+，不然按这样计算，小学的时候我就已经挂了.... 不过真的该戒了，或者控制一下了

引用 24 楼 Falleyes 的回复:[quote=引用 19 楼 N_sev7 的回复:] [quote=引用 18 楼 Falleyes 的回复:] 人生的意义又何在呢？楼主想过自己生存的意义吗？  往小的说，努力工作，工资能比较丰厚就可以了，然后要让自己的家人过的好 往大的说，做一番事业，改变一些事情，帮助那些需要帮助的人[/quote]嗯，简单而朴实。如若坚持一定会取得成功！祝楼主一帆风顺！[/quote]  引用 26 楼 zhuiyi_5 的回复:楼主加油！趁着年轻，好好拼一把~  多谢，大家共勉吧！！！

引用 40 楼 zhao4zhong1 的回复:百度搜一下相关内容。  多谢提醒！！！