Question: 用calloc函数分配的内存空间,怎样用二维数组的方式访问?

引用int (*p)[20];  刚刚试了一下,赵4老师的这一句原来只占一个指针的空间,我以为像定义一个整数数组一样占20个元素的空间. 很好的代码啊,谢谢

[quote 你应该看赵4老师那个，那个才像是高手写的代码。  评价下：你这样做和数组定义int a[m][n];差不多，没能体现malloc()和calloc()动态分配内存的优势，因为中间数组容量不能变，而我一开始形式，就自由的多，更节省内存，缺点是在堆内存中，效率应该低点。[/quote]  谢谢,因为我本来只想定义一个指针p,当需要二维数组存放数据时就用calloc动态分配,不用的时候就free,这样保证程序运行时尽量少占用内存.赵4老师的方式很严谨简洁,不过因为我之前没说明只用一个指针p,而我实际程序中的m和n值都很大,所以int (*p)[20]这个方法在我程序中可能也需要一直占用很多内存  另外也谢谢赵4老师,这代码简洁漂亮,学习一下有不少收获.  结帖比较早,没想到后面又有回复,谢谢各位

带斜杠那一行应该去掉。 去掉*(p + i) = (int*)calloc(n, sizeof(int));    //////

你这样想，很有创意。 我认为你是这样想的：先连续分配m*n个连续空间，然后在内存中进行修改，这样确实保证了一维。但正确代码应该如下：  #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j,k; 	int *base = (int*)calloc(m*n, sizeof(int)); 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int));    //////	 		*(p + i)=&base[i*n]; 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	printf("\n"); 	int *p1 = &p[0][0]; 	for (i = 0,k=0; i < m*n; i++){ 		printf("%d ",*(p1+i)); 		k++; 		if (k >= n){ 			printf("\n"); 			k=0; 		} 	} 	free(p); 	getchar(); 	return 0; }   你应该看赵4老师那个，那个才像是高手写的代码。  评价下：你这样做和数组定义int a[m][n];差不多，没能体现malloc()和calloc()动态分配内存的优势，因为中间数组容量不能变，而我一开始形式，就自由的多，更节省内存，缺点是在堆内存中，效率应该低点。

#include <stdio.h> #include <stdlib.h> #include <malloc.h> int main() {     int m=10,n=20,y,x;     int (*p)[20];     p=(int (*)[20])calloc(m*n, sizeof(int));     if (!p) return 0;     for (y=0;y<m;y++) {         for (x=0;x<n;x++) {             p[y][x]=y*n+x;         }     }     for (y=0;y<m;y++) {         for (x=0;x<n;x++) {             printf("%4d",p[y][x]);         }         printf("\n");     }     free(p);     return 0; } //   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19 //  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39 //  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59 //  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79 //  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 // 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 // 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 // 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 // 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 // 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 //

我不知道，具体应涉及：malloc(),free(),calloc()等函数在内存上的管理，应该是堆区。 还没学底层的，不过我用函数调试了一下，不是连续分配的，而是隔了16个数，而且后面有些不同。有待继续思考学习，抱歉  另：刚才的代码有缺陷，分配内存后未能释放，改正。  #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j,k; 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int)); 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	printf("\n"); 	int *p1 = &p[0][0]; 	for (i = 0,k=0; i < m*n+16*m; i++){ 		printf("%d ",*(p1+i)); 		k++; 		if (k >= n){ 			printf("\n"); 			k=0; 		} 	} 	for (i = 0; i < m; i++) 		free(*(p + i)); 	free(p); 	getchar(); 	return 0; }   应学的更深，更全面，还是不够。

引用 3 楼 liukeyong2110 的回复:这是很合理的想法，但你既然使用了**p，就应该为*p分配空间，即是设计旅馆，先分配楼，1-6楼，然后再为楼分配房间101-110，你只分配了房间，怎么分布呢？当然在具体存储时还是一维的，但你要用数组访问它，就需要这样： 参考代码： #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j; 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int)); 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	getchar(); 	return 0; }     谢谢指点,我明白了,因为我不知道多次调用calloc分配到的空间是否像正常定义二维数组那样连续,但是看了你的说明,我把你的代码有两行稍改一下,不知这样是否可行,请指教 int **p = (int**)calloc(m*n, sizeof(int*));	////  *(p + i) = (int*)(p+n);	//////   #include <stdio.h> #include <stdlib.h>  int main() {     int m=10,n=20;     int i,j;     int **p = (int**)calloc(m*n, sizeof(int*));	////     for (i = 0; i < m; i++) 	{         *(p + i) = (int*)(p+n);	//////     }     for (i = 0; i < m; i++){         for (j = 0; j < n; j++){             p[i][j]=m*i+j;             printf("%d ", p[i][j]);         }         printf("\n");     }     getchar();     return 0; }

引用 3 楼 liukeyong2110 的回复:这是很合理的想法，但你既然使用了**p，就应该为*p分配空间，即是设计旅馆，先分配楼，1-6楼，然后再为楼分配房间101-110，你只分配了房间，怎么分布呢？当然在具体存储时还是一维的，但你要用数组访问它，就需要这样： 参考代码： #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j; 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int)); 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	getchar(); 	return 0; }   谢谢,请问这样多次调用calloc分配到的空间是连续的吗

我实际程序中用到的二维数组比较大,用二维的方式是因为比较像表格的行列,这样写主要是考虑到代码的易读性,写的时候逻辑比较清晰,不易出错,另外正在学C,所以也想知道有没有什么简单的方法做到这一点

int m=10,n=20,i; int** p; p=(int**)calloc(m, sizeof(int*)); for(i=0;i<m;++i)     p[i]=(int*)calloc(n,sizeof(int));或者int m=10,n=20; int *p=(int*)calloc(m*n,sizeof(int)); // 调用:p[i*n+j];0<=i<m,0<=j<n

C语言中的二维数组的本质是一维数组，都是按线性存放的，何苦要用p[i][j]的方式访问


Question: 小白求助，关于DES密码~~~

仅供参考：#pragma comment(lib, "crypt32.lib") #pragma comment(lib, "advapi32.lib") #define _WIN32_WINNT 0x0400 #include <stdio.h> #include <windows.h> #include <wincrypt.h> #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 destination 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

http://blog.csdn.net/zidane_2014/article/details/37988657 我以前写的一个版本。 你可以对照一下。

代码略乱。 个人认为似乎是循环出了问题，只进行了一轮子密钥生成，或只进行了一轮加密。。。


Question: 大家都是怎么设计网络通信的？是层层传递，结果再反向传回？还是走到哪里，想发就发出去？

socket

引用 1 楼 hnwyllmm 的回复:现在有很多已经设计好的应用层协议，基于TCP的DCC协议，短连接的HTTP协议，都可以参考 楼主说的层层传递是什么意思？ 一般都是接收数据--> 解码--> 业务逻辑 --> 编码--> 返回结果  是的，进口和出口在一处


Question: 数据结构 数制转换问题

引用 14 楼 u010703975 的回复:[quote=引用 13 楼 zhangxiangDavaid 的回复:] 10进制转8进制：  #include<stdio.h> #include<stdlib.h> typedef struct Node { 	int Data; 	struct Node *Next; } LinkStack; LinkStack *CreateStack() { 	LinkStack *S; 	S = (LinkStack *)malloc(sizeof(LinkStack)); 	S->Next = NULL; 	return S; } int isEmpty(LinkStack *S) { 	return (S->Next == NULL);  //若为空 返回1 } LinkStack *Push(LinkStack *S, int item) { 	LinkStack *TempCell; 	TempCell = (LinkStack *)malloc(sizeof(LinkStack)); 	TempCell->Data = item; 	TempCell->Next = S->Next; 	S->Next = TempCell; 	//free(TempCell);    //这句话error } int Pop(LinkStack *S) { 	LinkStack *FirstCell; 	int TopElem; 	if (isEmpty(S)) { 		printf("堆栈空\n"); 		return 0; 	} 	else { 		FirstCell = S->Next; 		S->Next = FirstCell->Next; 		TopElem = FirstCell->Data; 		free(FirstCell); 		return TopElem; 	} } void conversion() { 	LinkStack *s; 	int n; 	int item; 	s = CreateStack(); 	scanf("%d", &n); 	while (n) { 		Push(s, n % 8); 		n = n / 8; 	} 	while (!isEmpty(s)) { 		int item; 		item = Pop(s); 		printf("%d", item); 	} } int main(){ 	conversion(); 	return 0; }  为啥第一个free就错了 第二个free就可以呢[/quote] 在push的时候，会创建一个新的节点，添加到栈顶后，当然不可以释放掉。否则白搭。 在pop的时候，一旦获取了它的data域后，理应释放掉，否则，内存泄露。

引用 2 楼 u010703975 的回复:[quote=引用 1 楼 brookmill 的回复:] // 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了[/quote] 我试了几个数，结果好像没错。你的数据？

引用 1 楼 brookmill 的回复:// 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了

// 把这一行删掉   free(TempCell);

早上起来看 发现我删错了 我一开始把FirstCell删了 手残了

引用 15 楼 u010703975 的回复:那为啥在Push函数里free掉临时的空间会报错 而在Pop函数里free掉临时的空间就可以了呢。 改怎么理解呢 因为Push之后还会继续用TempCell的内存，而Pop之后就不再使用FirstCell的内存了。  简单的说，这样的代码都是很可疑的： x = y; free(y); 而这种可能就是正确的 a = y->a; b = y->b; free(y);

引用 10 楼 u010703975 的回复:现在都删掉了 运行正常 那么现在又多了个问题 临时stack空间在最后不是要free掉吗 malloc得到的内存最后需要free，这是毫无疑问的，但是应该是用完之后才释放，而且free之后就不应该再用了。 现在的问题是，从楼主描述的现象来看，free的早了，free之后又使用了。等到conversion这个函数结束之前把所有的都free掉应该就没问题了。 free(TempCell)是明显的错误，但是free(FirstCell)应该是正确的，因为从代码来看这个free之后就没再用FirstCell的内容，而且我用gcc和vs2013运行也没出错。 很好奇楼主用的什么编译器

引用 7 楼 brookmill 的回复:[quote=引用 4 楼 u010703975 的回复:] [quote=引用 3 楼 brookmill 的回复:] [quote=引用 2 楼 u010703975 的回复:] [quote=引用 1 楼 brookmill 的回复:] // 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了[/quote] 我试了几个数，结果好像没错。你的数据？[/quote]  1348 -572662307 而且输出之后 弹出程序有错误  [/quote] -572662307 = 0xDDDDDDDD 我查了一下，据说有些运行环境会把free之后的堆内存用0xdd填充。 你确定把那个free(TempCell)删掉了？ 还可以试试把另一个free(FirstCell)也删掉，看看运行的结果有没有变化。 [/quote]  现在都删掉了 运行正常 那么现在又多了个问题 临时stack空间在最后不是要free掉吗

引用 8 楼 user-3 的回复:lz是不是搞错了free的用法？ 恩恩是的 发现对free的用法有错误

引用 11 楼 brookmill 的回复:[quote=引用 10 楼 u010703975 的回复:] 现在都删掉了 运行正常 那么现在又多了个问题 临时stack空间在最后不是要free掉吗 malloc得到的内存最后需要free，这是毫无疑问的，但是应该是用完之后才释放，而且free之后就不应该再用了。 现在的问题是，从楼主描述的现象来看，free的早了，free之后又使用了。等到conversion这个函数结束之前把所有的都free掉应该就没问题了。 free(TempCell)是明显的错误，但是free(FirstCell)应该是正确的，因为从代码来看这个free之后就没再用FirstCell的内容，而且我用gcc和vs2013运行也没出错。 很好奇楼主用的什么编译器[/quote]  那为啥在Push函数里free掉临时的空间会报错 而在Pop函数里free掉临时的空间就可以了呢。 改怎么理解呢

引用 13 楼 zhangxiangDavaid 的回复:10进制转8进制：  #include<stdio.h> #include<stdlib.h> typedef struct Node { 	int Data; 	struct Node *Next; } LinkStack; LinkStack *CreateStack() { 	LinkStack *S; 	S = (LinkStack *)malloc(sizeof(LinkStack)); 	S->Next = NULL; 	return S; } int isEmpty(LinkStack *S) { 	return (S->Next == NULL);  //若为空 返回1 } LinkStack *Push(LinkStack *S, int item) { 	LinkStack *TempCell; 	TempCell = (LinkStack *)malloc(sizeof(LinkStack)); 	TempCell->Data = item; 	TempCell->Next = S->Next; 	S->Next = TempCell; 	//free(TempCell);    //这句话error } int Pop(LinkStack *S) { 	LinkStack *FirstCell; 	int TopElem; 	if (isEmpty(S)) { 		printf("堆栈空\n"); 		return 0; 	} 	else { 		FirstCell = S->Next; 		S->Next = FirstCell->Next; 		TopElem = FirstCell->Data; 		free(FirstCell); 		return TopElem; 	} } void conversion() { 	LinkStack *s; 	int n; 	int item; 	s = CreateStack(); 	scanf("%d", &n); 	while (n) { 		Push(s, n % 8); 		n = n / 8; 	} 	while (!isEmpty(s)) { 		int item; 		item = Pop(s); 		printf("%d", item); 	} } int main(){ 	conversion(); 	return 0; }  为啥第一个free就错了 第二个free就可以呢

lz是不是搞错了free的用法？

引用 4 楼 u010703975 的回复:[quote=引用 3 楼 brookmill 的回复:] [quote=引用 2 楼 u010703975 的回复:] [quote=引用 1 楼 brookmill 的回复:] // 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了[/quote] 我试了几个数，结果好像没错。你的数据？[/quote]  1348 -572662307 而且输出之后 弹出程序有错误  [/quote] -572662307 = 0xDDDDDDDD 我查了一下，据说有些运行环境会把free之后的堆内存用0xdd填充。 你确定把那个free(TempCell)删掉了？ 还可以试试把另一个free(FirstCell)也删掉，看看运行的结果有没有变化。

我用gcc和vs2013都试了，运行都没出错。而且我也看不出来代码里有什么大问题了。  几个建议： 1. conversion函数返回之前应该free(s); 2. Push这个函数声明了有返回值但是实际上没有，声明成void即可。 3. 每次调用malloc的时候都要判断一下返回值是否NULL 4. 函数参数里如果有指针，首先应该判断它是否NULL  这些都只是属于良好的编程习惯，在你这个小程序里面应该都不会造成什么问题的。

我运行结果没错： $ ./a.exe 1348 2504 可能是有些内存越界之类的问题，我再看看

引用 3 楼 brookmill 的回复:[quote=引用 2 楼 u010703975 的回复:] [quote=引用 1 楼 brookmill 的回复:] // 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了[/quote] 我试了几个数，结果好像没错。你的数据？[/quote]  1348 -572662307 而且输出之后 弹出程序有错误


Question: 控制台输出的内容输入到记事本中

文件重定向  int main() { 	printf("Hello World"); 	return 0; }  一般情况下，这段代码会打印到控制台上：Hello World 当你在命令行下输入：test.exe > 1.txt       //程序名称可能不一样，你应该懂得相应修改  这个没有任何难度，动下小手，你一定会的

我是初学者，能否给我一些代码实例呢

1. 文件重定向 如有程序：test.exe 在命令行下：test.exe > 1.txt 程序test.exe的输出内容就会到1.txt，并且1.txt不用提前创建  2. 直接使用文件操作

谢谢各位大神！

话说用itoa把数字转换成字符串再fputs真的不累？直接用fprintf就行了，格式用%X，表示输出大写16进制数字

习惯用fprintf输出到文件

你可以学习学习 fputs,fprintf 这类f开头的函数。当然也可以使用输出重定向，就是上面zhangxiangDavaid说的那样。打开控制台，cd 到程序所在目录。然后 test.exe > 1.txt  就可以允许程序test.exe 并将结构输出到文件1.txt 里面了

#include<stdio.h> #include<ctype.h> #include<string.h> #pragma warning(disable:4996) int main() { 	char str[100] = { 0 }; 	int i = 0xA23456; 	itoa(i, str, 16);	 	printf("输入要创建文件的名字："); 	char s[100]; 	char s1[100] = ".txt"; 	scanf("%s", &s); 	strcat(s, s1); 	FILE *fp = fopen(s, "w"); 	fputs(str, fp); 	fclose(fp); 	system("pause"); 	return 0; } 上面的代码执行之后，在记事本中显示的字母为什么是小写的啊？


Question: 请问为什么这个数组定义编译不过了

引用 8 楼 jiht594 的回复: 	int b = 2; 	int *a = NULL; 	if (b > 0) 		a = new int[5]{ 1,2,3,4,5 }; 	else 		a = new int[5]{ 1,2,3,4,5 };  	//do something 	if (a) 	{ 		delete[] a; 	}  这是个好方法！

引用 12 楼 hanyue03 的回复:局部作用域问题和作用域无关  这里 定义数组 和 使用数组 都是在同一块作用域

局部作用域问题

int a【】是局部变量作用与实在在if（）else{}之间。到了for循环就无法调用了

#include <stdio.h> int main(void) {         int i;         int b = 2;         int a[][5] ={ {2,3,4,5,6}, {1,2,3,4,5} };         for(i=0;i<sizeof(*a)/sizeof(**a);i++)                 printf("%d ",a[b>0][i]);         putchar('\n'); }

“变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。

应楼主邀请，我来说几句哈。 首先，if语句有它自己的语法。在if (/* …… */)的后面必须是语句，而不能是声明。楼主放的是声明，这不对哩； 其次，即便这是允许的，那也不行。标准说得明白，选择语句和循环语句本身就是一个块。在块内声明的数组自然具有块作用域，这是不行滴。

引用 3 楼 lin5161678 的回复:if() 后面只能写语句 不能写声明 else 后面只能写语句 不能写声明 那假如我想根据条件的不同定义两个数组，并在后面的程序中使用，要怎么办了？

引用 1 楼 jiht594 的回复:      if (b > 0)                 int a[] = { 1,2,3,4,5 };      else                 int a[] = { 2,3,4,5,6 };   if(){   }和else{   }之外是不能使用a的, 超出作用域 那假如我想根据条件的不同定义两个数组，并在后面的程序中使用，要怎么办了？

引用 1 楼 jiht594 的回复:      if (b > 0)                 int a[] = { 1,2,3,4,5 };      else                 int a[] = { 2,3,4,5,6 };   if(){   }和else{   }之外是不能使用a的, 超出作用域没有复合语句什么事

修改如下：  #include <stdio.h> int main(void) { 	int i;     int b = 2; 	if (b > 0) 	{ 		int a[] = { 1,2,3,4,5 }; 	} 	else 	{ 		int a[] = { 2,3,4,5,6 }; 	} 	//a的作用域被限定在{}内部，在其他地方无法使用，故以下语句有问题     for (i = 0; i<sizeof(a) / sizeof(a[0]); i++) printf("%d ", a[i]);        putchar('\n'); }

if() 后面只能写语句 不能写声明 else 后面只能写语句 不能写声明

注意你的数组的作用域啊。它的作用域在if语句里面 在for语句里面肯定报无定义的错误了。  至于前面的两个错误，我不知道为什么。


Question: 用c语言写一个通讯录，开贴可能会出现好些问题来求教

引用 楼主 lax_Z 的回复:废话不多说，先放出第一个问题 代码： #include "stdio.h" #include "conio.h" #include "stdlib.h"  int add_people(); /*void check_people(); void revise_people(); void delete_people();*/ void save_exit();    main() { 	int com;                  /* 定义com变量用作读取操作符*/     printf("======================Welcome to Message manage system=========================\n");     printf("\n");     printf("===============1.Add contact people     2.Check contact people=================\n");     printf("\n");     printf("===============3.Revise contact people  4.Delete contact people================\n");     printf("\n");     printf("============================  5.Save&Exit======================================\n"); 	scanf("%d",&com);     while(1)     {         switch(com)         {             case 1:add_people();break;             /*case 2:check_people();break;             case 3:revise_people();break;             case 4:delete_people();break;*/             case 5:save_exit();break;         }     }       }  int add_people() { 	FILE *fp; 	char people,phone,filename[10],temp; 	temp=78; 	while(1) 	{ 		printf("输入要存储到的文件名\n"); 		scanf("%s",filename); 		if((fp=fopen(filename,"w"))==NULL) 		{ 			printf("无法打开\n"); 			exit(0); 		} 	loop:	printf("请输入你要保存的联系人（以#结束）\n"); 		people=getchar(); 		while(people!='#') 		{ 			fputc(people,fp); 			putchar(people); 			people=getchar(); 		} 		printf("请输入要保存的联系人号码（以#结束）\n"); 		phone=getchar(); 		while(phone!='#') 		{ 			fputc(phone,fp); 			putchar(phone); 			phone=getchar(); 		} 		putchar(10);	 		printf("是否继续添加联系人Y/N\n"); 		scanf("%s",&temp); 		if(temp=='n'||temp=='N') 		{ 			printf("按下任意键返回主菜单\n"); 			getchar(); 			return 0; 		}else 			goto loop; 	} 	fclose(fp); 	return 0; }  void save_exit() { 	printf("按下任意键退出\n"); 	getchar(); 	exit(0); } 问题是新建联系人后按n键我要返回到主函数进行继续选择，该怎么做？  数据结构的链表操作就可以了

引用 1 楼 zhangxiangDavaid 的回复:两种方法 1.使用while，整个main函数就是一个大while 2.使用goto语句能在我的代码上加入第一种方法来实现吗？就修改我的代码然后发出来嘛

if(strcmp(per[i].people,s)!=0) i++;	 //当要查找的联系人和文件中的联系人一样时且n值（每添加一个联系人i值增1）小于i值时执行后面的语句 你只查找i=0的情况？

引用 3 楼 zhangxiangDavaid 的回复:把scanf放到while中即可，如下：  	while (1) 	{ 		scanf("%d", &com); 		switch (com) 		{ 		case 1:add_people(); break; 			/*case 2:check_people();break; 			case 3:revise_people();break; 			case 4:delete_people();break;*/ 		case 5:save_exit(); break; 		} 	} 你回答的和我问的不是一个额....不过之前的那个问题倒是解决了，下面又有问题了

问题又来了，之前的自己已解决 #include "stdio.h" #include "conio.h" #include "stdlib.h" #include "string.h"  typedef struct 	{	 		char people[20]; 		char phone[11]; 	}person;				//用typedef声明一个新类型名Person  person pe[50];				//用新类型名person定义pe  int add_people(person per[],int n); int menu(); int check_people(person per[],int n); /*void revise_people(); void delete_people();*/ void save_exit();  void main() { 	                	int n=0;								//     while(1)     {         switch(menu())         {             case 1:printf("新建联系人到通讯录\n");n=add_people(pe,n);break;             case 2:printf("在通讯录中查找联系人\n");check_people(pe,n);system("pause");break;		//调用的暂停函数，等待用户输入任意值后执行             /*case 3:revise_people();break;             case 4:delete_people();break;*/             case 5:save_exit();break;         }     }    }   int menu()						        //菜单函数编写 { 	char com;                          //定义com变量用作读取操作符 	do 	{ 		system("cls"); 		printf("======================欢迎进入lax通讯录管理系统==============================\n"); 		printf("\n"); 		printf("===============1.添加联系人		2.查找联系人=========================\n"); 		printf("\n"); 		printf("===============3.修改联系人		4.删除联系人=========================\n"); 		printf("\n"); 		printf("============================  5.退出软件=====================================\n"); 		printf("\n"); 		printf("============================ 请选择要执行操作前的序号========================\n"); 		scanf("%s",&com); 	}while(com<'1'||com>'5'); 		return(com-'0'); }   int add_people(person per[],int n) { 	int i=0; 	FILE *fp; 	char filename[10],temp; 	printf("输入要存储到的文件名\n"); 	scanf("%s",filename); 	if((fp=fopen(filename,"a"))==NULL) 	{ 		printf("无法打开\n"); 		exit(0); 	} 	while(temp!='N'&&temp!='n') 	{ 		 		printf("请输入你要保存的联系人\n"); 		scanf("%s",per[n+1].people); 	 		fprintf(fp,"%s  ",per[n+1].people);	//向文件中保存联系人姓名 		printf("请输入要保存的联系人号码\n"); 		scanf("%s",per[n+1].phone); 		 		fprintf(fp,"%s\n",per[n+1].phone);	//向文件中保存联系人电话 		printf("是否继续添加联系人Y/N\n"); 		scanf("%s",&temp); 		i++; 	} 	    printf("按下任意键返回主菜单\n"); 		fclose(fp); 		getchar(); 		return (n+i);  }  int check_people(person per[],int n) { 	int t; 	printf("请选择按姓名还是按电话查找\n"); 	printf("=========1.姓名========== \n"); 	printf("\n"); 	printf("=========2.电话========== \n"); 	scanf("%d",&t); 	while(t!=1&&t!=2)     {  		printf("输入错误，请重新选择:"); 		scanf("%d",&t); 	} 	if(t==1) 	{ 		char s[10];				//定义要比较的联系人数组 		int i=0;					 		printf("请输入要查询的联系人姓名\n"); 		scanf("%s",s);	 		if(strcmp(per[i].people,s)!=0) 			i++;				//当要查找的联系人和文件中的联系人一样时且n值（每添加一个联系人i值增1）小于i值时执行后面的语句 		if(i==n) 		{ 			printf("你查找的联系人不在该通讯录，请检查你的输入是否有误\n"); 			return;			//返回到主函数，然后执行system（pause）函数 		}			 			printf("姓名：%s",per[i].people); 			printf("电话：%s",per[i].phone); 	} 	if(t==2) 	{ 		char p[15]; 		int i=0; 		printf("请输入要查询的联系人电话\n"); 		scanf("%s",p); 		while(strcmp(p,per[i].phone)!=0&&i<n) 			i++; 		if(i==n) 		{ 			printf("你查找的联系人不在该通讯录，请检查你的输入是否有误\n"); 			return; 			 		}			 		printf("姓名：%s",per[i].people); 		printf("电话：%s",per[i].phone);		 	}  }  void save_exit() { 	printf("按下任意键退出\n"); 	getchar(); 	exit(0); } 查找联系人时当输入正确的关键词不能正确输出该联系人


Question: 在C 中  输入包含标点的密文可最后得出的明文没有空格和标点，跪求完善，很急！！！

稍作修改，问题原因在注释中  #include<stdio.h> char shift(char letter);                                  //字母大小写转变 void main() { 	char ciphertext[200], alphabet[26], password_list[26];  //密文，字母表，密码表 	int statistics[26] = { 0 };                               //字母数量统计 	char x; 	int d, j, q, k, l = 0; 	printf("Please enter the password list:\n"); 	//scanf("%s", &password_list); 	scanf("%s", password_list); 	printf("Please enter the ciphertext:\n"); 	//scanf("%s", &ciphertext);  //输入密文 	scanf("%s", ciphertext); 	for (j = 0; j<200; j++)                                    //将大写字母转换成小写字母 		ciphertext[j] = shift(ciphertext[j]); 	for (q = 0, x = 'a'; q<26; q++, x++)                           //统计每个字母的个数 	{ 		for (j = 0; j<200; j++) 			if (ciphertext[j] == x) 			{ 				statistics[q]++; 				l++;             //l用于统计字母的个数 			} 	} 	for (j = 0; j<26; j++)//将26个字母赋值给b 		alphabet[j] = 'a' + j; 	for (j = 0; j<25; j++)//比较字母个数多少，个数多的排在前面 		for (q = 25; q>j; q--) 			if (statistics[q]>statistics[q - 1])   //从后向前的冒泡排序 			{ 				k = statistics[q]; 				statistics[q] = statistics[q - 1]; 				statistics[q - 1] = k; 				x = alphabet[q]; 				alphabet[q] = alphabet[q - 1]; 				alphabet[q - 1] = x; 			} 	for (k = 0; k<26; k++) 		printf("字母:%c  频率:%f \n", alphabet[k], ((float)statistics[k] / l)); 	for (j = 0; j<l; j++) 	{ 		for (d = 0; d<26; d++) 		{ 			//alphabet里面是字母a-z，没有空格或标点，当然无法打印出空格或标点 			if (ciphertext[j] == alphabet[d]) 			{ 				ciphertext[j] = password_list[d]; 				printf("%c ", ciphertext[j]); 				break; 			} 		} 	}  } char shift(char letter) { 	if (letter >= 'A'&&letter <= 'Z') 		letter = letter + 32; 	return (letter); }   &password_list;与password_list;的数值是一样的，但类型不同，原因参看 http://blog.csdn.net/zhangxiangdavaid/article/details/38085743

scanf("%s",&password_list);向一维数组中输入字符串，不能对数组名取地址


Question: C语言中如何将一个字符串型转为一个enmu的类型

引用 10 楼 bear234 的回复:用map------------这是唯一的方法 对12个元素map，没准需要的CPU指令条数比strcmp＋表格还多！

strcmp+表格

引用 楼主 xinsuixiaofeiyu 的回复:在程序中使用到月份，并且需要对月份做一些四则运算。但输入是按照字符串的形式。，然后就想着把12各月份做成一个枚举类型。然后可以让January与整型1对应起来。但不知道如何将字符串型转为一个枚举类型。或者对于这种情况有什么比较好的解决办法？  enum month{January=1,February,March,April,May,June,July,August,September,October,November,December}; 这样january就是等于1，feb = 2依次类推

自己写一个函数，逐一strcmp比较。

用map------------这是唯一的方法

引用 2 楼 wy_ei 的回复:你不能将字符串转化为枚举类型，你可以采用C++里面的map数据类型。如果是C的话可以写一个辅助函数，对传人的12个月份的字符串返回对应的数字。+1，不能直接转换

引用 2 楼 wy_ei 的回复:你不能将字符串转化为枚举类型，你可以采用C++里面的map数据类型。如果是C的话可以写一个辅助函数，对传人的12个月份的字符串返回对应的数字。最后不得已就这么干了

引用 1 楼 focuslight 的回复:直接把January写入enum类型这样还是不行的，因为输入传入的是“January”是字符串，不能转为枚举类型

直接把January写入enum类型


Question: 二叉树的建立输入问题。。。

应该 scanf("%c", &ch); getchar();  其他的改了一下, 勉强能用. 你自己再看看吧   #include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef struct node { 	char data; 	struct node * lchild;//左孩子 	struct node * rchild;//右孩子 }*BiTree, BiTNODE; typedef struct Node { 	BiTree data; 	struct Node * next; } NODE, *PNODE; typedef struct stack { 	PNODE ptop; 	PNODE pbottom; } STACK, *PSTACK; BiTree creat_tree(BiTree &T); void init_stack(PSTACK s); void push_stack(PSTACK ps, BiTree val); bool empty_stack(PSTACK ps); BiTree pop_stack(PSTACK ps); void traverse_zhongxu(BiTree root, PSTACK ps); int main() { 	BiTree T = NULL; 	T = creat_tree(T); 	STACK s; 	init_stack(&s); 	traverse_zhongxu(T, &s); 	fflush(stdin); 	getchar(); } /*先序构建二叉树*/ BiTree creat_tree(BiTree &T) { 	char ch; 	scanf_s("%c", &ch); 	getchar();  	if ('#' == ch) 	{ 		T = NULL; 	} 	else 	{ 		T = (BiTree)malloc(sizeof(BiTNODE)); 		if (T == NULL) 		{ 			printf("动态内存分配失败！"); 			exit(-1); 		} 		T->data = ch; 		creat_tree(T->lchild);//递归构建左子树 		creat_tree(T->rchild);////递归构建右子树 	} 	return T; } /*栈初始化*/ void init_stack(PSTACK ps) { 	ps->ptop = (PNODE)malloc(sizeof(NODE));//top指向新的节点 	if (ps->ptop == NULL) 	{ 		printf("动态内存分配失败！"); 		exit(-1); 	} 	else 	{ 		ps->pbottom = ps->ptop;//此时为空栈，因此bottom和top指向的位置一样 	} } /*入栈*/ void push_stack(PSTACK ps, BiTree val) { 	PNODE PNEW = (PNODE)malloc(sizeof(NODE)); 	PNEW->data = val;//数据 	PNEW->next = ps->ptop;//新节点在栈顶  指针域指向它下面的节点  实际为新节点入栈之前的栈顶top 	ps->ptop = PNEW;//将top指向栈顶 } /*判断空栈*/ bool empty_stack(PSTACK ps) { 	if (ps->ptop == ps->pbottom) 		return true; 	else 		return false; } /*出栈*/ BiTree  pop_stack(PSTACK ps) { 	BiTree t = NULL; 	if (empty_stack(ps))//(形参)ps=&S(实参) 		; 	else 	{ 		PNODE p = ps->ptop;//临时p指向栈顶 		ps->ptop = p->next;//p->pnext将为出栈后的栈顶 所以ptop指向它 		t = p->data; 		free(p);//释放栈顶 	} 	return t; } /*非递归中序遍历*/ void traverse_zhongxu(BiTree root, PSTACK ps) { 	BiTree q = root; 	if (q != NULL/* || empty_stack(ps)*/) 	{ 		while (q != NULL) 		{ 			push_stack(ps, q); 			printf("%d\n", q->data); 			q = q->lchild; 		}  		while (!empty_stack(ps)) 		{ 			q = ps->ptop->data;// 这里要把stack中存的BiTree指针取出来, 用来访问rchild 			pop_stack(ps); 			q = q->rchild;//这里访问rchild 			if (q) 			{ 				printf("%d\n", q->data); 			} 		} 	} }

#include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef struct node { 	char data; 	struct node * lchild;//左孩子 	struct node * rchild;//右孩子 }*BiTree,BiTNODE; typedef struct Node { 	char data; 	struct Node * next; }NODE,*PNODE; typedef struct stack { 	PNODE ptop; 	PNODE pbottom; }STACK,*PSTACK; BiTree creat_tree(BiTree T); void init_stack(PSTACK s); void push_stack(PSTACK ps, char val); bool empty_stack(PSTACK ps); bool pop_stack(PSTACK ps); void traverse_zhongxu(BiTree root, PSTACK ps); int main() { 	BiTree T=NULL; 	creat_tree(T); 	STACK s; 	init_stack(&s); 	traverse_zhongxu(T, &s); } /*先序构建二叉树*/ BiTree creat_tree(BiTree T) { 	char ch; 	fflush(stdin); 	scanf("%c", &ch); 	if ('#' == ch) 	{ 		T = NULL; 	} 	else 	{ 		T = (BiTree)malloc(sizeof(BiTNODE)); 		if (T==NULL) 		{ 			printf("动态内存分配失败！"); 			exit(-1); 		} 		T->data = ch; 		creat_tree(T->lchild);//递归构建左子树	 		creat_tree(T->rchild);////递归构建右子树 	} 	return T; } /*栈初始化*/ void init_stack(PSTACK ps) { 	ps->ptop = (PNODE)malloc(sizeof(NODE));//top指向新的节点 	if (ps->ptop = NULL) 	{ 		printf("动态内存分配失败！"); 		exit(-1); 	} 	else 	{ 		ps->pbottom = ps->ptop;//此时为空栈，因此bottom和top指向的位置一样 	} } /*入栈*/ void push_stack(PSTACK ps, char val) { 	PNODE PNEW = (PNODE)malloc(sizeof(NODE)); 	PNEW->data = val;//数据 	PNEW->next = ps->ptop;//新节点在栈顶  指针域指向它下面的节点  实际为新节点入栈之前的栈顶top 	ps->ptop = PNEW;//将top指向栈顶 } /*判断空栈*/ bool empty_stack(PSTACK ps) { 	if (ps->ptop == ps->pbottom) 		return true; 	else 		return false; } /*出栈*/ bool pop_stack(PSTACK ps) { 	if (empty_stack(ps))//(形参)ps=&S(实参) 		return false; 	else 	{ 		PNODE p = ps->ptop;//临时p指向栈顶 		ps->ptop = p->next;//p->pnext将为出栈后的栈顶 所以ptop指向它 		free(p);//释放栈顶 	} } /*非递归中序遍历*/ void traverse_zhongxu(BiTree root,PSTACK ps) { 	BiTree q = root;  	while (q != NULL||empty_stack(ps)) 	{ 		while (q != NULL) 		{ 			push_stack(ps, q->data); 			q = q->lchild; 		} 		while (empty_stack(ps)) 		{ 			pop_stack(ps); 			q = q->rchild; 		} 	} }

引用 3 楼 csdcr 的回复:你输的'#'不够多，因为你的程序表明，如果父节点得到的ch不为#，则构建左右子树，那么问题就来了，如果你读入的字符串不够长，导致做左子树的时候就读完了，那么你递归进入右子树的时候，由于字符串读完，返回的均为EOF（-1），和#恒不相等，那么就会死循环 那怎么办、、

如果是windows fflush(stdin); scanf("%c", &ch);

楼主用的是什么环境啊


Question: 为什么创建不了套接字？麻烦帮我看看哪里错了？

提示前面缺少分号

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

#include <winsock2.h>     改成大写

引用 1 楼 cjqpker 的回复:头文件 #include <winsock2.h> 改成 #include <winsock.h>  不对，你这代码没问题啊，看你报出的错误，应该是SOCKET不识别SOCKET这个类型

解决了，我用了VC版本不支持那个，下了个VC6，一样的代码，OK了，谢谢大家

把所有分号都检查遍，看看是不是有非英文输入状态下的分号。


Question: 求大神方法  和代码

把思路搭建好，代码就容易写出来了

这个又不难。还是好好自己看书做吧。

楼主是想让人帮忙把几道题全做了？？？  运行结果是输出数组中最小的数的值和相应的下标  这几道题都不算难，好好看看书，实在不行，网上搜相类似代码，看别人怎么写，自己试着敲一下代码，多动手，多思考、多看书吧


Question: 带头节点的单链表现则排序

(1) q->next != NULL (2) p->next = q->next (3) r->next = q


Question: 新手求帮助^_^

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

你打开了文件，然后什么都没做。

你只是打开了文件，并没有任何对文件内容进行打印或者处理，然后又关闭了文件。

你已经打开了,效果已经达到,只不过你什么都没做,文件就关了

你正常打开，然后什么也没做，那就是这个运行效果，你尝试读取文件内容，打印到屏幕试试

文件打开了，然后又关闭了，让后程序就结束了，很正常啊

你想显示什么？ 文件打开成功了，自然不会打印“打开失败”。

把门打开了，又把门关上，没有遇到什么问题，警铃没有响


Question: 求大神帮忙

区分大小写吗

1　统计频率，用位图法。 2　根据频率排序 3　用新字符集替换 代码就不写了。

就是照这样的顺序：ETAON RISHD LFCMU GYPWB VKJXQ Z，按文本中26个字母出现的频率高低来替换，比如说a出现的频率最高就用E来替换，b出现的频率次之，就用T来替换

指定替换的字符集是什么？

就是照这样的顺序：ETAON RISHD LFCMU GYPWB VKJXQ Z，按字母出现的频率高低来替换，比如说a出现的频率最高就用E来替换，b出现的频率次之，就用T来替换

统计频率用位图法，后面那个“替换”不知道什么意思。


Question: linux  Epoll  发送函数的封装问题...

来个人顶一下呀  也好结贴 呢  结贴，还能赚个50 嘿嘿

引用 3 楼 dooX8086 的回复:实现不好意思回这个贴了  上两次回贴都没帮到你。  发送数据跟 epoll 是没有关系的.  都可以直接 write(fd ,....)   Receive_Process(4,send_data_buffer_size_tcp ...) write(events[n].data.fd, send_data_buffer_size_tcp, 4);   // 直接发  下面的  所有关于EPOLLOUT 事件注册和处理都不要了  // --------------------------------------- 楼主是不是看了百度百科那份epoll 资料呀！？那份资料有点坑爹  上次帮到了 呵呵

好奇为何不直接用libevent呢？


Question: C语言 格式说明符%Lf 无法打印long double定义的变量

%llf 也不行，我又查了一下，好像是个BUG

long double与%lf   ?

%llf 试试 我刚百度搜的


Question: 排序问题

#include<stdio.h> #include<stdlib.h> #include<time.h>  int main() { 	int *p; 	int max0, max1; 	int length, i; 	while(scanf("%d", &length) != EOF) { 		p = (int *)malloc(sizeof(int) * length); 		if(!p) { 			printf("空间不足\n"); 			exit(0); 		} 		 		srand(time(NULL)); 		printf("数组："); 		for(i=0; i<length; ++i) { 			p[i] = rand() % 100 + 1; 			printf("%d ", p[i]); 		} 		printf("\n**********\n"); 		 		if(length == 1) { 			max0 = p[0]; 			printf("最大值：%d\n", max0); 			free(p); 		} else if(length == 2) { 			max0 = (p[0] > p[1]) ? p[0] : p[1]; 			max1 = p[0] + p[1] - max0; 			printf("最大值：%d\n次大值：%d\n", max0, max1); 			free(p); 		} else { 			max0 = (p[0] > p[1]) ? p[0] : p[1]; 			max1 = p[0] + p[1] - max0; 			for(i=2; i<length; ++i) { 				if(max0 == max1) { 					if(p[i] > max0) 						max0 = p[i]; 				} else if(p[i] >= max0) { 					max1 = max0; 					max0 = p[i]; 				} else if(p[i] < max0 && p[i] > max1) { 					max1 = p[i]; 				} 			} 			printf("最大值：%d\n次大值：%d\n", max0, max1); 			free(p); 		} 	} 	return 0; }

元素一个个比较呗


先做非常简单的题，把编程语言搞熟悉了，在去搞复杂的算法题。

#include <iostream> #include <vector> using namespace std;  int foo(int &beg , int &end_) { 	int n; 	int tmp; 	int max_sum; 	vector<int> v; 	cin >> n; 	//序列保存在 vector中 	for(int i = 0; i < n ; ++i) 	{ 		cin >> tmp; 		v.push_back(tmp); 	} 	max_sum = v[0]; 	size_t len; 	len = v.size(); 	int k; 	k = max_sum; 	for(int i = 0 ; i < len ; ++i) 	{ 		k = 0; 		for(int j = i; j < len ; ++j) 		{ 			//计算子序列和 			k += v[j]; 			if(k > max_sum) 			{ 			    beg = i; 				max_sum = k; 				end_ = j; 			} 		} 	}  	return max_sum; }   int main() { 	int n; 	int max_sum; 	int beg , end   	 ; 	cin >> n; 	for(int i = 1; i<= n; ++i) 	{ 		max_sum = foo(beg , end); 		cout << "Case " << i << ':' << endl; 		cout << max_sum << ' ' << beg + 1<< ' ' << end + 1<< endl; 	}  	return 0; }

这是一道动态规划的题目，有一定的难度。初学者的话还是先别着急做这题。


Question: 逗号运算符的第一个表达式可以是复合语句吗？

lz需要区分 expression和statement

引用 16 楼 u014360189 的回复:C语言的表达式由运算符、常量及变量构成。 这么说，复合字面值和函数调用都被表达式开除了么？

引用 5 楼 u013163178 的回复:即使能这么写，我也不会这么写，我认为写代码不是为了炫技，而是为了解决问题 这个人生啊，如果没有经历过一个炫耀词藻的年龄段，那么，一个作家不可能达到一个用普实的语言就能给人以清新和感人的境界。 如果一个孩子从小就被教育得老实巴交，他这一生在很大可能上就是碌碌之辈。 学计算机语言也是如此。

国人缺乏的就是逻辑思维。 你的问题充满了逻辑上的矛盾之处。 你既然知道逗号运算符的第一个是表达式，而复合语句又不是表达式，这还用问吗？

C语言的表达式由运算符、常量及变量构成。

建议楼主通览MSDN中的C++语法约定。

楼主没有理解清什么叫表达式?

引用 10 楼 lin5161678 的回复:[quote=引用 4 楼 flyhung 的回复:] 逗号表达式必须要有括号，你第一个写的根本就不是逗号表达式别误人子弟  逗号表达式从来没要求写括号 cinum ++;},  而楼主的 for(int i = 0; i < 100; x += 2, i ++); 中的 x += 2, i++ 就是一个逗号表达式 你自己不懂 别乱说 [/quote]这个的确是我没看清楚，其实我平时也是这样写的。

引用 21 楼 super_miker 的回复:[quote=引用 20 楼 u014360189 的回复:] [quote=引用 19 楼 sholber 的回复:] [quote=引用 16 楼 u014360189 的回复:] C语言的表达式由运算符、常量及变量构成。 这么说，复合字面值和函数调用都被表达式开除了么？[/quote] 原谅我是一只菜鸟吧，差点误人子弟了， C语言表达式：常量，变量，算术表达式，关系表达式，逻辑表达式，条件表达式，逗号表达式，赋值表达式，混合表达式， 函数调用表达式 不知道还有没有补充的，谢谢了[/quote] *和&和.和->以及[]呢？[/quote] 这么说来除了函数调用表达式，常量，变量，其他的都和运算符相关了？

引用 20 楼 u014360189 的回复:[quote=引用 19 楼 sholber 的回复:] [quote=引用 16 楼 u014360189 的回复:] C语言的表达式由运算符、常量及变量构成。 这么说，复合字面值和函数调用都被表达式开除了么？[/quote] 原谅我是一只菜鸟吧，差点误人子弟了， C语言表达式：常量，变量，算术表达式，关系表达式，逻辑表达式，条件表达式，逗号表达式，赋值表达式，混合表达式， 函数调用表达式 不知道还有没有补充的，谢谢了[/quote] *和&和.和->以及[]呢？

引用 19 楼 sholber 的回复:[quote=引用 16 楼 u014360189 的回复:] C语言的表达式由运算符、常量及变量构成。 这么说，复合字面值和函数调用都被表达式开除了么？[/quote] 原谅我是一只菜鸟吧，差点误人子弟了， C语言表达式：常量，变量，算术表达式，关系表达式，逻辑表达式，条件表达式，逗号表达式，赋值表达式，混合表达式， 函数调用表达式 不知道还有没有补充的，谢谢了

for语句在编译的时候， 是寻找；作为表达式分割符号的， 而楼主的；个数明显大于编译器的极限值了。

语句可以包括表达式，但是表达式不能包括语句。  expression is a part of statement, but statement cannot be a part of expression.  另外语句只有顺序语句，if和while语句三种。

引用 4 楼 flyhung 的回复:逗号表达式必须要有括号，你第一个写的根本就不是逗号表达式别误人子弟  逗号表达式从来没要求写括号  而楼主的 for(int i = 0; i < 100; x += 2, i ++); 中的 x += 2, i++ 就是一个逗号表达式 你自己不懂 别乱说

引用 8 楼 mbctb 的回复:[quote=引用 4 楼 flyhung 的回复:] 逗号表达式必须要有括号，你第一个写的根本就不是逗号表达式 逗号表达式必须有括号？这个我没有听说过啊。你说我写的哪一个有错误？ [/quote]最好还是带上，有些优先级还是得注意

引用 4 楼 flyhung 的回复:逗号表达式必须要有括号，你第一个写的根本就不是逗号表达式 逗号表达式必须有括号？这个我没有听说过啊。你说我写的哪一个有错误？

楼主，用if不行可以用那个类似if的三元运算符  tf ? true : false  这样可以达到你的要求

引用 3 楼 mbctb 的回复:[quote=引用 2 楼 lin5161678 的回复:] 只能写 表达式  语句不是表达式  复合语句是语句不是表达式 所以不行 明白了，看来有的语句就是表达式（象赋值语句），有的就不是表达式。  而逗号运算符两边都必须是表达式才行。 [/quote]任何语句都不是表达式

即使能这么写，我也不会这么写，我认为写代码不是为了炫技，而是为了解决问题

逗号表达式必须要有括号，你第一个写的根本就不是逗号表达式


Question: 如何在整数数组中找到2组相等的数

谢谢。6个数这样做没问题，如果增加的话能找到什么好办法呢。

if(1+2==3 && 4+5==6  ||1+2==4 && 3+5==6 ||1+2==5 && 3+4==6 ||1+2==6 && 3+4==5 ||2+3==4 && 1+5==6 ||2+3==5 && 1+4==6 ||2+3==6 && 1+4==5)

我比较笨，想不出O(1)的算法....

是这样的。 ｛1，2，3，6，7，9｝要是用了1+2=3，就不能再用3+6=9

每个数字不重复的意思是已经有了1+2=3,1,2,3就不用再考虑了吗？


Question: 在一个C程序中 我有个For循环 如何定义循环长度定义出来

5楼的宏定义，应该是没问题的

不可能不行的，楼主你肯定定义错了，具体参考楼上

#define DATA_SIZE 220 void Stard()  {  FILE *fp; float data1[DATA_SIZE ], data[DATA_SIZE ];    INT16  rri_r;  int i;  fp=fopen("E:/visualwork/300.txt","rb");  if(fp==NULL)  {  printf("文件读取失败！"); return;  }  i = 0;  while (1)  {  fscanf(fp, "%f%f\n", &data1[i], &data[i]);  rri_r=Num_count((INT16)data[i]);  printf("%d\n", rri_r);  i++;  if (i == DATA_SIZE ) break;  }  } 试试看

我在程序里面 #define了的呀

你确定是#define SIZE 200 吗？不是#define SIZE i;

都报错的啊  感觉不能写在符号  [ ]   里面

你确定不行吗？一定行。。


Question: 文件读写问题，求助

以下代码可以把共视卫星号存入数组：  int main() { 	int n, r; 	int *satelite;  //存放共视卫星号 	int nums;       //共视卫星个数 	double d; 	FILE *f; 	f = fopen("1.txt", "r"); 	n = 0; 	while (1) { 		r = fscanf(f, "%lf", &d); 		if (1 == r) { 			n++; 			printf("[%d]==%lg\n", n, d); 			//根据第一个数字，确定共视卫星个数 			if (1 == n) 			{ 				nums = (int)d; 				satelite = malloc(sizeof(int)*nums); 			} 			//共视卫星号存入数组 			if (2 <= n && n <= nums + 1) satelite[n - 1] = (int)d; 		} 		else if (0 == r) { 			fscanf(f, "%*c"); 		} 		else break; 	} 	fclose(f); 	return 0; }  至于双差距离，那个数字指定了双差距离的个数？

引用 1 楼 zhangxiangDavaid 的回复:借用代码：  #include <stdio.h> int main()  { 	int n, r; 	double d; 	FILE *f; 	f = fopen("1.txt", "r"); 	n = 0; 	while (1) { 		r = fscanf(f, "%lf", &d); 		if (1 == r) { 			n++; 			printf("[%d]==%lg\n", n, d); 		} 		else if (0 == r) { 			fscanf(f, "%*c"); 		} 		else break; 	} 	fclose(f); 	return 0; }   1.txt  共视卫星个数：7 共视卫星号： 6 15 18 21 22 24 27 参考卫星：序号 3卫星号21 双差几何距离： 12814.8 12814.8 12814.8 12814.8 -8532.57 -8532.57 -8532.57 -8532.57 3714.42 3714.42 3714.42   我如果把7赋给一个变量，共视卫星号付给一个数组，下面的也是，该怎么写。我是新手，非常感谢您的帮助！

楼上有bug，更改如下：  int main()  { 	int n, r; 	//int *satelite;  //存放共视卫星号 	int satelite[256];   //预先设定数组大小较好 	int nums;       //共视卫星个数 	double d; 	FILE *f; 	f = fopen("1.txt", "r"); 	n = 0; 	while (1) { 		r = fscanf(f, "%lf", &d); 		if (1 == r) { 			n++; 			printf("[%d]==%lg\n", n, d); 			//根据第一个数字，确定共视卫星个数 			if (1 == n) 			{ 				nums = (int)d; 				if (nums > 256) 				{ 					fprintf(stderr, "too many satelites!\n"); 					fclose(f); 					return 1; 				} 			} 			//共视卫星号存入数组 			if (2 <= n && n <= nums + 1) satelite[n - 1] = (int)d; 		} 		else if (0 == r) { 			fscanf(f, "%*c"); 		} 		else break; 	} 	fclose(f); 	return 0; }

新的文件格式是这样：  共视卫星个数： 7 共视卫星号： 6 15 18 21 22 24 27 参考卫星： 3 序号： 21 双差几何距离： 12814.8 12814.8 12814.8 12814.8 -8532.57 -8532.57 -8532.57 -8532.57 3714.42 3714.42 3714.42

更改文件格式：  /* 共视卫星个数：7 共视卫星号： 6 15 18 21 22 24 27 参考卫星：3 序号：21 双差几何距离： 12814.8 12814.8 12814.8 12814.8 -8532.57 -8532.57 -8532.57 -8532.57 3714.42 3714.42 3714.42 */ int main(void) { 	FILE *f; 	if (NULL == (f = fopen("1.txt", "r"))) 	{ 		fprintf(stderr, "can not open file:%s\n", "1.txt"); 		return 1; 	} 	int satelite[256], n1, n2, d; 	double dis[256]; 	char buf[256]; 	n1 = n2 = 0; 	fgets(buf, 256, f); 	fscanf(f, "%d\n", &d); 	printf("%d\n", d); 	//读一行 	fgets(buf, 256, f); 	//读取共视卫星号 	fgets(buf, 256, f); 	int x = 0; 	while (1) 	{ 		n = sscanf(buf + x, "%d", satelite + n1); 		if (1 == n) 		{ 			printf("%d ", satelite[n1]); 			while (buf[x]) 			{ 				if (' ' == buf[x]) 				{ 					x++; 					break; 				} 				x++; 			} 			if (++n1 >= 256) break; 		} 		else if (0 == n) sscanf(buf, "%*c"); 		else break; 	} 	printf("\n"); 	fgets(buf, 256, f); 	fscanf(f, "%d\n", &d); 	printf("%d\n", d); 	fgets(buf, 256, f); 	fscanf(f, "%d\n", &d); 	printf("%d\n", d);  	//再读一行 	fgets(buf, 256, f); 	//读入双差几何距离 	//fgets(buf, 256, f); 	while (!feof(f)) 	{ 		n = fscanf(f, "%lf", dis + n2); 		if (1 == n) 		{ 			printf("%lg ", dis[n2]); 			n2++; 		} 		else break; 	} 	fclose(f); 	return 0; }

一楼已有！！！


Question: 刚学c语言有点小疑问

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

C中的字符串以'\0'结尾，printf的%s参数将把对应的实参当成字符串对待。

也可以这样：  #include<stdio.h> int main() { 	char str[3]; 	fgets(str, 3, stdin); 	puts(str); 	return 0; }  fgets会自动在末尾加上'\0'，当然，如果长度过长，‘\n’也会被读入

修改如下：  #include<stdio.h> int main() { 	char str[3]; 	scanf("%c%c", &str[0], &str[1]); 	str[2] = '\0';       //字符串结束符 	printf("%s\n", str); 	return 0; }  一个汉字用两个字节存储，所以你可以输入一个汉字，或两个英文字符

C语言中处理字条串，都把字符数组当字符串处理。字符数组遇到0时表示字符串结束，否则还是作为字符数组的一部分处理。 输出字符数组时，如果遇到0就结束了。 C语言也不对数组进行初始化，就是说你定义了一个字符数组，数组里面的字符是乱码。你在给字符数组赋值时，最后必须补一个0。 scanf("%c%c",&str[0],&str[1]);  str[2]=0;

这是数组吧，好复杂的样子。。。

你烫？↑  这个是乱码，哈哈

scanf("%c%c",&str[0],&str[1]); str[2]=0;//要提供结束标志，或者后面的随机数会当成字符串的一部分，直到遇到0 printf("%s\n",str);


Question: C#   程序打不开求大神帮忙

新手，能帮忙改一下不

项目设置有问题, 选 \Clr

用depends.exe查看exe依赖的dll


Question: 关于数组的一个问题(C陷阱与缺陷中遇到的问题)

懂了一点点了 就是*（calendar+4） == calendar[4]   那么*（calendar+4）+ 7就是calendar[4][7] 的地址，在将*（calendar+4）+ 7 取值，就成了*(*(calendar + 4) + 7)

引用 8 楼 zhao4zhong1 的回复:A[B] *(A+B) *(B+A) B[A] 以上四行等价。  头一次看到B[A]的写法，学习了。

A[B] *(A+B) *(B+A) B[A] 以上四行等价。

a[i] == *(a + i) a[i][j] == *(*(a + i) +j)

calendar[4]  不就是 *(calendar + 4)

引用 2 楼 u011916206 的回复:我的理解是*(calendar + 4) 是第四个数组的地址。*(calendar + 4) + 7是第四个数组第七个元素的地址。  谁说的啊，内存是连续排放的，说白了就是一维的。二维只是人为加上去的概念，实际使用的时候得用乘法来表示第二维度

你完全可以把它理解为一个一维的线性组，这样的就容易理解了。 int calendar[12][31]; int (*p)[31]; 若想表示X= calendar[4][7]; 一样的效果；  calendar[12] <=>*p *p <=> calendar+0 *(p+4) <=>calendar+4//此为一维数组，里面有12个单元 *（*(p+4)+7） <=>   *(calendar + 4) + 7   //此为第4个单元里的一维数组中的第7个元素（每个单元共有31个元素）

arr[i] 相当于 *( arr + i )  calendar[4][7] 相当于 *( calendar[4] + 7 ) *( calendar[4] + 7 ) 相当于 *( *(calendar + 4) + 7 )

指针和数组 http://blog.csdn.net/zhangxiangdavaid/article/details/38085743


Question: 感觉做OJ的题好难，希望朋友们给点学习方法

从简单的题入手！

知难而上 知难而退 都是生活态度的一种 不要褒贬 随心

引用 10 楼 xteaj 的回复:学习编程，主要学逻辑思维。算法，其实就是逻辑思维的体现。 建议选从逻辑入手。 逻辑如何练习啊，话说有人说我逻辑特差

基本功无他，唯手熟而。

引用 9 楼 u010703975 的回复:楼主方便给个联系方式吗 我也在学数据结构 我QQ1123302584 看了你的博客..我学的没有你好那.嘿嘿，一起努力吧

引用 10 楼 xteaj 的回复:学习编程，主要学逻辑思维。算法，其实就是逻辑思维的体现。 建议选从逻辑入手。是离散数学那方面么？

引用 6 楼 FightForProgrammer 的回复:需要长时间的积累。可以自己写成博客 恩，看了楼上学长的代码..这两个问题学会了...慢慢学吧

楼主方便给个联系方式吗 我也在学数据结构

最重要的还是基本功，比如数据结构、简单算法、基本代码必须学的很扎实才行。 如果你看别人的解题思路和代码都能看懂，那就说明你的基本功不错，只是需要积累一点经验。 解题就像打比赛，学习就像日常训练。只比赛不训练、只训练不比赛，都是不好的。

选择适合自己的类别和难度，刚开始可以刷一些水题找找感觉，然后就可以有针对性的做一些稍微难一点的。 可以参考别人总结的题目分类，比如这个 http://blog.csdn.net/hjd_love_zzt/article/details/8976787 有时候做不出来也不用着急，可以看看别人关于这道题的解题报告作为参考，再对比一下正确的代码和你自己的代码。 很多题目都是相通的，看多了之后自然就有经验了。

学习编程，主要学逻辑思维。算法，其实就是逻辑思维的体现。 建议选从逻辑入手。

需要长时间的积累。可以自己写成博客

多动脑多练就行了。

什么学校????

引用 1 楼 zhangxiangDavaid 的回复:算法不是一天就练就的，需要几年的努力…… 约瑟夫问题 http://blog.csdn.net/zhangxiangdavaid/article/details/25057811 一元多项式的加减乘 http://blog.csdn.net/zhangxiangdavaid/article/details/31032251谢谢啦，我看看这两段代码。主要是最近有个选拔考试，不知道学什么好一点了

持续努力，加油


Question: 看《C语言大全》遇到了问题，求指教

*err[]是一个指针数组 数组与指针 http://blog.csdn.net/zhangxiangdavaid/article/details/38085743

第一个没什么问题，你每次打印的是二维数组的第一个值，崩溃的原因是你没有初始化，你改成q[t]是打印的地址 第二个没有任何问题，因为char*就是printf("%s");


Question: 关于如何提升编程的问题

都是练少了。

公司主要不是做软件的，就是自己想开发一个外汇交易平台，有2个开发的一个是PHP，一个是.NET，他们都有经验，我现在是不知道怎么办了。

引用 6 楼 liqinglai123 的回复:主要是刚从培训出来，而且现在一点头绪都没有，老板也不懂技术，公司没人懂C++方面，我不知道怎么个写法 公司没人懂C++，那你们公司C++项目是谁做出来的？难道是准备以后让你一个人带领公司的C++项目？？

没人带没关系  老板让你写的你写不出来，有两种可能： 1）你水平问题 2）老板写的东西确实超出了你的能力   一般基本是第一种情况......   我也在用c++做金融方面的东西，也是没人带，全是自己做，不过老板已经把框架设计好了，我要做的就是搞懂框架然后用c++实现之～～～ 如果你说你不会设计框架模块什么的，可以理解，如果你是说你写不出代码，那是你水平问题～～～  如果是你的水平问题，这就和有没有人带没关系了～～～有人带你也一样不行

主要还是多写代码、多看书、多思考，你接触的软件代码越多，就会学到越多的东西，对一份代码，一个软件的把握角度也会慢慢的成熟起来。至于书，论坛有好多推荐的帖子，你不妨多看看。勤奋+天赋吧，我觉得。现在你写不出来代码，对你而言也是个机会，说明你还有提升的巨大空间。

什么培训机构

自己顶起来 好迷茫


Question: 指针运算，这跟说好的不一样啊= - =

++a a++ 把 a 移动了两次你无视所


Question: EPOLL 方式的  TCP   如何封装一个发送函数，任意文件中可以定义？

可能描述不清，本帖结了 详见另个帖子：http://bbs.csdn.net/topics/391019613

引用 3 楼 dooX8086 的回复:不清楚楼主具体send不出数据是什么情况 但代码有些问题  int tcp_send_data_to_pc(int len,char* buffer) {         printf("in while n == %d \n",n);         send(events[n].data.fd,buffer,8,0);   // 这个 8 ???// 应该是参数 len 吧             ev.events = EPOLLIN;         ev.data.fd = events[n].data.fd;     epoll_ctl(epoll_fd_tcp, EPOLL_CTL_MOD, ev.data.fd, &ev);       }   // ... // 这个 buffer 不管recv 还是 send 都是它。且而还是共用的这样设计问题 unsigned char send_data_buffer_size_tcp[BUFFER_SIZE_TCP];    // ev.events=EPOLLIN | EPOLLET; 注册epoll 的 event 用的是 EPOLLET    边缘触发 模式。 但不管是accept,  recv 还是send 等处理的方式却 LT 模式   // ======================================= 很长时间没裸写 epoll 了, 详细情况我也说不清。 不了解 epoll 情况下, 个人不推荐祼写..  代码是网上找的，简单修改修改  想要实现的功能是  PC 发起命令，，服务器接收后，解析出命令包， 将命令重新打包， 代入一个函数（该函数在另个文件中），函数根据命令码，通过SPI与FPGA通信，在取得FPGA数据后，不通过函数参数方式传出去，，，而是想在函数中直接send出去，即发给PC...  比如工程有多个文件 main.c       中调用 do_epoll_tcp(),改函数在 epolltcp.c中  epolltcp.c   的do_epoll_tcp()，接PC端命令，解析后，将命令传入函数：do_data(cmd,type ...) 在 function.c文件中  function.c  的 do_data(cmd,type ...)，接到命令后，与FPGA交互，得到结果后，直接  send   给PC

引用 1 楼 zhao4zhong1 的回复:估计得用宏来实现了。www 指点指点呢

估计得用宏来实现了。


Question: 定义宏函数给数组排序老是出错给位大神能帮我看看吗

修改如下：  #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define SIZE(n) (n = sizeof(p1) / sizeof(*p1)) //#define  void ARR_MAX(int *p1, int n)  { 	int i, j, t; 	for (i = 0; i < n; i++) 	{ 		for (j = i + 1; j < n; j++) 		{ 			if (p1[i] < p1[j]) 			{ 				t = p1[i]; p1[i] = p1[j]; p1[j] = t; 			} 		} 		printf("%d ", p1[i]); 	} } void ARR_MIN(int *p1, int n) { 	int i, j, t; 	for (i = 0; i < n; i++) 	{ 		for (j = i + 1; j < n; j++) 		{ 			if (p1[i] > p1[j]) 			{ 				t = p1[i]; p1[i] = p1[j]; p1[j] = t; 			} 		} 		printf("%d ", p1[i]); 	} } //#define SORT(p1,c) (c == '>'?ARR_MAX(p1,n):ARR_MIN(p1,n)) void SORT(int *p1, int n, int c) { 	if (c == '<') ARR_MIN(p1, n); 	else ARR_MAX(p1, n); } int main() { 	char c; 	int p1[] = { 23,32,21,11,45 }; 	printf("请输入大于号或小于号\n"); 	scanf("%c", &c); 	SORT(p1, sizeof(p1)/sizeof(*p1), c); 	return 0; }

又见语法糖！  语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。

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

给个参考：  #include <stdio.h> #define PRINT(p)										\ {														\ 	for(int i=0;i<sizeof(p)/sizeof(*p);++i)				\ 	{													\ 		printf("%d\t",p[i]);							\ 	}													\ }  #define SORT(p,c)										\ {														\ 	for(int i=0;i<sizeof(p)/sizeof(*p)-1;++i)			\ 	{													\ 	for(int j=i+1;j<sizeof(p)/sizeof(*p);++j)		\ 		{												\ 		if(c=='<'&&p[i]<p[j]||c=='>'&&p[i]>p[j])	\ 			{											\ 			p[i]+=p[j];								\ 			p[j]=p[i]-p[j];							\ 			p[i]-=p[j];								\ 			}											\ 		}												\ 	}													\ 	PRINT(p);											\ }  int main() { 	char c; 	int p1[]={23,32,21,11,45}; 	printf("请输入大于号或小于号\n"); 	scanf("%c",&c); 	SORT(p1,c); 	return 0; }

为啥一定用宏啊？这种情况用宏貌似没啥优势

1、用if语句代替三元运算符?: 2、在语句块{}外面包上do...while(0)

仔细想想宏替换之后代码成什么样了， SORT一替换， 你看看第一句成什么了(c == ...)  前面的东西呢。

引用 8 楼 u010652824 的回复:谢谢楼上几位给我耐心解答看了视频感觉视频里讲得宏函数听懂了只是想尝试一下用宏写个数组排序写完后错误百出尝试改了很多次还是不行，赵老师说的用gcc -E我也尝试过不过在终端下显示替换后的程序看上去太乱了，还有我自学c语言每次看书或者看视频感觉里面讲得好像都懂了但是真正自己写的时候为什么一点思路都没有 看上去太乱的代码你不会将它们排版成不乱吗？ #include <stdio.h> long a=10000; long b; long c=2800; long d; long e; long f[2801]; long g; int main() {     for(;b-c;) f[b++]=a/5; //  while (1) { //      if (0==b-c) break; //      f[b]=a/5; //      b++; //  }      //f[0 - 2800] = 10000/5     for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)           for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); //  while (1) { //      d=0; //      g=c*2; //      if (0==g) break; //      b=c; //      while (1) { //          d+=f[b]*a; //          f[b]=d%--g; //          d/=g--; //          --b; //          if (0==b) break; //          d*=b; //      } //      c-=14; //      printf("%.4d",e+d/a); //      e=d%a; //  }      return 0; }

达内不是那个冒充公司骗人培训的培训机构吗.... 跟蓝翔有一拼, 貌似还不如蓝翔.


Question: 反汇编和win32 汇编编程是同一个概念吗这2个有什么区别

反汇编是读带啊, 汇编是写代码 你觉得读c代码难还是写c代码难? 难不难还是要看代码复杂不复杂.

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

反汇编是要把机器码变成汇编代码。win32汇编是用汇编语言来写代码，在这里win32汇编相当于C++这样东西，机器码相当于一串由0和1组成的数字，你说是读一串数字难还是读C++代码难？

win32汇编里面 有很多宏 可以简化代码，结构可以跟C的差不多。 反汇编出来的没有宏,看起来费劲啊


Question: 结构体位域定义的问题

仅供参考：#include <stdio.h> #pragma pack(push,1) union U {     unsigned char byte;     struct BF {         unsigned int b0:1;//a         unsigned int b1:1;//b         unsigned int b2:1;//c     } bf; } u; #pragma pack(pop) unsigned char bt; int a,b,c; int main() {     for (bt=0;bt<8;bt++) {         u.byte=(unsigned char)bt;         a=u.bf.b0;         b=u.bf.b1;         c=u.bf.b2;         printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);     }     for (c=0;c<2;c++)     for (b=0;b<2;b++)     for (a=0;a<2;a++) {         u.bf.b0=a;         u.bf.b1=b;         u.bf.b2=c;         bt=u.byte;         printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);     }     return 0; } //byte 0x00 -- c:0 b:0 a:0 //byte 0x01 -- c:0 b:0 a:1 //byte 0x02 -- c:0 b:1 a:0 //byte 0x03 -- c:0 b:1 a:1 //byte 0x04 -- c:1 b:0 a:0 //byte 0x05 -- c:1 b:0 a:1 //byte 0x06 -- c:1 b:1 a:0 //byte 0x07 -- c:1 b:1 a:1 //c:0 b:0 a:0 -- byte 0x00 //c:0 b:0 a:1 -- byte 0x01 //c:0 b:1 a:0 -- byte 0x02 //c:0 b:1 a:1 -- byte 0x03 //c:1 b:0 a:0 -- byte 0x04 //c:1 b:0 a:1 -- byte 0x05 //c:1 b:1 a:0 -- byte 0x06 //c:1 b:1 a:1 -- byte 0x07

你看错了吧。short的大小是2个字节啊

#include <stdio.h>  typedef unsigned char uchar8; typedef unsigned short uint16;  typedef union {     uchar8 ms1[2];     struct {         uint16  MSTA:6;         uint16  FSEQ:7;         uint16  ISEQ:3;     }; }MSTA_SEQ;  int main(void) {     MSTA_SEQ ms;     ms.ms1[0] = 0xa1;     ms.ms1[1] = 0xa4;      int size;     size = sizeof(MSTA_SEQ);     printf("MSTA = 0x%02x\n",ms.MSTA);     printf("FSEQ = 0x%02x\n",ms.FSEQ);     printf("ISEQ = 0x%02x\n",ms.ISEQ);     printf("size = %d\n",size);     return 0; } //MSTA = 0x21 //FSEQ = 0x12 //ISEQ = 0x05 //size = 2 //

#include <stdio.h>   2    3 typedef unsigned char uchar8;   4 typedef unsigned short uint16;   5    6 typedef union   7 {   8     uchar8 ms1[2];   9     struct MS  10     {  11         uint16  MSTA:6;  12         uint16  FSEQ:7;  13         uint16  ISEQ:3;  14     }Ms;  15 }MSTA_SEQ;  16   17 int main(void)  18 {  19     MSTA_SEQ ms;  20     ms.ms1[0] = 0xa1;  21     ms.ms1[1] = 0xa4;  22   23     int size;  24     size = sizeof(ms.Ms);  25     printf("MSTA = %02x\n",ms.Ms.MSTA);  26     printf("FSEQ = %02x\n",ms.Ms.FSEQ);  27     printf("ISEQ = %02x\n",ms.Ms.ISEQ);  28     printf("size = %d\n",size);  29     return 0;  30 }  这样改就可以了 谢谢大家了

引用 3 楼 zhao4zhong1 的回复:再供参考：#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   }; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);     u.bb=0x41;     u.cc=0x21;//dddccccccbbbbbbb     u.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)   这个是我数据帧结构的其中一个域，占用2个字节，D0-D5表示MSTA；D6-D12表示FSEQ;D13-D15表示ISEQ，我想用那个结构体和联合体来表示这个域 有问题吗？

楼主是想问为什么sizeof(ms)的大小是3吧。  那是因为联合体中Ms结构体定义的类型决定的 假设编译器分配地址从零开始，那么结构体元素位置如下： 地址：0x00                                   0x01                                        0x02 元素：ms1                                   ms2             MSTA（BIT0-bit5）        FSEQ（BIT0-BIT6）             ISEQ（BIT0-BIT2） 因为MSTA共有6位，占据"uchar8"一个字节后剩余2位，不足以存放下FSEQ的7位数据，所以FSEQ会从新的一个地址开始存放。 如果联合体中的uchar8改成uint16就不会有这个问题了。 地址：0x00                                   0x01                                                                              0x02 元素：ms1                                   ms2             MSTA（BIT0-bit5） FSEQ（BIT6-BIT12） ISEQ（BIT13-BIT15）

你看错了吧？运行输出结果为2


Question: 关于积分的使用

计算机是无法直接计算积分的。但你可以把积分化成离散数列来计算，这样可以得到积分的近似值，注意不是精确值。当步数足够多时，近似值逼近精确值。 下面是我写的例子，你可以看下。  #include"math.h" //返回中间无奇点的积分值。 double Shift(double(*Fun)(double x), double left, double right,double dx=0.000001) { 	double y = 0; 	for (double x = left; x < right; x += dx) 	{ 		y += ((*Fun)(x)+(*Fun)(x+dx))*dx/2.0; 	} 	return y; } //这个支持收敛点，convPoints是收敛点的数据，numConv是收敛点的个数。 double Shift(double(*Fun)(double x), double left, double right, double*convPoints, int numConv, double dx=0.001) { 	double y = 0; 	double*conv = new double[numConv + 2]; 	conv[0] = left; 	conv[numConv + 1] = right; 	if(numConv>0)memcpy(&conv[1], convPoints, numConv*sizeof(double)); 	for (int i = 0; i < numConv+2; i++) 	{ 		y += Shift(Fun, conv[i]+dx/100.0, conv[i + 1]-dx/100.0, dx); 	} 	delete conv; conv = 0; 	return y; } //积分的核<就是那个sin(x)^4/(x^2)>。 double Fun1(double x) { 	return (sin(x)*sin(x)*sin(x)*sin(x))/(x*x); } int _tmain(int argc, _TCHAR* argv[]) { 	double conv[1] = { 0 }; 	//把right设大一点，就相当于无穷大了。 	//增大区间会增加计算时间。 	//只对收敛的函数有效 	double y = Shift(Fun1, 0, 100,conv,1); 	printf("%lf\n", y); 	getchar(); 	return 0; }

参考《数值计算》


Question: c语言中#疑问

#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC

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

#include <stdio.h>  #define TYPE int  #define g(a) #a #define h(a) g(a)  int main(int argc, char *argv[]) {     printf("the type is %s\n", h(TYPE));      return 0; }

引用 3 楼 paschen 的回复:typeid(TYPE).name() 个人对c++还不是很熟，刚去查了尝试typeid(TYPE).name() 可行，可是c中有没有其他办法呢？

引用 2 楼 zhao4zhong1 的回复:请牢记 #define后面不要加分号 ！  搜“编译期 运行期” 有劲的话，还可以参考gcc源代码中对#define处理相关片断。这上面输的时候忘了。。

typeid(TYPE).name()

typeid 可以吗

#define TYPE int #define TOSTRING(type) #type #define TYPENAME(type) TOSTRING(type)  int main(void)  {          printf("the type is %s\n", TYPENAME(TYPE));          return 0;   }


我是个初学者，太专业不太明白呢，能不能简单举个例子，我想要详细点的代码解释

项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项


Question: 用除法怎么运算？

原来这样~~~~~~~~~

请问下z 代表是不是等于右边式子。

#include <stdio.h> int main () { 	int x,y,z;//定义被除数、除数、商 	scanf("%d,%d",&x,&y);//输入被除数、除数，任意的 	z=x/y;//计算        printf("%d\n",z);//输出商 	return 0; } 解释一下，int型的变量的取值范围是2的31次方，所以我们一般用的话用int型就足够了。建议把c语言教程上的定义、知识点好好看看。

引用 2 楼 zhao4zhong1 的回复:楼主目前处于干细胞状态。  赵老师赶快给她诱导一下

楼主目前处于干细胞状态。

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

太新手  #include <stdio.h> void main() { 	float x, y, z; 	x = 15; 	y = 3; 	z = x / y; 	printf("%f\n", z); }


Question: 求一份 c99的标准库chm格式的！！

引用 2 楼 zhao4zhong1 的回复:http://www.baigoogledu.com/s.php?hl=zh-CN&q=c99%B1%EA%D7%BC+chm  屌

pdf格式不行吗？


Question: 关于C语言重复释放问题

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

一般稍微健壮点的商用系统，都会在malloc和free的地方做上层封装，如加上魔术字，内存头等， 保证该块内存不会被破坏或者重复释放撒。

引用 3 楼 K616358281 的回复:在VS里会报错，估计是codeblock做了优化吧。 我试了一下，还真会错去，但是依然打印出了结果。

在VS里会报错，估计是codeblock做了优化吧。

与编译器的行为有关

重复释放会搞乱C库的内存管理链表，后续申请内存时就很有可能出错。你这个没有出错是因为free之后直接退出了，你可以试试free之后再多malloc几次试试。


Question: 求助：报错 - 应用程序无法正常启动（0xc0000142）,请单击‘确认’关闭应用程序”

解决就好

没办法，重装系统后，问题解决了。


Question: 反汇编异常处理的异常处理函数调用辨别

不是的，算了，pass异常处理这篇了，太难了

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

.text:004012B8                 call    __CxxThrowException@8 ; _CxxThrowException(x,x)  //这里抛出异常  text:004012E5 __catch$_main$1:                        ; DATA XREF: .rdata:00403670o //catch到异常 .text:004012E5                 push    offset aBbbbb   ; "BBBBB" .text:004012EA                 call    ds:__imp__printf .text:004012F0                 add     esp, 4 .text:004012F3                 mov     eax, offset $LN10 .text:004012F8                 retn .text:004012F8 _main           endp                                   //异常处理完成，结束main函数

名字中有catch的部分是要的结果吗


Question: 数据结构 插入排序

修改如下：  #include<stdio.h> typedef int keytype; typedef int infotype; typedef struct { 	keytype key; 	infotype data; }rectype; void insertsort(rectype r[], int n) { 	int i, j; 	rectype tmp; 	for (i = 1; i<n; i++) 	{ 		tmp = r[i]; 		j = i; 		while (j > 0 && tmp.data < r[j - 1].data)  //按data排序 		{ 			r[j] = r[j - 1]; 			j--; 		} 		r[j] = tmp; 	} } int main() { 	rectype a[5] = { {0,4}, {1,2}, {2,6}, {3,8}, {4,5} }; 	int i; 	insertsort(a, 5); 	for (i = 0; i < 5; i++) 	{ 		//cout << a[i] << endl; 		printf("%d\n", a[i].data); 	} 	return 0; } //2 //4 //5 //6 //8  插入排序：http://blog.csdn.net/zhangxiangdavaid/article/details/27373183

排序的代码没错，但这不可能编译过去，cout的头文件没有，自定义类型，传入参数又是整型，改了就好了

有点无厘头吧


Question: *&p 和 &*p, 求大神详细解释一下.

引用 10 楼 aw1555 的回复:可以看看c语言符号优先级和结合顺序//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

可以看看c语言符号优先级和结合顺序

引用 1 楼 z609292366 的回复:他们两条语句的汇编代码是相同的.  还是汇编语言来得直接、清楚

你理解有误 不能说先把(*p)]运算出来等于1 然后再对 1 进行 & 运算  (* p) 在这里就是等于a 啊 在对a进行 & 运算 结果 就是a的地址.

这里 &*p  和 *&p  都等于 p, 也就是 p 指向的 变量的地址，

《牛肉干》   C语言上机课，某女同学偷偷吃起牛肉干。   有一粒牛肉干掉到了键盘上，卡在7和8键之间。   女同学就在键盘上抠啊、抠啊、抠啊……   程序里一行代码变成这个样子：   int *pa=&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&a;   后来的结局是  ————程序顺利通过编译，运行结果正确！

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

引用 2 楼 zhangxiangDavaid 的回复:'*'的本意是解引用操作符，理解“引用”的概念。 这样的赋值语句：*p=1;  是成立的吧！ *P等同于变量a;  所以&(*p)就是&a;对头，*p对应于变量a，a=1，所以*p=1，而不是说*p对应于1这个常量

&与*互为逆运算

他们两条语句的汇编代码是相同的.


Question: 这个函数最终的输出结果是多少？

# include <stdlib.h>  char * alloc_mem(void) {     return malloc (128); }

char *alloc_mem(char **p)         {                 *p = (char *) malloc(128);                 return *p;         }         int main()         {             char *p = NULL;             char tmp[] = "hello world";               alloc_mem(&p);             memcpy(p,tmp,strlen(tmp));                          printf("result: %s\n",p);             return 0;         }

p是野指针  代码是错的 结果毫无意义

问题多多 其一char *tmp[]：tmp是一个指针数组，即数组的每个元素 是指向char类型的指针，而你给tmp初始化为“hello world” 其二char *alloc_mem(char *p)         {                 p = (char *) malloc(128);                 return p;         }你给形参p分配空间，而实参p依然未初始化

运行异常.     char *alloc_mem()          {   	char *p;    	p = (char*)malloc(128);                  	return p;          }           int main()          {              	char* p; 	//p = (char*)malloc(128);  	char tmp[] = "hello world";                	p = alloc_mem();              	memcpy(p,tmp,strlen(tmp));                           	printf("result: %s\n",p);     	 	getchar(); 	return 0;          }   这样有输出, 不过分配空间要初始化 为0

修改如下：   char *alloc_mem(char **p) { 	*p = (char *)malloc(128); 	return *p; } int main(void) { 	//char *tmp[] = "hello world"; //这么能编译过吗？  	char *p; 	char tmp[] = "hello world";  	alloc_mem(&p); 	memcpy(p, tmp, strlen(tmp)); 	p[strlen(tmp)] = '\0'; 	printf("result: %s\n", p);  	return 0; } //result: hello world

char *tmp[] = "hello world"; 这么能编译过吗？


Question: C++错误error LNK2019: 无法解析的外部符号 _main，该符号在函数 ___tmainCRTStartup 中被引用

一般情况下应该是源函数里面没有创建main（）函数，在源.cpp里面加上int main（）{}就好了。

void main(void) 改为 int main() 试试看。

你是不是打开过多个解决方案啊,可能是之前的解决方案没有彻底关闭导致的..

函数实现要写在CPP源文件里

这位同学，我用你贴出来的代码建了一个程序，编译通过，既然你的程序是控制台程序，这个问题的原因很有可能就是你的代码中没有main函数，所以报错，你再看看。


Question: c 语言的字符串拷贝

引用 7 楼 SEESEECN 的回复:感觉这面试的有点装B的嫌疑 http://mil.cankaoxiaoxi.com/2015/0416/744272.shtml 对付有点装B嫌疑的面试官，你要比他更装B！ “能装B方能镇装B，准备装才可能不必装，越不能装越可能挨装。”

赵老师,我那可是去面试啊.对方是做防火墙的.好想成功面试啊.,可惜. 另外谢谢zhangxiangDavaid 的提议,但现在c的公司字符串拷贝真的流行用memmove吗?那memcpy不更快吗?另外,我自己感觉这函数要使其安全的话,还得自己先设置一下条件啊. 还有刚查了有人推荐的一个非c标准的strlcpy. 哎,没进过正规军,自己还得继续努力啊! 再次感谢大家的回答!进不了正规军,我就当个好伪军吧!

引用 3 楼 zhao4zhong1 的回复:字符串那些事儿！http://blog.csdn.net/pizi0475/archive/2010/03/04/5346708.aspx 楼主试试反问面试官，你知道字符串有多少种常用的表示方法吗？

字符串拷贝函数用啥？ 你可以说，直接用等于号就可以了，你又没问我是 浅拷贝 还是 深拷贝

感觉这面试的有点装B的嫌疑

可以试试memmove

赵老师,别这样好吗?

谢谢 user-5的回答. 我也想到了strcpy_s ,但是我也想起了cplusplus论坛里面的老外有说I agree that for portability strcpy_s should be avoided.所以我就放弃了说这个函数. 哎,想进c/c++行业这么难啊. 再次感谢您的回答!

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

微软的_s系列 eg: strcpy_s 不过这东西注意一下编译器警告就可以了,,,


Question: asp.net想学C,能不能推荐点书之类的。

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

Windows平台就用vs。Linux下的话codeblocks不错

c语言程序设计， 随便哪本都行，谭浩强的也不是不可以。 编译器 vs， keil， gcc， 随意。


Question: 各路大神请显神力

我试了一下，都很正常，没有你说的一直显示主页。

换换浏览器。


Question: POJ 1056 没用数据结构的东西 自己想了一个 但是runtime error

建议把题目也贴出来

调试了两天，整个代码的思想，运行结果应该没问题，问题出在我不知道如何来安排这个程序结构，while那个可能是runtime error的原因

数组开大点放全局

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

char code[8][10];二维数组开大点吧，每个串的01个数不大于10个，如果刚好一个串有10个字符。数组越界了。另外 cnt=1;     while(1)     {         scanf("%s",code[cnt]);         if(code[cnt][0]=='9')             break;         cnt++; cnt为什么要从1开始，这样如果有8个字符串也会导致越界呀。


Question: C中类型的转换.unsigned char* 和 FILE *

可以转啊，32位系统下，所有指针都是32位数字啊，没有任何区别。 需要注意的是，这种转换有没有意义而已。

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

File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\stdio.h"       63: struct _iobuf {      64:         char *_ptr;      65:         int   _cnt;      66:         char *_base;      67:         int   _flag;      68:         int   _file;      69:         int   _charbuf;      70:         int   _bufsiz;      71:         char *_tmpfname;      72:         };      73: typedef struct _iobuf FILE;

这种转换没有意义

为什么不能？ #include <stdio.h> FILE *f,*f1; unsigned char *p; int i; int main() {     f=fopen("test.txt","w");     if (NULL==f) return 1;     printf("f->_flag==%d,f->_file==%d\n",f->_flag,f->_file);     p=(unsigned char *)f;     printf("p[0..63]:\n");     for (i=0;i<64;i++) printf("%02x ",p[i]);     printf("\n");     f1=(FILE *)p;     printf("f1->_flag==%d,f1->_file==%d\n",f1->_flag,f1->_file);     fclose(f1);     return 0; } //f->_flag==2,f->_file==3 //p[0..63]: //00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 //f1->_flag==2,f1->_file==3 //

在标准里面不可以直接转换。 但有的编译器管的很松。  不可以的时候，可以先转换成void *指针，再转换为目标指针。

引用 8 楼 yangyunzhao 的回复:[quote=引用 7 楼 my_live_123 的回复:] 这种转换怎么会没有意义呢？ 假设你从别处得到一段字节流，然后对方告诉你这是个FIFE结构的字节，这种转换肯定有意义的。只不过此种情况用途较少而已！ 底层就是一堆二进制，怎么解释它的数据含义，那是用户说的算！反之，任何结构体，数组，底层都是一堆连续的字节！  晕，我说的是要注意有没有意义，而不是说没有意义。 例如：多线程中传递一个void*，可能是有意义的。但是如果在局域网下，我把A电脑上打开的文件句柄，传递到B电脑上，自然就没有意义了啊。要用户自己判断有没有意义。[/quote]  我说三楼呢，忘了引用了

引用 7 楼 my_live_123 的回复:这种转换怎么会没有意义呢？ 假设你从别处得到一段字节流，然后对方告诉你这是个FIFE结构的字节，这种转换肯定有意义的。只不过此种情况用途较少而已！ 底层就是一堆二进制，怎么解释它的数据含义，那是用户说的算！反之，任何结构体，数组，底层都是一堆连续的字节！  晕，我说的是要注意有没有意义，而不是说没有意义。 例如：多线程中传递一个void*，可能是有意义的。但是如果在局域网下，我把A电脑上打开的文件句柄，传递到B电脑上，自然就没有意义了啊。要用户自己判断有没有意义。


Question: C语言求助

引用 2 楼 user-2 的回复:我用vs2010试验了一下，是pow函数的返回值问题，好像为double的。強转一下即可。浮点型的乘法 和预期的不一致。 			x=(a[i]-'0')*((int)pow((double)10,n-i-1))+x; 胡乱强转了一下，发现这个可以           x=(a[i]-'0')*(float)pow(10,n-i-1)+x; 百度了下，pow在不同软件的返回值类型不同，真是坑爹

引用 2 楼 user-2 的回复:我用vs2010试验了一下，是pow函数的返回值问题，好像为double的。強转一下即可。浮点型的乘法 和预期的不一致。 			x=(a[i]-'0')*((int)pow((double)10,n-i-1))+x; 按你这样做的话输出来的数值减少幅度更大了……

求解算法的错误在哪里


Question: c++编写的DLL出现一个warning

引用 1 楼 user-2 的回复:怎么觉得你在晒代码呢    dllimport 是调用者的声名方式 extern "C" _declspec(dllimport) int mytransfunc(char* exportpath,char* importpath);  改成 extern "C" _declspec(dllexport) int mytransfunc(char* exportpath,char* importpath);   最改好成头文件,并用 #define 来控制   大侠，您看看这么写对不对？

引用 3 楼 FightForProgrammer 的回复:see here http://blog.csdn.net/timmy_zhou/article/details/7284110  其实很多问题可以把信息放到搜索框。。。  这个我看了，不是没太明白么。。。

喵了一下....   // ... // ...     //初始化---获取适配器名单         if(PacketGetAdapterNames((PTSTR)AdapterNames ,&AdapterLength)==false)     {         printf("iiiiiiii");         return -1;     }       temp=AdapterNames;     temp1=AdapterNames;          // ...这段逻辑实在是.............     while((*temp!='\0')||(*(temp-1)!='\0'))// 这里的 *(temp - 1) != '\0'  是一个潜在的溢出问.有可能会导至系统抛 非法访问内存错误     {         if(*temp=='\0')         {             memcpy(AdapterList[j],temp1,(temp-temp1));//void *memcpy( void *dest, const void *src, size_t count )；dest-New buffer；src-Buffer to copy from；count-Number of characters to copy             temp1=temp+1;             j++;         }         temp++;     }  // ... // ...      sprintf (PB,"%s\\%s",importpath,B);     rep(PB,Str1,Str2);     FILE *fpopen = fopen(PA, "rb");   // =============>这里已经打了 PA ....     FILE *fpwr = fopen(PB, "wb");  // ... //  ...      header=&pheader;//链接确认的时候有改变header     for (int t = 0; t < 8; t++)                     {                       //FILE *fpopen = fopen("C:/Users/Frank/Documents/Visual Studio 2012/Projects/bin/regenerate_original_picture.txt", "rb");                     FILE *fpopen = fopen(PA, "rb");     // ==========> 这里继续  open....还在 for里面  //可能你这样做没有什么大问题。但逻辑上好混乱  // 还有  其中有  buf bufhead 等 malloc 出来都没有 free. // 看来楼主要好好查下，还有理一下逻辑


Question: C链表求助

仅供参考：//带表头结点的单向链表 #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-> //

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

一楼正解，段错误了。

对delete_Llist修改：  bool delete_Llist(Node *head, int data)//删除数据 { 	//查找待删除节点的前一个节点 	Node *q = head; 	while (q) 	{ 		if (q->next->data == data) break; 		q = q->next; 	} 	if (q == NULL) 	{ 		perror("The data empty!"); 		return false; 	} 	Node *p = q->next;   //p指向待删除节点 	q->next = p->next; 	free(p); 	return true; }

没人觉得Create_List(Node* head)有问题么？ Create_List(Node **head)才对吧

Node *p=NULL; p->next = q; p->next = q->next;   对NULL操作是什么心态。。。


Question: 用递归实现一元钱的兑换方案

int i=0,j=0,k=0;  void fun() { 	int sum = 0;   	sum = i + j*2 + k*5; 	if (sum == 10) 	{ 		printf("%d个1角，%d个2角，%d个5角。\r\n", i, j, k); 	}  	i ++; 	if (sum >= 10) 	{ 		if (i > 10) 		{ 			i = 0; 			j ++; 			if (j > 5) 			{ 				j = 0; 				k++; 				if (k > 2) 				{ 					return; 				} 			} 		} 	} 	 	fun();  }

引用 1 楼 focuslight 的回复:void func() { int i=0; int j=0; int k=0; if (i + j * 2 + k * 5 == 10)                 printf("%d个1毛，%d个2毛，%d个5毛\n", i, j, k); else     func(); }     不行啊     好像溢出了


Question: 字符串逆序输出的问题

如果是不考虑代码效率的话，你可以先用一个数组把字符串保存下来，当遇见（时就做个标记，当遇见）时就反转，这样子思路很简单。堆栈的思想。 当追求效率的时候，你可以去查阅ACM的一些题解，会有详细说明的。

引用 6 楼 u013163178 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 仅供参考：  int main(void)//40 { 	char str[] = "123(456(789)123(456)789)123"; 	cout << str << endl; 	stack<int> sta; 	int i = 0; 	while (true) 	{ 		if ('\0' == str[i]) break; 		if (sta.empty() || '(' == str[i]) sta.push(i); 		else if (')' == str[i]) 		{ 			reverse(str + sta.top() + 1, str + i); 			sta.pop(); 		} 		i++; 	} 	cout << str << endl;  	return 0; } //123(456(789)123(456)789)123 //123(987)456(321)789(654)123  如果这样呢 asd(sdfsdf(sdfd),你的右括号和哪一个匹配呢[/quote]  这样是非法输入！

我这个版本的bug很多，很多情况没考虑 #include <stack> #include <cstdio> #include <cstring> using namespace std;  void foo(char *str) { 	stack<char> st; 	int len = strlen(str);  	int state = -1; 	for(int i = 0 ; i < len ; ++i) 	{ 		switch(str[i]) 		{ 			case '(': 				state = 0; 				break; 			case ')': 				state = 1; 				break; 			default : 				if(state == 0) 				{ 					st.push(str[i]); 				} 				else if(state == 1) 				{ 				    putc('(' , stdout); 					while(!st.empty()) 					{ 						char top = st.top(); 						putc(top , stdout); 						st.pop(); 					} 					putc(')' , stdout); 					state = 2; 				} 				else 					putc(str[i] , stdout); 				break; 		} 	} }   int  main() { 	char buffer[256]; 	fgets(buffer , 256 , stdin); 	foo(buffer); 	return 0; }

引用 4 楼 zhangxiangDavaid 的回复:仅供参考：  int main(void)//40 { 	char str[] = "123(456(789)123(456)789)123"; 	cout << str << endl; 	stack<int> sta; 	int i = 0; 	while (true) 	{ 		if ('\0' == str[i]) break; 		if (sta.empty() || '(' == str[i]) sta.push(i); 		else if (')' == str[i]) 		{ 			reverse(str + sta.top() + 1, str + i); 			sta.pop(); 		} 		i++; 	} 	cout << str << endl;  	return 0; } //123(456(789)123(456)789)123 //123(987)456(321)789(654)123  如果这样呢 asd(sdfsdf(sdfd),你的右括号和哪一个匹配呢

逆序处理通常都放栈里， 多重处理的结果看题目要求了。

引用 4 楼 zhangxiangDavaid 的回复:仅供参考：  int main(void)//40 { 	char str[] = "123(456(789)123(456)789)123"; 	cout << str << endl; 	stack<int> sta; 	int i = 0; 	while (true) 	{ 		if ('\0' == str[i]) break; 		if (sta.empty() || '(' == str[i]) sta.push(i); 		else if (')' == str[i]) 		{ 			reverse(str + sta.top() + 1, str + i); 			sta.pop(); 		} 		i++; 	} 	cout << str << endl;  	return 0; } //123(456(789)123(456)789)123 //123(987)456(321)789(654)123   你的回答帮到我了，其实面试题是不用考虑括号嵌套。

弄个标记记号就行了吧

我想知道括号里套括号的怎么处理？比如： 123(456(789)123(456)789)123 是 123(456(789)123(456)789)123 还是 123(456(789)123(456)789)123


Question: 卡尔曼滤波C\C++语言程序

看一看，最近也开始做了

楼主你好，我现在也在学习EKF，想用在毫米波雷达目标跟踪中，希望能够交流一下。390028260谢谢

我也在做77G的毫米波雷达数据处理，Delphi ESR有时间交流一下，QQ：723616221

你需要www.opencv.org


Question: 请问这个问题怎么解决？求大神帮忙

这个就是模拟三维浓度场中的一部分，这个地方要的是A，这个A根本输不出来，我就是把运行了a的程序全都拿出来了，别的地方跟着地方没有关系。

问题不清楚，什么二维三维？ 程序也没输出


Question: 一个简单的c程序   上面的指针传参问题

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

恩。我试了一下，你的是对的。谢谢你！那如果我想用指针数组该咋办？

指针和数组：http://blog.csdn.net/zhangxiangdavaid/article/details/38085743

这不是函数传参的问题， 而是你把 结构体数组 定义为了 结构体指针数组，指针数组有另外的用法。 该3个地方 1：struct STU students[N]; 2：case 1:input(students);break; 3：case 2:output(students);break;


Question: 数据结构的一问题

解决了？解贴吧！

约瑟夫问题的多种求解： http://blog.csdn.net/zhangxiangdavaid/article/details/25109205

本人已经解决

用c实现、求解啊


Question: VS2013里面无法输出字符串，程序见内容

跟着提示输入，没有问题，当然，字符串不要太长。

name里有东西吗？ 读入可能有问题

1.程序编译完成后,进入dos目录执行程序就可以了 2.VS2013编辑器中显示信息使用TRACE函数


Question: 多目录Makefile的编写，请教大神，本人小白

参阅GNUmake

主目录：main.c  common network include                   common目录：common.c common.h                   network目录：socket.c socket.h                   include目录： define.h 简单的：   main: main.o common.o socket.o          cc -o main main.o common.o socket.o main.o:          cc -c main.c ./include/define.h common.o:          cc -c ./common/common.c ./common/.h socket.o:          cc -c ./socket/socket.c  ./socket/socket.h

主目录的makefile cd进各子目录，用make调用各子目录的makefile

如果仅仅解决一下问题的话，不用那么麻烦，建议楼主直接在linux图形界面下，用eclipse+cdt配置。自动生成makefile。 PS：最好还是学习一下makefile语法较好

搜“跟我一起写makefile”


Question: 如何用WinHex工具搜索特定字符串后定位到字符串存放的逻辑位置？

通读WinHex联机帮助。 如果还解决不了问题，搜WinHex相关博客文章。


Question: C语言求两个方位角，角度的平均值

引用 8 楼 memecaoyu 的回复:[quote=引用 3 楼 u014444402 的回复:] 这不就是向量的相加？？  却是是两个向量相加， 如果用向量的算法就比较复杂了 需要求Sin和Cos的和 然后arctan,然后判断象限[/quote]  归一化之后取平均值不行吗？

引用 3 楼 u014444402 的回复:这不就是向量的相加？？  却是是两个向量相加， 如果用向量的算法就比较复杂了 需要求Sin和Cos的和 然后arctan,然后判断象限

引用 2 楼 zhao4zhong1 的回复:个人意见，此例不应取平均值；而应取中值。  嗯，对，应该是去中间值

引用 1 楼 super_miker 的回复:为何用宏？内联函数感觉更好  //type为角度的类型 inline type avg(type a, type b){    type tmp = (a + b) / 2;    if ((a > b ? a - b : b - a) > 180)       if (tmp >= 180) tmp -= 180; else tmp += 180;    return tmp; }  顺便0跟180的平均值应该是多少？  内联确实要好很多，嵌入式系统里面用内联，感觉会受到编译器的限制 0和180度的平均应该是按照角度的变化趋势来看。 或者如果发生这么大的角度变化，这个数据应该设置成为不可信的数据

那请问0°与180°平均是90°还是270°？

这不就是向量的相加？？

个人意见，此例不应取平均值；而应取中值。

引用 4 楼 mewiteor 的回复:那请问0°与180°平均是90°还是270°？ 那请问北与南平均是东还是西？ 我觉得是上！