Question: hash表，请帮忙改进！！

现有一个问题请教： struct element__ i_element; Element element = &i_element; 这里为什么要这么做？ 如果简单的声明一个Element element;   /* ** file hash.h */ #ifndef HASH_H__ #define HASH_H__  #ifdef _cplusplus extern "C"{ #endif   typedef struct element__*     Element; typedef struct jhashtable__*  JHashTable;  typedef unsigned int (*hash_func)    (Element element, int capcity); typedef int          (*hash_compare) (Element element1, Element element2); typedef void         (*hash_insert)  (JHashTable hashtable, Element element); //typedef Element      (*hash_get)     (JHashTable hashtable, Element element); typedef void         (*hash_destory) (JHashTable hashtable);  typedef struct hash_method__  {     hash_func    hash;     hash_compare compare;     hash_insert  insert;     hash_destory destory; }Hash_method;   struct element__ {     void*             data;    ///<  兼容内置类型和复杂类型     struct element__* next; };  struct jhashtable__ {     int          capcity;     Element*     lists;     Hash_method  method;     };  /* **创建一个JHashTable，对于不同的类型，需不同的hash函数和compare函数，由用户自定义 */ JHashTable hash_create(int capcity, hash_compare compare, hash_func hash);  #ifdef _cplusplus } #endif  #endif /* ** file hash.c */ #include "hash.h" #include <stdio.h> #include <stdlib.h>  static unsigned int hash_capcity(unsigned int size)                                   {                                                                                const int primes[] =     {       11,       19,       37,       73,       109,       163,       251,       367,       557,       823,       1237,       1861,       2777,       4177,       6247,       9371,       14057,       21089,       31627,       47431,       71143,       106721,       160073,       240101,       360163,       540217,       810343,       1215497,       1823231,       2734867,       4102283,       6153409,       9230113,       13845163,       20767751,       31151639,       46727459,       70091201,       105136807,       157705213,       236557861,       354836813,       532255237,       798382861,       1197574073,       1796361143,       2000000011,     };     int i;     for(i = 0; primes[i] < 2000000000; i++)     {         if(primes[i] > size)         break;     }     return primes[i];    }   static void insert( JHashTable hashtable,Element element) {     Element current;     unsigned int index = hashtable->method.hash(element, hashtable->capcity);     {         current = (Element)malloc(sizeof(struct element__));         if(current)         {             current->data = element->data;             current->next = hashtable->lists[index];             hashtable->lists[index] = current;         }     } }  static void destory(JHashTable hashtable) {     int i;     for(i = 0;i<hashtable->capcity; i++)     {         Element element  = hashtable->lists[i];         Element temp;          while(element!= NULL)         {             temp = element->next;             free(element);             element= temp;         }     }     free(hashtable->lists);     free(hashtable); }  JHashTable hash_create(int capcity, hash_compare compare, hash_func hash) {     JHashTable hashtable;     int i = 0;     hashtable= (JHashTable)malloc(sizeof(struct jhashtable__));     if(hashtable)     {         hashtable->capcity = hash_capcity(capcity); ///<  计算表的容量         hashtable->lists = (Element*)malloc(sizeof(Element)*hashtable->capcity);  ///<  lists[capcity]         if(hashtable->lists)         {             for(i=0;i<hashtable->capcity;i++)             {                 hashtable->lists[i] = (Element)malloc(sizeof(struct element__));                 if(hashtable->lists[i])                 {                     hashtable->lists[i]->next = NULL;                     hashtable->lists[i]->data = 0;                 }             }         }              }     hashtable->method.compare = compare;     hashtable->method.hash = hash;     hashtable->method.insert = insert;     hashtable->method.destory = destory;     return hashtable; } /* ** file hash_test.c */ #include "hash.h" #include <stdio.h> #include <string.h>  static unsigned int RShash(char *str) {     unsigned int b = 378551;     unsigned int a = 63689;     unsigned int hash = 0;      while(*str)     {        hash = hash * a + (*str++);        a *= b;     }     return (hash & 0x7FFFFFFF); }  static unsigned int hash_int(Element element, int capcity) {     int p = (int)element->data;     return p%capcity; }  static int compare_int (Element element1, Element element2) {     int p1 = (int)element1->data;     int p2 = (int)element2->data;     return p1 - p2; }  static unsigned int hash_string(Element element, int capcity) {     char* p = (char*)element->data;     return RShash(p)%capcity; }  static int compare_string (Element element1, Element element2) {     char* p1 = (char*)element1->data;     char* p2 = (char*)element2->data;     return RShash(p1) - RShash(p2); } int main() {     JHashTable hashtable;     struct element__ i_element;     Element element = &i_element;     int i = 0;     printf("---------test int hash------------!!!!\n");     hashtable = hash_create(15, compare_int, hash_int);         int array[] = {19,14,23,01,68,20,84,27,55,11,10,79};     int len = sizeof(array)/sizeof(array[0]);             for(i=0;i<len;i++)     {         element->data = array[i];         hashtable->method.insert(hashtable, element);     }     for(i = 0; i < hashtable->capcity; i++)     {         element = hashtable->lists[i];         while(element)         {             printf("address=%d value = %d\n", i, element->data);             element= element->next;         }     }      printf("---------test string hash------------!!!!\n");     element = &i_element;     char* string[] = {"hello", "word", "china", "USA", "green"};     hashtable = hash_create(10, compare_string, hash_string);     len = sizeof(string)/sizeof(string[0]);     for(i = 0; i < len; i++)     {         element->data = string[i];         hashtable->method.insert(hashtable, element);     }     for(i = 0; i < hashtable->capcity; i++)     {         element = hashtable->lists[i];         while(element)         {             printf("address=%d value = %s\n", i, element->data);             element= element->next;         }     }      return 0; } /* **  结果如下： [root@gnos-x64-dev wx]# ./hash  ---------test int hash------------!!!! address=0 value = 19 address=0 value = 0 address=1 value = 20 address=1 value = 1 address=1 value = 0 address=2 value = 0 address=3 value = 79 address=3 value = 0 address=4 value = 23 address=4 value = 0 address=5 value = 0 address=6 value = 0 address=7 value = 0 address=8 value = 27 address=8 value = 84 address=8 value = 0 address=9 value = 0 address=10 value = 10 address=10 value = 0 address=11 value = 11 address=11 value = 68 address=11 value = 0 address=12 value = 0 address=13 value = 0 address=14 value = 14 address=14 value = 0 address=15 value = 0 address=16 value = 0 address=17 value = 55 address=17 value = 0 address=18 value = 0 ---------test string hash------------!!!! 5 address=0 value = green address=0 value = (null) address=1 value = USA address=1 value = word address=1 value = (null) address=2 value = hello address=2 value = (null) address=3 value = (null) address=4 value = (null) address=5 value = (null) address=6 value = (null) address=7 value = china address=7 value = (null) address=8 value = (null) address=9 value = (null) address=10 value = (null) */

引用 5 楼 u012889234 的回复:[quote=引用 4 楼 neustar1 的回复:] 如果不想用模板的话，最好定义一个接口，譬如 class IHashable { public: int Hash(JHashTable* pHashTable);//计算其哈希值 } 然后void*指针指向IHashable，就可以兼容复杂类型了，至于基本类型的话，建议另外定义一个共用体成员来保存。  我定义的 struct node__ {    void*   data;    struct node__* next; }; 这里的data就是void* 类型的，在这里兼容类型不可以吗？？[/quote] 不好意思，如果是c的话，就不能用模板了。。。 你这里void也可以兼容基本类型，但是你要用一个变量区分一下基本类型和复杂类型。

引用 4 楼 neustar1 的回复:如果不想用模板的话，最好定义一个接口，譬如 class IHashable { public: int Hash(JHashTable* pHashTable);//计算其哈希值 } 然后void*指针指向IHashable，就可以兼容复杂类型了，至于基本类型的话，建议另外定义一个共用体成员来保存。  我定义的 struct node__ {    void*   data;    struct node__* next; }; 这里的data就是void* 类型的，在这里兼容类型不可以吗？？

引用 2 楼 neustar1 的回复:[quote=引用 1 楼 u012889234 的回复:] 来者都给分！！！！ 可以考虑使用模板[/quote] c 语言怎么设计模板的？？请指教！！

引用 1 楼 u012889234 的回复:来者都给分！！！！ 可以考虑使用模板

来者都给分！！！！


Question: 求一道算法题，c语言

填充法？一层一层往里面填 一直填到外围最小的层数为止，看看填了多少数

最外围的扩容，里面的是填充，用最大的数组成外围，其余的填充里面的的空间 设数组维度为M*N ， 组成外围的2*（M+N-2）中最小的数为 H ，其余的小数字之和为 S 所以，储水量为： V（M,N） = H*（M-2）*（N-2） - S

哎 不对 不能这么做

最小值 + 1 直到 漏水  +了多少次 1 就是能保留多少单位的水

楼主又来了，这道题不简单啊


Question: 关于PeekMessage

PM_NOREMOVE：PeekMessage处理后，消息不从队列里除掉。      PM_REMOVE：PeekMessage处理后，消息从队列里除掉。


Question: 标准输出重定向问题

1. 要检查函数的返回值 2.使用write而不是printf #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <string.h>  int main(void) {   int fd = open("log.txt",O_CREAT|O_RDWR),outfd;   if(fd == -1)   {     perror("");   }   outfd = dup(STDOUT_FILENO);   int fd2 = dup2(fd,STDOUT_FILENO);   if(-1 == fd2)   {     perror("");   }   write(STDOUT_FILENO, "Hello world!\n",13);   //printf("Hello world!\n");   fd2 = dup2(outfd,STDOUT_FILENO);   if(-1 == fd2)   {     perror("");   }   write(STDOUT_FILENO, "Freopen STDOUT_FILENO!\n", strlen("Freopen STDOUT_FILENO!\n"));   //printf("Freopen STDOUT_FILENO!\n");   return 0; }

在每个最后不带\n的printf后面加fflush(stdout);

printf函数会使用stdout这个FILE指针。把而FILE结构里面有一个成员指向了输出文件描述符，把这个输出文件描述符修改就可以完成printf的重定向了。及时fflush也是很重要的。  引用 2 楼 luotuo44 的回复: int main() {     int fd;     fd = open("log.txt", O_CREAT|O_RDWR);     fileno(stdout) = fd;     printf("Hello world!\n");     fflush(stdout);       fileno(stdout) = STDOUT_FILENO;     printf("Freopen STDOUT_FILENO!\n");      return 0; }

首先楼主你的标题是重定向，可是内容却没有一点关于重定向的，重定向是用freopen高数的， 是freopen(“文件名”，“w",stdout);可以重定向。但是你又不是全部的把printf写到文件里，所以你不用重定向，用文件就能做做到 FILE *f if(f=fopen("data.txt","w")==NULL)     printf("文件没打开”)； 然后就能写到文件里了


Question: 99乘法表 指针和数组问题

char * [9][9] 就是9 * 9个char

引用 1 楼 uuuououlcz 的回复: typedef void (*pFun)(char* arr[9][9]); void dojob(pFun f, char* arr[9][9]) {     f(arr); } void init(char* arr[9][9]) {     int i, j;     for(i = 0; i < 9; ++i){         for(j = 0; j < 9; ++j){             arr[i][j] = (char*)malloc(7);             sprintf(arr[i][j], "%d*%d=%d", i+1, j+1, (i+1)*(j+1));         }     } } void print(char* arr[9][9]) {     int i, j;     for(i = 0; i < 9; ++i){         for(j = 0; j < 9; ++j) puts(arr[i][j]);     } } void clear(char* arr[9][9]) {     int i, j;     for(i = 0; i < 9; ++i){         for(j = 0; j < 9; ++j) free(arr[i][j]);     } }   2楼的朋友讲下char* [9][9]是怎么理解的呢

for i in range(1,10)     for j in range(1,i+1)         print "%d*%d=%d " %(i,j,i*j),     print

大家都很给力，那么我要结贴了，谢谢大家踊跃的解决问题~

错了，是一楼

/* 基于二楼的三角版 */ #include <stdio.h> #include <stdlib.h> #include <string.h>  typedef void (*pFun)(char* a[][9]); void dojob(pFun f, char* a[][9]) {     f(a); }  void init(char* a[][9]) {     int i, j;     for(i = 0; i < 9; ++i){         for(j = 0; j <= i; ++j){             a[i][j] = (char*)malloc(8);             sprintf(a[i][j], "%d*%d=%d", i+1, j+1, (i+1)*(j+1));         }     } } void print(char* a[][9]) {     int i, j;     for(i = 0; i < 9; ++i){         for(j = 0; j <=i; ++j){ 			if(j>1) printf(" "); 			printf("%-6s",a[i][j]); 		} 		printf("\n");     } } void clear(char* a[][9]) {     int i, j;     for(i = 0; i < 9; ++i){         for(j = 0; j <=i ; ++j) free(a[i][j]);     } }  int main(void) {  	char * c[9][9]; 	 	dojob(init, c); 	dojob(print,c); 	dojob(clear,c); 	 	return 0; }


Question: while中表达式的定义

X86上，32Bits Windows 操作系统下，MS VC6，7，8，9，10.。。etc long double 是 64Bits

80 Bits 浮点数一位符号，15位指数，64位尾数 所以可以表示的数最大的正数到最小正数，大约是 2^ (2^14)-1 ~ 2^ (-(2^14 +64-1))  2^14 =16384   18384* lg(2) = 16453* 0.3010 = 4931.584 2^(- 16384 +64 -1) =2^-16453 16453* lg(2) = 16453* 0.3010 = 4952.35  10^ 4931.584 ~10^- 4952.35 省略小数部分 即10^ 4931 ~10^- 4952 10 大约 除以 4952次10 以后，等于0.000000000000000 即正0  X86上，32Bits Windows 操作系统下，有些系统long double 是 80Bits（BCB，minGw），有些是64Bits（MS） X86上，32Bits Windows 操作系统下，minGw 的long double是 12字节的，80Bits浮点数，其中前两个字节恒为0；

来自你的num定义的long double格式的最小表示数值的10的幂次数绝对值。

为什么 num循环的第一个输出值 为0.000000  而不是1.000000

n没有初始化，得到多少都有可能

我用gcc上编译的时候，n被默认赋值为0了，这个是我没有留意，那么可以将int n = 0；，关于这个我主要是想知道在长精度浮点型的情况下，while中的条件表达式是如何等于0而停止循环的？

1. n没有初始化，结果多少都有可能 2. double的指数范围-1023 ~1024, 2^-1023约等于10^-308 所以循环大约会执行309次

引用 3 楼 Falleyes 的回复:楼主的程序在vs2013上忽略错误，运行：  未赋值的n初始赋值-858993460。  这个赋值要看编译器。 确实楼主的n没有赋初值，呵呵。

while(num);//用以下汇编翻译，楼主可以参考下 00412043  fldz              00412045  fcomp       qword ptr [num]  00412048  fnstsw      ax    0041204A  test        ah,44h  0041204D  jp          main+2Eh (41200Eh)

常量也有类型！ C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value  C++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );


Question: C读取 文本文件 没有问题，除文本文件之外的文件就有问题

引用 13 楼 zhao4zhong1 的回复:不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  不加白不加！ 引用 13 楼 zhao4zhong1 的回复:不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  不加白不加！ 引用 13 楼 zhao4zhong1 的回复:不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  不加白不加！  能用fread()读取整个文件么？   while ( fread(buffer,NUMB,1,stream) != NULL) 	{ 		 		 printf("%s\n", buffer);  为什么我这么写，这能读取到一点东西啦。也是结束符的问题？

引用 11 楼 zhao4zhong1 的回复:#include <stdio.h> #include <string.h> FILE *stream; int const NUMB = 1024 * 63; char buffer[NUMB] = {0}; char filePath[256]; int r,a; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main() {     strcpy(filePath,"c:\\windows\\system32\\msimg32.dll");     stream=fopen(filePath,"rb");     if (NULL==stream) {         printf("Can not open file %s!\n",filePath);         return 1;     }     a=0;     while (1) {         r=fread(buffer,1,NUMB,stream);         HexDump(buffer,r,a);         a+=r;         if (r<NUMB) break;     }     fclose(stream);     return 0; }   感谢赵老师，fgets() 函数不能用于二进制文件，fgets函数用于二进制文件的时候会自动转码。转完之后可能就发生变化了。可能会遇到意想不到的问题，比如我这里的提前结束。

引用 6 楼 user-2 的回复:文本文件是最简单的，每个二进制字节直接按ASCII码表对应一个字符，所以有fgets等等字符串相关函数自动替你处理 其他格式的文件，必须自己按照该文件格式的定义处理每一个二进制字节——当然，如果是比较通用的格式，可以找到相应的处理模块不必自己从头写，例如处理word文件就可以直接使用微软放在word软件里的模块 但是根本上，作为一个程序员，你就不该有“任何问题都可以找几条语句直接搞定”的想法，一门语言应该提供给你的都是最基本的操作，任何稍微复杂一点的问题都需要你自己动脑子将这些基本操作组合成你需要的解决方法，如果你能找到一些比较简单的处理方法，那是因为别人替你做了大部分工作，不代表这大部分工作就不存在

引用 7 楼 zhao4zhong1 的回复:推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 正在看，好像没什么用！

引用 4 楼 zhao4zhong1 的回复:对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A  In Visual C++ 2005, fopen supports Unicode file streams. A flag specifying the desired encoding may be passed to fopen when opening a new file or overwriting an existing file, like this:  fopen("newfile.txt", "rw, ccs=<encoding>");  Allowed values of the encoding include UNICODE, UTF-8, and UTF16-LE. If the file is already in existence and is opened for reading or appending, the Byte Order Mark (BOM) is used to determine the correct encoding. It is not necessary to specify the encoding with a flag. In fact, the flag will be ignored if it conflicts with the type of the file as indicated by the BOM. The flag is only used when no BOM is present or if the file is a new file. The following table summarizes the modes used in for various flags given to fopen and Byte Order Marks used in the file.  Encodings Used Based on Flag and BOM Flag  No BOM (or new file)  BOM: UTF-8  BOM: UTF-16   UNICODE  ANSI  UTF-8  UTF-16LE   UTF-8  UTF-8  UTF-8  UTF-16LE   UTF-16LE  UTF-16LE  UTF-8  UTF-16LE  还是不行。

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

引用 4 楼 zhao4zhong1 的回复:对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A  In Visual C++ 2005, fopen supports Unicode file streams. A flag specifying the desired encoding may be passed to fopen when opening a new file or overwriting an existing file, like this:  fopen("newfile.txt", "rw, ccs=<encoding>");  Allowed values of the encoding include UNICODE, UTF-8, and UTF16-LE. If the file is already in existence and is opened for reading or appending, the Byte Order Mark (BOM) is used to determine the correct encoding. It is not necessary to specify the encoding with a flag. In fact, the flag will be ignored if it conflicts with the type of the file as indicated by the BOM. The flag is only used when no BOM is present or if the file is a new file. The following table summarizes the modes used in for various flags given to fopen and Byte Order Marks used in the file.  Encodings Used Based on Flag and BOM Flag  No BOM (or new file)  BOM: UTF-8  BOM: UTF-16   UNICODE  ANSI  UTF-8  UTF-16LE   UTF-8  UTF-8  UTF-8  UTF-16LE   UTF-16LE  UTF-16LE  UTF-8  UTF-16LE 确实提前结束了。

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

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

fread Reads data from a stream.  size_t fread( void *buffer, size_t size, size_t count, FILE *stream );  Function Required Header Compatibility  fread <stdio.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Use the feof or ferror function to distinguish a read error from an end-of-file condition. If size or count is 0, fread returns 0 and the buffer contents are unchanged.  Parameters  buffer  Storage location for data  size  Item size in bytes  count  Maximum number of items to be read  stream  Pointer to FILE structure  Remarks  The fread function reads up to count items of size bytes from the input stream and stores them in buffer. The file pointer associated with stream (if there is one) is increased by the number of bytes actually read. If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters. The replacement has no effect on the file pointer or the return value. The file-pointer position is indeterminate if an error occurs. The value of a partially read item cannot be determined.  Example  /* FREAD.C: This program opens a file named FREAD.OUT and  * writes 25 characters to the file. It then tries to open  * FREAD.OUT and read in 25 characters. If the attempt succeeds,  * the program displays the number of actual items read.  */  #include <stdio.h>  void main( void ) {    FILE *stream;    char list[30];    int  i, numread, numwritten;     /* Open file in text mode: */    if( (stream = fopen( "fread.out", "w+t" )) != NULL )    {       for ( i = 0; i < 25; i++ )          list[i] = (char)('z' - i);       /* Write 25 characters to stream */       numwritten = fwrite( list, sizeof( char ), 25, stream );       printf( "Wrote %d items\n", numwritten );       fclose( stream );     }    else       printf( "Problem opening the file\n" );     if( (stream = fopen( "fread.out", "r+t" )) != NULL )    {       /* Attempt to read in 25 characters */       numread = fread( list, sizeof( char ), 25, stream );       printf( "Number of items read = %d\n", numread );       printf( "Contents of buffer = %.25s\n", list );       fclose( stream );    }    else       printf( "File could not be opened\n" ); }   Output  Wrote 25 items Number of items read = 25 Contents of buffer = zyxwvutsrqponmlkjihgfedcb   Stream I/O Routines  See Also   fwrite, _read


Question: 短小精悍，不知问题在哪儿，路过的大神进来看看，拜托！万分感谢

while(a>0) {k=t%10;t=t/10;s=k+s*10;} 循环里完全没有改变a的值，也就是判断条件永远不变，一旦进去就出不来了

两个while会结束吗？

怎么没人呢？求大神路过哈


Question: socket recv 无长度域如果检测数据是否收完？

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

最好做一个协议，附加上长度

tcp是流， 需要自己提取消息。 无长度域，则需要消息分割符，没有其他选择。

早期的方式是这样:先发送4字节的数据(header),说明后续的发送长度,然后是指定长度的data 需要你自己定义结构 struct data_s {    int32 length;    unsigned char data[1]; };

引用 3 楼 bravery36 的回复:tcp是流传输，所以不会有“收完”的情况，只能在应用层定义长度，比如说定义定长包头，包头带长度。 难道必须加长度头么？这个也是设计的时候没考虑，现在要加有点麻烦。。。

引用 2 楼 thefirstz 的回复:recv返回的时候，如果出错，判断下errno的值 errno是该加上，但是貌似解决不了问题。。  我现在主要判断不了是否收完数据了

假设我是程序，你不告诉我哪里结束，我就会一直读，直到错误。

recv返回的时候，如果出错，判断下errno的值

int RecvDataFromHost(int nSockfd, char *pRecvData, int *nRecvDataLen,int iTimeOut) {     int rlen = 0, ret, len = 0; #ifdef RACAL 	int iLengthHeader = 2; #else 	int iLengthHeader = 0; #endif     int nLenSize = 0;       fd_set r_fds;     struct timeval tv;       if(pRecvData == NULL)         return -1;      if(nSockfd <= 0) 	return -2;      FD_ZERO(&r_fds);     FD_SET((u_int)nSockfd, &r_fds);      if(iTimeOut > 0) {          tv.tv_sec = iTimeOut;         tv.tv_usec = 0;          ret = select(nSockfd + 1, &r_fds, NULL, NULL, &tv);         if (ret <= 0 || !FD_ISSET(nSockfd, &r_fds))             return -3;      } else {         ret = select(nSockfd + 1, &r_fds, NULL, NULL, NULL);//block         if (ret <= 0 || !FD_ISSET(nSockfd, &r_fds))             return -4;     }  	if (0 == iLengthHeader) 	{ 		do 		{ 			ret = recv(nSockfd, &pRecvData[rlen], 4096, 0);  			if (ret <= 0) 				return -5;  			rlen += ret;  		} while(0 != ret);//循环是我后加上去的，但是如果这样的话，会阻塞回去，单次收包又收不全数据。 	} 	else if (2 == iLengthHeader) 	{ 		int iRecvDataLen = -1; 		ret = recv(nSockfd, &pRecvData[rlen], 2, 0); 		if (ret <= 0) 			return -5; 		iRecvDataLen = (unsigned char)pRecvData[0]; 		iRecvDataLen = iRecvDataLen << 8 | (unsigned char)pRecvData[1]; 		rlen += ret;  		do{ 			ret = recv(nSockfd, &pRecvData[rlen], 1024, 0); 			if (ret <= 0) 				return -5;  			rlen += ret; 			iRecvDataLen -= ret; 		} while(iRecvDataLen > 0); 	}      if((len + nLenSize) > SECBUF_MAX_SIZE)         return -6;          *nRecvDataLen = rlen;      return 0; }


Question: 大家帮忙看看，矩阵输出最大元素，无法实现啊！！

也可以这样做  #include <stdio.h> int max_value(int *a, int n) {     int max = *a;     int *p;     for (p = a + 1; p < a + n; p++)         if (*p > max) max = *p;                 return max;  } int main() {     int a[3][4] = { { 1, 3, 61, 7 }, { 2, 4, 6, 8 }, { 15, 17, 12, 3 } };    //1)整个数组当作一维数组计算，只能适应内置的二维数组表示的    //或者动态模拟二维数组存储方式，表示的矩阵。     printf("Max value is %d\n", max_value(a[0],3 * 4));    //2) 逐个一维数组计算，可以适应任何方式，用若干一维数组，表示的矩阵。    //包括二维数组，因为多维数组，是数组得数组     {       int max =  max_value(a[0],4);       int cur_max;        for(int i=0;i<3;i++)      {          cur_max = max_value(a[i],4);          if(max >cur_max) max = cur_max;        }       printf("Max value is %d\n", max);    ｝     return 0; }

给a赋值是这样的... int a[3][4] = { { 1, 3, 61, 7 }, { 2, 4, 6, 8 }, { 15, 17, 12, 3 } };  #include <stdio.h> int max_value(int array[4][4]) { 	int i, j, max; 	max = array[0][0]; 	for (i = 0; i < 3; i++) 	for (j = 0; j < 4; j++) 	if (array[i][j]>max) max = array[i][j]; 	return max; } int main() { 	int a[3][4] = { { 1, 3, 61, 7 }, { 2, 4, 6, 8 }, { 15, 17, 12, 3 } }; 	printf("Max value is %d\n", max_value(a)); 	return 0; }

引用 楼主 u013761183 的回复: 看到这样的代码，就蛋疼，为什么要用向量数组啊，写起来也累。 int max_value(int* pArray, int row, int col) { int max=pArray[0]; for(int i=0; i<row; ++i) {     for(int j=0; j<col; ++j)     {       if(pArray[i*col+j]>max)max=pArray[i*col+j];     } } return max; }

没什么问题，把函数声明前置下。

输出的是61，不是最大元素吗？

引用 2 楼 u011393042 的回复:说错了，我照你的打了一遍，没问题啊！！可是输出的不是最大元素啊。。。

说错了，我照你的打了一遍，没问题啊！！

自定义函数声明是在main函数外边的吧。。。。你写错地方了


Question: 合并线性表

引用 23 楼 u012514377 的回复:这个样子的逆置和输出是不是就是带头结点的类型？ 这个样子是了  不过，这是C++语言（用到引用）写的C链表（1.没有分开链表和节点的概念,2.没有用到类）  而且，不是标准形式（C标准的链表,会把 链表 typedef 为指针,一般数据结构的书上，都是这么做的）  不知道该OJ的标准是啥，刷题的时候，最好看看OJ，有何标准。  不同平台的标准，可能不一样，C,C++代码要求可能不一样。 其他，可能包括代码的时间复杂度（很多算法题在3S以内），和空间复杂度要求等等。

恩 已经AC了，  题目要求的是实现不带头结点的链表→_→，但是题目没有说，TMD····   void printlist_single(list *&L)//has been done { 	list *p; 	p=L; 	while(p->next!=NULL) 	{ 		p=p->next; 		printf("%d",p->D); 		if(p->next==NULL) 			printf(" "); 	} }  void mergelist(list *&L,list *&Q,list *&head) { 	init_single(head); 	list *p,*q; 	p=L->next; 	q=Q->next; 	while(p!=NULL || q!=NULL) 	{ 		if(p->D>=q->D) 		{ 			head->next=p; 			p=p->next; 		} 		else if(p->D<q->D) 		{ 			head->next=q; 			q=q->next; 		} 		head=head->next; 	} 	while(p!=NULL) 	{ 		head->next=p; 		p=p->next; 		head=head->next; 	} 	while(q!=NULL) 	{ 		head->next=q; 		q=q->next; 		head=head->next; 	} 	head->next=NULL;  }     我就不另开贴了~~~~  还是那个合并线性表，  在有头结点的实现情况下，  这样写问题出在哪里了咩？

这个样子的逆置和输出是不是就是带头结点的类型？

void init_single(list *&L)//has been done { 	L=(list*)malloc(sizeof(list)); 	L->next=NULL; }  void creatlist_single(list *&L,int n)//has been done { 	list *s,*r; 	init_single(L); 	r=L; 	int i=1; 	while(i<=n) 	{ 		s=(list*)malloc(sizeof(list)); 		if(scanf("%c",&s->D) && (s->D!=' ')) 		{ 			r->next=s; 			r=r->next;//use plus to position to position 			i++; 		} 		else 			free(s); 	} 	r->next=NULL; }  void printlist_single(list *&L)//has been done { 	list *p; 	p=L; 	while(p->next!=NULL) 	{ 		p=p->next; 		printf("%c",p->D); 		if(p->next!=NULL) 			printf(" "); 	} }  list* reverseList(list *&L)   {   	list *p1,*p2; 	if(L==NULL || L->next==NULL) 		return L; 	p1=L->next; 	L->next=NULL; 	while(p1!=NULL) 	{ 		p2=p1;; 		p1=p1->next; 		p2->next=L->next; 		L->next=p2; 	} 	return L; }         咳 改成这样了，可是OJ还是没过，OJ上没说要不要有头结点

void printlist_single(list *&L)//has been done { 	list *p; 	p=L; 	while(p->next!=NULL) 	{ 		printf("%c",p->D); 		p=p->next; 		if(p->next!=NULL) 			printf(" "); 	} }  list* reverseList(list *&L)   {   	list *p1,*p2,*p3; 	if(L==NULL || L->next==NULL) 		return L; 	p1=L; 	p2=L->next; 	while(p2!=NULL) 	{ 		p3=p2->next;//存后一个节点 		p2->next=p1;//翻转 		p1=p2;//p1记录当前节点 		p2=p3;//p2向后一个位置 	} 	L->next=NULL; 	L=p1; 	return L; }         带空节点的输出函数是怎么样的？请问我这样改可以不？

有点混乱，init里看到是带空头节点，print和reverse却是不带。貌似把接口重新改写定好来，除了init，free传引用，其它参数最好是不用引用，避免误操作，合并嘛2个参数就好，和并到第一个表里...

1)void mergelist(list *&L,list *&Q,list *head) 合并链表的参数错误,写成这样才行 void mergelist(const list *L,const list *Q,list *&Dst) 2)你这个反转链表和创建操作不符合,  创建的是带空的头节点的链表, 原因是init_single创建了空的头节点  反转的时候,当成了不带空的头节点的链表反转  输出,也是按照,不带空的头节点的链表输出的  结果是,你自己的程序调试的时候,结果是正确的. OJ 测试的时候,不正确. 原因是,算法错误. 这是我个人的看法  PS: 带空的头节点的链表,输出的时候,不需要输出头结点 OJ测试算法的时候,不是用你的输出算法,所以你自己测试貌似正确,OJ测试错误  ----你自己输出了,不需要输出的头结点, OJ测试的时候,不会输出头结点,因为这个节点,不存储数据. 所以你的程序中,输出的头结点数据,是错误的数据,不是链表的第一个数据. 原因是,你没有正确实现,反转算法  先看清楚,OJ要求实现的, 是带空的头节点的链表, 还是带空的头节点的链表, 再写代码

na  引用 9 楼 lm_whales 的回复:基本上还是可以的,不过对单链表本身的类型,了解的不是很好  混淆了带空的头节点的链表,和不带空的头节点的链表. 这两种链表的数据是一样的,不同的是有没有,多加一个空的(无数据的)节点.  不过你这里,企图通过修改输出函数,   而不是数据结构的核心算法,来达到结果正确的方式,是不应该出现的. 需要做正确的,是数据结构的算法,  包括建表,插入,删除,销毁,查找,以及反转. 可能的话,还包括遍历.  输出链表,其实就是一种遍历算法,哪有不输出最后一个数据的..  一般顺序表(包括各种链表),不讲遍历,因为比较简单. 树等比较复杂的数据结构,才考虑遍历算法.  那个是因为这个朋友说我第一个节点是空节点，不用翻转，所以把它跳过去了！  实际运行也是木有问题的！

L=L->next;头结点丢失

void printlist_single(list *&L)//has been done {     list *p;     p=L;     while(p!=NULL)     {         printf("%c",p->D);         p=p->next;         if(p!=NULL)             printf(" ");     } }   Printlist原来是这样的，提交也不对，我就改成L，还是不对。 我觉得所有的节点都连上了，实际上自己VC上的输出也是对的，  可是OJ判断上 YOUR OUTPUT 少输出了翻转后第一个节点的内容，  我十分不解呐！！！

1) #14  printlist_single 错误,输出结束后,所有节点丢失,因为传递的是指针引用,可以修改指针参数的值  2)合并算法,   大有这么几种,   2.1)排序,非破坏合并,目标跟源不同;   这种就是创建新的链表,所有两个链表中的数据,按大小先后插入新的链表   方法是比较两个链表,当前结点的数据大小,大(或者小)的数据插入新链表(需要分配内存),然后继续...   2.2)排序,破坏合并,目标跟源不同      方法同上,每次比较两个链表,头结点的数据大小,大(或者小)的节点插入新链表,不用分配内存    2.3)不用排序,非破坏合并,目标跟源不同,合并只是复制数据.;      依次复制两个链表的数据直接插入新的链表   2.4)不用排序,破坏合并,目标跟一个源相同,两个合并成一个,所有节点合并到一起,另一个成为空链表.      两个链表首尾相接成一个链表   2.5)不用排序,非破坏合并(半破坏),目标跟一个源相同,合并只是复制数据.       直接在尾部插入另一个链表的数据

void creatlist_single(list *&L,int n)//has been done { 	list *s,*r; 	init_single(L); 	r=L; 	int i=1; 	while(i<=n) 	{ 		s=(list*)malloc(sizeof(list)); 		if(scanf("%c",&s->D) && (s->D!=' ')) 		{ 			r->next=s; 			r=r->next;//use plus to position to position 			i++; 		} 		else 			free(s); 	} 	r->next=NULL; }  void printlist_single(list *&L)//has been done { 	while(L!=NULL) 	{ 		printf("%c",L->D); 		L=L->next; 		if(L!=NULL) 			printf(" "); 	} }  list* reverseList(list *&L)   {       //让p1和p2都指向第一个结点       list *p1=NULL;       list *p2=NULL; 	L=L->next;     while(L!=NULL) //p1存后一个节点，p2存当前节点      {           p1=L->next;//存后一个节点         L->next=p2;//后一个节点指向前一个节点         p2=L;//p2作为表头 依次储存L         L=p1;//L向后遍历一个节点     }       return p2; }     根据楼上的楼上的建议，我改成这样了，感觉节点接上了啊，自己输出的时候也没错，可是还是不行啊，另外 不是最后一个节点没有输出，是第一个节点没输出，我自己VC上是对的。  OJ给的提示是：  INPUT 10 1 2 3 4 5 6 7 8 9 a  YOUR OUTPUT 9 8 7 6 5 4 3 2 1 OUR INPUT a 9 8 7 6 5 4 3 2 1  可是我自己VC上是对的！！！

合并不需要排序，就取上一个元素下一个元素这样反复取啊，但是为什么ABAB这样也不行捏？

你合并的时候怎么没有考虑head所指节点数值的大小啊，怎么能ABAB这样呢，有可能是ABBA什么的。。

您说的是第二个吧？我懂了，但是第一个合并线性表的问题出在哪里啊？

1)printlist_single 错误,少输出一个节点. 2)reverselist 错误,你这个创建的是,带空头节点的链表. 所以头节点不用翻转.

怒顶！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！

还是不太懂，可以说一下我的代码为什么运行不成的原因不？  我是愣没看出来QAQ


Question: 关于共享内存的疑问

引用 10 楼 mrlgy 的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 u011339091 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 参考 Microsoft SDK\samples\winbase\SharedMem\Consumer.Cpp Microsoft SDK\samples\winbase\SharedMem\Makefile Microsoft SDK\samples\winbase\SharedMem\Producer.Cpp Microsoft SDK\samples\winbase\SharedMem\Queue.h Microsoft SDK\samples\winbase\SharedMem\ReadMe.Txt Microsoft SDK\samples\winbase\SharedMem\Common.h 这个在哪里有源码？[/quote] 搜索下载Microsoft SDK[/quote] 哪一个版本的sdk[/quote] 我一般不提版本，就默认6.0

引用 9 楼 zhao4zhong1 的回复:[quote=引用 7 楼 u011339091 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 参考 Microsoft SDK\samples\winbase\SharedMem\Consumer.Cpp Microsoft SDK\samples\winbase\SharedMem\Makefile Microsoft SDK\samples\winbase\SharedMem\Producer.Cpp Microsoft SDK\samples\winbase\SharedMem\Queue.h Microsoft SDK\samples\winbase\SharedMem\ReadMe.Txt Microsoft SDK\samples\winbase\SharedMem\Common.h 这个在哪里有源码？[/quote] 搜索下载Microsoft SDK[/quote] 哪一个版本的sdk

引用 7 楼 u011339091 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 参考 Microsoft SDK\samples\winbase\SharedMem\Consumer.Cpp Microsoft SDK\samples\winbase\SharedMem\Makefile Microsoft SDK\samples\winbase\SharedMem\Producer.Cpp Microsoft SDK\samples\winbase\SharedMem\Queue.h Microsoft SDK\samples\winbase\SharedMem\ReadMe.Txt Microsoft SDK\samples\winbase\SharedMem\Common.h 这个在哪里有源码？[/quote] 搜索下载Microsoft SDK

创建一个共享名的事件event或者Mutex,然后每个进程进去前都等待这个event或mutex, 访问完成后再释放这个event或mutex. 这是最简单的。  如果考虑读写锁的话，那么麻烦点。 下面这篇文章读写锁考虑的比较齐全，可以参考下。 http://blog.csdn.net/querw/article/details/7214925

引用 6 楼 zhao4zhong1 的回复:参考 Microsoft SDK\samples\winbase\SharedMem\Consumer.Cpp Microsoft SDK\samples\winbase\SharedMem\Makefile Microsoft SDK\samples\winbase\SharedMem\Producer.Cpp Microsoft SDK\samples\winbase\SharedMem\Queue.h Microsoft SDK\samples\winbase\SharedMem\ReadMe.Txt Microsoft SDK\samples\winbase\SharedMem\Common.h 这个在哪里有源码？

不介意脏读就无所谓，否则就要同步。

如果不考虑锁，而采用多个共享内存块的方式呢？ 效率会不会比较低下？ 在操作的时候，先查询共享内存块的序列，如果正在使用，则继续查找下一个。

还有传说中的共享锁，就是用来解决读多写少的锁保护的效率问题

只要保证所有线程都只读不写，就不需要保护了

所有访问共享内存的任务都要考虑，所有访问都要用锁保护，才能避免数据的不一致。  至于有人说读不需要保护，写需要保护，你看看就行了，不要当真。只有极其特殊的情况下，读才不需要考虑。

这是一个时间差的问题，如果时间差非常小，或者处理特殊，这种情况是会发生的。  所以，用一个全局锁来保护是很有必要的。


Question: window 驱动开放 按esc 建 可以闪烁 num lock 的灯

键盘过滤　 写这样个驱动可以


Question: 请问C/C++里面有什么类库可以绘画可拉伸的矩形、多边形？

直接用鼠标事件来update绘制区域也可以实现的。

引用 9 楼 qimo601 的回复:[quote=引用 8 楼 y_gemini 的回复:] 直接用鼠标事件来update绘制区域也可以实现的。  自己实现绘制 矩形，三角形等形状都不是太难。。。 关键每个形状的后期的变化，还得自己实现啊，挺繁琐的。 比如选中的时候，四周出现可变指示框。如下图： [/quote]  我的博客和资源里都有介绍。我的Wavesoft截屏里，还可以调节这些方形柄的大小 自己重绘是最简单的。 知道了框坐标之后，就可以绘制了，很简单的线性几何。

这些也是一样的哈，重载一个类，鼠标点击后，绘制周围的可拉伸点 画这些不难，关键在于管理各种事件 和 管理多个形状的效果展示。 过这么久了，你应该已经解决了吧

引用 8 楼 y_gemini 的回复:直接用鼠标事件来update绘制区域也可以实现的。  自己实现绘制 矩形，三角形等形状都不是太难。。。 关键每个形状的后期的变化，还得自己实现啊，挺繁琐的。 比如选中的时候，四周出现可变指示框。如下图：

引用 5 楼 qimo601 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 应用于 Shape 和 ShapeRange 对象的 Type 属性。  返回或设置图形类型。MsoShapeType 类型，只读。  MsoShapeType 可为以下 MsoShapeType 常量之一。  msoAutoShape  msoCallout  msoCanvas  msoChart  msoComment  msoDiagram  msoEmbeddedOLEObject  msoFormControl  msoFreeform  msoGroup  msoLine  msoLinkedOLEObject  msoLinkedPicture  msoMedia  不能与此属性一同使用。该常量与其他 Microsoft Office 应用程序中的图形一同使用。  msoOLEControlObject  msoPicture  msoPlaceholder  不能与此属性一同使用。该常量与其他 Microsoft Office 应用程序中的图形一同使用。  msoScriptAnchor  msoShapeTypeMixed  msoTable  msoTextBox  msoTextEffect   这个应该不行吧[/quote] 至少在office里面所有绘制的图形都是可编辑的.

看我资源里的Wavesoft截屏工具，是否满足你的需求。 当时我是这么开发的（QQ截屏的方框绘图也是这么做的）： 使用BitBlt绘图自己写不断的覆盖重绘，可以完成你的需求。

引用 4 楼 zhao4zhong1 的回复:应用于 Shape 和 ShapeRange 对象的 Type 属性。  返回或设置图形类型。MsoShapeType 类型，只读。  MsoShapeType 可为以下 MsoShapeType 常量之一。  msoAutoShape  msoCallout  msoCanvas  msoChart  msoComment  msoDiagram  msoEmbeddedOLEObject  msoFormControl  msoFreeform  msoGroup  msoLine  msoLinkedOLEObject  msoLinkedPicture  msoMedia  不能与此属性一同使用。该常量与其他 Microsoft Office 应用程序中的图形一同使用。  msoOLEControlObject  msoPicture  msoPlaceholder  不能与此属性一同使用。该常量与其他 Microsoft Office 应用程序中的图形一同使用。  msoScriptAnchor  msoShapeTypeMixed  msoTable  msoTextBox  msoTextEffect   这个应该不行吧

Office里面的Shape ？

我用的是qt，发现qt中的QRubberBand可以用来绘画直线和矩形，并支持拉伸修改。但是暂时还没发现支持其他形状，比如椭圆、多边形自由变化。

这个没有，一般有的是渲染，也就是绘制几何图形的开源库，但是绘制完后，你要选择，则必须自己来做。


Question: c语言结构要在函数内部初始化的时候参数为什么要传二级指针？

引用 2 楼 stormier 的回复:[quote=引用 1 楼 derekrose 的回复:] int a = 10; 你要改变a的值 是call func(a)呢 还是func(&a);  指针同理 一级指针可以理解，二级指针不明白为什么[/quote]  int* a = 0x12345678; 你如果想改a的值怎么办

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

传的都是值，你要初始化指针，就要给指针所在地址附别的地址值

引用 1 楼 derekrose 的回复:int a = 10; 你要改变a的值 是call func(a)呢 还是func(&a);  指针同理 一级指针可以理解，二级指针不明白为什么


Question: 新手c语言scanf函数问题求解！

lz可以看看这个——http://blog.csdn.net/u012421456/article/details/18501309

1 scanf 不需要\n的 2 处理下每次输入的回车符！

同楼上。 另外，请检查scanf函数的返回值。

scanf别写什么 \n 作死


Question: 循环跳不出去！！！！求前辈们指点。

引用 2 楼 luobinshan 的回复:一般在fgets循环中, 增加一个 if ( input[0] == 'q' ) break; 这样按q就可以退出了.  由键盘产生EOF也行. windows Ctrl+Z linux   Ctrl+d  这解决办法不错。但为什么跳不出来呢？

引用 3 楼 u012889234 的回复:stdio 不是标准输入吗？  while永远为真。 在循环内给结束条件(在if里加break)  为什么输入流就永远为真呢？

引用 1 楼 user-7 的回复:stdin是你的文件指针？  输入流。

Enter，Ctrl+Z，Enter

stdin是输入流的话，fgets 读入回车算成功不返回失败 怎么按回车也不结束啊~ 要结束就像2楼说的那样产生EOF

你可以捕获fgets的返回值 调试看看 为什么一直不等于NULL

Linux ^D Windows ^Z 产生EOF

stdin是你的文件指针？


Question: 学C语言碰到个问题，求教！

#include<stdio.h> main() {    int a[5]={1,2,3,4,5};    int i,t;    for(i=0;i<=5/2/*这个地方你要用总的个数除以2，不然当i=3时，你原先已经互换位置后又会互换回来，所以结果是没变的*/;i++)    {       t=a[i];       a[i]=a[4-i];       a[4-i]=t;     }     for(i=0;i<=4;i++)        printf(" %d",a[i]); }或者你直接 #include<stdio.h> main() {    int a[5]={1,2,3,4,5};    int i;     for(i=4;i>=0;i--)        printf(" %d",a[i]); }希望对你有用

你这个问题我也是一样的，你要把循环条件除以2，不然后面的又是回到原来的值

#include<stdio.h> main() {    int a[5]={1,2,3,4,5};    int i,t;    for(i=0;i<=4;i++)    {       t=a[i];       a[i]=a[4-i];       a[4-i]=t;     }     for(i=0;i<=4;i++)        printf(" %d",a[j]); }  当i=2的时候已经完成了交换的目的，i=3的时候有一次把第2个和第四个数据交换了一次，同理，后面的也全交换了。所以你交换了两次，自然是顺序输出的啊

完全没必要这么做，直接重新定义一个一维数组，把这个一维数组按照倒序赋值给另外一个数组很简单

刚学编程入门的话应该学会自己设置断点。这样的题目让别人告诉你那里出错了对你的提高是没有好处的。

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

引用 1 楼 chenyegui 的回复:#include<stdio.h> main() {    int a[5]={1,2,3,4,5};    int i,t;    for(i=0;i<=4;i++)    {       t=a[i];       a[i]=a[4-i];       a[4-i]=t;     }     for(i=0;i<=4;i++)        printf(" %d",a[j]);//靓仔！仔细点j? }  你的这个 j 哪里来的啊？

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

我看第二遍才看出来！

引用 3 楼 u013748984 的回复:我自己找出错误了，应该把那个循环变量i<=4改成i<=2,如果是4的话，就会出现2次交换，数据又会换成原来的数组a #include<stdio.h> main() {    int a[5]={1,2,3,4,5};    int i,t;    for(i=0;i<=2;i++)    {       t=a[i];       a[i]=a[4-i];       a[4-i]=t;     }     for(i=0;i<=4;i++)        printf(" %d",a[i]); } 刚看到，原来lz已经想到了，我多此一举了

细心可以避免很多不必要的问题！人家4楼回复都这么有耐心，你自己怎么就不能画画尼？

至于为什么，你再好好想想，看能明白吗

# include <stdio.h>  int main(void) {    int a[5] = {1, 2, 3, 4, 5};    int i, t;     for(i=0; i<=2; i++) //  把 i<=4 改为 i<=2    {       t = a[i];       a[i] = a[4-i];       a[4-i] = t;     }      for(i=0; i<=4; i++)        printf(" %d\n",a[i]);  	return 0; }

猫哥，那个j我不小心写错的，但是就算把那个换成i也还是不行啊

引用 5 楼 user-13 的回复:[quote=引用 4 楼 chenyegui 的回复:] i=0:a[0]=5,a[4]=1 i=1:a[1]=4,a[3]=2 i=2:a[2]=3,a[2]=3 i=3:a[3]=4,a[1]=2 i=4:a[4]=5,a[0]=1  这就是FOR循环实习的功能啊。。你想说什么？ 倒置数值？ 如果是那就strlen(a)/2  从中间分开嘛[/quote]

引用 4 楼 chenyegui 的回复:i=0:a[0]=5,a[4]=1 i=1:a[1]=4,a[3]=2 i=2:a[2]=3,a[2]=3 i=3:a[3]=4,a[1]=2 i=4:a[4]=5,a[0]=1  这就是FOR循环实习的功能啊。。你想说什么？ 倒置数值？ 如果是那就strlen(a)/2  从中间分开嘛


Question: 请大家指点迷津。这个数组里保存的怎么是一样的数据？

引用 8 楼 buyong 的回复:自己动手单步调试 你何必跑来占个位置？

自己动手单步调试

新的一天，新的起点，新的气象！！！！

引用 4 楼 ForestDB 的回复:是。。。。。 这样结果没有任何变化？

是。。。。。

引用 1 楼 user-3 的回复:57行malloc返回值给谁了？ Infotable[i] = (Info*)malloc(sizeof(Info)); 这样吗。。

引用 1 楼 user-3 的回复:57行malloc返回值给谁了？ 这里是想为Infotable数组分配内存空间并初始化。

57行malloc返回值给谁了？

哎，来人瞧一瞧哦！！！


Question: 如何用c语言调用摄像头

引用 9 楼 u013749006 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 用OpenCV不超过10行语句。 那10行语句是什么呢？[/quote] 《学习OpenCV（中文版）》

引用 3 楼 zhao4zhong1 的回复:用OpenCV不超过10行语句。 那10行语句是什么呢？

引用 6 楼 wdekifjr 的回复:还想问一下，监控视频传输时时一张一张图片传，还是整个视频传。 传的是比如mp4或H.264压缩格式的视频流，我猜。

引用 楼主 wdekifjr 的回复:如何用c语言调用摄像头，并且每隔几帧储存在文件中。  首先你的摄像头得有驱动,然后驱动允许你读数据

还想问一下，监控视频传输时时一张一张图片传，还是整个视频传。

要找相应的库或者接口。

引用 3 楼 zhao4zhong1 的回复:用OpenCV不超过10行语句。 别忘了OpenCV 1.0好象是纯C语言。

引用 1 楼 starytx 的回复:c语言没有这么高级的功能。如果是windows下可以使用vfw(比较古老的一个多媒体操作库，video for window)，简单实用

用OpenCV不超过10行语句。


Question: QQ好友列表是什么控件做的？Treeview吗？

引用 3 楼 zhuobattle 的回复:spy++抓不到了，应该是自绘了。  豪迪软件好像可以抓到句柄

spy++抓不到了，应该是自绘了。

以前那种卷起来的好像是“抽屉”控件，现在应该不是了吧

应该是自绘, 无句柄.  有点类似于duilib那种完全自己贴图.


Question: c程序编译出错，不知怎么错了

宏定义不用分号，结贴！


Question: 从小到大输出10个整数，程序没报错误啊，但显示编译器已停止工作

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

不好意思啊，刚才断网了，要不按12楼的试试吧，感觉lz代码有点乱

引用 5 楼 no_Talent 的回复: p = array[0]; q = array[n-1];  这里p,q都是指针，因该为：  p = &array[0]; q = &array[n-1];  这样不行么？

引用 10 楼 u012421456 的回复:# include <stdio.h>  int main() { 	void like(int array[],int n); 	int i,j; 	int fan[10]; 	printf("请输入10个整数: "); 	for(i=0;i<10;i++) 		scanf("%d",&fan[i]); 	like(fan,10); 	for(j=0;j<10;j++) 		printf("%3d\n",fan[j]);  	return 0; } void like(int array[],int n) { 	int *p,*q; 	int x,y; 	int love; 	p=array[0];   //22行，不能把 int 型数据改为 int * 	q=array[n-1]; 	for(x=0;x<n;x++,p++) 	{ 		for(y=n-1;y>0;y--,q--) 		{ 			if(*p>*q) 			{ 				love=*p; 				*p=*q; 				*q=love; 			} 		} 	} } 22行，有问题啊那该怎样改啊？

引用 1 楼 misakamm 的回复:排序代码完全错了，建议先用好了数组再玩指针

引用 6 楼 u012421456 的回复:lz你确定没错？ 我这里怎么是这种情况——我这真心没error,只有4个警告

引用 2 楼 u010957746 的回复:指针问题。是指针我感觉也是，刚刚学指针，想试试效果

lz你确定没错？ 我这里怎么是这种情况——

引用 3 楼 bedynamic 的回复:简单的排序……。冒泡会不……搞这么麻烦，还有这样的代码谁愿意看？乱七八糟的。 新手，没必要这么打击吧，我知道你很牛逼！！！！！

简单的排序……。冒泡会不……搞这么麻烦，还有这样的代码谁愿意看？乱七八糟的。

指针问题。是指针

排序代码完全错了，建议先用好了数组再玩指针


从楼上的表中可看出 （）里的东西最先结合 [ ]的优先级高于*的优先级 若类型为char,char *p[10]可以理解为有一个数组，数组的10个元素都指向char类型的数据  若类型为char,char (*p)[10]先结合*p,表示指向十个一维数组的指针 例如 char a[3][10];  char (*p)[10]=a; 可用来访问数组的每个元素。 p[2][1]表示第三行第一列的元素。

//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 | //+------------------+-----------------------------------------+---------------+

楼主这个是声明啊还是使用啊

int *p[10] p首先是个数组，因为它先和[10]结合 其次，这个数组里面存的内容是int*,也就是数组有10个元素，每个元素都是一个指针，  int (*P)[10] p先和*结合，意味着p是一个指针，他指向int [10]，即p是一个指向一个数组的指针

引用 楼主 qq1041256623 的回复:*p[10]和(*P)[10]有区别吗？ 比如int *p[10]，也可以这么写 int* p[10]，p是一个数组，数组元素p[i]的类型是int*，就是指向int的指针。  比如a[3][10]，它包括a[0][10],a[1][10],a[2][10],a[0],a[1],a[2]可以表示成a[i]==*(a+i)，所以(*P)[10]，p可以等于a+i，p是指向大小为10的数组，p的增一减一是以一行为单位的（比如3行10列）。

看看预算符: * []的优先级和结合性。   *p[10] 和 *(p[10]);  是一样的。

引用 2 楼 misakamm 的回复:你可以把(*P)[10]看成P[0][10] 而*p[10]只能是*(p[10]) *p[]和p[][]差不多意思吧

完全不一样...


Question: for循环嵌套if判断语句时间复杂度的计算

引用 楼主 mary__lin 的回复:for里面有if怎么算时间复杂度？if判断语句中的条件也要算进去吗？  这种情况下就不仅仅是算法复杂度的问题了，还需要加上概率论的知识，正因为类似应用的存在，不少高校的计算机专业课程也包括概率论。

一般都是执行一半吧，就是执行次数除以二

循环本身，如果有和规模相关的控制条件的话，可以判断基本操作的执行的次数 if  语句，可以提前终止循环，从而可以缩小基本操作的执行的次数。。。比只考虑循环时候执行的次数要少。  同样是排序。  内部排序，内存读写，比较属于基本操作。  外部排序，外设的读写操作，才是基本操作。

如果基本操作就是比较，那么一条if 语句的计数为1 如果比较不是基本操作，相对基本操作，比较的时间可以忽略，那么只需要对基本操作计数 if 语句中，不执行基本操作的不计数，执行的计数。  时间复杂度是针对基本操作来说的； 一般循环的判断，计数，以及if 的比较操作，不计算在内，除非比较，循环计数，就是基本操作。  以各种基于比较的排序为例，有两种基本操作：  1）比较元素的大小的比较操作 2）交换元素的位置；  很多时候，由于这两种操作，的耗时时间差距不大，都是不可忽略的，所以都属于基本操作。 那么，以这两种操作的，时间复杂度最高的，计算时间复杂度。  如果，比较只是针对，大对象的一个比较小的键值的操作， 那么比较也是可以忽略的，可以不用计算他的时间复杂度。  这个排序过程中，还会执行循环变量的比较，和递增递减操作，不过和前面两种操作比较起来，耗时可以忽略。。。 特别是对象比较大的时候，所以他们不是基本操作。  基本操作，就是解决一个问题的主要操作，往往是耗时最长的操作，而且执行次数，往往和数据规模相关。

引用 2 楼 caozhy 的回复:你有程序要算复杂度很简单，在最内侧加上一个计数器变量，每执行1次加1。 在程序运行完后记录下这个计数器的值。  改变程序的规模（比如输入数组的长度），重复这个过程。  然后你得到了很多 程序规模-计数器 的值对。  在一张纸上描点画图。看曲线是什么类型的即可。其实很难定义“最内侧”，就算是“最内侧”也不一定是执行次数最多的代码，不过也有估算价值 改变程序的规模直接测运行时间也可以做估算  但是如果你要较准确的时间复杂度，那最好阅读算法导论

具体情况具体分析


Question: socket accept error

引用 2 楼 boygo1982 的回复:fork如果创建失败了，你的错误处理后while会继续循环执行，但是accept的第一个参数servfd已经在你的错误处理里被关闭了。 应该是fork失败了，因为我没有在su下运行程序，菜鸟表示很蛋疼

str_echo(clifd); 这一句出的问题吗？


Question: C语言全局变量有时无法写入'\0'，有时又可以，请问怎么破？

这里似乎看不出明显问题。可能是memcpy之前出的,strcpy, 或者更早，var_val就已经错了。别拘泥在这里

如果对效率不是很敏感的话，可以考虑在拷贝之前memset一下，把内存空间清0

引用 15 楼 insisted_search 的回复:我们看楼主的需求和现象，我们在真的他的问题分析，而不是讨论到编程的习惯。 好吧,我的话可能让大家不舒服了,我其实是无意的调侃,请接受我真诚的抱歉

引用 13 楼 yanran_hill 的回复:[quote=引用 7 楼 insisted_search 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 为什么不用strncpy呢？ 注意：strncpy(t,s,n);t[n]=0; strcpy有什么问题吗？以你的经验。[/quote] 问题大了去了,如果字符串不是以'\0'结尾,那么复制的长度可能超过了从地球到月球:完全符合物理学的测不准原理 $man strcpy [/quote] 我们看楼主的需求和现象，我们在真的他的问题分析，而不是讨论到编程的习惯。

引用 7 楼 insisted_search 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 为什么不用strncpy呢？ 注意：strncpy(t,s,n);t[n]=0; strcpy有什么问题吗？以你的经验。[/quote] 问题大了去了,如果字符串不是以'\0'结尾,那么复制的长度可能超过了从地球到月球:完全符合物理学的测不准原理 $man strcpy

引用u_char strtmp[256]; strcpy(strtmp,var_val);  strcpy接受char*， u_char是什么类型？

引用 10 楼 insisted_search 的回复:[quote=引用 8 楼 zhxianbin 的回复:] function <cstring> strcpy char * strcpy ( char * destination, const char * source ); Copy string Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).  To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.  Parameters destination Pointer to the destination array where the content is to be copied. source C string to be copied.  Return Value destination is returned. 关键。。。。。[/quote] 用 memcpy

strcpy(strtmp,var_val); 这句最好用 memcpy(strtmp, val_val, var_val_len); strtmp[var_val_len] = 0; 来处理。          case COMMIT:              memset(myname, 0, sizeof (myname));              memcpy(myname,strtmp,strlen(strtmp)+1); 这里也类似。  要是想不明白就跟踪一下。

引用 8 楼 zhxianbin 的回复:function <cstring> strcpy char * strcpy ( char * destination, const char * source ); Copy string Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).  To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.  Parameters destination Pointer to the destination array where the content is to be copied. source C string to be copied.  Return Value destination is returned. 关键。。。。。

引用 8 楼 zhxianbin 的回复:function <cstring> strcpy char * strcpy ( char * destination, const char * source ); Copy string Copies the C string pointed by source into the array pointed by destination, [color=#FF0000]including the terminating null character (and stopping at that point).  To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.[/color]  Parameters destination Pointer to the destination array where the content is to be copied. source C string to be copied.  Return Value destination is returned. 黄色是关键，红色是关键的关键。

引用 6 楼 zhao4zhong1 的回复:为什么不用strncpy呢？ 注意：strncpy(t,s,n);t[n]=0; strcpy有什么问题吗？以你的经验。

你自己把memcpy和strcpy搞混乱了

看了代码没有看出什么问题，不过我想问一下，你是怎么确定这个的： ”全局变量的前一部分字节被新设置的覆盖，而原来的字符串多出来的一部分不会被memcpy复制过来的'\0'所断开“ 是通过snmpget吗？能不能把源码贴一下。

另外你这里u_char应该是unsigned char吧，怎么一会用strcpy,一会用memcpy,有点乱。

单步跟踪看下，别是因为字符串长度超过256了吧。

u_char strtmp[256];初始化  ={0}


Question: 汇编！！！  大家帮忙解决下，关于movdqa的使用

虽然是array[16]，但传进去的只是array，你可以通过“数据类型 PTR 地址表达式 ”强制转换

引用 1 楼 user-2 的回复:movdqa xmm0, OWORD PTR array   能不能说下为什么用OWORD？我查了很多有dword，qword，没有见过oword 谢谢。

align用法没有问题，只是要注意align只对下一个变量定义起作用，如果要定义多个需要对齐的变量，每个变量定义前都要用align

movdqa xmm0, OWORD PTR array


Question: linux c socket，求助

你不是说makefile tab被改成空格了？makefile中不能有空格吗？貌似我把这句注释了，就可以了,我实在看不出这句有啥错误啊 bin_PROGRAMS = configd_test

if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) //.goto close_err;  if没有注释掉, 导致后面的逻辑错误

error: extended registers have no high halves 这种错误感觉不是语法错误啊，你刚回复过我的makefile的帖子，我感觉是哪个makefile弄的

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

引用 4 楼 littlelocker 的回复:不是注释的这个问题，我光用gcc指令编译是可以过的，估计是makefile的问题 提醒：makefile里面的Tab字符必须是Tab字符本身，不能用空格代替。


Question: 对一个数列求取峰值，求C代码编写算法

点搞，我现在也在做峰峰值算法，我先做的滤波，滤波之后就不知道怎么弄了

先低通，再FFT看看主信号的间隔点数，算峰值的时候注意间隔，最后找出峰值位置，没试过，不知道效果咋样。

请问楼主解决问题了吗？我也遇到同样的问题，求楼主能提供具体的解决方案，定当酬谢

引用 18 楼 vipcxj 的回复:我但土办法就是求导，导数接近0的就是峰值，当然对于拐点，导数也是0，所以还得求下2次导数。不过因为是离散点，所以求出的导出误差比较大，阀值难以掌控，所以说是土办法。  说的很在理

还是采集点加个滤波吧。

搜“低通滤波”

引用 12 楼 lpcads 的回复:法1：计算 X[i-n] 到 X[i+n] 这 2n+1 个点的平均值，作为 Y[i] 的值； 法2：计算积分（可以用梯形法），再求导（中心差分法），结果和法1应该差不多。 因为你说“采样频率合适，有足够的数据点，而且数据点时间距离可以看成是“绝对均匀”的”，而且从图上看，噪音的幅度和持续实现较短，因此使用这两种滤波法效果应该还不错。  法1应该是不合适的。求这2n+1个点的平均值，肯定比真实的峰值小。

引用 11 楼 bbs2241 的回复:拟合下我觉得是可以的，拟合后噪声的影响就去掉了  具体如何拟合？请简要说说方法，谢谢。

额，没看到噪音，其实你先去噪后在用LS的办法取峰值就行了，当然这会导致误差又大了点。我去噪还是土办法，取临近N个点取平均~

突发性的噪声用中值滤波啊。

引用 14 楼 cjfdqchwh 的回复:[quote=引用 12 楼 lpcads 的回复:] 法1：计算 X[i-n] 到 X[i+n] 这 2n+1 个点的平均值，作为 Y[i] 的值； 法2：计算积分（可以用梯形法），再求导（中心差分法），结果和法1应该差不多。 因为你说“采样频率合适，有足够的数据点，而且数据点时间距离可以看成是“绝对均匀”的”，而且从图上看，噪音的幅度和持续实现较短，因此使用这两种滤波法效果应该还不错。  法1应该是不合适的。求这2n+1个点的平均值，肯定比真实的峰值小。 [/quote] 那就加个权 1,2,4,2,1 之类的。 既然是滤波，精确要求就得放低。

引用 7 楼 cjfdqchwh 的回复:[quote=引用 6 楼 reFreever 的回复:] 如果只是计算峰值点个数，可以试着先进行滤波将数据平滑处理，将噪声的波幅减小。  现在内存上存在这么一段数列，通过什么方法，实现“先进行滤波将数据平滑处理，将噪声的波幅减小”的目的？谢谢[/quote] 法1：计算 X[i-n] 到 X[i+n] 这 2n+1 个点的平均值，作为 Y[i] 的值； 法2：计算积分（可以用梯形法），再求导（中心差分法），结果和法1应该差不多。  因为你说“采样频率合适，有足够的数据点，而且数据点时间距离可以看成是“绝对均匀”的”，而且从图上看，噪音的幅度和持续实现较短，因此使用这两种滤波法效果应该还不错。

拟合下我觉得是可以的，拟合后噪声的影响就去掉了

如果你数据点足够多可以进行再采样, 比如你这段数据有上W个点的话就适用.数据点少的话就不用了。 至于平滑处理的方法有很多， 简单的均值滤波，中值滤波，5点3次平滑滤波等。复杂点的FFT,小波都行。不过平滑滤波多是对于含有高频噪声进行滤波的，你这种噪声滤波的意义不会太大。只能适当的将噪声减小，如果噪声与有效数据的差别很大的话， 也可以过度平滑将噪声减到最小。

引用 8 楼 user-11 的回复:1.首先你得保证采样率合适，即有足够的数据点； 2.噪声是什么类型的噪声，高斯白噪声？有没有突发噪声？ 3.判断峰值干嘛用呢？能判断出高低电平还不够？ 问的好 首先，采样频率合适，有足够的数据点，而且数据点时间距离可以看成是“绝对均匀”的； 2. 不是高斯白噪声，这种噪声绝大多数都是突发噪声，由于外力影响导致的； 3. 解决方案就是要提取出峰值，提取峰值就是唯一的目标。

引用 6 楼 reFreever 的回复:如果只是计算峰值点个数，可以试着先进行滤波将数据平滑处理，将噪声的波幅减小。  现在内存上存在这么一段数列，通过什么方法，实现“先进行滤波将数据平滑处理，将噪声的波幅减小”的目的？谢谢

含有噪声的图片在实际环境中的原始数据是这样显示的吗？ 这噪声频率有点低，貌似还是挺有规律的、 可以根据已知的波幅大小与波峰之间的距离设置阀值：当前峰值点离上个峰值点的横向最小距离与纵向最小距离，若找到一个峰值首先判断横纵距离是否大于最小阀值。 如果只是计算峰值点个数，可以试着先进行滤波将数据平滑处理，将噪声的波幅减小。

在算法处理上，本人粗陋浅薄，恳请大家不吝指教，非常感谢！


Question: iconv 字符集转换出错

引用 14 楼 zw91683 的回复:[quote=引用 13 楼 neustar1 的回复:] 还有一个原因就是  if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )     {         printf("errno =%d ;\n",errno);        return -1;         } 你的系统是64位的,size_t与 unsigned int大小不一样，你把这个变量改一下看看。  拜服！！ 确实是这个原因，谢谢！[/quote]不用谢了，给分吧

引用 13 楼 neustar1 的回复:还有一个原因就是  if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )     {         printf("errno =%d ;\n",errno);        return -1;         } 你的系统是64位的,size_t与 unsigned int大小不一样，你把这个变量改一下看看。  拜服！！ 确实是这个原因，谢谢！

引用 12 楼 zw91683 的回复:[quote=引用 11 楼 neustar1 的回复:] 确认一下你setlocale是否成功了  printf("locale =%s ;\n",setlocale(LC_ALL,"zh_CN.gb18030")) ;  返回结果 locale =zh_CN.gb18030 ;  [/quote] 还有一个原因就是  if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )     {         printf("errno =%d ;\n",errno);        return -1;         } 你的系统是64位的,size_t与 unsigned int大小不一样，你把这个变量改一下看看。

引用 11 楼 neustar1 的回复:确认一下你setlocale是否成功了  printf("locale =%s ;\n",setlocale(LC_ALL,"zh_CN.gb18030")) ;  返回结果 locale =zh_CN.gb18030 ;

确认一下你setlocale是否成功了

引用 9 楼 zw91683 的回复:[quote=引用 8 楼 neustar1 的回复:] [quote=引用 7 楼 zw91683 的回复:]  还是不行啊 linux下，源文件默认保存为utf-8格式，你一定要改成多字符编码格式才行。你改了源文件编码？[/quote]    这个对吧？[/quote]对的

引用 8 楼 neustar1 的回复:[quote=引用 7 楼 zw91683 的回复:]  还是不行啊 linux下，源文件默认保存为utf-8格式，你一定要改成多字符编码格式才行。你改了源文件编码？[/quote]    这个对吧？

引用 7 楼 zw91683 的回复: 还是不行啊 linux下，源文件默认保存为utf-8格式，你一定要改成多字符编码格式才行。你改了源文件编码？

#include <stdio.h> #include <iostream> #include <locale.h>  #include "iconv.h"  #include <string.h> #include <errno.h>  //#include <string>   int code_convert(char* from_charset, char* to_charset, char* inbuf,                 int inlen, char* outbuf, int outlen)  {      iconv_t cd;      char** pin = &inbuf;         char** pout = &outbuf;      cd = iconv_open(to_charset,from_charset);         if(cd == 0)         return -1;      memset(outbuf,0,outlen);         if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)         == -1)     {                         printf("errno =%d ;\n",errno);        return -1;         }      iconv_close(cd);      return 0;     }   char* u2g(char *inbuf)     {      int nOutLen = 255;      char* szOut = (char*)malloc(nOutLen);      if (-1 == code_convert("utf-8","gb18030",inbuf,strlen(inbuf),szOut,nOutLen))      {         free(szOut);         szOut = NULL;      }      return szOut;  }      char* g2u(char *inbuf)    {      int nOutLen = 255;      char* szOut = (char*)malloc(nOutLen);      if (-1 == code_convert("gb18030","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))      {          printf("error no = %d;\n",errno);        free(szOut);         szOut = NULL;      }      return szOut;  }        int main(int argc, char **argv)  {    setlocale(LC_ALL,"zh_CN.gb18030") ;     char src[128]={0};            sprintf(src,"天空");      char* szOut = g2u(src);          return 1;  }  还是不行啊

引用 5 楼 zw91683 的回复:[quote=引用 4 楼 neustar1 的回复:] [quote=引用 3 楼 zw91683 的回复:] 引用错误说明是： 非法字节序列  我知道啊，问题是怎么就非法字节序列了？ 哪非法了？弄了半天没搞明白。  还有同样的代码在AIX环境下测试通过了， 真搞不懂了 setlocale，设置好程序的本地化的字符编码类型，linux下默认是utf-8，这个与系统的本地化字符编码类型不一致。[/quote]  引用 4 楼 neustar1 的回复:[quote=引用 3 楼 zw91683 的回复:] 引用错误说明是： 非法字节序列  我知道啊，问题是怎么就非法字节序列了？ 哪非法了？弄了半天没搞明白。  还有同样的代码在AIX环境下测试通过了， 真搞不懂了 setlocale，设置好程序的本地化的字符编码类型，linux下默认是utf-8，这个与系统的本地化字符编码类型不一致。[/quote]  我在2楼的回复里写明了操作系统的字符集设置，用的是gb18030啊，我把gbk改成gb18030也是一样的错误！[/quote]程序开始要调用setlocale(LC_ALL,"zh_CN.gb18030");另外源文件记住保存成anscii编码，不可以保存为utf-8编码。

引用 4 楼 neustar1 的回复:[quote=引用 3 楼 zw91683 的回复:] 引用错误说明是： 非法字节序列  我知道啊，问题是怎么就非法字节序列了？ 哪非法了？弄了半天没搞明白。  还有同样的代码在AIX环境下测试通过了， 真搞不懂了 setlocale，设置好程序的本地化的字符编码类型，linux下默认是utf-8，这个与系统的本地化字符编码类型不一致。[/quote]  引用 4 楼 neustar1 的回复:[quote=引用 3 楼 zw91683 的回复:] 引用错误说明是： 非法字节序列  我知道啊，问题是怎么就非法字节序列了？ 哪非法了？弄了半天没搞明白。  还有同样的代码在AIX环境下测试通过了， 真搞不懂了 setlocale，设置好程序的本地化的字符编码类型，linux下默认是utf-8，这个与系统的本地化字符编码类型不一致。[/quote]  我在2楼的回复里写明了操作系统的字符集设置，用的是gb18030啊，我把gbk改成gb18030也是一样的错误！

引用 3 楼 zw91683 的回复:引用错误说明是： 非法字节序列  我知道啊，问题是怎么就非法字节序列了？ 哪非法了？弄了半天没搞明白。  还有同样的代码在AIX环境下测试通过了， 真搞不懂了 setlocale，设置好程序的本地化的字符编码类型，linux下默认是utf-8，这个与系统的本地化字符编码类型不一致。

错误说明是： 非法字节序列

操作系统环境是  redhat 5.5  字符集环境： LANG=zh_CN.gb18030 LC_CTYPE="zh_CN.gb18030" LC_NUMERIC="zh_CN.gb18030" LC_TIME="zh_CN.gb18030" LC_COLLATE="zh_CN.gb18030" LC_MONETARY="zh_CN.gb18030" LC_MESSAGES="zh_CN.gb18030" LC_PAPER="zh_CN.gb18030" LC_NAME="zh_CN.gb18030" LC_ADDRESS="zh_CN.gb18030" LC_TELEPHONE="zh_CN.gb18030" LC_MEASUREMENT="zh_CN.gb18030" LC_IDENTIFICATION="zh_CN.gb18030" LC_ALL=zh_CN.gb18030  iconv 版本 iconv (GNU libc) 2.5 Copyright (C) 2006 Free Software Foundation, Inc.  编译器版本 g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48) Copyright (C) 2006 Free Software Foundation, Inc.


Question: 这里人多,继续来借人气!

热情帮顶!!!

接10分！楼主别小气啊！

记得是。。。

问题已解决快来占楼散粉!

不明觉厉

问题好复杂的样子


Question: makefile求助

提醒：makefile里面的Tab字符别让无良编辑器给替换成空格了。

我写了个socket的程序，在函数结尾处，gcc老爆错误 error: extended registers have no high halves 怎么回事啊？  IPCHandle ipc_client_init(char *server_ip, unsigned short port) { 	int fd; 	struct sockaddr_in addr; 	struct in_addr server;  	fd = socket(AF_INET, SOCK_STREAM, 0); 	if (fd < 0) 		goto err;  	memset(&addr, 0, sizeof(addr)); 	addr.sin_family = AF_INET; 	addr.sin_port = htons(port);  	if (server_ip) { 		//if (inet_aton(server_ip, &server) == 0) 			//goto close_err; 		addr.sin_addr.s_addr = server.s_addr; 	} else 		addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);  	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) 		//.goto close_err; 	sock_keepalive(fd); 	return fd;  close_err: 	close(fd); err: 	return -1; }

16进制看看你的回车对不对。


Question: socket编程 多线程 网络聊天

理论弟别来，我伤不起，学了一两天SOCKET，多线程的都踊跃参加。 我课程设计快结束了！！！

这也不是啥深奥问题，我不需要深奥，我大三，准备读研，不要太高技术，socket， CreateThread 都他妈书上的，我把它结合到一起有错吗？？？ 这么简单都没人回答，都他妈大学教授级人物，，， 老子范低级错误我容易吗？？？？

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

不会用CSDN ，告诉你百度空间有。 费了老大劲 你不回答，我就骂你  ！！！！！

服务器代码：server.cpp #include<stdio.h> #include<Winsock2.h> #include<string.h> #include<windows.h> #pragma comment(lib,"ws2_32.lib") DWORD WINAPI Fun1Proc(  LPVOID lpParameter);   SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);   SOCKADDR_IN addrClient;   int len=sizeof(SOCKADDR);   SOCKET sockConn;   char sendBuf[50]; void main() {    WORD wVersionRequested;   WSADATA wsaData;   int err;   HANDLE hThread1;    //创建线程   hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);   CloseHandle(hThread1);   wVersionRequested=MAKEWORD(1,1);   err=WSAStartup(wVersionRequested,&wsaData);   if(err!=0)   {     return;   }   if(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1)   {     WSACleanup();   return;   }   SOCKADDR_IN addrSrv;   addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);   addrSrv.sin_family=AF_INET;   addrSrv.sin_port=htons(6000);   bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));   listen(sockSrv,5);   printf("服务器已启动!\n");   char recvBuf[50];  while(1) {               sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);       memset(recvBuf,0,sizeof(recvBuf));          Sleep(4000);    recv(sockConn,recvBuf,50,0);          if(!strcmp(recvBuf,"EOF"))    {       break;    }    printf("客户端说：%s\n",recvBuf);    }      closesocket(sockConn); } DWORD WINAPI Fun1Proc(  LPVOID lpParameter) {         printf("发送信息\n");  scanf("%s",&sendBuf);  if(!strcmp(sendBuf,"EOF"))  {   closesocket(sockConn);  }  send(sockConn,sendBuf,strlen(sendBuf)+1,0);  return 0; }   客户端代码client.cpp #include<stdio.h> #include<Winsock2.h> #include<string.h> #include<windows.h> #pragma comment(lib,"ws2_32.lib") DWORD WINAPI Fun1Proc(   LPVOID lpParameter  );      SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);   SOCKADDR_IN addrSrv;     char recvBuf[50];    char sendBuf[50];  void main(){   WORD wVersionRequested;   WSADATA wsaData;   int err;       wVersionRequested=MAKEWORD(1,1);   err=WSAStartup(wVersionRequested,&wsaData);   if(err!=0)   {     return;   }   if(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1)   {     WSACleanup();  return;   }    addrSrv.sin_addr.S_un.S_addr=inet_addr("10.1.13.215");  addrSrv.sin_family=AF_INET;   addrSrv.sin_port=htons(6000);   printf("客户端已启动!\n");     HANDLE hThread1;   hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);   CloseHandle(hThread1);    connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));    while(1)   {                memset(recvBuf,0,sizeof(recvBuf));      Sleep(100);      scanf("%s",&sendBuf);      if(!strcmp(sendBuf,"EOF"))      {         break;      }      send(sockClient,sendBuf,strlen(sendBuf)+1,0);        }       closesocket(sockClient);    WSACleanup(); }  DWORD WINAPI Fun1Proc(    LPVOID lpParameter) {      printf("发送信息\n");  recv(sockClient,recvBuf,50,0);  if(!strcmp(recvBuf,"EOF"))  {    closesocket(sockClient);    WSACleanup();  }  printf("服务器说：%s\n",recvBuf);  return 0; }

你这代码整的忒乱了，不知道的还以为是乱码大赛的获奖作品呢！！！ 整理好格式，再来发吧

引用 8 楼 zhao4zhong1 的回复:特供土造日志系统一枚供调试多线程代码使用：#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中 好东西，已收藏！

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


Question: 不知道怎么构建数据结构

三角网属于水准网吧.  三角网的每个点的数据,就是坐标和高程,坐标是经度纬度,高程是海拔高度.

那个 WINDOWS游戏编程大师技巧 和 DirectX 9.0 3D游戏开发编程基础   DirectX 里面  就有类似关于三角形点的结构体定义吧 你看看适合你不


Question: glibc 库函数变量没有定义

LZ都是在哪些目录下找定义？

引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 u011751581 的回复:] 可是glibc里确实没有这些类型的定义啊。楼上谷歌的那个.h文件在glibc里压根就没有 unix不是linux[/quote]   麻烦楼上的说清楚点嘛。真心猜不透你说的啥呀

麻烦楼上的说清楚点嘛。真心猜不透你说的啥呀

引用 2 楼 u011751581 的回复:可是glibc里确实没有这些类型的定义啊。楼上谷歌的那个.h文件在glibc里压根就没有 unix不是linux

引用 6 楼 user-3 的回复:#include <sys/mman.h>  void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);    为啥要看全部源码？ 部分代码可能不在glibc，而在内核。  哥哥，内核中也没有这个类型的定义。

引用 5 楼 u011751581 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] [quote=引用 2 楼 u011751581 的回复:] 可是glibc里确实没有这些类型的定义啊。楼上谷歌的那个.h文件在glibc里压根就没有 unix不是linux[/quote]   麻烦楼上的说清楚点嘛。真心猜不透你说的啥呀 [/quote] 搜索结果里面不是说这是unix源代码里面的吗？


Question: 一段程序,ubuntu 12.04下编译运行提示段错误 (核心已转储),windows下正常

引用 2 楼 xuch318 的回复:那在代码里怎么修改可以使t[]放在可以执行的内存区呢？  通过mprotect()修改页属性

gdb下出错是在call *%rax，也就是在跳转到t所在地址时出错，指令有错误的话应该是跳转过去后再出错的吧

引用 1 楼 truelance 的回复:在linux下,可能t[]所在的内存页没有设置可执行权限, 因此你试图把它当代码执行, 就会触发错误 这可能是一个原因。 另外，可能你这些指令执行序列本身就有问题。

那在代码里怎么修改可以使t[]放在可以执行的内存区呢？

引用 5 楼 truelance 的回复:[quote=引用 2 楼 xuch318 的回复:] 那在代码里怎么修改可以使t[]放在可以执行的内存区呢？  通过mprotect()修改页属性[/quote] 谢谢,可行


Question: char c2[]={′\x10′, ′xa′, ′\x8′} 这里的'xa'是什么意思？

char c2={′\x10′, ′xa′, ′\x8′};字符型变量只占一个字节，可以用花括号去定义，你这样可你这样定义了多个变量取得的第一个字符，也就是'\x10'； 如果用char c2='xa'；编译器会警告多字符，但没错误，因为开始写入c2的是x然后被a覆盖掉了，所以打印出来的是a。

确定不是'\xa'？  如果没有笔误的话，就是multi-character constant，非标准的东西，编译会给warning的。

这应该是转义字符那得知识，如果在字符串中加入十六进制数，用\x加十六进制数，如果想加入八进制数，用\o加八进制数

'xa'就是16进制的'0xa'的意思吧。 验证代码如下： void main() {     char c1 = {'\x10'}; 	printf("c1:%c\n", c1);      char c2 = {'xa'}; 	printf("c2:%c\n", c2);  	char c20 = 'xa'; 	printf("c20:%c\n", c20);  	char c21 = {'0xa'}; 	printf("c21:%c\n", c21);  	char c22 = {'a'}; 	printf("c22:%c\n", c22);      char c3 = {'\x8'}; 	printf("c3:[%c]\n", c3);  	char c4 = {'\x10', 'xa', '\x8'}; 	printf("c4:%c\n", c4);  }  编译警告如下：  gcc test.c  -o test test.c: 在函数‘main’中: test.c:9:16: 警告： 多字节字符常量 [-Wmultichar] test.c:9:5: 警告： 隐式常量转换溢出 [-Woverflow] test.c:12:13: 警告： 多字节字符常量 [-Wmultichar] test.c:12:2: 警告： 隐式常量转换溢出 [-Woverflow] test.c:15:14: 警告： 多字节字符常量 [-Wmultichar] test.c:15:2: 警告： 隐式常量转换溢出 [-Woverflow] test.c:24:21: 警告： 多字节字符常量 [-Wmultichar] test.c:24:2: 警告： 标量初始值设定项中有多余元素 [默认启用] test.c:24:2: 警告： (在‘c4’的初始化附近) [默认启用] test.c:24:2: 警告： 标量初始值设定项中有多余元素 [默认启用] test.c:24:2: 警告： (在‘c4’的初始化附近) [默认启用]  运行结果如下：

额，看错了，c2是一个字符而不是数组？？

编译过去应该没问题，一个字符常量中包含多个字符 是 implementation-defined 的行为。  搜 multi-character character 应该找到很多相关内容

C++ Character Constants Character constants are one or more members of the “source character set,” the character set in which a program is written, surrounded by single quotation marks ('). They are used to represent characters in the “execution character set,” the character set on the machine where the program executes.  Microsoft Specific   For Microsoft C++, the source and execution character sets are both ASCII.  END Microsoft Specific  There are three kinds of character constants:   Normal character constants   Multicharacter constants   Wide-character constants  Note   Use wide-character constants in place of multicharacter constants to ensure portability.  Character constants are specified as one or more characters enclosed in single quotation marks. For example:  char ch = 'x';          // Specify normal character constant. int mbch = 'ab';        // Specify system-dependent                         //  multicharacter constant. wchar_t wcch = L'ab';   // Specify wide-character constant.  Note that mbch is of type int. If it were declared as type char, the second byte would not be retained. A multicharacter constant has four meaningful characters; specifying more than four generates an error message.  Syntax  character-constant :  'c-char-sequence' L'c-char-sequence'  c-char-sequence :  c-char c-char-sequence c-char  c-char :  any member of the source character set except the single quotation mark ('), backslash (\), or newline character escape-sequence  escape-sequence :  simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence  simple-escape-sequence : one of  \' \" \? \\ \a \b \f \n \r \t \v  octal-escape-sequence :  \octal-digit \octal-digit octal-digit \octal-digit octal-digit octal-digit  hexadecimal-escape-sequence :  \xhexadecimal-digit hexadecimal-escape-sequence hexadecimal-digit  Microsoft C++ supports normal, multicharacter, and wide-character constants. Use wide-character constants to specify members of the extended execution character set (for example, to support an international application). Normal character constants have type char, multicharacter constants have type int, and wide-character constants have type wchar_t. (The type wchar_t is defined in the standard include files STDDEF.H, STDLIB.H, and STRING.H. The wide-character functions, however, are prototyped only in STDLIB.H.)  The only difference in specification between normal and wide-character constants is that wide-character constants are preceded by the letter L. For example:  char schar = 'x';               // Normal character constant wchar_t wchar = L'\x81\x19';    // Wide-character constant  Table 1.2 shows reserved or nongraphic characters that are system dependent or not allowed within character constants. These characters should be represented with escape sequences.  Table 1.2   C++ Reserved or Nongraphic Characters  Character ASCII  Representation ASCII  Value Escape Sequence  Newline NL (LF) 10 or 0x0a \n  Horizontal tab HT 9 \t  Vertical tab VT 11 or 0x0b \v  Backspace BS 8 \b  Carriage return CR 13 or 0x0d \r  Formfeed FF 12 or 0x0c \f  Alert BEL 7 \a  Backslash \ 92 or 0x5c \\  Question mark ? 63 or 0x3f \?  Single quotation mark ' 39 or 0x27 \'  Double quotation mark " 34 or 0x22 \"  Octal number ooo — \ooo  Hexadecimal number hhh — \xhhh  Null character NUL 0 \0    If the character following the backslash does not specify a legal escape sequence, the result is implementation defined. In Microsoft C++, the character following the backslash is taken literally, as though the escape were not present, and a level 1 warning (“unrecognized character escape sequence”) is issued.  Octal escape sequences, specified in the form \ooo, consist of a backslash and one, two, or three octal characters. Hexadecimal escape sequences, specified in the form \xhhh, consist of the characters \x followed by a sequence of hexadecimal digits. Unlike octal escape constants, there is no limit on the number of hexadecimal digits in an escape sequence.  Octal escape sequences are terminated by the first character that is not an octal digit, or when three characters are seen. For example:  wchar_t och = L'\076a';  // Sequence terminates at a char    ch = '\233';     // Sequence terminates after 3 characters  Similarly, hexadecimal escape sequences terminate at the first character that is not a hexadecimal digit. Because hexadecimal digits include the letters a through f (and A through F), make sure the escape sequence terminates at the intended digit.  Because the single quotation mark (') encloses character constants, use the escape sequence \' to represent enclosed single quotation marks. The double quotation mark (") can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a character constant, you must type two backslashes in a row (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)

你这一句能编译过去？


Question: 求助，十六进制字符转为字符串的问题，有代码，请问错误原因。

学习了，

我自己试了一下，并没有出现你所说的那种情况（0xF5做sprintf后，token获得结果为“FFFFFFF5”）  我是这么做的：#include <stdio.h> #include <string.h>  #define LEN 2  int main(int argc, char** argv) { 	int nums[LEN] = {0x02, 0xf5};  	char tmp[] = "00"; 	char result[512] = {0};  	for(int i=0; i<LEN; ++i) 	{ 		sprintf(tmp, "%02x", nums[i]); 		strcat(result, tmp); 	}  	return 0; }

引用 3 楼 zhao4zhong1 的回复:sprintf(token, "%02X", (unsigned char)Hex[i]);  确实是这个问题呀，看到FFFFFF我怎么没想到呢。 非常感谢

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

int i = 0; char token[3] = {0,0,0}; for (...) {   sprintf(token, "%02X", Hex[i]); token[2] = '\0'   result[i*2] = token[0];   result[i*2+1] = token[1]; }  试试  token[2] = '\0'  不一定需要


Question: 有没有c语言编写的开源模板编辑器

用VBA for EXCEL开发。


Question: 关于不同文件之间的值传递

你这交叉包含了……新手代码结构设计不好经常的，用全局变量吧……简单点。

个人意见，不如用全局变量来的简单直接。

include b.c中这个函数所在的头文件就能调用该函数了

引用 3 楼 q422513331 的回复:其实感觉主要是我这边逻辑有点乱了，我这样问吧，假如我在a.c文件中的某个函数中跑了    LocalDateTime(StartTime, &StartDate);得到了StartDate的值需要用在b.c文件中，那我应该怎么做，StartTime又是a.c文件中某个模块的局部变量，应该没法直接调用到另一个文件中的吧？就像写一个接口直接把StartDate的值传递过去，这接口逻辑上要怎么写？  谢谢 如果你没使用多线程技术，那么你所有的代码都是顺序执行的，两个函数之间只有先后顺序，跟它们是否处在一个文件中没有任何关系 所有的模块都是由main函数直接调用或间接调用的，调用第一个模块时返回那个局部变量保存在main函数的一个变量里，调用第二个模块时把这个变量传进去

不明白你的疑问在哪里？直接引用b.c里边的函数不就完了（顶多加个函数声明）

int x = a(); b( x );

//b.h int getVar();  //its implementation is in b.c    //a.c #include <b.h>  void foo() {    //....    int v = getVar();    //.... }


Question: socket通信，client显示send成功但是server收不到任何东西??

server 好像不是c/c++

请注意成功地完成send()调用并不意味着数据传送到达。 5.1.19 send() 简述：    向一个已连接的套接口发送数据。       #include <winsock.h>       int PASCAL FAR send( SOCKET s, const char FAR* buf, int len, int flags);       s：一个用于标识已连接套接口的描述字。    buf：包含待发送数据的缓冲区。    len：缓冲区中数据的长度。    flags：调用执行方式。     注释：    send()适用于已连接的数据报或流式套接口发送数据。对于数据报类套接口，必需注意发送数据长度不应超过通讯子网的IP包最大长度。IP包最大长度在WSAStartup()调用返回的WSAData的iMaxUdpDg元素中。如果数据太长无法自动通过下层协议，则返回WSAEMSGSIZE错误，数据不会被发送。    请注意成功地完成send()调用并不意味着数据传送到达。    如果传送系统的缓冲区空间不够保存需传送的数据，除非套接口处于非阻塞I/O方式，否则send()将阻塞。对于非阻塞SOCK_STREAM类型的套接口，实际写的数据数目可能在1到所需大小之间，其值取决于本地和远端主机的缓冲区大小。可用select()调用来确定何时能够进一步发送数据。    在相关套接口的选项之上，还可通过标志位flag来影响函数的执行方式。也就是说，本函数的语义既取决于套接口的选项也取决于标志位。后者由以下一些值组成：  值      意义  MSG_DONTROUTE   指明数据不选径。一个WINDOWS套接口供应商可以忽略此标志；参见2.4节中关于SO_DONTROUTE的讨论。  MSG_OOB     发送带外数据（仅适用于SO_STREAM；参见2.2.3节）。     返回值：    若无错误发生，send()返回所发送数据的总数（请注意这个数字可能小于len中所规定的大小）。否则的话，返回SOCKET_ERROR错误，应用程序可通过WSAGetLastError()获取相应错误代码。     错误代码：    WSANOTINITIALISED：在使用此API之前应首先成功地调用WSAStartup()。    WSAENETDOWN：WINDOWS套接口实现检测到网络子系统失效。    WSAEACESS：要求地址为广播地址，但相关标志未能正确设置。    WSAEINTR：通过一个WSACancelBlockingCall()来取消一个（阻塞的）调用。    WSAEINPROGRESS：一个阻塞的WINDOWS套接口调用正在运行中。    WSAEFAULT：buf参数不在用户地址空间中的有效位置。    WSAENETRESET：由于WINDOWS套接口实现放弃了连接，故该连接必需被复位。    WSAENOBUFS：WINDOWS套接口实现报告一个缓冲区死锁。    WSAENOTCONN：套接口未被连接。    WSAENOTSOCK：描述字不是一个套接口。    WSAEOPNOTSUPP：已设置了MSG_OOB，但套接口非SOCK_STREAM类型。    WSAESHUTDOWN：套接口已被关闭。一个套接口以1或2的how参数调用shutdown()关闭后，无法再用sned()函数。    WSAEWOULDBLOCK：    WSAEMSGSIZE：套接口为SOCK_DGRAM类型，且数据报大于WINDOWS套接口实现所支持的最大值。    WSAEINVAL：套接口未用bind()捆绑。    WSAECONNABORTED：由于超时或其他原因引起虚电路的中断。    WSAECONNRESET：虚电路被远端复位。

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

没人吗？？。。。。。


Question: C指针看着好晕！

推荐《C和指针》，讲的比较详细

充分理解“间接性”的概念和优势，无论在设计中还是编码中都会受益的。

多看多打代码，慢慢就会了，指针是C的难点，谁一开始都会晕的。

你得上手编程 光看没用 我当时学指针的时候也晕头转向的 用熟了就好了 都要经历这个过程的

学指针可以画画指向图，比较直观，再做做练习，比如用字符指针char*来遍历一个字符数组，找出所有数字字符来等等

看多了就好了..谁一开始看都晕

指针就是变量的地址，一块内存空间的起始地址。 多看，多练习。可参考的书籍有《C和指针》。  个人建议，仅供参考。

一开始看真的很头晕，多动手联系。就不晕了

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

可以使用画图，矩形表示内存块，箭头表示指针的方式帮助理解C里面的指针，刚开始学都这样，学会之后就会觉得这块很有意思的，很多东西利用指针很方便处理。


Question: 一个错误程序带来的问题~~求指点~~

引用 4 楼 huoqingna2332 的回复:明显是多了一个回车符，如果要别人的结果的话，代码增加处理回车符的程序。  while((ch=getchar())!='#') 		{  			if(ch!='\n') 				printf("Step 1\n"); 			else 				continue; 			if(ch=='b') 				break; 			else if(ch!='c') 			{ 				if(ch!='g') 					printf("Step 2\n"); 				printf("Step 3\n"); 			} 		}   增加如果遇到回车符，就continue，这样执行结果就是别人做出来的结果了。

需要吸收回车符，你每次输入一个字符然后有还有一个回车符

#include<stdio.h> int main(void) {     char ch;     while((ch=getchar())!='#')     {         if(ch!='\n')             printf("Step 1\n");         if(ch=='b')             break;         else if(ch!='c')         {             if(ch!='g')                 printf("Step 2\n");                 printf("Step 3\n");         }         while((ch = getchar()) != '\n') 	    ;     }     printf("Done!\n");     return 0; }

比如，你输入的是q，然后回车，即输入了两个字符：'q' + '\n'。'\n'就会打印"Step 2"和"Step 3"。


Question: 各位大神有没有打包的适合c语言初学着敲的程序代码，求支援啊

书上的示例程序就可以，多看书，多敲代码。我基本上都是多看书的，因为书上的代码出错率低

引用 5 楼 u013720580 的回复:引用 3 楼 oYinGui1 的回复:把书看了，课后习题做了就够。。要编好的你去背代码？知一不知二有什么意思不是背代码，我背那玩意干嘛，练敲代码的速度 你这个有点像中国足协搞得体能测试，测试踢足球的跑步速度。

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

引用 5 楼 u013720580 的回复:引用 3 楼 oYinGui1 的回复:把书看了，课后习题做了就够。。要编好的你去背代码？知一不知二有什么意思不是背代码，我背那玩意干嘛，练敲代码的速度 把书上的敲个几十遍，速度就上去了。

把书看了，课后习题做了就够。。要编好的你去背代码？知一不知二有什么意思

我现在才刚学没两天，自己编还不会，我想要编好的，我直接输，就像练打字一样

当当网《C++程序设计案例分析》，很多C程序： 第1章c++语言程序设计起步 　案例一自然数e的计算 　案例二产生10个随机数 　案例三求等式中方框里的数 　案例四四渠注水 第2章基本算法策略 　案例一鸡兔同笼问题 　案例二完全数 　案例三货币兑换问题 　案例四勾股数 　案例五打印年历 　案例六字符串的复制和连接 　案例七求支付方法的种类 第3章数据的组织(数组、指针、函数、结构体) 　案例一自由落体 　案例二回文数猜想 　案例三大赛评分 　案例四八进制、十进制、十六进制数之间的直接转换 　案例五姓名查找 　案例六电影票房排行榜 　案例七兔子繁殖问题 　案例八汉诺塔问题 　案例九学生信息管理系统 第4章数据的组织(类和对象、继承)  第4章开始C++程序。


Question: ZJU pat1012 通不过，求帮助

引用 1 楼 user-1 的回复:if (i==N)	printf("N/A"); 改为 if (i==N)	printf("N/A\n"); 即可AC.  太感谢了，我检查了好久，没想到就差了一个细节


Question: 有没有知道树的序列化与反序列化

《算法精解（C语言实现）》

是。。。。。

比如:     _30_    /    \      10    20  /     /  \ 50    45  35 就可以输出：30 10 50 # # # 20 45 # # 35 # #  反序列话的时候可以利用递归构造。

你按照顺序打印就好了（先序、中序、后序），之后按顺序取回数据然后重新构造下，如果左\右节点为空，可以输出特殊字符表示。  至于Java直接输出对象，的确是我孤陋寡闻了。

之前找到过那篇代码。我只想要个思路。。晓得怎么存，然后怎么重建，代码得自己写。。。

看下这个吧：http://blog.chinaunix.net/uid-24981687-id-351667.html

作为对象存？？啥意思？存些啥？类型信息，然后用反射重新构造该对象？  不是应该像反序列化Json一样，把字符串反过来构造成对象么？存的时候是字符串输出到文件上啊！！

谢谢解答。但是怎么作为一个对象存啊？

可以这么实现，不过严格来讲存的应该是一个object，像Java一样 纯属个人理解


Question: 求大神帮助，关于fopen的一点问题

不懂的问，不过记得给分

还有第三点，fgets函数的参数你用错了

#include<stdio.h> #include<stdlib.h> #include<string.h>  #define MAXSIZE 1000  int main() {     FILE *fp;     char input[MAXSIZE];     char output[MAXSIZE];     int in_len=0,ou_len=0;     fp=fopen("answer","r");      if(fp == NULL)     {         perror("fopen");         return 1;     }           while( fgets(input,MAXSIZE,fp)!=NULL )     {         in_len=strlen(input);         printf("number %d\n",in_len);         if(in_len>ou_len)         {             strcpy(output,input);             ou_len=in_len;             output[ou_len]='\0';         }     }      printf("%s,%d",output,ou_len);     fclose(fp);     return 0; } 以上是正确的代码。你的逻辑基本没有问题，但是小的细节有错 1）计算长度最好用strlen()函数 2）字符数组最后的字符为‘\0’或者0

改为fgets(input,MAXSIZE,fp)， fp=fopen("D:\\abc.txt","r+"); 这样可以免得无文件读取，刚弄出来，有人已经发了，

while( fgets(input,MAXSIZE, fp)!=NULL ) /*   **    你写错了! 其他的没仔细看。  */

FILE *fp=NULL;

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

output[ou_len]='0'; 应该改为 output[ou_len]= '\0'; 其他的没细看