Question: 谁能帮我用c语言的DES解一下密。

引用 2 楼 newcdl2 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 仅供参考#pragma comment(lib, "crypt32.lib") #pragma comment(lib, "advapi32.lib") #define _WIN32_WINNT 0x0400 #include <stdio.h> #include <windows.h> #include <wincrypt.h> #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) #define KEYLENGTH  0x00800000 void HandleError(char *s); //-------------------------------------------------------------------- //  These additional #define statements are required. #define ENCRYPT_ALGORITHM CALG_RC4 #define ENCRYPT_BLOCK_SIZE 8 //   Declare the function EncryptFile. The function definition //   follows main. BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword); //-------------------------------------------------------------------- //   Begin main. void main(void) {     CHAR szSource[100];     CHAR szDestination[100];     CHAR szPassword[100];     printf("Encrypt a file. \n\n");     printf("Enter the name of the file to be encrypted: ");     scanf("%s",szSource);     printf("Enter the name of the output file: ");     scanf("%s",szDestination);     printf("Enter the password:");     scanf("%s",szPassword);     //--------------------------------------------------------------------     // Call EncryptFile to do the actual encryption.     if(EncryptFile(szSource, szDestination, szPassword)) {         printf("Encryption of the file %s was a success. \n", szSource);         printf("The encrypted data is in file %s.\n",szDestination);     } else {         HandleError("Error encrypting file!");     } } // End of main //-------------------------------------------------------------------- //   Code for the function EncryptFile called by main. static BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword) //-------------------------------------------------------------------- //   Parameters passed are: //     szSource, the name of the input, a plaintext file. //     szDestination, the name of the output, an encrypted file to be //         created. //     szPassword, the password. {     //--------------------------------------------------------------------     //   Declare and initialize local variables.     FILE *hSource;     FILE *hDestination;     HCRYPTPROV hCryptProv;     HCRYPTKEY hKey;     HCRYPTHASH hHash;     PBYTE pbBuffer;     DWORD dwBlockLen;     DWORD dwBufferLen;     DWORD dwCount;     //--------------------------------------------------------------------     // Open source file.     if(hSource = fopen(szSource,"rb")) {         printf("The source plaintext file, %s, is open. \n", szSource);     } else {         HandleError("Error opening source plaintext file!");     }     //--------------------------------------------------------------------     // Open destination file.     if(hDestination = fopen(szDestination,"wb")) {         printf("Destination file %s is open. \n", szDestination);     } else {         HandleError("Error opening destination ciphertext file!");     }     //以下获得一个CSP句柄     if(CryptAcquireContext(                 &hCryptProv,                 NULL,               //NULL表示使用默认密钥容器，默认密钥容器名                 //为用户登陆名                 NULL,                 PROV_RSA_FULL,                 0)) {         printf("A cryptographic provider has been acquired. \n");     } else {         if(CryptAcquireContext(                     &hCryptProv,                     NULL,                     NULL,                     PROV_RSA_FULL,                     CRYPT_NEWKEYSET))//创建密钥容器         {             //创建密钥容器成功，并得到CSP句柄             printf("A new key container has been created.\n");         } else {             HandleError("Could not create a new key container.\n");         }     }     //--------------------------------------------------------------------     // 创建一个会话密钥（session key）     // 会话密钥也叫对称密钥，用于对称加密算法。     // （注: 一个Session是指从调用函数CryptAcquireContext到调用函数     //   CryptReleaseContext 期间的阶段。会话密钥只能存在于一个会话过程）     //--------------------------------------------------------------------     // Create a hash object.     if(CryptCreateHash(                 hCryptProv,                 CALG_MD5,                 0,                 0,                 &hHash)) {         printf("A hash object has been created. \n");     } else {         HandleError("Error during CryptCreateHash!\n");     }     //--------------------------------------------------------------------     // 用输入的密码产生一个散列     if(CryptHashData(                 hHash,                 (BYTE *)szPassword,                 strlen(szPassword),                 0)) {         printf("The password has been added to the hash. \n");     } else {         HandleError("Error during CryptHashData. \n");     }     //--------------------------------------------------------------------     // 通过散列生成会话密钥     if(CryptDeriveKey(                 hCryptProv,                 ENCRYPT_ALGORITHM,                 hHash,                 KEYLENGTH,                 &hKey)) {         printf("An encryption key is derived from the password hash. \n");     } else {         HandleError("Error during CryptDeriveKey!\n");     }     //--------------------------------------------------------------------     // Destroy the hash object.     CryptDestroyHash(hHash);     hHash = NULL;     //--------------------------------------------------------------------     //  The session key is now ready.     //--------------------------------------------------------------------     // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的块加密的，所以被加密的     // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的     // 数据长度。     dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;     //--------------------------------------------------------------------     // Determine the block size. If a block cipher is used,     // it must have room for an extra block.     if(ENCRYPT_BLOCK_SIZE > 1)         dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;     else         dwBufferLen = dwBlockLen;     //--------------------------------------------------------------------     // Allocate memory.     if(pbBuffer = (BYTE *)malloc(dwBufferLen)) {         printf("Memory has been allocated for the buffer. \n");     } else {         HandleError("Out of memory. \n");     }     //--------------------------------------------------------------------     // In a do loop, encrypt the source file and write to the source file.     do {         //--------------------------------------------------------------------         // Read up to dwBlockLen bytes from the source file.         dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);         if(ferror(hSource)) {             HandleError("Error reading plaintext!\n");         }         //--------------------------------------------------------------------         // 加密数据         if(!CryptEncrypt(                     hKey,           //密钥                     0,              //如果数据同时进行散列和加密，这里传入一个                     //散列对象                     feof(hSource),  //如果是最后一个被加密的块，输入TRUE.如果不是输.                     //入FALSE这里通过判断是否到文件尾来决定是否为                     //最后一块。                     0,              //保留                     pbBuffer,       //输入被加密数据，输出加密后的数据                     &dwCount,       //输入被加密数据实际长度，输出加密后数据长度                     dwBufferLen))   //pbBuffer的大小。         {             HandleError("Error during CryptEncrypt. \n");         }         //--------------------------------------------------------------------         // Write data to the destination file.         fwrite(pbBuffer, 1, dwCount, hDestination);         if(ferror(hDestination)) {             HandleError("Error writing ciphertext.");         }     } while(!feof(hSource));     //--------------------------------------------------------------------     //  End the do loop when the last block of the source file has been     //  read, encrypted, and written to the destination file.     //--------------------------------------------------------------------     // Close files.     if(hSource)         fclose(hSource);     if(hDestination)         fclose(hDestination);     //--------------------------------------------------------------------     // Free memory.     if(pbBuffer)         free(pbBuffer);     //--------------------------------------------------------------------     // Destroy session key.     if(hKey)         CryptDestroyKey(hKey);     //--------------------------------------------------------------------     // Destroy hash object.     if(hHash)         CryptDestroyHash(hHash);     //--------------------------------------------------------------------     // Release provider handle.     if(hCryptProv)         CryptReleaseContext(hCryptProv, 0);     return(TRUE); } // End of Encryptfile //-------------------------------------------------------------------- //  This example uses the function HandleError, a simple error //  handling function, to print an error message to the standard error //  (stderr) file and exit the program. //  For most applications, replace this function with one //  that does more extensive error reporting. void HandleError(char *s) {     fprintf(stderr,"An error occurred in running the program. \n");     fprintf(stderr,"%s\n",s);     fprintf(stderr, "Error number %x.\n", GetLastError());     fprintf(stderr, "Program terminating. \n");     exit(1); } // End of HandleError  哥哥，您能给说明一下你的这代码是干什么的吗？？运行不了，我是弄java的，我只能运行解密java产生的密文，你能弄个能解出上面java中的密文的代码吗？？小弟十分感激。[/quote]  你这个基本上应该花钱找人做了。

调用Win32 API加密解密的例子。仅供参考。 其它爱莫能助。

引用 1 楼 zhao4zhong1 的回复:仅供参考#pragma comment(lib, "crypt32.lib") #pragma comment(lib, "advapi32.lib") #define _WIN32_WINNT 0x0400 #include <stdio.h> #include <windows.h> #include <wincrypt.h> #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) #define KEYLENGTH  0x00800000 void HandleError(char *s); //-------------------------------------------------------------------- //  These additional #define statements are required. #define ENCRYPT_ALGORITHM CALG_RC4 #define ENCRYPT_BLOCK_SIZE 8 //   Declare the function EncryptFile. The function definition //   follows main. BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword); //-------------------------------------------------------------------- //   Begin main. void main(void) {     CHAR szSource[100];     CHAR szDestination[100];     CHAR szPassword[100];     printf("Encrypt a file. \n\n");     printf("Enter the name of the file to be encrypted: ");     scanf("%s",szSource);     printf("Enter the name of the output file: ");     scanf("%s",szDestination);     printf("Enter the password:");     scanf("%s",szPassword);     //--------------------------------------------------------------------     // Call EncryptFile to do the actual encryption.     if(EncryptFile(szSource, szDestination, szPassword)) {         printf("Encryption of the file %s was a success. \n", szSource);         printf("The encrypted data is in file %s.\n",szDestination);     } else {         HandleError("Error encrypting file!");     } } // End of main //-------------------------------------------------------------------- //   Code for the function EncryptFile called by main. static BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword) //-------------------------------------------------------------------- //   Parameters passed are: //     szSource, the name of the input, a plaintext file. //     szDestination, the name of the output, an encrypted file to be //         created. //     szPassword, the password. {     //--------------------------------------------------------------------     //   Declare and initialize local variables.     FILE *hSource;     FILE *hDestination;     HCRYPTPROV hCryptProv;     HCRYPTKEY hKey;     HCRYPTHASH hHash;     PBYTE pbBuffer;     DWORD dwBlockLen;     DWORD dwBufferLen;     DWORD dwCount;     //--------------------------------------------------------------------     // Open source file.     if(hSource = fopen(szSource,"rb")) {         printf("The source plaintext file, %s, is open. \n", szSource);     } else {         HandleError("Error opening source plaintext file!");     }     //--------------------------------------------------------------------     // Open destination file.     if(hDestination = fopen(szDestination,"wb")) {         printf("Destination file %s is open. \n", szDestination);     } else {         HandleError("Error opening destination ciphertext file!");     }     //以下获得一个CSP句柄     if(CryptAcquireContext(                 &hCryptProv,                 NULL,               //NULL表示使用默认密钥容器，默认密钥容器名                 //为用户登陆名                 NULL,                 PROV_RSA_FULL,                 0)) {         printf("A cryptographic provider has been acquired. \n");     } else {         if(CryptAcquireContext(                     &hCryptProv,                     NULL,                     NULL,                     PROV_RSA_FULL,                     CRYPT_NEWKEYSET))//创建密钥容器         {             //创建密钥容器成功，并得到CSP句柄             printf("A new key container has been created.\n");         } else {             HandleError("Could not create a new key container.\n");         }     }     //--------------------------------------------------------------------     // 创建一个会话密钥（session key）     // 会话密钥也叫对称密钥，用于对称加密算法。     // （注: 一个Session是指从调用函数CryptAcquireContext到调用函数     //   CryptReleaseContext 期间的阶段。会话密钥只能存在于一个会话过程）     //--------------------------------------------------------------------     // Create a hash object.     if(CryptCreateHash(                 hCryptProv,                 CALG_MD5,                 0,                 0,                 &hHash)) {         printf("A hash object has been created. \n");     } else {         HandleError("Error during CryptCreateHash!\n");     }     //--------------------------------------------------------------------     // 用输入的密码产生一个散列     if(CryptHashData(                 hHash,                 (BYTE *)szPassword,                 strlen(szPassword),                 0)) {         printf("The password has been added to the hash. \n");     } else {         HandleError("Error during CryptHashData. \n");     }     //--------------------------------------------------------------------     // 通过散列生成会话密钥     if(CryptDeriveKey(                 hCryptProv,                 ENCRYPT_ALGORITHM,                 hHash,                 KEYLENGTH,                 &hKey)) {         printf("An encryption key is derived from the password hash. \n");     } else {         HandleError("Error during CryptDeriveKey!\n");     }     //--------------------------------------------------------------------     // Destroy the hash object.     CryptDestroyHash(hHash);     hHash = NULL;     //--------------------------------------------------------------------     //  The session key is now ready.     //--------------------------------------------------------------------     // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的块加密的，所以被加密的     // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的     // 数据长度。     dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;     //--------------------------------------------------------------------     // Determine the block size. If a block cipher is used,     // it must have room for an extra block.     if(ENCRYPT_BLOCK_SIZE > 1)         dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;     else         dwBufferLen = dwBlockLen;     //--------------------------------------------------------------------     // Allocate memory.     if(pbBuffer = (BYTE *)malloc(dwBufferLen)) {         printf("Memory has been allocated for the buffer. \n");     } else {         HandleError("Out of memory. \n");     }     //--------------------------------------------------------------------     // In a do loop, encrypt the source file and write to the source file.     do {         //--------------------------------------------------------------------         // Read up to dwBlockLen bytes from the source file.         dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);         if(ferror(hSource)) {             HandleError("Error reading plaintext!\n");         }         //--------------------------------------------------------------------         // 加密数据         if(!CryptEncrypt(                     hKey,           //密钥                     0,              //如果数据同时进行散列和加密，这里传入一个                     //散列对象                     feof(hSource),  //如果是最后一个被加密的块，输入TRUE.如果不是输.                     //入FALSE这里通过判断是否到文件尾来决定是否为                     //最后一块。                     0,              //保留                     pbBuffer,       //输入被加密数据，输出加密后的数据                     &dwCount,       //输入被加密数据实际长度，输出加密后数据长度                     dwBufferLen))   //pbBuffer的大小。         {             HandleError("Error during CryptEncrypt. \n");         }         //--------------------------------------------------------------------         // Write data to the destination file.         fwrite(pbBuffer, 1, dwCount, hDestination);         if(ferror(hDestination)) {             HandleError("Error writing ciphertext.");         }     } while(!feof(hSource));     //--------------------------------------------------------------------     //  End the do loop when the last block of the source file has been     //  read, encrypted, and written to the destination file.     //--------------------------------------------------------------------     // Close files.     if(hSource)         fclose(hSource);     if(hDestination)         fclose(hDestination);     //--------------------------------------------------------------------     // Free memory.     if(pbBuffer)         free(pbBuffer);     //--------------------------------------------------------------------     // Destroy session key.     if(hKey)         CryptDestroyKey(hKey);     //--------------------------------------------------------------------     // Destroy hash object.     if(hHash)         CryptDestroyHash(hHash);     //--------------------------------------------------------------------     // Release provider handle.     if(hCryptProv)         CryptReleaseContext(hCryptProv, 0);     return(TRUE); } // End of Encryptfile //-------------------------------------------------------------------- //  This example uses the function HandleError, a simple error //  handling function, to print an error message to the standard error //  (stderr) file and exit the program. //  For most applications, replace this function with one //  that does more extensive error reporting. void HandleError(char *s) {     fprintf(stderr,"An error occurred in running the program. \n");     fprintf(stderr,"%s\n",s);     fprintf(stderr, "Error number %x.\n", GetLastError());     fprintf(stderr, "Program terminating. \n");     exit(1); } // End of HandleError  哥哥，您能给说明一下你的这代码是干什么的吗？？运行不了，我是弄java的，我只能运行解密java产生的密文，你能弄个能解出上面java中的密文的代码吗？？小弟十分感激。


Question: c语言 解析NMEA协议 获得经纬度数据

怎么没有人回复呢，大家帮帮忙呢


Question: 关于 C中 unsigned char * pImage

引用 2 楼 user-1 的回复:GetByteArrayElements用这个转换即可： pImage = (*env)->GetByteArrayElements(env,imgBuff,JNI_FALSE); 嗯，谢谢。不过第二个参数起什么作用呢。自己看看先。

有人帮忙吗？


Question: C语言怎么把任务栏盖住

引用 1 楼 modyaj 的回复:程序有运行窗口吗？ 有啊

WS_OVERLAPPEDWINDOW 改为 WS_POPUP|WS_MAXIMIZE

任务栏属性：自动隐藏 ？

引用 2 楼 u014123498 的回复:[quote=引用 1 楼 modyaj 的回复:] 程序有运行窗口吗？ 有啊[/quote] 我知道 去掉最大化按钮可以实现挡住任务栏 不知道楼主是不是可以这么做 先去掉： long styles = ::GetWindowLong(m_hWnd,GWL_STYLE); styles &= ~WS_MAXIMIZEBOX; ::SetWindowLong(m_hWnd,GWL_STYLE,styles);  然后再显示 ShowWindow(SW_MAXIMIZE) 此时的最大化显示时挡住了任务栏的  前段时间我弄这个希望不要挡住 弄了很久

程序有运行窗口吗？


Question: 前辈可以给我c语言或c++的视频教程

C语言推荐郝斌的视频，适合入门，这是地址——http://www.xuexi111.com/jiaocheng/shipin/26243.html C++可以是孙鑫的——http://club.topsage.com/thread-156290-1-1.html

不建议看视频，付出和收获不成正比。

这玩意网上随便搜一下就能搜到一大把


Question: gethostbyaddr()的问题

目测是因为这一行：if(inet_aton(*argv,addr)!=0)  addr这个指针没有分配内存

单步，格式太乱了


Question: 请教前辈一个文件操作问题

/*data.txt .i  3 .o 1 .p 3 111 1 101 1 110 1 .e */  #include<stdio.h>  int main(void) { 	FILE fp; 	int data1, data2, buf[10];  	fp = fopen("data.txt", "r"); 	if(fp == NULL) 	{ 		printf("Failed to open the file!"); 		return -1; 	} 	fgets(buf, 10, fp); 	fgets(buf, 10, fp); 	fgets(buf, 10, fp); 	while(fscanf("%d%d", &data1, data2) == 2) 	{ 		printf("%d %d", data1, data2);//在这里做你的数据处理，我只简单的打印了一下 	} 	fclose(fp); 	return 0; }

嗯 学习学习

前辈能给我编一个框架看看不，刚开始用C不太会！大恩不言谢了！

首先用fopen打开这个文件， 之后因为要第四行，可以简单地直接用fgets 读出三行丢弃，之后读取还是用fgets读取每一行，然后对读出的数据进行处理即可，循环结束的条件是读到的数据是 .e  。


Question: 如何把伪代码变成源代码

我有个群，大家一起来探讨下好吗178879269

先看现成的代码，学习已有的，比你敲伪代码要进步更快！

我也是刚开数据结构课，还是看郝斌的视频，自己照着上面的敲代码，书是严蔚敏的，也都是伪代码，不过高一凡倒是给出了相应的代码，对于lz的问题，真不会，这个上网查或好好看书应该能解决吧

引用 6 楼 Bzy_NET 的回复:我有个群，大家一起来探讨下好吗178879269 我以前也加过一些类似的群，可惜人虽不少但不活跃，你问个问题不知啥时候才有人回甚至没人回，于是我灰心了，把那些群都退了，现在就依靠网络资源，看视频，上论坛，还有博客等等，实在没法时向一个技术还可以的朋友或老师请教，唉，还是感觉自己一个人学习比较好，虽然没人讨论，但也不妨碍自己静下心去学

读懂伪代码，熟悉源代码的语法。

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

引用 3 楼 Bzy_NET 的回复:给点建设性的意见可否 建设性的意见没有，我也是在学习。 编程这种东西，需要某一段时间连续大强度的训练，这样会提高很快。日积月累不见得会有太大提高。 这就像大师修炼绝世武功，也要闭关好久。计算机的很多东西，我感觉都是需要某一段时间，比如一个月，连续大强度的训练。这样才能获得瞬间提升。我自己也经常这样做。

给点建设性的意见可否

编程肯定不是看会的。多写。

引用 楼主 Bzy_NET 的回复:链表不难理解，难的就是把书上的伪代码自己敲出来。。。想找机械工业出版社的数据结构的源代码 struct Node; typedef struct Node * PtrToNode; typedef PtrToNode List; typedef PtrToNode Position; 这个是伪代码，我自己的理解是这样的 typedef struct Node { int data; struct Node * PtrToNode; }List; 是这样的吗？不过这个Position不知道是干嘛用的慢慢来


Question: 2. 编写函数，实现遍历单链表。序列按指数降序排序

不明白.怎么做?

相当于，链表插入排序，每插入一个数据，排下序。---就是找到一个位置，插入新节点。 无数据，直接插入 有数据查找一个位置插入  遇到次数相同的，系数相加就行了，不必单列一项了。


Question: 有关linux线程资源回收的问题

应使用“线程池”的思想：仅在程序初始化时创建线程，仅在程序结束退出前结束线程，杜绝在程序运行中创建或销毁线程。 参考下面：//循环向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; }

其他线程调用close(sockfd)时，处于阻塞状态的write会立即返回。 但更好的建议是用非阻塞套接字+select的套接字模型。

引用 6 楼 max_min_ 的回复:[quote=引用 5 楼 etangyushan 的回复:] [quote=引用 4 楼 max_min_ 的回复:]  如果进程没有结束，这样回收也只是表面上的回收而已！达不到实际回收的效果的 没明白啊。。。例如在线程里面申请一个socket描述符sockfd,那我在退出线程的时候需要 close (sockfd), 这个线程有突然立刻终止的需求，那么我这个close (sockfd) 放在哪里合适啊？是不是让起线程的进程直接结束就可以了吗？进程结束的话，资源还是回收不了吧。。。[/quote] 进程都结束了，资源99%的都可以回收了，除了一些什么硬盘这些的资源了。 线程突然终止之前关闭socket呗，不能知道什么时候结束，结束的状态总能捕捉吧！[/quote]  像这个线程处理函数，如果运行在write()那里还没有写完，需要终止，怎么关闭sockfd啊?，结束的状态怎么捕获啊？ void task(void *p) {       int sockfd = socket(AF_INET,SOCK_STREAM,0);      {           write(。。。。);      }      close(sockfd); }

引用 5 楼 etangyushan 的回复:[quote=引用 4 楼 max_min_ 的回复:]  如果进程没有结束，这样回收也只是表面上的回收而已！达不到实际回收的效果的 没明白啊。。。例如在线程里面申请一个socket描述符sockfd,那我在退出线程的时候需要 close (sockfd), 这个线程有突然立刻终止的需求，那么我这个close (sockfd) 放在哪里合适啊？是不是让起线程的进程直接结束就可以了吗？进程结束的话，资源还是回收不了吧。。。[/quote] 进程都结束了，资源99%的都可以回收了，除了一些什么硬盘这些的资源了。 线程突然终止之前关闭socket呗，不能知道什么时候结束，结束的状态总能捕捉吧！

引用 4 楼 max_min_ 的回复:如果进程没有结束，这样回收也只是表面上的回收而已！达不到实际回收的效果的 没明白啊。。。例如在线程里面申请一个socket描述符sockfd,那我在退出线程的时候需要 close (sockfd), 这个线程有突然立刻终止的需求，那么我这个close (sockfd) 放在哪里合适啊？是不是让起线程的进程直接结束就可以了吗？进程结束的话，资源还是回收不了吧。。。

如果进程没有结束，这样回收也只是表面上的回收而已！达不到实际回收的效果的

有什么方法吗？

根据什么判断啊？怎么判断啊？

在线程函数里自己写判断，判断线程是否结束


Question: IP地址与域名互查的问题

还可以暂时在hosts文件中写死。

IP地址和域名的映射是通过DNS实现的，gethostbyname和gethostbyaddr只是查找本地缓存或配置的域名映射。 要真正实现IP与域名的查找，必须通过向DNS服务器发出查询请求来获得。有以下两方法： 一：自己按照DNS协议发查询报文，获取其响应报文并解析结果； 二：调用操作系统线程的shell命令获取（linux是dig命令，windows是nslookup命令）

引用 4 楼 u012107622 的回复:[quote=引用 1 楼 u013061236 的回复:]  一，检查gethostbyaddr的相关操作  二，struct结构一般因为比较大，所以为了提高效率，传递指针，不用再重新拷贝一份副本。另外一般带*的，也可以作为传出参数   您能帮我看看gethostaddr 哪里错了么？实在找不出来。。。[/quote]  网上搜搜，具体的我也没用过

引用 1 楼 u013061236 的回复: 一，检查gethostbyaddr的相关操作  二，struct结构一般因为比较大，所以为了提高效率，传递指针，不用再重新拷贝一份副本。另外一般带*的，也可以作为传出参数   您能帮我看看gethostaddr 哪里错了么？实在找不出来。。。

@u013061236  您能帮我看看gethostaddr 哪里错了么？实在找不出来。。。


Question: sscanf（）的段错误问题

sscanf(s,"%d",int_arr[n++]) --> sscanf(s, "%d", &int_arr[n++])


Question: [SWU]利用二维数组设计按行和列分别求和和平均值的函数程序

引用 1 楼 user-2 的回复:你在使用数组时，访问位置越界了。 ++

你在使用数组时，访问位置越界了。


Question: 利用二维数组设计按行和列分别求和和平均值的函数程序

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

嘛问题。。自言自语/?

楼主是要我们看图找错么？

楼主发这个贴是干嘛啊？


Question: 字符串处理

#include <stdio.h>  int main(void) { 	int x = 1234, i;  	for (i = 4; i < 10; i++) 		printf("%0*d\n", i, x);  	getchar(); 	return 0; }  输出: 1234 01234 001234 0001234 00001234 000001234  这样是LZ想要的不?

普通的string就可以啊

嘎哈不用变量长度数组？仅C99+支持哟……  void f (int len) { int a [len]; /* …… */ }

printf("%06d\n" ,123);  显示 000123

sprintf 不行么？


Question: 请教float或double精度相关的问题

无法保证任何一个double 或者float 为 X.Y000000000000 例如 47.100000000000000000000000 但是可以分别取到整数部分和 十分位的 值.    float fVal = 47.1234454343 unsigned int n1, n2;  // 如果想在百分位进行四舍五入. fVal += 0.05;  // 整数部分. n1 = fVal;  //十分位部分. n2 = fVal * 10; n2 %= 10; // 没有考虑负数哈,方法类似.

引用 3 楼 movsd 的回复:如果只是要求精确到0.1的话，可以将数值放大10倍，用整数计算： int x=470; x+=1; 取结果的时候x/10就是整数部分，x%10是小数部分。  好办法..好办法~

引用 2 楼 starytx 的回复:float的精度无法保证你的需求，换成double就可以  double类型测试了,没问题,但貌似会耗资源经较大

引用 1 楼 user-5 的回复:GCC 提供有 decimal的扩展  http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html 表示看不懂英文

引用 3 楼 movsd 的回复:如果只是要求精确到0.1的话，可以将数值放大10倍，用整数计算： int x=470; x+=1; 取结果的时候x/10就是整数部分，x%10是小数部分。 这也是常见的处理方法.

引用 楼主 orangerx 的回复:各位大大,本人有个关于精度计算的实例,做不下去特来此处请教  float x=47; x+=0.1; 此时 printf x的值是47.099998,因为有特别需要,要求计算的时候可 以精确到0.1; 请问有什么办法可以确保x+=0.1 等于 47.1呢? 还有就是41.7xxxx 这里的xxxx要为0的,因为只想要的是0.1这个小数位; 请问C可以办到吗? 如果要求比较严格,那就换成高精度的库,如GMP, 否则#1介绍的类型就够用了。

float的精度无法保证你的需求，换成double就可以


Question: 请问怎么把枚举值enum{kOne='AAA'};的AAA给取出来？

引用 4 楼 ForestDB 的回复:'AAA'是多字节字符常量，就是个int，可以通过循环右移取最后一字节得到每一个字节的内容，然后拼出string。 是通过这种方法解决的。

'A'是char类型 'AA'     'AAA'     'AAAA'都是int类型 'AAAAA'错误  #include <typeinfo> printf("%s\n", typeid('A').name()); printf("%s\n", typeid('AA').name()); printf("%s\n", typeid('AAA').name()); printf("%s\n", typeid('AAAA').name());

如果一个整型字符常量包含的字符多于一个，那么，它的值是实现定义的。如果无视可移植性，则办法还是很多的，但要视具体情况而定。

把枚举变量值直接strcpy过去不行吗


Question: 关于c语言指针的问题

我也蒙了，这都没看出来

引用 9 楼 derekrose 的回复:

引用 7 楼 derekrose 的回复:[quote=引用 6 楼 Jerryup 的回复:] [quote=引用 3 楼 derekrose 的回复:] 30-28=8（16进制） 30-28=2（10进制） 30-28=100（108进制）我想问的是为什么是不同的2种结果啊？都是16进制表示的啊[/quote]  哪里是2种结果了  明明是一种！[/quote]谢谢你，我知道了。刚才蒙了。提这么一个愚蠢的问题。

引用 6 楼 Jerryup 的回复:[quote=引用 3 楼 derekrose 的回复:] 30-28=8（16进制） 30-28=2（10进制） 30-28=100（108进制）我想问的是为什么是不同的2种结果啊？都是16进制表示的啊[/quote]  哪里是2种结果了  明明是一种！

引用 3 楼 derekrose 的回复:30-28=8（16进制） 30-28=2（10进制） 30-28=100（108进制）我想问的是为什么是不同的2种结果啊？都是16进制表示的啊

引用 1 楼 richyhuang 的回复:你机器的int类型是几个字节的? 一般pc都是4个字节的啊,所以才加8我的机器int也是4字节

引用 2 楼 sholber 的回复:因为你用的是Turbo C，而作者用的是较新的编译器。我用的是vc6.0

因为你用的是Turbo C，而作者用的是较新的编译器。

你机器的int类型是几个字节的? 一般pc都是4个字节的啊,所以才加8


Question: c语言程序在不同环境下运行情况不同

//朕之解一:     for (int px = 0; px<823/19; px++)                 for (int yx = 0; yx <823/19; yx ++)                         if (23*px + 19*yx == 823 && px < yx) printf("%d,%d\n", px, yx);          //朕之解二:     for (int px = 0; px<823/19; px++)         for (int yx = 0; yx <823/19; yx ++)             if (2.3*px + 1.9*yx <= 82.3 && 2.3*px + 1.9*yx >= 82.3 && px < yx) printf("%d,%d\n", px, yx); 赶紧给分,别磨唧!

这个是精度问题，你可以这么改改 82.3-a < 1e-6，或者把价格都乘10倍，这样就都是整数了。能得出正确结果。浮点数类型不要直接做相等的判断。

引用 楼主 a775467383 的回复:我在dev-c++下和VC6.0分别都是输入同样的代码(VC6.0下在retnrn 0;前有加上getch();） 为什么dev-cpp下没结果显示出来（不是窗口一闪而过，而是黑窗口，但没结果输出），而VC6.0下则输出 11 30 ？请大神指导，谢谢 #include int main() {   int i,j;   float a;   for(i=1;i<=100;i++)   {            for(j=1;j<=100;j++)           {                  a=2.3*i+1.9*j;                 if(a==82.3&&i<j)printf("%d %d\n",i,j);           }    }    return 0; }  说实在，新人凡是遇到浮点数的问题统统绕道吧，纠结float没有任何意义。

引用 3 楼 a775467383 的回复:题目是这样的：啤酒每罐2.3元，饮料每罐1.9元。小明买了若干啤酒和饮料，一共花了82.3元。     我们还知道他买的啤酒比饮料的数量少，请你计算他买了几罐啤酒。 那请问按你们的看法，应该怎样修改？ 同意8楼做法 以角或分为单位，化为整形不但不会出错，性能可能提升（只是可能，但好像有的arm没有浮点指令，会发生质的变化）

引用 8 楼 PDD123 的回复:这个题目的浮点数精度问题，完全可以把价格换算成角或者分来做嘛。  至于dev-c++下不输出结果，是不是dev-c++和VC++6.0的printf函数有点不同？ 就VC 6这种垃圾，把两个浮点数比较成相等，也不太奇怪。

引用 5 楼 a775467383 的回复:[quote=引用 2 楼 tuzhutuzhu 的回复:] float型，由于精度的问题，一般不直接使用==进行比较 题目是这样的：啤酒每罐2.3元，饮料每罐1.9元。小明买了若干啤酒和饮料，一共花了82.3元。     我们还知道他买的啤酒比饮料的数量少，请你计算他买了几罐啤酒。 那请问按你的看法，应该怎样修改？[/quote]  for (int px = 0; px<823/19; px++)         for (int yx = 0; yx <823/19; yx ++)             if (23*px + 19*yx == 823 && px < yx) printf("%d,%d\n", px, yx);

引用 5 楼 a775467383 的回复:[quote=引用 2 楼 tuzhutuzhu 的回复:] float型，由于精度的问题，一般不直接使用==进行比较 题目是这样的：啤酒每罐2.3元，饮料每罐1.9元。小明买了若干啤酒和饮料，一共花了82.3元。     我们还知道他买的啤酒比饮料的数量少，请你计算他买了几罐啤酒。 那请问按你的看法，应该怎样修改？[/quote] 一般用if(abs(a-b)<=delta)来判断，delta的值取决于你想要的精度

引用 2 楼 tuzhutuzhu 的回复:float型，由于精度的问题，一般不直接使用==进行比较 题目是这样的：啤酒每罐2.3元，饮料每罐1.9元。小明买了若干啤酒和饮料，一共花了82.3元。     我们还知道他买的啤酒比饮料的数量少，请你计算他买了几罐啤酒。 那请问按你的看法，应该怎样修改？

引用 1 楼 user-7 的回复:a==82.3 深坑慎入题目是这样的：啤酒每罐2.3元，饮料每罐1.9元。小明买了若干啤酒和饮料，一共花了82.3元。     我们还知道他买的啤酒比饮料的数量少，请你计算他买了几罐啤酒。 那请问按你的看法，应该怎样修改？

float型，由于精度的问题，一般不直接使用==进行比较

a==82.3 深坑慎入


Question: 怎么把一个文件加入到另一个文件，在vc中用什么函数实现？

引用 3 楼 derekrose 的回复:[quote=引用 1 楼 z616913706 的回复:] 比如我现在压缩了一个zip的文件  我怎么在这个压缩文件中添加自己的文件头，版本号之类的 求大神知道啊。大神们快点来帮我看看啊 不就是读写文件吗？难点是什么？具体一点[/quote]大神求给个简单的例子或者伪代码也行

引用 2 楼 user-4 的回复:1. 写模式创建一个二进制文件File1，写入1kb 0，写入文件头，版本号之类； 2. 读模式打开zip文件File2，读取数据，计算校验码，写入File1。 3. 将读取到的数据写入File1。 4. 关闭两个文件。大神能说的详细点吗

CreateFile(...); WriteFile(...);

创建一个新文件，写文件中附上文件头，版本号，校验码之类， 读入压缩的文件， 一并写入新文件

引用 1 楼 z616913706 的回复:比如我现在压缩了一个zip的文件  我怎么在这个压缩文件中添加自己的文件头，版本号之类的 求大神知道啊。大神们快点来帮我看看啊 不就是读写文件吗？难点是什么？具体一点


Question: open 的时候返回了0，没有去重定向文件描述符0.

引用 3 楼 luckyaslan 的回复:[quote=引用 2 楼 ak47_wz 的回复:] 你打开什么了？ 这个和打开什么设备有关系吗[/quote] 有一定关系。但也并完全。 open会返回你当前可用的最小文件描述符。你能返回0，要么你是你打开了标准输入。 要么是，你在调用open之前，你关掉了标准输入。这样子，再调用open，会返回最小文件描述符，也就是0.

引用 7 楼 ak47_wz 的回复:[quote=引用 3 楼 luckyaslan 的回复:] [quote=引用 2 楼 ak47_wz 的回复:] 你打开什么了？ 这个和打开什么设备有关系吗[/quote] 有一定关系。但也并完全。 open会返回你当前可用的最小文件描述符。你能返回0，要么你是你打开了标准输入。 要么是，你在调用open之前，你关掉了标准输入。这样子，再调用open，会返回最小文件描述符，也就是0.[/quote]  是，昨天想了下，程序中用到了开源的东西，可能是这个里面关闭了文件描述符0.

引用 7 楼 ak47_wz 的回复:[quote=引用 3 楼 luckyaslan 的回复:] [quote=引用 2 楼 ak47_wz 的回复:] 你打开什么了？ 这个和打开什么设备有关系吗[/quote] 有一定关系。但也并完全。 open会返回你当前可用的最小文件描述符。你能返回0，要么你是你打开了标准输入。 要么是，你在调用open之前，你关掉了标准输入。这样子，再调用open，会返回最小文件描述符，也就是0.[/quote] 精辟！

STDIN_FILENO 0 STDOUT_FILENO 1 STDERR_FILENO  2 不谢

open的对象问题吧1

stdin : 0 stdout : 1 stderr : 2

引用 2 楼 ak47_wz 的回复:你打开什么了？ 这个和打开什么设备有关系吗

你打开什么了？

返回0，表示打开了标准输出，你open的是什么设备？？？


Question: 省略号在数组初始化内核模块

引用 1 楼 akirya 的回复:这是GCC的扩展吧 确实是的.  gnu c对c90的扩充语法。在这里的作用就把0~PLIP_MAX-1范围内的数组元素初始化为-1。  看参考gcc编译器手册获取更多细节，或者网络搜索“Designated Initializers”关键字获取帮助信息。

这是GCC的扩展吧


Question: setvbuf的v是什么意思？

引用 1 楼 user-1 的回复:virtual？ 本来就是我问你的，现在变成你问我了

virtual？


Question: char类型赋负值的问题

这样可能更直观 #include <stdio.h>  int main() {     char c1 = -6;     unsigned char c2 = -6;     int i1 = c1;     int i2 = c2;      printf("%x %x\n", i1, i2);      return 0; }

printf这类变参函数，传参数的时候会进行缺省参数提升，char和short会被提升为int，float提升为double。

学习了。。

这是隐式类型转换。char is promoted to int. 楼主可以看看这篇文章 http://www.ilanever.com/article/sitedetail.html?id=253

对于16进制输出, 都需要转换成无符号类型, 否则就会出现char按4字节输出的问题.   printf("%X\n",ch);//char类型-6的十六进制       修改成--------------->  printf("%X\n",(BYTE)ch);     printf("%X\n",ch_2);//char类型 6的十六进制   修改成------------>  printf("%X\n",(BYTE)ch_2);

学习了，看来printf也没那么简单啊

引用 1 楼 iamkconghua 的回复:printf("%X\n",ch);函数中的%X意味着其后对应的参数为int类型, ch会转换成int 引用 6 楼 zhao4zhong1 的回复:printf("%02X\n",(unsigned char)ch);  大神

学习了，谢谢大家的回答。

printf("%02X\n",(unsigned char)ch);


Question: 结构体指针 后面跟方括号

指针操作与操作符[ ]的运用  char name[32]; char *str = name;  访问第x属于[0，31],则下列语句等价 name[x] *（name + x）  *（str + x）  str = name + x； *str

对int * a; *(a + i) == a[i]

引用 8 楼 fuyongming 的回复:引用 7 楼 zhao4zhong1 的回复:A[B]等价于*(A+B)等价于*(B+A)等价于B[A]不是数学题啊，这交换律有点粗鲁。 //A[B]等价于*(A+B)等价于*(B+A)等价于B[A] //设A为"xyz",B为1 #include <stdio.h> int main() {     printf("[%c]\n",  "xyz"[1]);     printf("[%c]\n",*("xyz"+1));     printf("[%c]\n",*(1+"xyz"));     printf("[%c]\n",  1["xyz"]);     return 0; } //[y] //[y] //[y] //[y] //  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

A[B]等价于*(A+B)等价于*(B+A)等价于B[A]

引用 楼主 zxasqwedc 的回复:typedef struct _VIDEO_BLK_INFO { 	int 	video_type; 	int	width; 	int	height; 	..... } VIDEO_BLK_INFO;   typedef struct _STREAM_PARM{ 	MEM_MNG_INFO 	MemInfo; 	... }	STREAM_PARM;   typedef struct _MEM_INFO{ 	... 	VIDEO_BLK_INFO	*video_info;   } MEM_MNG_INFO;  STREAM_PARM *pParm; MEN_MNG_INFO MemInfo;   VIDEO_BLK_INFO *PVidInfo = &pParm->MemInfo.vedio_info[x];  如上，，[x]是什么意思？指什么呢。。。 MEM_MNG_INFO结构体里面的VIDEO_BLK_INFO不是数组指针啊？？？求解简单地说，[x]是数据的第x的元素，指针可以表示数组的首元素地址，&[x]表示当前元素的地址，也就是指针偏移到该元素的地址。

引用数组也是一个指针来的， VIDEO_BLK_INFO    *video_info;可表示一个结构体的指针，或一个数组的首地址 vedio_info[x] 可表示数组的第几个项，也可理解为在内存里从首地址开始的第x个位置 基本上是这个意思，数组指针也是指针啊，用法是一样的

pParm就没指向，只是个空指针，怎么能对其成员取地址呢

这个是基础中的基础，多看下书吧

typedef struct _MEM_INFO {      ...      VIDEO_BLK_INFO    *video_info;     //这里是个指针，看具体用法，可以指向一个VIDEO_BLK_INFO数组的首地址 } MEM_MNG_INFO;   例如 MEM_MNG_INFO tmpMngInfol; VIDEO_BLK_INFO tmpBlkInfo[10]; tmpMngInfol.video_info = tmpBlkInfo; tmpMngInfol.video_info[0];// 就相当于tmpBlkInfo[0]  指针其实就是地址，MemInfo.vedio_info[x];  说白了就是指向MemInfo.vedio_info+x*sizeof（VIDEO_BLK_INFO）


Question: 哪位大神可以帮帮我

流就是一堆数据，    打个比方，你开水龙头，源源不断的出水，每滴水都是 数据，远远不断的数据。

1、流是线性的； 2、流可以单向或者是双向传输； 3、流中数据是动态变化的； 4、流中的数据是大量的或者是传送速度要求比较快的。  引用 楼主 u014362443 的回复:由于初学C语言，不知道流是怎么一个概念，还有就是它跟直接传输有什么传输有什么区别，谁能够给我最直观的解释或者打比方，谢谢，好人一生平安

先  http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express  点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装   再参考  C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c  和  C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c  以及  C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\目录下其它和输入输出相关的C/C++源代码

我认为流就是一段延直线排列的数据。


Question: C语言&运算符问题。。。。

1011和100都是10进制哦。 位运算符：http://www.ilanever.com/article/sitedetail.html?id=244

int a = (1011)&100 1011 表示1000 + 10 + 1    十进制 100 代表100   十进制  你当然不能得出2进制结果

1111110011  // 1011 & 0001100100  // 100 ------------   0001100000  难道LZ把1011和100当成二进制?

你怎么算成0的


Question: STM32 CAN如何通过PGN来过滤数据

楼主，怎么解决的？

已经解决了，谢谢哈！

你这是要解1939的协议吗？我弄过1939，有类似的代码 如果需要 加QQ 522511920

自己顶啊！！！！


Question: 关于fread读取结构体fwrite输出的问题几个

引用 3 楼 u012774187 的回复:引用 1 楼 JiMoKuangXiangQu 的回复:这个就不用操心了,读写统一用sizeof()来指定大小,输入/输出保持一致即可.那我应该怎么修改呢？？ /*  * Build with Code::Blocks 13.12, and set GCC as compiler.  */  #include <stdio.h> #include <stdlib.h>  #define N 2  struct node //这是每个学生节点包含的信息 { 	char name[31]; 	long number; //	int  course1; //	int  course2; //	int  course3; //	int  course4; //	int  course5; //	int total; //	float average; //	PNODE next; //	int rank; } stu[N] = {     {"ZhanSan", 20040301},     {"LiSi",    20040302}, };  int main(void) {     const char *stuDataFile = "Students.dat";     FILE *fp;     int i;     struct node student;      // write students records     if ((fp = fopen(stuDataFile, "wb")) == NULL)     {         fprintf(stderr, "create file %s failed\n", stuDataFile);         exit(EXIT_FAILURE);     }     for (i = 0; i < N; i++)         fwrite(&stu[i], sizeof(struct node), 1, fp); // 最好判断是否写入成功     fclose(fp);      // read the records     if ((fp = fopen(stuDataFile, "rb")) == NULL)     {         fprintf(stderr, "open file %s failed\n", stuDataFile);         exit(EXIT_FAILURE);     }     for (i = 0; i < N; i++)     {         fread(&student, sizeof(struct node), 1, fp);         printf(".name: %s\n.number: %ld\n\n", student.name, student.number);     }     fclose(fp);      return 0; } 参考一下.

open 时设定 rw 不就行了吗

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

另外,最好不要对同一个同时读写. LZ的读失败的原因是: 首先在读,可惜此时文件里面没有任何内容; 其次即使先写后读,也要把缓冲的内容刷到输出文件(fflush,fclose),菜油内容可读.


Question: 关于程序入口时数据区大小的分配

《程序员的自我修养——链接、装载与库》

引用 2 楼 JiMoKuangXiangQu 的回复:推荐LZ学习下 Linkers and Loaders类的书籍.如果针对特定平台,Windows可以看看PE格式,Linux可以看看ELF. 另外,进程/线程也需要了解.  个人意见,仅供参考.  恩恩，谢谢推荐，我要走的路还很长，，， 但是能现在解释一下么？

引用 1 楼 N_sev7 的回复:几存放数据内存段： 1）正文段——CPU执行机器指令部分；程序只有副本；只读防止程序由于意外事故而修改自身指令；  2）初始化数据段（数据段）——程序所有赋了初值全局变量存放里  3）非初始化数据段（bss段）——程序没有初始化全局变量；内核此段初始化0  4）栈——增长方向：自顶向下增长；自动变量及每次函数调用时所需要保存信息（返回地址；环境信息）  5）堆——动态存储 这个我知道，程序代码有个区域放置的，但是在VC心爱调试的时候，到一个函数入口，内存的一块区域会高亮，我可以理解为给这个程序段分配的内存的吗？但问题是每次一样的代码区域大小不一样啊


Question: 定义 unsigned char *pImage;报错错误： expected expression before ‘unsigned’

引用 6 楼 lgmsyy 的回复:[quote=引用 5 楼 gqjjqg 的回复:] unsigned char pImage[10]; 在C中不能这么定义，请参考3，4楼答案。  [/quote]  别搞笑好吗?  回去看看C99怎么定义一个数组。

引用 5 楼 gqjjqg 的回复:unsigned char pImage[10]; 在C中不能这么定义，请参考3，4楼答案。

unsigned char pImage[10];

引用 2 楼 N_sev7 的回复:[quote=引用 1 楼 lgmsyy 的回复:] 在c++中可以这么定义：  unsigned char *pImage； pImage = new unsigned char[100];  C应该怎么写，我按照以下方式，报错 unsigned char *pImage;   pImage = unsigned char[10]; 错误： expected expression before ‘unsigned’  unsigned char *pImage = (unsigned char *)malloc(sizeof(unsigned char)*10); [/quote] 用malloc动态分配一个 unsigned char 的空间，在这里空间分配了10个字节。然后把malloc返回的地址强制类型转换为unsigned char指针，在将结果付给指针变量pImage。是这个意思吗？

引用 1 楼 lgmsyy 的回复:在c++中可以这么定义：  unsigned char *pImage； pImage = new unsigned char[100];  C应该怎么写，我按照以下方式，报错 unsigned char *pImage;   pImage = unsigned char[10]; 错误： expected expression before ‘unsigned’  pImage = unsigned char[10]; C中有这样的表达式吗？

引用 1 楼 lgmsyy 的回复:在c++中可以这么定义：  unsigned char *pImage； pImage = new unsigned char[100];  C应该怎么写，我按照以下方式，报错 unsigned char *pImage;   pImage = unsigned char[10]; 错误： expected expression before ‘unsigned’  unsigned char *pImage = (unsigned char *)malloc(sizeof(unsigned char)*10);

引用 8 楼 lgmsyy 的回复:[quote=引用 7 楼 gqjjqg 的回复:] [quote=引用 6 楼 lgmsyy 的回复:] [quote=引用 5 楼 gqjjqg 的回复:] unsigned char pImage[10]; 在C中不能这么定义，请参考3，4楼答案。  [/quote]  别搞笑好吗?  回去看看C99怎么定义一个数组。[/quote]  刚才看错了。  unsigned char pImage[10];是没问题的。 但我需要的是unsigned char *pImage 这种指针方式，4楼给的答案是正确的，请参考。[/quote]  才10个字节的数组要去malloc一把,free一把.

引用 4 楼 lgmsyy 的回复:[quote=引用 2 楼 N_sev7 的回复:] [quote=引用 1 楼 lgmsyy 的回复:] 在c++中可以这么定义：  unsigned char *pImage； pImage = new unsigned char[100];  C应该怎么写，我按照以下方式，报错 unsigned char *pImage;   pImage = unsigned char[10]; 错误： expected expression before ‘unsigned’  unsigned char *pImage = (unsigned char *)malloc(sizeof(unsigned char)*10); [/quote] 用malloc动态分配一个 unsigned char 的空间，在这里空间分配了10个字节。然后把malloc返回的地址强制类型转换为unsigned char指针，在将结果付给指针变量pImage。是这个意思吗？[/quote]

引用 7 楼 gqjjqg 的回复:[quote=引用 6 楼 lgmsyy 的回复:] [quote=引用 5 楼 gqjjqg 的回复:] unsigned char pImage[10]; 在C中不能这么定义，请参考3，4楼答案。  [/quote]  别搞笑好吗?  回去看看C99怎么定义一个数组。[/quote]  刚才看错了。  unsigned char pImage[10];是没问题的。 但我需要的是unsigned char *pImage 这种指针方式，4楼给的答案是正确的，请参考。


Question: 求解深度优先搜索问题

dp的代码，主要看思路哈下面代码许多边界条件都没有考虑） 而且内存相当大，可能行不通  void Baozang(int m, int n, int k) { 	int baoNumber[m][n] //记录各个地点宝藏 	dp Baozang[m][n][m+n]  //记录各个情况宝藏数目 	 	                       //这里最好用vector之类的替换省一点内存 	min[0][0] = baoNumber[0][0]; 	 	for(int i = 1; i <= m + n - 2; ++i) 	{ 		for(int j = 0; j <= i; ++ j) 		{ 			//更新各个位置宝藏数目以及最小宝藏数 			int p = 0,q = 0; 			while(dp[j][i - j][p].minbao != -1) 			{//上面来的情况 				if(dp[j][i - j] + baoNumber[j][i - j] <= k) 				{ 					baozang[j][i - j][q] = dp[[j][i - j - 1][p] + baoNumber[i][i - j]; 					++ q; 				} 				++ p; 			}  			p = 0; 			while(dp[i - 1][i - j][p].minbao != -1) 			{//左面来的情况 				if(dp[i - 1][i - j][p] + baoNumber[i][i - j] <= k) 				{ 					baozang[i][i - j][q] = dp[i - 1][i - j][p] + baoNumber[i][i - j]]; 					++ q; 				} 				++ p; 			}  			 		} 	} 	 }ud   下面深搜的代码，作了最简单的减枝，应该TLE，有兴趣的话继续优化一下减枝条件吧  int count = 0;  void search(int minbao, int curBao, int m, int n,  			int targetM, int targetN, int k) { 	if(curBao > k) 	   return; 	if(m == targetM && n == targetN) 	{ 		if(minbao + baoNumber[m][n] == k) 		{ 			++ count; 			return; 		} 		else  			return;  	} 	if(baoNumber[m][n] < minbao) 	{ 		minbao = baoNumber[m][n]; 		curBao += baoNumber[m][n]; 	} 		 	if(m + 1 < targetM) 		search(minbao, curBao, m + 1, n ,targetM, targetN, k); 	 	if(n + 1 < targetM) 		search(minbao, curBao, m , n + 1,targetM, targetN, k); }

空间允许的话(需要O(m*n*k)的辅助空间)，用动态规划吧。 到每个位置经过的步数都一定的，只要每次更新到这里 的可能得到的宝藏一直更新到终点就可以了。  深搜的话注意减枝，要不肯定要TLE。吃饭去了，一会吃完上代码

1)找出可以拿到K件的若干最短路径。 2)查找每条最短路径的替代方案总数目。 3)去重或者设法使得计算中，没有重复方案。 PS: 这里只需要数目，不需要给出每种方案。

个人见解：动态规划只是在概率往往接近最优解而已，想要准确的不行吧。

显然是动态规划。搜索等着超时吧。


Question: 看到c专家编程上面有一个有意思的东西

引用 1 楼 zengraoli 的回复: #include "stdio.h" #include "stdlib.h"   // static unsigned short stopwatch[] = { // 	0x07C6, // 	0x1FF7, // 	0x383B, // 	0x600C, // 	0x600C, // 	0xC006, // 	0xC006, // 	0xDF06, // 	0xC106, // 	0xC106, // 	0x610C, // 	0x610C, // 	0x3838, // 	0x1FF0, // 	0x07C0, // 	0x0000 // };   #define X )*2+1 #define _ )*2 #define s ((((((((((((((((0 /* For building glyphs 16 bits wide */   static unsigned short stopwatch[] = { 	s _ _ _ _ _ X X X X X _ _ _ X X _ , 	s _ _ _ X X X X X X X X X _ X X X , 	s _ _ X X X _ _ _ _ _ X X X _ X X , 	s _ X X _ _ _ _ _ _ _ _ _ X X _ _ , 	s _ X X _ _ _ _ _ _ _ _ _ X X _ _ , 	s X X _ _ _ _ _ _ _ _ _ _ _ X X _ , 	s X X _ _ _ _ _ _ _ _ _ _ _ X X _ , 	s X X _ X X X X X _ _ _ _ _ X X _ , 	s X X _ _ _ _ _ X _ _ _ _ _ X X _ , 	s X X _ _ _ _ _ X _ _ _ _ _ X X _ , 	s _ X X _ _ _ _ X _ _ _ _ X X _ _ , 	s _ X X _ _ _ _ X _ _ _ _ X X _ _ , 	s _ _ X X X _ _ _ _ _ X X X _ _ _ , 	s _ _ _ X X X X X X X X X _ _ _ _ , 	s _ _ _ _ _ X X X X X _ _ _ _ _ _ , 	s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ };    int main() { 	int index; 	printf("1111"); 	for (index = 0; index < 16; index++) 	{ 		printf("%x", stopwatch[index]); 		printf("\n"); 	} 	printf("222");  	return 0; }   未明白，这里111和222都没输出，输出只有0x07C6、0x1FF7、0x383B……这些的十进制数值，而且是连在一起的。。  int main() { 	int index; 	printf("1111\n\n\n");    ///多加几个换行你就看到了   - _ -!!! 	for (index = 0; index < 16; index++) 	{ 		printf("%x", stopwatch[index]); 		printf("\n"); 	} 	printf("\n\n222\n"); 	 	return 0; }

自己的问题。。编译器 没设置正确。。


Question: 哪位大神有VS的使用教程？

VS2010或者以上，不建议修改字体大小，你可以用代码编辑器右下角的百分比缩放来调整大小。

嗯，这些都是可以搜到的，一楼说的不错

字体： 工具 --> 选项 --> 环境 --> 字体和颜色 代码序号（大概说的是行号吧）：工具 --> 选项 --> 文本编辑 --> C/C++ --> 常规，右边的 “行号”前打勾勾 以上是vs2013的设置，其他版本类似。  vs2012和vs2013的文档似乎是通用的，这里有下载链接： http://www.microsoft.com/zh-CN/download/details.aspx?id=34794


Question: for循环问题

for(i=0;i<n;i++); 你想要初始化时，注意for循环后面的逗号，循环完了，i就是9了 应该去掉后面的逗号

这么细致的问题都看出来了,真是厉害啊

for(i=0;i<n;i++);  多了个分号“；”

谢谢！qwq

for(i=0;i<n;i++);因为这里多了一个  ；


Question: 子窗口控件问题

CreateWindow             参数 lpClassName     EDIT    检查创建编辑框 给的参数给的对不对。

稍微修改了下LZ的代码，请参考。 #include<Windows.h> //#include "header.h"  /* header.h start */ #define BUTTONS 3 #define MAXSIZE 20 // ??? struct ChildWindow { 	ULONG iStyle; 	CONST TCHAR* szText; }; /* header.h end */  LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { 	TCHAR szAppName[] = TEXT("Computation"); 	WNDCLASS		wndclass; 	HWND			hwnd; 	MSG				msg;  	wndclass.style = CS_VREDRAW | CS_HREDRAW; 	wndclass.lpfnWndProc = WndProc;									//设定窗口消息处理程序 	wndclass.cbClsExtra = 0;										//在窗口类别结构中预留一些额外空间 	wndclass.cbWndExtra = 0;										//在Windows内部保存的窗口结构中预留一些额外空间 	wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);	//设定画刷 	wndclass.hInstance = hInstance;								//程序的执行实体句柄 	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);			//设定程序图标 	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);			//设定光标 	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);		//窗口的背景颜色 	wndclass.lpszMenuName = NULL;									//指定窗口类别菜单 	wndclass.lpszClassName = szAppName;								//窗口类别的名称  	RegisterClass(&wndclass);												//注册窗口  	hwnd = CreateWindow(szAppName,											//窗口类别的名称 		TEXT("计算方法"),													//窗口标题 		WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,			//标准窗口且窗口不能缩放 		CW_USEDEFAULT,														//窗口左上角相对于屏幕左上角的初始位置(x坐标轴方向) 		CW_USEDEFAULT,														//窗口左上角相对于屏幕左上角的初始位置(y坐标轴方向) 		600,																//窗口x轴方向的大小 		400,																//窗口y轴方向的大小 		NULL,																//父母窗口句柄 		NULL,																//窗口菜单句柄 		hInstance,															//程序执行实体句柄 		NULL																//执行参数 		);  	ShowWindow(hwnd, iCmdShow);						//显示窗口 	UpdateWindow(hwnd);					        //重画窗口，发送消息WM_PAINT   	while (GetMessage(&msg, NULL, 0, 0)) 	{ 		TranslateMessage(&msg); 		DispatchMessage(&msg); 	} 	return msg.wParam; }  LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { 	static int			cxChar, cyChar, i, j; 	static	HWND		hwndButton[BUTTONS], hwndEdit[MAXSIZE*MAXSIZE]; 	static	HWND		temp; 	HDC					hdc; 	PAINTSTRUCT			ps; 	struct ChildWindow	childwindow[] = { 		BS_PUSHBUTTON, TEXT("高斯顺序消元法"), 		BS_PUSHBUTTON, TEXT("高斯列主元消元法"), 		BS_PUSHBUTTON, TEXT("LU分解"), 		WS_BORDER, NULL, 	};  	switch (message) 	{ 	case WM_CREATE:					//函数CreateWindow调用发送VM_CREATE #if 1 		temp = CreateWindow(TEXT("edit"), TEXT("YEDS"), 			WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 			100, 120, 100, 100, 			hwnd, (HMENU)20,  			((LPCREATESTRUCT)lParam)->hInstance, NULL); #else 		temp = CreateWindow(TEXT("input"), TEXT("YEDS"), 			WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 			0, 0, 0, 0, 			//100, 10, 100, 100, 			hwnd, (HMENU)20, ((LPCREATESTRUCT)lParam)->hInstance, NULL 			); #endif 		for (i = 0; i < BUTTONS; i++) 		{ 			hwndButton[i] = CreateWindow(TEXT("button"), childwindow[i].szText, 				WS_CHILD | WS_VISIBLE | childwindow[i].iStyle, 				0, 0, 0, 0, 				hwnd, (HMENU)i, ((LPCREATESTRUCT)lParam)->hInstance, NULL 				); 		}  		return 0;  	case WM_SETFOCUS: 		SetFocus(temp); 		return 0;  	case WM_SIZE: 		cxChar = LOWORD(GetDialogBaseUnits()); 		cyChar = HIWORD(GetDialogBaseUnits());  		for (i = 0; i < BUTTONS; i++) 		{ 			MoveWindow(hwndButton[i], cxChar, cyChar*(1 + 2 * i), 20 * cxChar, 7 * cyChar / 4, TRUE); 		} 		return 0;  	case WM_PAINT: 		hdc = BeginPaint(hwnd, &ps); 		EndPaint(hwnd, &ps); 		return 0;  	case WM_DESTROY: 		PostQuitMessage(0);				//在消息队列中加入WM_QUIT消息 		return 0; 	} 	return DefWindowProc(hwnd, message, wParam, lParam); }


Question: 求解：该循环的过程

这个应该还蛮好理解的。就是三层for循环，从最内层开始，知道最外层结束。

//for循环的循环体，即使只有一行，也建议加上大括号 #include <stdio.h>  void main() { 	int i, j, k; 	for (i = 0; i < 2; i++) 	{ 		for (j = 0; j < 2; j++) 		{ 			for (k = 0; k < 2; k++) 			{ 				printf("%d%d%d\n", i, j, k); 			} 		} 	} }

你就当第一行for是主循环程序

这是一个比较基础的问题，lz可以看看这个——http://see.xidian.edu.cn/cpp/html/45.html ——http://blog.163.com/kam_1993/blog/static/15026799020103322249279/  对于学习，我个人的建议是遇到不会的就仔细想想，想不出来就看书，看不出来就谷歌百度，再不行了来论坛，这样的流程下来，许多问题就被解决了，而且自己也能体会到学习的快乐，何乐而不为呢？ 像这样的问题，前两步就差不多解决了，即使稍有些不清楚，第三步就可以解决了，lz要善于使用网络资源啊

最里面的循环2x2x2=8次，所以输出8行 k循环执行2x2=4次 j循环执行2次 i循环执行一次

结果都打印出来了，还不明白循环过程吗？一层层进入最内层循环，此时i=0,j=0,k=0,k循环完毕后此循环结束，退出到j层循环，j此时自增为1，继续进入k循环，k循环结束，此时j自增为2，j循环也结束，i自增为1....


Question: 数组内存分配

不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。

楼主你是猴子请来的逗兵吗

逗你玩

哇。。。地址相同？不会吧！怎么会有这种情况

楼主是想让他们两个用同一段地址吗

这是两个不同的二维数组，占用两段不同的连续内存空间，如果是全局的，则在初始化数据段，如果是局部的，则在栈里面，不存在有交集的情况。

引用 9 楼 sholber 的回复:dbsrcY[0][15]是内存地址？你们是故意逗我开心的吗？ dbsrcY[0][15]是一个指示对象的左值。 “除非作为sizeof、一元&、++、--、赋值和.的左操作数，左值被转换为它所指示的对象的存储值” 楼主也搞笑，这事不可能。 看到后面修改没？

~~~~上源码

引用 1 楼 user-14 的回复: 只是试一试的回答，不知道对不对。 这个只是声明不是定义，并没有实际分配内存。C语言中指的定义是指实际分配内存。 改为下面的代码试一试，    int dbsrcY[36][36]={0};   int dbsrcU[18][18]={0}; 我看你自己都有点模糊。。这是声明？？？ -------------------------------------------------------------------------------- 糊涂了吧？定义也是声明，反之则不然。

引用 3 楼 zengraoli 的回复:dbsrcY[0][15]本来就是一个内存地址，对他进行&？有什么意思呢？  数组在分配的数据，内存是连续的；  起始地址不同，代表两个数组区域不同，显然不存在“有一段元素内存地址相同”。  dbsrcY[0][15]本来就是一个内存地址，对他进行&？有什么意思呢？这句话修改一下： &dbsrcY[0][15]本来就是一个已经分配的内存地址，分配之后变成了等价于const的地址，无法进行修改了

还有可能就是其他数组越界，栈乱了

下标越界

楼主，本人亲自实验，编译器vs2008,没有相同的地址，在栈上分配的不同的地址，事实胜于一切。

引用 1 楼 user-14 的回复:只是试一试的回答，不知道对不对。 这个只是声明不是定义，并没有实际分配内存。C语言中指的定义是指实际分配内存。 改为下面的代码试一试，    int dbsrcY[36][36]={0};   int dbsrcU[18][18]={0};  我看你自己都有点模糊。。这是声明？？？

显然这是不可能的！ 除非你中间作了操作


Question: 求助！！！！！！！！！！！！啊

CreateFile/ReadFile/WriteFile通常就够了。 但如果你的下位机设备比较特殊，那就还得自己定制驱动程序。

那就按一般的网络程序的写就行了啊，上位机主动连接就socket,connect,send,recv,send,recv...,closesocket,上位机监听由下位机主动连接就socket,bind,listen,accept,recv,send,recv,send...,closesocket，如果过程简单就用命令行，阻塞模式。功能要做多点就做个界面，异步模式。

引用 2 楼 u014034731 的回复:[quote=引用 1 楼 movsd 的回复:] 首先，你得先确定连接方式，比如是串口，USB，还是其它……，然后制定通信协议，最后才是写上位机软件。 TCP  而且下位机的程序是已经完成的  里面有和上位机链接的协议，协议方面只要迎合下就行了吧[/quote] 那就简单了,有协议照协议做就可以了, tcp用soket编程就可以了.两个函数实现交互send,receive

引用 1 楼 movsd 的回复:首先，你得先确定连接方式，比如是串口，USB，还是其它……，然后制定通信协议，最后才是写上位机软件。 TCP  而且下位机的程序是已经完成的  里面有和上位机链接的协议，协议方面只要迎合下就行了吧


Question: 链表求助啊！！根本不会啊！么么哒

卤煮要是男是女。

太长，没兴趣。小官人休要长篇大论，文绉绉地，只管捡紧要的说来。

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

你的帖子发的猛，这让人怎么回帖

要补充子函数...各种卡住。。烦死了。。


Question: 一元二次方程求解 复数的格式输出

其实我根本都没考虑到你说的浮点数问题 我只考虑了整数 主要是想输出正确的格式 至于格式问题照你说的 分别对特殊情形加个判断就搞定了 多谢你详细的回答

有点难度，实数用浮点数表示，有精度问题 0.999999999到底算不算，1。  要想绝对精确表示实数，复数，就不能用浮点数。 用了浮点数，计算结果，可能不是精确的2 + i , 2 - i  而是可能是 2+ 0.999999i,2+1.000000000005i 和 2 - 0.999999i,2 - 1.000000000005i 等等。 这时候，无法表示成  2 + i ，2-i  个人觉多 对于1i 的表示，不要过于吹毛求疵， 非要这样的话，加个判断， 虚部绝对值==1的时候 只输出+/- 和 i ，不输出虚部即可。 大概如下： 1) 虚部实部 同时为零，输出0 2) 虚部为0 ，只输出实部， 3) 实部为零，只输出虚部和i 4) 虚部绝对值为1的时候，只输出+/- 和 i ，不输出虚部即可。 5）其他时候分别输出    A: 实部    B: 虚部的符号（+/-）   C:虚部的绝对值 D:虚数单位( i )


Question: C语言如何与其他语言实现通信？

不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……

可以通过socket网络通信了，协议内容自己定就行了。

动态链接，静态链接，内存映射。 知道的就这几个（从来没做过C语言）

socket通讯最通用哈。

假设A语言的进程间通信方式有A1，A2，A3……，B语言的进程间通信方式有B1，B2，B3…… 如果Am与Bn相同，则A语言和B语言就可以通过Am（即Bn）方式进行通信。

语言只是完成一些逻辑功能 如果你想调用另外一种语言的模块，你需要做一个接口吧， 比如java运行在不同的OS上都要一个JVM


Question: 无法运行一个由VC++6.0生成的.exe文件

如果是缺少dll文件，会有弹框的 引用 6 楼 u013707588 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 用depends.exe查看exe依赖的dll  在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。问题应该是我的系统里却少了好几个API-MS-WIN-CORE-WINRT-L1-1-0.DLL这样的文件，该怎么办呢？[/quote]

有提示吗，比如没有找到什么什么的...

引用 6 楼 u013707588 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 用depends.exe查看exe依赖的dll  在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。问题应该是我的系统里却少了好几个API-MS-WIN-CORE-WINRT-L1-1-0.DLL这样的文件，该怎么办呢？[/quote] 将对应文件拷贝到和exe相同目录下试试看。

引用 2 楼 zhao4zhong1 的回复:用depends.exe查看exe依赖的dll  在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。问题应该是我的系统里却少了好几个API-MS-WIN-CORE-WINRT-L1-1-0.DLL这样的文件，该怎么办呢？

引用 2 楼 zhao4zhong1 的回复:用depends.exe查看exe依赖的dll  在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。用depend查了下有好多DLL文件没找到

可能是你的程序根本没有输出，没有窗口，运行起来在哪一步就退出了。

引用 1 楼 user-3 的回复:有提示吗，比如没有找到什么什么的...没有任何提示，编译链接都没有错误且显示已经生成可执行文件，可是点击运行无任何反应。去文件目录双击此可执行文件也不行


Question: 怎么把数组中的每4个元素放到另一个数组作为该数组的一个元素？

可以用sprintf实现。当然了，你题意表示太不清晰了

你的问题不太清晰，你之前的数组元素是整型的，合并之后的数组也要是整型数组还是字符串类型？看你写的例子貌似应该是整型的。这个代码参考一下： #include <iostream> using namespace std; int main() { 	int size=0; 	int i=0; 	int crt=0; 	int mergeData=0; 	 	cout<<"input the array size:"<<endl; 	do  	{ 		cin>>size; 		if(size%4!=0) 		{ 			cout<<"error ,size must be four times!"<<endl; 		} 	}while(size%4); 	 	int *a=new int[size]; 	int *b=new int[size/4]; 	cout<<"input the array data:"<<endl; 	for(i=0;i<size;i++) 	{ 		cin>>a[i]; 	} 	 	for(i=0;i<size;i++,crt++) 	{ 		mergeData=mergeData*10+a[i]; 		if((crt+1)%4==0) 		{ 			b[i/4]=mergeData; 			mergeData=0; 		} 	} 	 	for(i=0;i<size/4;i++) 	{ 		cout<<b[i]<<endl; 	} 	 	return 0; }  代码没做太细的调试，你参考看看

题目要求不是很清。 你这a如果是 a[8]={3456,7890,1,23455665,3444,4,7889, -1}; 请问你放到b后想怎么放？

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

b数组应该是二维数组，b[][4] = {1234,5678};

引用 楼主 u011779380 的回复:怎么把数组中的每4个元素放到另一个数组作为该数组的一个元素？ 例如  int a[8]={1,2,3,4,5,6,7,8}; b数组就是 b[]={1234,5678}  这样可以实现吗？


Question: 定义一个结构体，来存储N个学生的姓名，学号，性别，四门课的成绩，输出总平均成绩最高的学生的信息，这样写行吗？求指点

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

#include <stdio.h>  #define N 1  struct student {     long stu_number;     char name[15];     char sex;     int score[4];     float average; };  int main(void) {     int i,j;     float  sum=0.0;     float max;     struct student stua[N];      /* 读取每个学生的学号、姓名、性别、以及每个科目的成绩 */     printf("please input the informations of the students:\n");     for(i=0; i<N; i++)     {         /* 这个输入语句有点问题："%s%c"，这样有问题 */         /*scanf("%ld%s%c",&stua[i].stu_number,stua[i].name,&stua[i].sex);*/         scanf("%ld%s %c",&stua[i].stu_number,stua[i].name,&stua[i].sex);         for(j=0; j<4; j++)             scanf("%d",&stua[i].score[j]);     }      /* 计算每个学生的平均分 */     for(i=0; i<N; i++)     {         sum = 0.0f;         for(j=0; j<4; j++)             sum=sum+stua[i].score[j];         stua[i].average=sum/4.0;     }      /* 寻找最高平均分 */     max=stua[0].average;     int index=0;     for(i=0; i<N; i++)         //for(j=0; j<4; j++) // 删除了这一句         if(stua[i].average>max)         {             max=stua[i].average;             index=i;         }     /* 打印获得最高平均分的学生信息 */     printf("%ld %s %c %f",stua[index].stu_number,stua[index].name,stua[index].sex,stua[index].average);      return 0; } 基本没动LZ的代码,加了几对大括号,加了几个空格,以及删除修改个一句.

为什么要N 1，还有为什么删去那一句？


Question: matlab c语言编写s函数输出的指针问题

不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。


Question: 输入结束符为EOF，输入多行，但输出只有一行，求帮助，有代码

谢谢，那就是环境问题了，我是在虚拟机搭建的环境xp+eclipse

win7 + vs2010的测试环境

我的输出是正确的。。

感觉不要这么用，这代码写的好乱，而且也有容易出错的危险。定义一大推我都不知道有啥用的指针。

fgets(buf,len,stdin);


Question: 关于char*和unsigned char*的问题求解

引用 4 楼 ak47_wz 的回复:我感觉，要用就用同一个，不要一下子用这个，一下子用那个。巨烦。不过大神可能是为了另外方面的考虑吧。我这种小虾米，揣测不出啊。 我等小虾米。。只有膜拜和求助

引用 2 楼 wang0635 的回复:compress((Bytef*)buf,....)也可以吧 buf是char*，不强转编译器不愿意 关键是参数是Bytef，为什么要定义char*然后去强转，没明白

引用 1 楼 user-4 的回复:感觉都行吧，不都是表示一个字节吗，有符号、无符号不都由程序员强转决定吗 我也觉得是这样的

感觉都行吧，不都是表示一个字节吗，有符号、无符号不都由程序员强转决定吗


Question: ro data数据区 运行时分配内存吗...

取决于链结脚本的配置以及系统空间的规划。 嵌入式（系统）不同于pc操作系统，通常pc操作系统各种类型的段的空间布局都是固定的，而嵌入式（系统）需要显式的编写链结脚本配置板卡的存储空间：什么样的段放在那块存储空间，段的LMA和VMA是否相同等等。 不管怎样，const全局变量都是要占据空间的，只不过位置可能会产生变化，取决于变量所在段的LMA和VMA是否相同。很常见的一种情况是，系统程序是一个独立的整体，然后由一个名为Loader的程序负责将系统映象加载到目的位置。

一般全局的const或局部静态的const会放在Flash中，不占用RAM，不过有些编译器会使用一些特殊的关键字来指示将常量放入Flash，比如“_flash”。

你说的是片内rom对吧！我的程序是放在这个位置。

看你的ro data是放在什么位置，放在XIP的芯片中定义const可以节省RAM空间

引用 2 楼 aq7811985 的回复:你说的是片内rom对吧！我的程序是放在这个位置。这个可以节省


Question: 求大神指教！

引用 楼主 u014251655 的回复:一,、用exit()语句终止执行程序并报告错误。 二、以函数的返回值区别正确返回或错误返回。 三、设置一个整形变量的函数参数以区别正确返回或某种错误返回。 这三种错误处理方法各自有什么优缺点？ exit()副作用太大了，好的程序应该是尽量让它能够恢复。 函数的返回值是正统做法啦。但是有时候比如你一个函数叫 calculateMoney()，你期望返回的是值而不是错误信息，比如除0错误，这个时候就棘手了。 至于“一个整形变量的函数参数”就是in out的参数，这样是能解决之前的问题。但是函数调用有时候强调“可重入性”，给定一个可变的参数引用给函数，往往会增加函数的耦合性。

才疏学浅，实在不懂有啥优缺点。 return 不会让程序关闭，exit则是关闭程序。这个要看用在不同地方吧？ 当然了，如果在main函数中，我觉得没有区别。

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

_Noreturn void f (void) {}


Question: 写了个练习题，求指点

引用 24 楼 u013061236 的回复:LZ那么写，是定义了两个变量i，并不是重复定义，因为两个i的作用域都只在for循环中，出了for循环，就没有i这一说了 知道了，谢谢指点

引用 13 楼 u012421456 的回复:[quote=引用 12 楼 derekrose 的回复:] [quote=引用 10 楼 u012421456 的回复:] [quote=引用 9 楼 derekrose 的回复:] [quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote] 你的意思是VC6.0报的“重复定义错误”可能是错的？或许吧！VC6.0不是完全按标准来的 不过lz这个应该的确是重复定义吧！第14行已经定义了int型变量 i，而36行又来了一次，这个应该是错误吧[/quote] NO 这样写没问题 XD[/quote]  能解释简单一下吗[/quote]  LZ那么写，是定义了两个变量i，并不是重复定义，因为两个i的作用域都只在for循环中，出了for循环，就没有i这一说了

谢谢，不过要求是统计单词长度和输出它的直方图，

#include "stdio.h" #include "stdlib.h" #include "string.h"  #define BUFF 12 // the max word len  int main(void) { 	int wdlen[BUFF]; // count all of the word len 	int index_row; 	int row_length;  	memset(wdlen, 0, BUFF); 	printf("Get me a string, I will put it out of image:\n"); 	fgets(wdlen, BUFF, stdin); 	row_length = strlen(wdlen);  	// 水平方向的 	printf("水平方向的：\n"); 	for (index_row = 0; index_row < row_length; index_row++) 	{ 		printf("+"); 	} 	printf("\n\n");  	// 垂直方向的 	printf("垂直方向的：\n"); 	for (index_row = 0; index_row < row_length; index_row++) 	{ 		printf("+"); 		printf("\n"); 	} 	printf("\n");  	printf("Thank you!\n"); }

#include "stdio.h" #include "stdlib.h" #include "string.h"  #define BUFF 12 // the max word len #define IN    1  #define OUT   0   int main(void) { 	int ch;          // buff a character 	int wdlen[BUFF]; // count all of the word len 	int wd = 0; 	int status = OUT; // outside  	int index_row; 	int index_col;  	memset(wdlen, 0, BUFF); // 	for (index = 0; index < BUFF; index++) // 		wdlen[i] = 0; // init 	printf("Get me a string, I will put it out of image:\n"); 	while ((ch = getchar()) != EOF) 	{ 		if(ch ==  ' ' || ch ==  '\t' || ch == '\n') 		{ 			if(status == IN) 				++wdlen[wd]; 			status = OUT; 			wd = 0; 		} 		else if (status == IN) 		{ 			++wd; 		} 		else 		{ 			status = IN; 			++wd; 		} 	}  	// 水平方向的 	for (index_row = 0; index_row < BUFF; index_row++) 	{ 		for (index_col = 0; index_col < wdlen[index_row]; index_col++) 		{ 			printf("+"); 		} 		printf("\n"); 	}  	// 垂直方向的 	for (index_row = 0; index_row < BUFF; index_row++) 	{ 		for (index_col = 0; index_col < wdlen[index_row]; index_col++) 		{ 			printf("+"); 			printf("\n"); 		} 	}  	printf("Thank you!\n"); }

引用 21 楼 zengraoli 的回复:[quote=引用 20 楼 derekrose 的回复:] [quote=引用 19 楼 zengraoli 的回复:] [quote=引用 9 楼 derekrose 的回复:] [quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote]  没有bug吧，这明显是重复定义了的。 如果应用说bug，连2010 2012都有问题。。 c++可以这么用，这样for循环内部是一个局部变量。[/quote]  2008 2010都是不支持c99的 2012我试了一下 没报错 不算bug，就是不支持吗标准而已[/quote]  [/quote]  原来2012也不支持c99

引用 20 楼 derekrose 的回复:[quote=引用 19 楼 zengraoli 的回复:] [quote=引用 9 楼 derekrose 的回复:] [quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote]  没有bug吧，这明显是重复定义了的。 如果应用说bug，连2010 2012都有问题。。 c++可以这么用，这样for循环内部是一个局部变量。[/quote]  2008 2010都是不支持c99的 2012我试了一下 没报错 不算bug，就是不支持吗标准而已[/quote]  之前在论坛上讨论过： http://bbs.csdn.net/topics/350127071  是ms的编译器好像都懒得支持c99，一直都是c90然后就c11了。c11也是一部分。。

引用 19 楼 zengraoli 的回复:[quote=引用 9 楼 derekrose 的回复:] [quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote]  没有bug吧，这明显是重复定义了的。 如果应用说bug，连2010 2012都有问题。。 c++可以这么用，这样for循环内部是一个局部变量。[/quote]  2008 2010都是不支持c99的 2012我试了一下 没报错 不算bug，就是不支持吗标准而已

引用 9 楼 derekrose 的回复:[quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote]  没有bug吧，这明显是重复定义了的。 如果应用说bug，连2010 2012都有问题。。 c++可以这么用，这样for循环内部是一个局部变量。

引用 6 楼 u013854998 的回复:谢谢，不过要求是统计单词长度和输出它的直方图，  仔细看：row_length 是不是字符串(即你说的单词)的长度？

引用 16 楼 u013163178 的回复:引用 2 楼 u012421456 的回复:lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉作用范围不一样，只是不规范而已 好吧！谢谢了，又长知识了

引用 14 楼 derekrose 的回复:不是都告诉你了嘛 -std=c99   其实就是标准的支持，vc6.0不支持c99 谢谢了

引用 13 楼 u012421456 的回复:[quote=引用 12 楼 derekrose 的回复:] [quote=引用 10 楼 u012421456 的回复:] [quote=引用 9 楼 derekrose 的回复:] [quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote] 你的意思是VC6.0报的“重复定义错误”可能是错的？或许吧！VC6.0不是完全按标准来的 不过lz这个应该的确是重复定义吧！第14行已经定义了int型变量 i，而36行又来了一次，这个应该是错误吧[/quote] NO 这样写没问题 XD[/quote]  能解释简单一下吗[/quote] 不是都告诉你了嘛 -std=c99   其实就是标准的支持，vc6.0不支持c99

引用 2 楼 u012421456 的回复:lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。

引用 12 楼 derekrose 的回复:[quote=引用 10 楼 u012421456 的回复:] [quote=引用 9 楼 derekrose 的回复:] [quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote] 你的意思是VC6.0报的“重复定义错误”可能是错的？或许吧！VC6.0不是完全按标准来的 不过lz这个应该的确是重复定义吧！第14行已经定义了int型变量 i，而36行又来了一次，这个应该是错误吧[/quote] NO 这样写没问题 XD[/quote]  能解释简单一下吗

引用 10 楼 u012421456 的回复:[quote=引用 9 楼 derekrose 的回复:] [quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote] 你的意思是VC6.0报的“重复定义错误”可能是错的？或许吧！VC6.0不是完全按标准来的 不过lz这个应该的确是重复定义吧！第14行已经定义了int型变量 i，而36行又来了一次，这个应该是错误吧[/quote] NO 这样写没问题 XD

引用 8 楼 chn3698 的回复:[quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 我没用过旧的编译器，但是我比较确定楼主第36行的i是没有重定义的[/quote] 麻烦请解释一下10楼的疑问吧，谢谢

引用 9 楼 derekrose 的回复:[quote=引用 7 楼 u012421456 的回复:] [quote=引用 3 楼 user-6 的回复:] [quote=引用 2 楼 u012421456 的回复:] lz，先不说别的，36行 i 重复定义，需要把这个 i 前面的 int 去掉 请你把vc6给丢了。[/quote]  你的意思是VC6.0太落后了？[/quote]  不是  重复定义这个问题上 vc6.0有bug[/quote] 你的意思是VC6.0报的“重复定义错误”可能是错的？或许吧！VC6.0不是完全按标准来的 不过lz这个应该的确是重复定义吧！第14行已经定义了int型变量 i，而36行又来了一次，这个应该是错误吧


Question: 在文件中直接对比

内存映射用的也是读出来, 修改, 再写入的方式, 只不过是系统来做了这个管理而已

我记得APUE上面有讲到关于这个问题，是关于内存映射的。不过你打算作这种字符串匹配的话，平常的算法肯定都很慢，可以去了解一下KMP算法。

如果修改后内容长度≤修改前内容长度，可以 fopen(...,"rb+"); ... fseek fputc或fwrite fclose

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

都读出来比的想法挺好的，文件大的话用内存映射读比较快。


Question: 递归调用将一个整数逆序

int Reverse(unsigned int num, unsigned int reversenum = 0) {     return (num == 0) ? reversenum : Revert(num / 10, reversenum * 10 + num % 10); }  用尾递归还不损失效率

引用 9 楼 u013707588 的回复:[quote=引用 5 楼 u010749411 的回复:] void Reverse(int num) { 	if( !num )  		return; 	else	 		Reverse(num / 10);  	printf("%d", num % 10); 	 }亲，你的代码不对哦[/quote] 看成正序输出了 void Reverse(int num) { 	if ( num == 0) 		return ; 	else 	{ 		printf("%d",num%10); 		Reverse(num/10); 	} }

引用 5 楼 u010749411 的回复:void Reverse(int num) { 	if( !num )  		return; 	else	 		Reverse(num / 10);  	printf("%d", num % 10); 	 }亲，你的代码不对哦

#include <iostream.h>  void Rev(int num) { 	if(num/10 ==0) 	{ 		cout<<num<<'\n'; 		return; 	} 	cout<<(num%10)<<'\t'; 		Rev(num/10); } void main() { 	int num; 	cout<<"请输入一串数字"; 	cin>>num; 	Rev(num); } 仅供楼楼参考。。

这玩意儿，感觉没啥用啊。 你把递归理解成 “栈” ，就很好理解了。 递归调用，相当于就是用系统栈， 这样逆序输出，不是很简单么。。

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

#include <stdio.h>  int Rev(int x) { 	if (x/10 == 0) return x; 	 	int m = (x % 10); 	int n = x; 	while (n /= 10) m *= 10;  	return m + Rev(x/10); }  void main() { 	int a = 987654321; 	a = Rev(a); 	printf("%d\n", a); }

看错了，每次取一下最后一位就可以了   void Reverse(int num) {   if(!num)      return;        printf("%d", num % 10);    Reverse(num / 10); }

不说废话直接上代码吧  void Reverse(int* num, int start, int end) {    if(start > end)      return;        int temp = num[start];    num[start] = num[end]    num[end] = temp;     Reverse(num, ++ start, -- end); }

逆序输出了不就好了嘛

递归逆序，就是递归调用和操作（输出）的顺序问题。 递归懂了就行。


Question: 缓冲区是不是分为输入和输出两个缓冲区？

缓冲区就是一块你分出的内存，输入还是输出由你决定。


Question: txt输入多个二维数，并搜索相同项（C小白跪求大神解答）

跪求代码~~！！！

最直接的办法就是拿pattern数组在在你随机生成的数组中遍历 遍历的方法比较简单，就是先比较第一行，比如0,0找到了，然后改变列方向上+1判断 以此类推。。。  当然，应该有比较优化的算法来实现吧，我这智商智能用最笨的方法了

麻烦大神详细解答，十分感谢！！！

第一行匹配，其他行比较

可能题目我写的有点不好懂。。。 例如：txt文件中pattern 1是{(00),(11)}；需要找出在随机生成的300x50的二维数组里有多少个跟pattern 1一样的二维数，然后显示坐标。以此类推。。。

表示看不懂题目要求 对自己的智商表示压力很大


Question: 二维数组与二级指针

引用 29 楼 sholber 的回复:[quote=引用 25 楼 u013061236 的回复:] [quote=引用 13 楼 sholber 的回复:] 代码是错的 不可以用二级指针 进行遍历   你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样    你试试这段代码  ---------------------------------------------------------------------- 你就不要添乱了，他的错在于根本不懂指针，本质上不是类型的问题。 char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 你这代码有问题啊，既然是char数组，你往里放整数，很明显不会是你想象的样子，如果都解释成字符，绝对没有问题[/quote]  char属于整数类型。 显然你这最基础的东西都不明白。[/quote]  好吧，当我啥也没说，最起码你放进去3，取出来的不是3，只需要知道这一点就行了

引用 30 楼 songzhichao4444 的回复: char a[3][3] = {1,2,3,4,5,6,7,8,9};     char **p = (char**)a; 	char ***q = (char***)a;     int i,j;   //  puts(""); 	/** 	*两个for循环的结果是一样的。 	*/     for(i=0;i<3;i++)     {         printf("p+i d :%d \n ",(p+i));     }  	for(i=0;i<3;i++)     {         printf("q+i d :%d \n ",(q+i));     } 两个for循环输出的结果是一致的，他们每次都跳过一个指针的长度，windows下为4个字节，linux下为8个字节。 但是为什么，下面的两个输出结果的秩却是不一样的？？？ 	 char *u = （char*）a; for(i=0;i<9;i++)// 1 2 3 4  5 6 7  8 9 {   printf("%c",*(a+i)+'0'); }  for(i=0;i<3;i++)     {         printf("q+i c:%c \n ",*(q+i)+'0');//乱码？？？？？？     } /**/for(i=0;i<3;i++)     {         printf("p+i c:%c \n ",*(p+i)+'0');//1  5  9 每次跳过指针个长度     } 上面的循环前两个可以输出结果，为什么第三个for循环输出乱码？？？我一开始的问题应该可以解释这个问题，但是我第一个问题依然没搞明白。希望大家多给我一些指点。谢谢！ 前面说了那么多，你都还没明白，看来你很难明白了。

int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};     int *b = (int*)a; /* **以上，编译器什么也没做，都是你在做。编译器只知道，b是指向int的指针，其它什么 **也不知道了。以后，任何针对b的操作都只按指针运算的规则进行，而不管它实际上指 **向的地方是一个int[3][3]。 **也就是说，强制类型转换尽管是合法的，但丢失了和数组有关的信息，比 **如数组的大小（维度）之类的。在这种情况下，*b是一个int，而*(b+i)是另外的某个int。*/ int **p = (int**)a; /* **道理同上。p是指向指针的指针。在这种情况下，*p的结果是指向int的指针，*(p+i)是 **另外的某个指向int的指针。printf("%d  ",*(p+i));是将指针的值转换成整数打印出来。 **不过荒谬和搞笑的是，这个值其实是原数组a的内容，而不是真正的指针值。造成这种 **现象的原因，只是程序员自己搞怪，欺骗自己而已。 */

引用 8 楼 songzhichao4444 的回复:sholber 均陵鼠侠貌似没有看明白我的问题，我的重点是 int a[3][3]; int **b = (int**)a; 以及int *b = (int*a);为什么可以将a强制转换成一个二级指针 #include<stdio.h> int main(void) { 	int **p = (int**)a;//二级指针，编译器到底做了什么，想不明白？？？  	for(i=0;i<9;i++)//对这个二级指针可以进行遍历，为什么？？结果：1 2 3 4 5 6 7 8 9 	{ 		printf("%d  ",*(p+i)); 	} } 问题在代码中，谢谢大神的指教。 代码是错的 不可以用二级指针 进行遍历  你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样   你试试这段代码  #include<stdio.h> int main(void) {     char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)     {         printf("%d  ",*(b+i));     }     puts("");     for(i=0;i<9;i++)     {         printf("%d  ",*(p+i));     }     return 0; }

sholber 均陵鼠侠貌似没有看明白我的问题，我的重点是  int a[3][3];  int **b = (int**)a;  以及int *b = (int*a);为什么可以将a强制转换成一个二级指针 ---------------------------------------------------------------------------- 不是朕不明白，汝自糊涂耳。朕已经说得很明白了，C标准规定： 1，除非做为sizeof和一元&运算符的操作数，数组名将被转换为指向其首元素的指针； 2，一个指向对象类型的指针可以转换为指向另一种不同的对象类型的指针，……，转换回来后，结果和原先的指针相等； 3，一个指向任何对象类型的指针可以转换为void指针并转换回来，结果和原始指针相等。 以上三点，请瘘猪自己对照一下。

当然我这种使用方式是极其不合理的并且是错误的。我知道二维数组、数组指针这些基本的东西。但是对8#中提到的问题想不明白。可能自己已经进入了某种思考的死角了吧，现在出不来了。我真新想弄明白8#中我提出问题的原理。

引用 25 楼 u013061236 的回复:[quote=引用 13 楼 sholber 的回复:] 代码是错的 不可以用二级指针 进行遍历   你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样    你试试这段代码  ---------------------------------------------------------------------- 你就不要添乱了，他的错在于根本不懂指针，本质上不是类型的问题。 char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 你这代码有问题啊，既然是char数组，你往里放整数，很明显不会是你想象的样子，如果都解释成字符，绝对没有问题[/quote]  char属于整数类型。 显然你这最基础的东西都不明白。

你能说void ** p存在的意义就是为了要** p吗？

引用 26 楼 user-3 的回复:[quote=引用 23 楼 sholber 的回复:] 你是从哪里看到程序做了 **操作 ++操作 +10操作？有吗？ 臆想是要不得的，只要程序没有语法问题，你就不能说它没有意义。 我没说程序没意义  我说的变量p 没意义  程序没做 ** 操作  但是 做 **操作是 变量p 存在的意义 之一  对于这个变量p 他什么操作都不要 那么我说这个变量 没意义 有何不可? [/quote]  不能这么说啊。 你能说void * p存在的意义就是为了要** p吗？

引用 23 楼 sholber 的回复:你是从哪里看到程序做了 **操作 ++操作 +10操作？有吗？ 臆想是要不得的，只要程序没有语法问题，你就不能说它没有意义。 我没说程序没意义  我说的变量p 没意义  程序没做 ** 操作  但是 做 **操作是 变量p 存在的意义 之一  对于这个变量p 他什么操作都不要 那么我说这个变量 没意义 有何不可?

引用 13 楼 sholber 的回复:代码是错的 不可以用二级指针 进行遍历   你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样    你试试这段代码  ---------------------------------------------------------------------- 你就不要添乱了，他的错在于根本不懂指针，本质上不是类型的问题。 char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 你这代码有问题啊，既然是char数组，你往里放整数，很明显不会是你想象的样子，如果都解释成字符，绝对没有问题

引用 8 楼 songzhichao4444 的回复:sholber 均陵鼠侠貌似没有看明白我的问题，我的重点是 int a[3][3]; int **b = (int**)a; 以及int *b = (int*a);为什么可以将a强制转换成一个二级指针 #include<stdio.h> int main(void) { 	int a[3][3] = {1,2,3,4,5,6,7,8,9}; 	int *b = (int*)a;//一级指针 	int **p = (int**)a;//二级指针，编译器到底做了什么，想不明白？？？ 	int i,j; 	for(i=0;i<9;i++) 	{ 		printf("%d  ",*(b+i)); 	} 	 	for(i=0;i<9;i++)//对这个二级指针可以进行遍历，为什么？？结果：1 2 3 4 5 6 7 8 9 	{ 		printf("%d  ",*(p+i)); 	} 	return 0; } 问题在代码中，谢谢大神的指教。 看这个样子，应该是把二维数组转换为一维数组顺序输出了，二维数组在内存中实际上也是按顺序排列的 只要获得首个元素的地址，知道元素的类型，完全可以自己解析

引用 22 楼 user-3 的回复:[quote=引用 21 楼 sholber 的回复:] 你觉得我下面的代码有问题么？ char a[3] = {1,2,3,};     int ***** p = (int *****)a;     printf("%d\n", *(char *)(char *****)p);当然有  那个问题就是我之前说过的  脱裤子放屁的 问题  p作为一个 int*****的意义 几乎完全不存在  作为一个 int***** 的p 他做 * 操作 **操作 ++操作 +10操作 这些都丢失了不是吗 [/quote]  你是从哪里看到程序做了 **操作 ++操作 +10操作？有吗？ 臆想是要不得的，只要程序没有语法问题，你就不能说它没有意义。

引用 21 楼 sholber 的回复:你觉得我下面的代码有问题么？ char a[3] = {1,2,3,};     int ***** p = (int *****)a;     printf("%d\n", *(char *)(char *****)p);当然有  那个问题就是我之前说过的  脱裤子放屁的 问题  p作为一个 int*****的意义 几乎完全不存在  作为一个 int***** 的p 他做 * 操作 **操作 ++操作 +10操作 这些都丢失了不是吗

引用 20 楼 user-3 的回复:[quote=引用 19 楼 sholber 的回复:] 胡说什么“做类型转换的过程 原来的指针的意义几乎完全丢失”。 这个指针 除了值以为 所有意义都没有意义 所以我说几乎完全丢失  char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 是不是丢失了 你可以这么看  这里的char** p 换成  char**********************************p int****************** * p void******** p int p long p char **(*p)[132];  是不是结果都一样  p 作为一个char **(*)[132] 的意义是不是几乎完全消失  [/quote]  只要是转换成指针，再转换回来，就没有问题，就不会丧失原来的意义。 你觉得我下面的代码有问题么？ char a[3] = {1,2,3,};     int ***** p = (int *****)a;     printf("%d\n", *(char *)(char *****)p);

引用 19 楼 sholber 的回复:胡说什么“做类型转换的过程 原来的指针的意义几乎完全丢失”。 这个指针 除了值以为 所有意义都没有意义 所以我说几乎完全丢失  char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 是不是丢失了 你可以这么看  这里的char** p 换成  char**********************************p int****************** * p void******** p int p long p char **(*p)[132];  是不是结果都一样  p 作为一个char **(*)[132] 的意义是不是几乎完全消失

引用 18 楼 user-3 的回复:[quote=引用 16 楼 sholber 的回复:] 他的代码只有一个小小的问题，不是大问题。一个类型转换就解决了。  糙点的说法是 脱裤子放屁 做类型转换的过程 原来的指针的意义几乎完全丢失 [/quote] 麻烦你有点常识，不要信口开河，胡说什么“做类型转换的过程 原来的指针的意义几乎完全丢失”。C标准说得很清楚：  1，除非做为sizeof和一元&运算符的操作数，数组名将被转换为指向其首元素的指针；  2，一个指向对象类型的指针可以转换为指向另一种不同的对象类型的指针，……，转换回来后，结果和原先的指针相等；  3，一个指向任何对象类型的指针可以转换为void指针并转换回来，结果和原始指针相等。


Question: Linux C编程的返回值含义

这玩意儿，没啥特定标准吧？。APUE，好像是有一个error的头文件，对各种返回值的信息有做一个描述。

复杂函数的话，还是返回错误代码比较好，或者写个GetErr函数返回错误信息 个人习惯问题，返回int的函数，我是用负数代表错误，正数代表正确

百家争鸣，百花齐放。

不是说Linux下返回值是2个吗


Question: 毕业设计

看你出多少￥。

百度一大把。。。大一课程设计。。

让你用C写个界面出来，不要在 dos 窗口来运行

不是有这种毕设，这种现在一般都是用BS模式吧

用java实现感觉好一点

你们毕业设计这么简单

各种语言的书上差不多都有图书管理的例子

用c来做这个 太屈才了

http://wenku.baidu.com/link?url=THxim5z4Kp3mMbcJrlaGg_FEFPtxR2g0jYNc8sDhSV9pvJqCiCHDiejQG6Wrmz0zcZLH4MKv21Bm9vxpD8JU84UOf2mt98d-eHlRDYzX0GG  lz要是感觉这个不好就再搜搜，这个网上不少呢

现在的一把，搜搜


Question: 奇怪的现象

引用 10 楼 zhao4zhong1 的回复:[quote=引用 8 楼 u012564309 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] 关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”  i don know you !  what is the meaning of this? 我想知道为什么 存在空格导致了读取两次的结果的根本  就是 你应该让我看看C编译器中的机制 最好让我看目睹一下数据结构以及中文释义 而不是 waste time time time...[/quote] 先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c [/quote]   冲着这位哥哥的头像  都得给上3分

谢谢哥哥们 在技术上支持  结贴

scanf里的空格，匹配0或多个空格，那到底匹配多少，输入缓存里必须有非空白的字符才能做出判断，不然sacnf就一直阻塞等待...

对库函数不是十分感兴趣，没有什么研究……路过。

空格在scanf那儿也是非输入控制符，关于scanf，lz可以看看这个——http://blog.csdn.net/u012421456/article/details/18501309

引用 10 楼 zhao4zhong1 的回复:[quote=引用 8 楼 u012564309 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] 关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”  i don know you !  what is the meaning of this? 我想知道为什么 存在空格导致了读取两次的结果的根本  就是 你应该让我看看C编译器中的机制 最好让我看目睹一下数据结构以及中文释义 而不是 waste time time time...[/quote] 先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c [/quote]  哥哥 我不喜欢用 visual studio 我一直在用记事本 看你的头像感觉你挺聪明的 能不能交一个朋友 以后有机会一起玩

引用 8 楼 u012564309 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”  i don know you !  what is the meaning of this? 我想知道为什么 存在空格导致了读取两次的结果的根本  就是 你应该让我看看C编译器中的机制 最好让我看目睹一下数据结构以及中文释义 而不是 waste time time time...[/quote] 先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c

引用 6 楼 Ai_YOU127 的回复:[quote=引用 5 楼 u012564309 的回复:] [quote=引用 1 楼 user-9 的回复:] scanf("%d ",&i3);  这里多了一个空格 scanf("%d",&i3); 嗯 谢谢哥哥 但这是为什么呢？[/quote]   scanf  按格式输入！有空格输入等待[/quote] 你是怎么知道的？

引用 7 楼 zhao4zhong1 的回复:关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”  i don know you !  what is the meaning of this? 我想知道为什么 存在空格导致了读取两次的结果的根本  就是 你应该让我看看C编译器中的机制 最好让我看目睹一下数据结构以及中文释义 而不是 waste time time time...

引用 5 楼 u012564309 的回复:[quote=引用 1 楼 user-9 的回复:] scanf("%d ",&i3);  这里多了一个空格 scanf("%d",&i3); 嗯 谢谢哥哥 但这是为什么呢？[/quote]   scanf  按格式输入！有空格输入等待

引用 1 楼 user-9 的回复:scanf("%d ",&i3);  这里多了一个空格 scanf("%d",&i3); 嗯 谢谢哥哥 但这是为什么呢？

眼力哥.............

确实好眼力，真牛

楼上的眼力好好


Question: 求问如何把含有字母和数字的字符串转换成整形？3Q~~

/*  * 最近纠结于一个如何用C语言把含有字母和数字的字符串转换成整形的问题，  * 如规定A=11，B=12，...F=16，,则字符串（ED D8 9F 39）可显示为151414891639，  * 以此类推，有没有通用的方法或者程序呀？求大神们指点！感激不尽！   */  #include <stdio.h>   typedef void (*mf_t)(char, int*, int*);  __int64 str_to_int(const char *s, mf_t mf) { 	__int64 n = 0; 	const char *p = s;  	while (*p) 	{ 		int v, q; 		mf(*p++, &v, &q); 		//printf("v=%d, q=%d, ", v, q); 		n = n * q + v; 		//printf("n = %I64d\n", n); 	} 	return n; }   void map(char c, int *v, int *q) { 	/* 在此表中建立字符和数值以及权值间的映射关系 */ 	static const int m[][3] = { 		{ '3',  3, 10  },  		{ '8',  8, 10  },  		{ '9',  9, 10  }, 		{ 'D', 14, 100 }, 		{ 'E', 15, 100 },  		{ 'F', 16, 100 },  	}; 	int i;  	*v = *q = -1; 	for (i = 0; i < sizeof(m)/sizeof(m[0]); i++) 	{ 		if (m[i][0] == c) 		{ 			*v = m[i][1]; *q = m[i][2]; 			break; 		} 	} }   int main(void) { 	const char *s = "EDD89F39";  	printf("%I64d\n", str_to_int(s, map));  	getchar(); 	return 0; }  参考一下，更大的数字得借助大数（库）操作了。

#include<stdio.h> void main() { char str[100];    int i,j;   gets(str); for(i=0;i<100;i++) {if(i%5==0) printf("\n");   printf("%d",str[i]); } } 直接就转换为assⅡ码输出，不过你也可以自己定义，

atoi,可以转换例如"123456789"这样的内容是数字的字符串


Question: 一道acm题目

另外，二叉树，去重再好不过了。 《C 程序设计语言》有个二叉树的设计 里面的节点，绝对不会出现重复数据的。

考虑到插了很多2，最多几千个字符串，去重而已。 每次读到 2，就开始去重了，所以没有多少重复的 如果不想复制数据  建个行指针，或者行索引表，这样去重的复制任务减轻一半。 也可用链表处理，这样每次去重的复制开销  = 1

下个靠谱的avl代码。

上面那个无视了吧，应该是不行。 还是老老实实建一个左儿子，右兄弟的二叉树吧。 之后搜索来的靠谱点

8个字符==sizeof(long long) 就是10000个long long去重

用tried树吧。 这么来，准备8个含有a-z数组的代表单词各个位置上的字母。和8个长为26的标识布尔数组。 每进来一个单词，对进来一个单词，把记录和前面单词是否重复的全程变量设成false。 对单词各个位置字母扫描，如果重复了把标识数组改一下，什么都不用作。没重复则 把记录单词数目的变量加1。  思路不算很难，就是挺麻烦的，有兴趣的话写一下试试吧。

引用 4 楼 xurui20100834 的回复:不能用stl的话 树形结构也行大哥，你这不等于白说吗？

引用 1 楼 user-4 的回复:才10000行。拿个set记都能过。怎么写代码啊

才10000行。拿个set记都能过。


Question: 我用的dev-c提示没有sleep函数，所以在网上找了个，但是太高端我不知道怎么用，请问大虾们怎么样。。。

#define WIN32   #ifdef WIN32   如果定义了 WIN32 就。。。 。。。 #else   没有的话就。。。 。。。。 #endif  为什么我#define WIN32 会有那样的提示 而不定义就没有问题呢

#include <stdio.h> #include <stdlib.h> #include <string.h>   //#define WIN32   我这里还有个一问题如果加了这句我定义为WIN 才会进入 #ifdef WIN32 #include <windows.h> void sleep_ms(int ms) {      printf("你进入的是win");     Sleep(ms);// Sleep以毫秒为单位 } 但是我定义了后DEV-C++会出现 sleep.c [Warning] "WIN32" redefined  <built-in> [Warning] this is the location of the previous definition  的提示     void sleep_ms(int ms); int main( void ) {  sleep_ms(5000);  printf("LOOK");   system("pause");    return 0;      }    #ifdef WIN32 #include <windows.h> void sleep_ms(int ms) {      printf("你进入的是win");     Sleep(ms);// Sleep以毫秒为单位 } #else #include <unistd.h> void sleep_ms(int ms) {      printf("你进入的是linux");     usleep(ms*1000);//usleep单位是微秒us*1000毫秒  } #endif

引用 1 楼 zhao4zhong1 的回复:#ifdef WIN32 #include <windows.h> void sleep_ms(int ms) {     Sleep(ms); } #else #include <unistd.h> void sleep_ms(int ms) {     usleep(ms*1000); } #endif   谢谢赵老师


Question: 文件的打开和写入的问题

引用 3 楼 u013869048 的回复:[quote=引用 2 楼 Automation_dmu 的回复:]  fpFood=fopen("Recipes.txt","rw");//这里搞不懂需要用什么方式打开？ "w+b" 不可以哦，运行到printf("测试1");//测试是否运行到这 程序就结束了[/quote]             p = (Food *)malloc(sizeof(Food));                 printf("请输入菜的名字(输入N代表结束输入):\n");                 scanf("%s",p->name);你忘了给name分配内存了

引用 2 楼 Automation_dmu 的回复: fpFood=fopen("Recipes.txt","rw");//这里搞不懂需要用什么方式打开？ "w+b" 不可以哦，运行到printf("测试1");//测试是否运行到这 程序就结束了

"r+"  Opens for both reading and writing. (The file must exist.)  "w+"  Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.  "a+"  Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn’t exist.  When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file. The file pointer can be repositioned using fseek or rewind, but is always moved back to the end of the file before any write operation is carried out. Thus, existing data cannot be overwritten.  The "a" mode does not remove the EOF marker before appending to the file. After appending has occurred, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file. The "a+" mode does remove the EOF marker before appending to the file. After appending, the MS-DOS TYPE command shows all data in the file. The "a+" mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.  When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for “update”). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, fseek, or rewind operation. The current position can be specified for the fsetpos or fseek operation, if desired.


Question: 谁有VS2010的MSDN  别藏了

微软官方网站上有在线联机的 VS2010 MSDN！可以联机看！