Question: char数组初始化问题

C++ String Literals A string literal consists of zero or more characters from the source character set surrounded by double quotation marks ("). A string literal represents a sequence of characters that, taken together, form a null-terminated string.  Syntax  string-literal :  "s-char-sequenceopt" L"s-char-sequenceopt"  s-char-sequence :  s-char s-char-sequence s-char  s-char :  any member of the source character set except the double quotation mark ("), backslash (\), or newline character escape-sequence  C++ strings have these types:   Array of char[n], where n is the length of the string (in characters) plus 1 for the terminating '\0' that marks the end of the string   Array of wchar_t, for wide-character strings  The result of modifying a string constant is undefined. For example:  char *szStr = "1234"; szStr[2] = 'A';      // Results undefined  Microsoft Specific   In some cases, identical string literals can be “pooled” to save space in the executable file. In string-literal pooling, the compiler causes all references to a particular string literal to point to the same location in memory, instead of having each reference point to a separate instance of the string literal. The/Gf compiler option enables string pooling.  END Microsoft Specific  When specifying string literals, adjacent strings are concatenated. Therefore, this declaration:  char szStr[] = "12" "34";  is identical to this declaration:  char szStr[] = "1234";  This concatenation of adjacent strings makes it easy to specify long strings across multiple lines:  cout << "Four score and seven years "         "ago, our forefathers brought forth "         "upon this continent a new nation.";  In the preceding example, the entire string Four score and seven years ago, our forefathers brought forth upon this continent a new nation. is spliced together. This string can also be specified using line splicing as follows:  cout << "Four score and seven years \ ago, our forefathers brought forth \ upon this continent a new nation.";  After all adjacent strings in the constant have been concatenated, the NULL character, '\0', is appended to provide an end-of-string marker for C string-handling functions.  When the first string contains an escape character, string concatenation can yield surprising results. Consider the following two declarations:  char szStr1[] = "\01" "23"; char szStr2[] = "\0123";  Although it is natural to assume that szStr1 and szStr2 contain the same values, the values they actually contain are shown in Figure 1.1.  Figure 1.1   Escapes and String Concatenation    Microsoft Specific   The maximum length of a string literal is approximately 2,048 bytes. This limit applies to strings of type char[] and wchar_t[]. If a string literal consists of parts enclosed in double quotation marks, the preprocessor concatenates the parts into a single string, and for each line concatenated, it adds an extra byte to the total number of bytes.   For example, suppose a string consists of 40 lines with 50 characters per line (2,000 characters), and one line with 7 characters, and each line is surrounded by double quotation marks. This adds up to 2,007 bytes plus one byte for the terminating null character, for a total of 2,008 bytes. On concatenation, an extra character is added to the total number of bytes for each of the first 40 lines. This makes a total of 2,048 bytes. (The extra characters are not actually written to the string.) Note, however, that if line continuations (\) are used instead of double quotation marks, the preprocessor does not add an extra character for each line.  END Microsoft Specific  Determine the size of string objects by counting the number of characters and adding 1 for the terminating '\0' or 2 for type wchar_t.  Because the double quotation mark (") encloses strings, use the escape sequence (\") to represent enclosed double quotation marks. The single 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 string, you must type two backslashes (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)  To specify a string of type wide-character (wchar_t[]), precede the opening double quotation mark with the character L. For example:  wchar_t wszStr[] = L"1a1g";  All normal escape codes listed in Character Constants are valid in string constants. For example:  cout << "First line\nSecond line"; cout << "Error! Take corrective action\a";  Because the escape code terminates at the first character that is not a hexadecimal digit, specification of string constants with embedded hexadecimal escape codes can cause unexpected results. The following example is intended to create a string literal containing ASCII 5, followed by the characters five:  \x05five"  The actual result is a hexadecimal 5F, which is the ASCII code for an underscore, followed by the characters ive. The following example produces the desired results:   "\005five"     // Use octal constant. "\x05" "five"  // Use string splicing.

ANSI C标准 5.1.1.2 Translation phases 6.Adjacent string literal tokens are concatenated.  6.4.5 String literals 4.In translation phase 6, the multibyte character sequences specified by any sequence of adjacent character and wide string literal tokens are concatenated into a single multibyte character sequence. If any of the tokens are wide string literal tokens, the resulting multibyte character sequence is treated as a wide string literal; otherwise, it is treated as a character string literal.

有的 预编译阶段  会把 连续的多个字符串字面量处理成 一个字符串字面量  "123"           "321"   "123"                    "321"  会被处理为  "123321123321"    ps 有一些细则需要了解清楚 不过的确有这个规则就是了


Question: 如何把字符串作为变量名使用？？？可以吗？或者有解决的方法吗？

c++做不到。。

参考Code Generation

引用 2 楼 xihu1364 的回复:map<char*,num> mapVar;  mapVar.insert("num",1);  printf("%d\n",mapVar["num"]);  这样？

没有可能，看起来你似乎有些脚本方面的需求，可以看看C和Lua的结合。  引用 楼主 u012749695 的回复:如何把字符串作为变量名使用？？？可以吗？或者有解决的方法吗？ 比如已知a[3]="num" 我想定义一个int num 怎么样用已知的字符串完成这个定义

如果是编译时候还能用define搞搞，如果运行时基本不可能


Question: 优先级疑问

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

p++　这个表达式的值相当于是p，所以total=*p

错了，  因为 后++ 的表达式值是加之前的值。  a = *p ++ ; 等价为：  a = *p; p ++ ;  如果是前++，你的理解才对。


Question: 关于C语言，新手求教。。

引用 6 楼 bijiaoben 的回复:我没用过啊，求1楼的哥们儿来解答了 引用 1 楼 user-2 的回复:graphics.h？？可以做到吗 谢谢大家乐，用graphics.h可以解决。。至于那个错误问题也解决了，需要编译时文件命名为.cpp而不是.c

我没用过啊，求1楼的哥们儿来解答了

graphics.h？？可以做到吗

引用 4 楼 bijiaoben 的回复:头文件中肯定会有接口 调用库函数做事，虽然我不知道有没有符合你要求的函数，但是1楼说的大概就是这么个思路  这样啊，但是我在VC上调用graphics.h时出现错误提示耶：Easyx only for C++

引用 1 楼 user-2 的回复:graphics.h？？可以做到吗 ？？？你的意思是用graphics.h这个头文件？？但是具体怎样做呢

？？？你的意思是用graphics.h这个头文件？？但是具体怎样做呢

其实应该给1楼分多点，他的答案直中要害，我就是打打杂，愧受了分数


Question: 求C项目源码！！

vim源码行不？

CSDN里不是有很多..

libc(http://ftp.gnu.org/gnu/glibc/)源码比较合适。  引用 楼主 tr3301103 的回复:之前都只是用C敲一些简单的算法代码，现在希望能提升C语言软件开发方面的能力，就想找些源码来学习，在开源中国社区上找了一下，但貌似都很大，以目前本人的水平有点困难，所以求哪位有C语言项目开发经验的前辈指点一下，最好能够提供比较成熟的C项目代码（1万行以内的），或是C项目开发方面比较经典的书也行，谢谢！

接触一个好的项目代码，确实受益很大，但是是好的项目代码哦....

一开始不要搞那么复杂的，别人写的代码，不见得就好，或许你看别人写的一万行代码，得到的收获还比不上看一小段经典书籍中的代码得到的启发大，建议还是看经典的东西。比如《C算法》1-4卷，学习算法的同时，又可以学作者的编程思想，巩固基础。

linux源代码中随便摘录一段。

ngix, 好像有中文的源码分析书。  http://www.bing.com/search?q=ngix+%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90&qs=AS&form=QBRE&pq=ngix+%E9%B1%BC%E5%95%8A&sc=3-8&sp=2&sk=AS1

这个可以网上看一些开源的小游戏什么的！自己琢磨琢磨！


Question: 谁能帮忙看看这个程序段哪里不对。。。万分感激。。c，socket。

来个大神，拜托。问题一个接一个，烦死了

break只能退出一层循环


Question: 怎么按位与实现数据对齐。。

坚决消灭零恢复。

((ulong)char_ptr & (sizeof(ulong) - 1)) == 0表示与ulong对齐，例如： 假如a为一个2^n的数，那么测试一个数b与上a-1是否为0，则可以判断b是否是与n位对齐的数。 a = 2 ^ n if((b & (a - 1)) == 0   引用 楼主 u012559195 的回复:要求：判断一个字符直到内存对齐，如果在内存对齐之前就遇到'\0'则直接return typedef unsigned long  ulong;     size_t strlen_c(const char * str)     {           const char * char_ptr;       const ulong * longword_ptr;       register ulong longword, magic_bits;        for (char_ptr =  str; ((ulong)char_ptr& (sizeof(ulong) - 1)) != 0 ;++ char_ptr)           {              if (*char_ptr == '\0' )                   return char_ptr -  str;                  }     }    问题： for (char_ptr =  str; ((ulong)char_ptr& (sizeof(ulong) - 1)) != 0 ;++ char_ptr)  这个怎么实现数据对齐呢？ PS：数据对齐(data alignment)，是指数据所在的内存地址必须是该数据长度的整数倍，这样CPU的存取速度最快。比如在32位的计算机中，一个WORD为4 byte，则WORD数据的起始地址能被4整除的时候CPU的存取效率比较高。CPU的优化规则大概如下：对于n字节(n = 2,4,8...)的元素，它的首地址能被n整除才能获得最好的性能。

引用 6 楼 mujiok2003 的回复:假设sizeof(ulong) = 4, 则sizeof(ulong)-1= 3 = 0x03(二进制位0000 0011) 地址char_ptr & 0x03的结果是只保留地址的低2位,如果char_ptr & 0x03 = 0, 那么说明地址的低两位都是0，第一个非0的位置至少是第三位 地址的形式是: xxxx xxxx  xxxx xx00，那么肯定是4字节对齐了的。  明白了，谢谢啊。

引用 4 楼 u012559195 的回复:[quote=引用 1 楼 turingo 的回复:] ((ulong)char_ptr & (sizeof(ulong) - 1)) == 0表示与ulong对齐，例如： 假如a为一个2^n的数，那么测试一个数b与上a-1是否为0，则可以判断b是否是与n位对齐的数。 a = 2 ^ n if((b & (a - 1)) == 0   [quote=引用 楼主 u012559195 的回复:] 要求：判断一个字符直到内存对齐，如果在内存对齐之前就遇到'\0'则直接return typedef unsigned long  ulong;     size_t strlen_c(const char * str)     {           const char * char_ptr;       const ulong * longword_ptr;       register ulong longword, magic_bits;        for (char_ptr =  str; ((ulong)char_ptr& (sizeof(ulong) - 1)) != 0 ;++ char_ptr)           {              if (*char_ptr == '\0' )                   return char_ptr -  str;                  }     }    问题： for (char_ptr =  str; ((ulong)char_ptr& (sizeof(ulong) - 1)) != 0 ;++ char_ptr)  这个怎么实现数据对齐呢？ PS：数据对齐(data alignment)，是指数据所在的内存地址必须是该数据长度的整数倍，这样CPU的存取速度最快。比如在32位的计算机中，一个WORD为4 byte，则WORD数据的起始地址能被4整除的时候CPU的存取效率比较高。CPU的优化规则大概如下：对于n字节(n = 2,4,8...)的元素，它的首地址能被n整除才能获得最好的性能。[/quote]可是地址不一定是2^n的数。能再讲详细点吗？你举的这个例子我能理解，但是觉得你的例子太特殊了。[/quote] n不就是2，4，8，等，难道不是2^n？

引用 1 楼 turingo 的回复:((ulong)char_ptr & (sizeof(ulong) - 1)) == 0表示与ulong对齐，例如： 假如a为一个2^n的数，那么测试一个数b与上a-1是否为0，则可以判断b是否是与n位对齐的数。 a = 2 ^ n if((b & (a - 1)) == 0   [quote=引用 楼主 u012559195 的回复:] 要求：判断一个字符直到内存对齐，如果在内存对齐之前就遇到'\0'则直接return typedef unsigned long  ulong;     size_t strlen_c(const char * str)     {           const char * char_ptr;       const ulong * longword_ptr;       register ulong longword, magic_bits;        for (char_ptr =  str; ((ulong)char_ptr& (sizeof(ulong) - 1)) != 0 ;++ char_ptr)           {              if (*char_ptr == '\0' )                   return char_ptr -  str;                  }     }    问题： for (char_ptr =  str; ((ulong)char_ptr& (sizeof(ulong) - 1)) != 0 ;++ char_ptr)  这个怎么实现数据对齐呢？ PS：数据对齐(data alignment)，是指数据所在的内存地址必须是该数据长度的整数倍，这样CPU的存取速度最快。比如在32位的计算机中，一个WORD为4 byte，则WORD数据的起始地址能被4整除的时候CPU的存取效率比较高。CPU的优化规则大概如下：对于n字节(n = 2,4,8...)的元素，它的首地址能被n整除才能获得最好的性能。[/quote]可是地址不一定是2^n的数。能再讲详细点吗？你举的这个例子我能理解，但是觉得你的例子太特殊了。

[quote=引用 1 楼 turingo 的回复:] ((ulong)char_ptr & (sizeof(ulong) - 1)) == 0表示与ulong对齐，例如： 假如a为一个2^n的数，那么测试一个数b与上a-1是否为0，则可以判断b是否是与n位对齐的数。 a = 2 ^ n if((b & (a - 1)) == 0)  可是地址不一定是2^n的数。能再讲详细点吗？你举的这个例子我能理解，但是觉得你的例子太特殊了。


Question: 关于fread读取dat文件求助

fread不到文件结束不会不读吧

fread是按照指定长度去读取的，fgets才是遇到00结束。  引用 楼主 u010673033 的回复:我用fread去读dat文件时每次读取到00时系统就默认数据读取结束，而这00只是发送的数据，有什么办法可以使得读取dat文件能够完整呢，求各位大神帮忙，谢谢了！

fread如果没有到文件结尾的话，调用成功的话，都是按照用户提供的长度去读数据的！ 确认你的代码是否有bug吧！ 贴一部分源码上来看看

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  请检查每个函数的返回值。  不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

发代码来看


Question: 单链表删除节点操作，为什么执行到DeleteList（）时程序异常停止

引用 4 楼 u012330750 的回复:感谢大奶兔白糖和未注销，大奶兔白糖你讲的很到位，让我恍然大悟，谢谢你。未注销你以代码说话，也戳中了要害。谢谢你们！ 兄弟客气了，咱们就是要互相帮助，多谢给分

CreatList(L,n,arr); 	printf("输出链表："); 	LinkList tmp = L; 	for(int i=0;i<n;i++) 	{ 		printf("%d  ",tmp->next->data); 		tmp=tmp->next; 	} 	printf("\n");

你的void CreatList(LinkList &L,int n,int *arr)函数定义，是要传入一个LinkList的引用？如果是的话，这应该发C++那边去，因为在我的印象中C语言中没有引用。如果不是要传引用的话，这个代码就需要改了吧？ 输出链表的时候更改了L的值: printf("输出链表："); for(int i=0;i<n;i++) {  printf("%d  ",L->next->data);  L=L->next; } 所以后面在Delete链表的时候，L已经没有指向链表头了，而是指向了链表的。。。所以你删除的时候会出错。 while(p&&j<i-1) { p=p->next; printf("%d",p->data); j++; } r=p->next; 如果上面的循环是因为p为空的时候才退出的，下面的代码就完蛋了。

大神帮忙看一下


Question: XML复制到字符数组

xml信息里 有转义字符

""里面有"，注意转义。


Question: 类似QQ聊天对话框

你自己根据名称什么的管理所有创建的窗口，然后想怎么激活都没问题了

呵呵是什么意思？

有没有做过具体的案例呢呵呵

根据窗口标题FindWindow，找到窗口句柄后SetFocus或者好像有个SetActiveWindow

form.focus()?


Question: 指针问题不懂！

void swap(int *p1,int *p2) {     int *t;     t=p1;     p1=p2;     p2=t; } 这样更改的只是形参p1,p2的值，而不是p1,p2指向的变量的值。 因此这样在函数调用结束后，子函数栈帧数据被销毁。主函数栈帧将a,b地址弹出栈后，a,b的内容也没有改变。 而 void swap(int *p1,int *p2) {     int t;     t=*p1;     *p1=*p2;     *p2=t;   } 改变的是p1,p2指向单元的值，因此在主函数栈帧将a,b的地址弹出后，a,b的值发生了交换。

第一种交换的是地址上的值...但是地址没变~第二种是直接交换了地址

void swap(int *p1,int *p2) swap函数的参数是指针变量，你如果在函数体内对p1,p2进行操作的话，实际上操作的是形参而已，对实参(外部的a,b的地址)一点影响也没有。  把你的函数拆开,你的做法相当于 int* _p1 = p1; int* _p2 = p2; int* t; t = _p1; _p1 = _p2; _p2 = t; 结果只是改变_p1和_p2的值，当然对p1,p2没影响了。 假如a = 1, b = 2 按正确的写法,函数拆开是 int t; t = a;  //此时t = 1 a = b;  //此时a = 2 b = t;  //此时b = 1 (这里的*p1和*p2替换成a和b) 相当于直接给a,b赋值了。

先弄懂什么叫指针  什么叫取值  什么叫取地址

可以结贴了 2 4楼就是答案

地址取值 也还是只是一个值操作！   通过地址去操作地址上的内容！

楼主，看来你是初学者，没有理解好函数调用的形参与实参的含义。 记住并理解一句话：“要在调用函数中修改主函数的变量的值就一定要传递变量的指针”。 首先要搞清楚： 一： void swap(int a,int b) {     int t;     t = a;     a = b;     b = a;  } swap(a, b); 此函数不能交换变量a,b的值。 二： void swap(int *p1,int *p2) {     int t;     t = *p1;     *p1 = *p2;     *p2 = t;  } 此函数能改变原函数中变量a,b的值，因为传递的是a,b的指针（地址） 三： 你的这个函数： void swap(int *p1,int *p2) {     int *t;     t=p1;     p1=p2;     p2=t; } 我知道你意在交换指针变量p1,p2的值，但是它无法改变原函数中的p1,p2的值。 因为，原函数的p1,p2与被调函数的p1,p2是完全不同的，是互不影响的。 你交换了swap函数中p1,p2的值，是不会改变主函数中的p1,p2的值的。 要改变原函数的p1,p2的值，就必须传递p1,p2的指针。所谓指针的指针，其实就是指针变量的指针（地址）。  可以这样子改： #include<stdio.h> void main() {     void swap(int **p1,int **p2);     int a,b;     int *p1,*p2;     scanf("%d,%d",&a,&b);     p1=&a;     p2=&b;     if(a<b)         swap(&p1, &p2);     printf("%d,%d\n",*p1,*p2); }   void swap(int **p1,int **p2) {     int *t;     t = *p1;     *p1 = *p2;     *p2 = t;   } 当然这个程序实际意义不大，只是能让你更清楚地理解指针与指针变量的概念，以及函数调用的知识。 变量就是一段内存单元，变量的指针就是其内存单元的地址。 所以，任何一个变量都有指针，指针变量也有指针。 要想在被调函数修改主调函数中的变量的值，就必须传递变量的指针。

2楼给的例子很好

http://blog.csdn.net/sunruihua0522/article/details/17291881 参看下这篇文章

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

你写的代码好多小错误。 void main() {     void swap(int *p1,int *p2); //声明放到值函数外面，前面      scanf("%d,%d",&a,&b);    //，神马的。。。。  指针p1指向对象a的地址，改变*p1则指针所指的的值也随之改变  至于这个方法 void swap(int *p1,int *p2) {     int *t;     t=p1;     p1=p2;     p2=t; }  没感觉到与void swap(int p1,int p2) {     int t;     t=p1;     p1=p2;     p2=t; } 类型相似，只是函数中的形参在交换。只要一离开这个函数，指针所指的地址还是原来那样

因为swap函数中操作的是指针所指向的内存，也就是主函数中定义的变量a和b


Question: 已安装了libevent，编译已加-levent,为什么编译还是不能通过

应该要装libevent-devel

没有加头文件路径  -I<头文件路径>


Question: 求人指点一下数据结构的学习方向

用清华出版社严蔚敏写的那本数据结构(c语言版)

当你在选择数据结构的时候，能够产生出心情的时候，这就太棒了。这就像下围棋，我知道局部平衡度，但是我的心情不爽。嘎嘎

前面说到的数据结构是基本必须具备的。麻烦的问题是太多的变种是书上没有的。链表很简单，根据内存开销，至少有4种。这是需要研究的。众所周知，hash表是数组进行散列后的链表结构。如果维护个静态字典，纯粹的单向链表就足够了。在网络应用中，我们有时候想快速的清除一些过期session，hash下的爬表都有点不情愿。这时候需要能够自删除链表节点。这相当的高效。stl不是万能的，它只是普通情况的下的学术性解决方案。如果你开始学习数据结构，linux下的标准头文件目录下有个文件叫queue.h。里面描述了一部分链表的使用方式。

主要是看你是学这个考试比如考研还是致用。如果是致用的话，很简单。STL里有的数据结构都要熟悉。链表，hash表，AVLtree，RBtree，稍微复杂点的B+B-。排序类可以基本忽略太简单也太深，图类涉猎一下，需要的时候补一补。关键的是能灵活的用，每次选择一个数据结构能够提出自己的观点。比如说hash表，有至少16种变种。不同的情况使用不同的结构。

好高端...听都没听过= =。....那就清华的那本，别的几个人也是这么推荐的


Question: 运行时程序终止~~没有报错~~求指教~~

char *filename="E:\\temp\\mydata.bin"; 文件路径不存在新建一个文件夹temp

if(length+1>MAXLEN)         {             if(length+1>MAXLEN)             {                 printf("\nName too long.");                 exit(1);             }             fread(name,sizeof(char),length,pFile);             name[length]='\0';             fread(&age,sizeof(age),1,pFile);             printf(format,name,age);         }  这两个if真心让人看不懂啊。。。。   scanf(" %d",age);  楼上说的这个也是个问题

仅供参考： #include<stdio.h> #include<ctype.h> #include<string.h> #include<stdlib.h> #define MAXLEN 30 void listfile(char *filename); int main(void) {     char *filename="/tmp/test_dir/write.log"; //要有读写权限     char name[MAXLEN];     size_t length=0;     int age=0;     char answer='y';     FILE *pFile=fopen(filename,"wb+");     do     {         fflush(stdin);         printf("\nEnter a name less than %d characters:",MAXLEN);         gets(name);         printf("Enter the age of %s:",name);         scanf(" %d", &age); //这里的第二个参数是指针         length=strlen(name);         fwrite(&length,sizeof(length),1,pFile);         fwrite(name,sizeof(char),length,pFile);         fwrite(&age,sizeof(age),1,pFile);         printf("Do you want to enter another(y or n)?");         scanf("\n%c",&answer);     }while(tolower(answer)=='y');     fclose(pFile);     listfile(filename);     return 0; } void listfile(char *filename) {     size_t length=0;     char name[MAXLEN];     int age=0;     char format[20];     sprintf(format,"\n%%-%ds Age:%%4d",MAXLEN);     FILE *pFile=fopen(filename,"rb");     if(NULL != pFile){ //判断返回指针是否为NULL     	printf("\nThe contents of %s are:",filename);     	while(fread(&length,sizeof(length),1,pFile)==1)     	{     		if(length+1>MAXLEN) //原来这里你的判断逻辑有问题     		{     			printf("\nName too long.");     			exit(1);     		}     		fread(name,sizeof(char),length,pFile);     		name[length]='\0';     		fread(&age,sizeof(age),1,pFile);     		printf(format,name,age);     	}     	fclose(pFile);     } }

void listfile(char *filename) {     size_t length=0;     char name[MAXLEN];     int age=0;     char format[20];     sprintf(format,"\n%%-%ds Age:%%4d",MAXLEN);     FILE *pFile=fopen(filename,"rb");     printf("\nThe contents of %s are:",filename);     while(fread(&length,sizeof(length),1,pFile)==1)     {         if(length+1>MAXLEN)         {             if(length+1>MAXLEN)             {                 printf("\nName too long.");                 exit(1);             }             fread(name,sizeof(char),length,pFile);             name[length]='\0';             fread(&age,sizeof(age),1,pFile);             printf(format,name,age);         }         fclose(pFile);     } }  这函数代码很怪啊，fclose（）放在循环里面，fopen放在循环外面。。。。。

请判断每个函数调用的返回值！

scanf(" %d",age); scanf(" %d",&age);  另外fopen创建文件路径要先存在

判断下fopen打开是否成功吧！  对应api都判断下返回值！使用句柄前，判断下是否有效！


Question: 求助：输出单个字符的问题

可能win下底层自带清空缓存功能了。

引用 4 楼 zhao4zhong1 的回复:#include <stdio.h> #include <unistd.h>  void delay_play(char *str) {     while(*str)     {         putchar(*str++);         fflush(stdout);         usleep(1000000);     } }  int main(void) {     char *text = "I am chinese";      for(;;)     {         delay_play(text);         puts("");     }       return 0; } 可以简单解释一下吗？为什么清空缓存，而win下却不用

Name  usleep - suspend execution for microsecond intervals  Synopsis  #include <unistd.h>  int usleep(useconds_t usec); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): usleep(): Since glibc 2.12: _BSD_SOURCE ||     (_XOPEN_SOURCE >= 500 ||         _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) &&     !(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) Before glibc 2.12: _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED Description     The usleep() function suspends execution of the calling thread for (at least) usec microseconds. The sleep may be lengthened slightly by any system activity or by the time spent processing the call or by the granularity of system timers.

引用 2 楼 max_min_ 的回复:ulseep Linux是微秒级的吧  usleep(100000); //试试 你有没有测试一下啊？我测试还是不行，只是把整行输出延时久一点了。

ulseep Linux是微秒级的吧  usleep(100000); //试试


Question: cout<

需要严格控制的自己计算以下，不要依赖实现。

制表位置，根据已经输出的字符个数计算，然后再按照每个制表符占有的字符个数 计算制表符输出后下一个数据的位置。  例如 puts("123\tabcdefg"); 每个制表符 8字符，该行已经输出“123” ，3个字符，那么输出制表符后，下一个位置在（3+8）/8 =8 的位置 再输出 abcdefg 即输出  123_____abcdefg 其中下划线代表输出\t产生的空白。    其他输出也是这么处理的。

具体加在什么地方

cout << "...\t...";   不行？

cout<<'\t';

01.#include <iostream>   02.#include <iomanip>   03.#include <limits>   04.using std::cout;   05.using std::endl;   06.using std::setprecision;   07.using std::numeric_limits;   08.  09.int main() {   10.  const double pi = 3.14;   11.  cout << endl;   12.  13.  for(double radius = .2 ; radius <= 3.0 ; radius += .2)   14.    cout << "radius = "  15.    << setprecision(numeric_limits<double>::digits10 + 1)   16.    << std::scientific << radius<< "  area = "  17.         << std::setw(10) << setprecision(6)<< std::fixed << pi * radius * radi   18.us << endl;   19.  return 0;   20.}  #include <iostream> #include <iomanip> #include <limits> using std::cout; using std::endl; using std::setprecision; using std::numeric_limits; int main() {   const double pi = 3.14;   cout << endl;   for(double radius = .2 ; radius <= 3.0 ; radius += .2)     cout << "radius = "     << setprecision(numeric_limits<double>::digits10 + 1)     << std::scientific << radius<< "  area = "          << std::setw(10) << setprecision(6)<< std::fixed << pi * radius * radi us << endl;   return 0; }   radius = 2.0000000000000001e-001  area =   0.125600 radius = 4.0000000000000002e-001  area =   0.502400 radius = 6.0000000000000009e-001  area =   1.130400 radius = 8.0000000000000004e-001  area =   2.009600 radius = 1.0000000000000000e+000  area =   3.140000 radius = 1.2000000000000000e+000  area =   4.521600 radius = 1.3999999999999999e+000  area =   6.154400 radius = 1.5999999999999999e+000  area =   8.038400 radius = 1.7999999999999998e+000  area =  10.173600 radius = 1.9999999999999998e+000  area =  12.560000 radius = 2.1999999999999997e+000  area =  15.197600 radius = 2.3999999999999999e+000  area =  18.086400 radius = 2.6000000000000001e+000  area =  21.226400 radius = 2.8000000000000003e+000  area =  24.617600


Question: 四个输出，你的答案是什么？

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

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

2 2 3 0

作用域和生命周期  即可判断。

哦 纠正 注释有写 全局 那么D是 0

2 2 3 未定义行为 结果不可靠


Question: 用C语言，初学不会

可以封装成函数。如下： void FormatTime(unsigned int time) {     unsigned int seconds;     unsigned int minutes;     unsigned int hours;       seconds = time%60;     minutes = (time/60)%60;     hours = time/3600;     printf("%u:%.2u:%.2u\n",hours, minutes, seconds); }

引用 5 楼 bijiaoben 的回复:[quote=引用 4 楼 SKATE11 的回复:] 智者的梦再美，也不如愚人实干的步伐！ 讲一千遍理论，不如写一行代码！  任何语言不落实到实际行动上都等于白说， 没读过MSDN例子代码的程序员实在让人感到可怕！  用C语言1000行源码能完成的工作千万不要用C++重写， 整天把高级技术放在嘴边那是一种浮夸！  少年啊，千万要重视单步调试和设置断点， 用VC调试时记得按下Alt+5、Alt+6、Alt+7和Alt+8。   对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和 寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时 候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文 字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针 的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  进程都退出了，输入缓冲区刷不刷新都无关痛痒。  不要企图优雅的结束（因为这是不可能办到的） 而要在烂的不能再烂的摊子上也能重整河山！ 赵老师灵魂附体[/quote] 为什么有剪贴板这种应用

//输入一个0～86400的数作为秒数，将其转换成HH:MM:SS的格式输出 #include <stdio.h> int main() {     int secs;     while (1) {         printf("Input second(s)[0..86400]:");fflush(stdout);         rewind(stdin);         if (1==scanf("%d",&secs)) {             if (0<=secs && secs<=86400) break;         }     }     printf("%02d:%02d:%02d\n",secs/3600,secs/60%60,secs%60);     return 0; }

#include<stdio.h> int main() {    int a;    printf("%d:%d:%d\n",a/3600,a/60%60,a%60); }

引用 4 楼 SKATE11 的回复:智者的梦再美，也不如愚人实干的步伐！ 讲一千遍理论，不如写一行代码！  任何语言不落实到实际行动上都等于白说， 没读过MSDN例子代码的程序员实在让人感到可怕！  用C语言1000行源码能完成的工作千万不要用C++重写， 整天把高级技术放在嘴边那是一种浮夸！  少年啊，千万要重视单步调试和设置断点， 用VC调试时记得按下Alt+5、Alt+6、Alt+7和Alt+8。   对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和 寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时 候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文 字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针 的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  进程都退出了，输入缓冲区刷不刷新都无关痛痒。  不要企图优雅的结束（因为这是不可能办到的） 而要在烂的不能再烂的摊子上也能重整河山！ 赵老师灵魂附体

int num = 1234567; int h = num/3600; int m = (num - h*3600)/60; int s = num - h*3600 -m*60;


Question: md5算法，如果对一个文件生成md5

# time dd if=/dev/urandom ibs=1M count=5 | md5sum    5+0 records in 10240+0 records out c70b84415e6dd943ef1054f4cfdc5839  - 5242880 bytes (5.2 MB) copied, 0.705356 seconds, 7.4 MB/s  real    0m0.759s user    0m0.012s sys     0m0.708s  # time dd if=/dev/urandom ibs=1M count=50 | md5sum  50+0 records in 102400+0 records out 52428800 bytes (52 MB) copied, 7.16639 seconds, 7.3 MB/s 459e2d00b5a06761316caa9093d40b5e  -  real    0m7.184s user    0m0.060s sys     0m6.920s  # time dd if=/dev/urandom ibs=1M count=500 | md5sum  500+0 records in 1024000+0 records out 524288000 bytes (524 MB) copied, 69.3534 seconds, 7.6 MB/s 488c72f1c1e3df27535fc04082902eec  -  real    1m9.362s user    0m0.524s sys     1m7.668s  LZ可以猜猜，如果count继续变大，要算个MD5要多久？

顶16L，LZ确实想多了。  buffer为1024也许效率不是最高，那多少最高呢？  LZ可以自己先想想。  我的答案是，设置成和底层的disk io的一次读的buffer的大小一致，效率最好。  其实对待这个问题，最简单的方式就是先功能，后性能；在功能保证的前提下profile，调优。  而且就MD5来说，问题不在于计算，而是要读50G这么大的文件，天生磁盘IO就很大。

楼主想多了，

引用 10 楼 ForestDB 的回复:int MD5_Init(MD5_CTX *c);         int MD5_Update(MD5_CTX *c, const void *data,                          unsigned long len);         int MD5_Final(unsigned char *md, MD5_CTX *c); 基本操作就是： MD5_CTX c; MD5_Init(&c); // 初始化上下文 char buffer[1024]; // 定义一小块buffer，文件会读入此buffer while (read_1024_byte_of_file_into_buffer()) // 反复读文件内容，只到文件全部读完   MD5_Update(&c, buffer, 1024) // 用每次读到的内容去update md5上下文 char md5_digest[64]; MD5_Final(md5_digest, &c); // 从上下文中提取md5  上述的核心就是while循环，每次读一部分文件，然后根据读到的内容更新MD5值，如此反复，直至全部文件结束。  buffer小心为1024是否合适呢？可能不是效率最高吧

还真不慢，50M/S还不够你读的吗。

反正你眨一下眼睛就可以扫描好几次了

如果是几G的文件，还是要点时间的。

do it! you will know the truth

linux   md5sum 有源码

是 没你想的慢，比你想的快多了。

能耗多少时间？50MB/s ？

要不然你MD5计算的是什么呢。

需要的，文件中即使多一个空格，md5码也会不一样

必须将整个文件从头到尾读一遍。

当然要整个文件扫描，不会很慢。  引用 楼主 zrdongjiao 的回复:那么，这个算法是不是对整个文件扫描一遍？  如果整个文件扫描的话，那岂不是很慢，很耗时？

整个读取必须的

引用 3 楼 thefirstz 的回复:需要的，文件中即使多一个空格，md5码也会不一样 引用 6 楼 ForestDB 的回复:是 没你想的慢，比你想的快多了。  是否得开一个很大的缓冲区域，读取整个文件，进行计算？  比如几十g的电影，如何计算呢？


Question: sqrt

编译器没有那么智能，看到格式串里有%d并不会自动把double类型转成int型。而是把64位的double数据压到栈上，然后printf函数执行的时候解释栈上的数据，看到%d只会从栈里拿32位的数据。很有可能这个double数据的低32位当整数看待时就是0。

引用 3 楼 u011488256 的回复:[quote=引用 2 楼 ivyvae 的回复:] 因为double sqrt(double)返回类型是double。没有int sqrt（int）的重载。。   也就说你的sqrt（25）得出的结果是double类型，你用"%d"输出，肯定是0。改为"%f"就没问题了。 返回的是double类型，我用%d输出也应该有整数部分啊。就像我把double给了int c  打印C用%d 也是5啊   [/quote]不对，你用int c赋值就会隐试类型准换。"%d"输出则不会。。

我做了几次实验，每次输出都是不同的。我是UBUNTU13.10系统。           听说C语言中的函数参数传递是，C语言中，参数压栈的方向是从右往左。这样的话你的第二个参数 sqrt（25）就先输出。因为你sqrt(25)没有先初始化为int。输出的是人看不懂的乱码。 所以我的机器才会是一时正的很大，一时负的很大。

仅供参考： #include<stdio.h> #include<math.h> int main() {     printf("%d",(int)sqrt(25)); //sqrt返回值是double型的，强制转换成int     return 0; }

我的电脑输出是负数。-1195402056。。。。

我说的不对了。。。。。不懂

printf(const char *,....); printf函数是把内存中的值打印出来。  你这个程序 printf("%d\n", sqrt(25)); sqrt(25)是个函数，也是个指针。sqrt（25）指向一个值。  这个并不是你想象的 5.00000或者5什么的。 其实这个值用二进制表示 可能是 000111100111什么一堆乱七八糟的代码。 如果内存中的值不经过格式化。 那么内存的值，对于人来说是毫无意义的。  格式化，是把人眼看不懂的东西，利用输入输出设备强制转换成人眼看得懂的东西。5.0000这个值在CPU的角度看来毫无意义。

那么楼主你希望 printf("%此参数按熊猫的格式输出\n",CSDN中的u011488256); 输出啥呢？

引用 2 楼 ivyvae 的回复:因为double sqrt(double)返回类型是double。没有int sqrt（int）的重载。。   也就说你的sqrt（25）得出的结果是double类型，你用"%d"输出，肯定是0。改为"%f"就没问题了。 返回的是double类型，我用%d输出也应该有整数部分啊。就像我把double给了int c  打印C用%d 也是5啊

因为sqrt返回的是double类型 你应该使用printf（“%f”，sqrt（25））   或者printf（“%d”，(int)(sqrt（25）)）


Question: 对大端小端还有个疑问

要先转成网络字节顺序吧

是可以不用转换，只要你能保证两端是一致的就可以

对网络数据包的处理，接收到网络数据包，根据字节顺序进行存储，需要在网络字节顺序和主机字节顺序之间进行转换，c语言中提供的转换函数有：  #include <arpa/inet.h> uint32_t ntohl(uint32_t netlong); 　netlong：一个以网络[字节顺序表达的32位数。  uint32_t htonl(uint32_t hostlong);  hostlong：主机字节顺序表达的32位数。  u_short  htons( u_short hostshort);  hostshort：主机字节顺序表达的16位数。  uint16_t ntohs(uint16_t netshort);  本函数将一个32位数从主机字节顺序转换成网络字节顺序。

void HexDump(char *buf,int len) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%04x -",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]:'.');             }             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);     } }

如果你都是按字节来处理数据, 就不用管大端还是小端了.

应该是这样

你要是能确定都是小端，按理说不转也没问题。 更普遍的情况是，你不知道对方是大端还是小端机器。  因此 网络传输一般采用大端序，也被称之为网络字节序，或网络序。IP协议中定义大端序为网络字节序。

如果两边确定都是小端，确实可以不转。

如果你是写给自己用的代码, 确实可以不用转换. 但对于正式软件, 以后该代码可能会被移植到其他运行环境, 比如从PC(x86小端)移植到手机(arm大端), 这种假设就不成立了. 所以正式软件不能假设运行环境的字节序是怎样的.

谁说网络是大端模式。 网络不管模式，它是按字节流传输。多字节组合时才有大端小端的问题。

除了网络协议需要的数据（比如端口），用户数据不用转换。


Question: 单词博弈-这个代码哪里有问题？

“我在VS2012上跑了，都没有问题，似乎没有超过3秒。”  楼主确定自己计算的时间没错？

谁回复一下，给分结贴了。免得浪费。

自己顶上，想搞清楚这个问题。


Question: 一句难以理解的语句

前面一句的理解是：任意类型的指针都可以赋给void类型的指针。 后面一句的理解是：通过该指针来操作的数据都是操作数据本身，而不是数据的副本。  回答完毕。。

你想要用内存里面一段数据会怎么做 1. 把那段数据的全部内容拷贝过来再使用 2. 把那段数据的指针，也就是地址的值拷贝过来，使用的时候去访问这个值


Question: ++和+1的问题

后++保持表达式的值不变，所以条件不满足进入else事件中；+1表达式则会进1； 打印一下值，一目了然。 如果你的代码是完全正确的话，那么这个++是鸡肋(多余的)；至于书上是+1可能考虑到字符串尾端'\0'，请检查你的程序是否完全正确个人觉得起初定义时候char  str[][40]中应该是41比较符合书上中要表达的意思。  /*在这里打印一下下面if里的判断就一目了然*/ printf("sizeof(str[0])=%d,c1=%d,c2=%d\n",sizeof(str[0]), 	   count[0],count[1]);//40，18，22 //-->可以得出count[0]=strlen(str[0]),count[1]=strlen(str[1]);得到的是字符串的长度。 if(sizeof str[0]<count[0]+count[1]) printf("\nYou can't put a quart into a pint pot."); else { 	count[1]=0; 	while((str[0][count[0]++] = str[1][count[1]++])); 	 	printf("\n%s\n", str[0]); }

if (sizeof str[0]<count[0]+count[1]+1) 相当于 int temp = count[0]+count[1]+1; if (sizeof str[0] < temp) ----------------------------------------------- if (sizeof str[0]<count[0]+count[1]++) 相当于 int temp = count[0]+count[1]; count[1] = count[1] + 1; if (sizeof str[0] < temp)


Question: 一个自己真的完全都写不来的程序，求各位帮个忙

先写好 kmp 然后输入小说文件名 然后输入词汇集合，排个序（字典序）？ 然后，内部先匹配一下？？ 然后开始匹配。


Question: 这个头文件有什么作用？

machine-dependent definitions  看此头文件注释， 定义一些常量

这题太大了


Question: 关于TCP长连接

定时发送心跳包，收不到回应重连。

做应用层心跳。

引用 6 楼 max_min_ 的回复:心跳，保活！ +断线重连 这么多人要建立常连接？

心跳，保活！

但是也还会有意外断开的时候，然后再建立自动重连的机制。这是对长连接的很好的补充。

保持或保活的意思不就是发现断开马上重连吗？

不马上断就进入长连接

不就那几步，楼上说的就很对，保持双方都在线就ok！

引用 1 楼 user-9 的回复:客户端与服务端，心跳保持啊。 没啥可补充的了。

客户端与服务端，心跳保持啊。


Question: 可变参数列表

引用 8 楼 u012909623 的回复:[quote=引用 7 楼 bijiaoben 的回复:] *sarrayp++=va_arg(var_arg,int);//KEY problem 这个是先加再赋值还是先赋值再加？ 简单点说，先赋值再加 并且我也单独测试过分开赋值与加，结果一样的[/quote] 先赋值再加的话，你在gdb里看到的应该是未赋值的地址空间

此题已解决了

引用 7 楼 bijiaoben 的回复:*sarrayp++=va_arg(var_arg,int);//KEY problem 这个是先加再赋值还是先赋值再加？ 简单点说，先赋值再加 并且我也单独测试过分开赋值与加，结果一样的

因为我的代码有一部分内容不相干，所以我注释掉了，代码如下： 1.c #include "1.h" int array_offset(int arrayinfo[],...) { 	int loc; 	int low[10]; 	int high[10]; 	int sarray[10]; 	int *lowp=low; 	int *highp=high; 	int *sarrayp=sarray; 	int *arrayinfop=&arrayinfo[1]; 	 	va_list(var_arg); 	va_start(var_arg,arrayinfo); /* 	int dimension=arrayinfo[0]; 	if(dimension<1||dimension>10) 		return -1;  	while(dimension-->0) 	{ 		*lowp=*arrayinfop++; 		*highp=*arrayinfop++; 		if(*lowp>*highp) 			return -1; 		lowp++; 		highp++; 	} */	  	for(dimension=1;dimension<=arrayinfo[0];dimension++) 		*sarrayp++=va_arg(var_arg,int);//KEY problem 	va_end(var_arg);  	lowp=low; 	highp=high; 	sarrayp=sarray;  	//compute the consult; 	loc=*sarrayp++-*lowp++; 	if(arrayinfo[0]==1) 		return loc; 	for(dimension=2;dimension<=arrayinfo[0];dimension++) 	{ 		loc*=*highp++-*lowp+++1; 		loc+=*sarrayp-*lowp++; 	} 	return loc; } main.c #include "1.h" int main(void) { 	int arrayinfo[]={3,4,6,1,5,-3,3}; 	printf("%d\n",array_offset(arrayinfo,4,1,-3)); 	return 0; } 1.h #include <stdarg.h> int array_offset(int arrayinfo[],...);

请帖代码，不要只帖截图。

你看一下你的sarray数组里面的值呢。

引用 2 楼 user-4 的回复:#include <stdarg.h> #include <stdio.h> void foo(int argc,...) {     va_list vl;     va_start(vl,argc);     int* array = va_arg(vl,int*);     while(argc-- > 0)     {      *array++ = va_arg(vl,int);     }      va_end(vl);     }  int main() {   int array[] = {0,1,2,3,4,5},i;   foo(2, array, 10,9);   for(i = 0; i < 6; ++i)   {     printf("%d\n", array[i]);   }   return 0; }  参考一下。++

哟哟来人色    。


Question: 新手问题

char a[100];//a[0..99]里面有内存中原来的不确定值。

你的字符数组没有初始化，里面可能存有任何值的，而你从尾部开始查找非结束符，可能找到的并不是你输入的字符串的结尾。

char a[100];没有人为初始化， 对于栈上的变量一般是随机值， 全局的会用0初始化其内存， 最常见的就是访问违例和结果和预料的不一样， 所以要养成良好的编码习惯。


Question: 数据如何从内存中取出

如果字节序（写入的字节序和主机字节序)没有发生变化则不用考虑。

看看ntohs, ntohl, htons, htonl等怎么实现的。 提示:网络字节序是大端的。

大端小端是针对数据存放的位置, 在内存或者在磁盘等中. 比如有一个数据: DWORD val = 0xF1F2F3F4; 如果是小端: BYTE *pVal = (BYTE*)&val; pVal[0] == 0xF4 pVal[1] == 0xF3 pVal[2] == 0xF2 pVal[3] == 0xF1 大端就与之相反.  所以读取数据就没有你所说的问题, 大端, 按字节顺序访问,就先得到数据的高位, 如果小端就先得到数据的低位.

跨字节的数据结构需要考虑这个问题

参考http://blog.csdn.net/ce123_zhouwei/article/details/6971544  引用 楼主 mousestuman 的回复:我们知道大端是将数据的低位放入高字节内存中，小端与之相反，那么取数据时是先取低字节内存中的值，还是先取高字节呢？还有取出后高低字节的数据如何组织呢？事实上不同的取法也会导致不同的数据


Question: 【紧急求解】试写简易c语言网络答题软件时遇到的问题

已经解决。谢谢

在我之后尝试进行除错时将exit（0）都变成注解。得到结果如图，请问是怎么样的问题导致这样的结果，并且应当如何解决

if((select(10,&readfd,NULL,NULL,&tv))<=0) { printf("Select Error：%d\n",GetLastError()); exit(0);  } 错误打印出来看看


Question: fgets()参数问题。

安全无公害。

是没有必要，但是那样写也没有错。  引用 楼主 hyp41226 的回复://lianxi9.c 从l开始，根据加入列表的顺序为每个单词编号。当再次运行程序时，确保新的单词编号接着前面的编号开始。 #include <stdio.h> #include <stdlib.h> #define MAX 40 int main(void) {     FILE *fp; 	char words[MAX]; 	int count = 0; 	 	if((fp = fopen("worddy","a+")) == NULL) 	{ 	    fprintf(stderr,"Can't open \"worddy\" file.\n"); 		exit(EXIT_FAILURE); 	} 	rewind(fp); 	while(fgets(words,MAX-1,fp) != NULL)count++;             //这里没看懂，第二个参数有必要-1吗？fgets不是读取MAX-1个字符吗？然后在第MAX个字符加'\0' 	 	puts("Enter words to add to the file: press the Enter"); 	puts("key at the beginning of a line to terminate."); 	while(gets(words) != NULL && words[0] != '\0') 	    fprintf(fp,"%d:%s\n",count++,words);  	puts("File contents: "); 	rewind(fp); 	while(fscanf(fp,"%s",words) == 1) 	    puts(words); 	if(fclose(fp)!=0) 	    fprintf(stderr,"Errorclosing file\n"); 	return 0; }


Question: 关于数组函数的疑问

如果是我，将数组声明为全局变量，函数无参数，直接读写全局数组变量。

形参是形参，实参是实参，不一样。调用函数的时候是把实参复制了一份传给了形参，在子函数里改变形参的值并不会改变实参的值，如果需要在子函数里改变实参的值，需要传实参的地址进去，对实参的地址进行取值访问，然后对这个结果进行赋值就可以改变实参的值。

问题描述要准确 形参实参在任何时候都不同

引用 3 楼 user-6 的回复:C，C++数组在参数传递的时候，传递的是指针； 如果在函数里，改变这个指针的值，则不能修改实参，除非采用C++引用传递。  如果修改数组元素，因为这其实就是通过指针，修改指针指向的对象； 所以实参数组的的每个元素可以被改变。  从参数传递的角度考虑，除了C++的引用传递，可以改变实参本身以外；  C，C++的其他方式都是值传递，实参本身是不会被修改的，值传递是单向的。  PS： 指针参数值传递，可以改变数组元素，不可以改变指针本身。  ++

形参 和实参 一样的吗  是什么意思？  1  形参名字 跟 实参 名字可以不一样  2  这个函数调用后， 会改变 参数的值

疑问就在这里，这里形参和实参是一样的，实参与形参之间还是单身传递的吗，为什么我这个程序就可以将实参n的值改变，源code如下 #include  <stdio.h>  #define STU 30 #define COURSE 3  void Input(long num[],int score[][COURSE],int n); void GetSumAver(int score[][COURSE],int n,int sum[],float aver[]); void Sort(long num[],int score[][COURSE],int n,int sum[],float aver[]); void Print(long num[],int score[][COURSE],int n,int sum[],float aver[]); int  Search(long num[], int n, long x);  main() { 	int n, score[STU][COURSE], sum[STU], pos; 	long num[STU], x; 	float aver[STU];  	printf("Please enter the total number of the students(n<=30):"); 	scanf("%d", &n);					/*输入参加考试的学生人数*/  	printf("Enter No. and score as: MT  EN  PH\n"); 	Input(num, score, n);				/*输入学生成绩*/  	GetSumAver(score, n, sum, aver);	/*计算总分和平均分*/ 	printf("Before sort:\n"); 	Print(num, score, n, sum, aver);  	Sort(num, score, n, sum, aver);		/*排名次*/ 	printf("After sort:\n"); 	Print(num, score, n, sum, aver);  	printf("Please enter searching number:"); 	scanf("%ld", &x);					/*以长整型格式输入待查找学生的学号*/ 	pos = Search(num, n, x);			/*名次查询*/ 	if (pos != -1) 	{ 		printf("position:\t  NO \t  MT \t  EN \t  PH \t  SUM \t AVER\n"); 		printf("%8d\t%4ld\t%4d\t%4d\t%4d\t%5d\t%5.0f\n", 				     pos+1,num[pos],	score[pos][0],score[pos][1], 				     score[pos][2],	sum[pos],aver[pos]); 	} 	else 	{ 		printf("Not found!\n"); 	} }  /* 函数功能：输入某班学生期末考试三门课程成绩    函数参数：长整型数组num，存放学生学号              整型数组score，存放学生成绩 			    整型变量n，存放学生人数    函数返回值：无 */ void Input(long num[], int score[][COURSE], int n) { 	int  i, j;  	for (i=0; i<n; i++) 	{ 		scanf("%ld", &num[i]); 		for (j=0; j<COURSE; j++) 		{ 				scanf("%d", &score[i][j]); 		} 	} }  /* 函数功能：计算每个学生的总分和平均分    函数参数： 整型数组score，存放学生成绩 			     整型变量n，存放学生人数 		整型数组sum，计算得到的每个学生的总分 				实型数组aver，计算得到的每个学生的平均分    函数返回值：无 */ void GetSumAver(int score[][COURSE], int n, int sum[], float aver[]) { 	int i, j;  	for (i=0; i<n; i++) 	{ 		sum[i] = 0; 		for (j=0; j<COURSE; j++) 		{ 				sum[i] = sum[i] + score[i][j]; 		} 		aver[i] = (float)sum[i] / COURSE; 	} }  /* 函数功能：按总分成绩由高到低排出成绩的名次    函数参数：长整型数组num，存放学生学号              整型数组score，存放学生成绩 			整型变量n，存放学生人数 			整型数组sum，存放每个学生的总分 			实型数组aver，存放每个学生的平均分    函数返回值：无 */ void Sort(long num[],int score[][COURSE], int n, int sum[], float aver[]) { 	int i, j, k, m; 	int temp1; 	long temp2; 	float temp3;  	for (i=0; i<n-1; i++) 	{ 		k = i; 		for (j=i+1; j<n; j++) 		{ 				if (sum[j] > sum[k])  k = j; 		} 		if (k != i) 		{ 				temp1 = sum[k];  sum[k] = sum[i];  sum[i] = temp1; 				temp2 = num[k];  num[k] = num[i];  num[i] = temp2; 				temp3 = aver[k];  aver[k] = aver[i];  aver[i] = temp3; 				for (m=0; m<COURSE; m++) 				{ 					temp1 = score[k][m]; 					score[k][m] = score[i][m]; 					score[i][m] = temp1; 				} 		} 	} }  /* 函数功能： 打印名次表，表格内包括学生编号、各科分数、总分和平均分    函数参数： 长整型数组num，存放学生学号 				整型数组score，存放学生成绩 				整型变量n，存放学生人数 				整型数组sum，存放每个学生的总分 				实型数组aver，存放每个学生的平均分    函数返回值：无 */ void Print(long num[], int score[][COURSE], int n, 				int sum[], float aver[]) { 	int  i, j;  	printf("  NO \t|   MT \t  EN \t PH \t SUM \t AVER\n"); 	printf("----------------------------------------------------\n"); 	for (i=0; i<n; i++) 	{ 		printf("%ld\t| ", num[i]); 		for (j=0; j<COURSE; j++) 		{ 				printf("%4d\t", score[i][j]); 		} 		printf("%5d\t%5.0f\n", sum[i], aver[i]); 	} }  /* 函数功能：在学号数组中顺序查找学生的学号    函数参数：长整型数组num，存放学生学号              整型变量n，存放学生人数 		长整型变量x，存放待查找学生的学号    函数返回值：找到时，返回学生学号在学号数组中的下标位置，否则返回值-1 */ int Search(long num[], int n, long x) { 	int  i;  	for (i=0; i<n; i++) 	{ 		if (num[i] == x)  return(i); 	} 	return (-1); }


Question: 这是我写的暴破web密码c源代码，产生自卑感了吗？

引用 11 楼 Meteor_Code 的回复:lz可以试试用多线程，10个线程，这个测试量我估计能快5倍， 我看你好象是输入一个uid，其实没必要，学校的uid都是有规律的，你可以自动生成，你们系统的密码一般也是系统有默认的方式，比如生日这种，你就根据uid应该可以推算出这个人的生日年代，然后最多测试366次，总有很多人不修改自己默认密码的，这样扫一天下来，命中率一定不少  我是为定向暴破某号准备的，大范围扫有什么意思，不如用burp suite了，所以还是要自己输入要暴破的ID的，目的不同嘛。

LZ你又来调皮了。

Are you kidding me?

除了代码风格有点恶心外，  功能确认令人汗颜阿！

陷入的深深的自卑中

确实深深的汗言

深深的汗言,

我年轻那会儿，大家都抱着dos内核分析这本书，我们当时有个协会。大家写的程序也大多是tsr程序，现在叫病毒吧。后来再也没写过。我坦白交代下这些年我用程序做的坏事儿。很多年前，我对启点读书网的等级着迷，我写了个perl的脚本去刷积分，达到了大恶魔级，后来被封了，我确实是恶魔。我在wow里写了个lua脚本，天天玩战场，所有的UT或YY团队都骂这家伙怎么总是出现，哇哈哈。继续wow继续lua，我写了差不多几千行的lua脚本，外面写了个外挂，去打boss。猫德，每次我一身垃圾装备进去跟人彪dps，然后在YY里吹嘘自己的技术，嘎嘎。每次，我的任务就是跑好位，蹲在boss的屁股后面。我没传播，我差不多干了2年这种无耻的事情，没被发现，OY。我想想，我还干过什么无耻的事情？我儿子最近学英语，我希望用英语考他的书写。当时，我好像用个很傻缺的语言，flash air在google的官网上下载了很多的语音。后来我发现自己很傻缺，那个你敲点啥进去都能发音，不过确实挺准的。哈哈。娱乐我觉得挺有意思，不要危害他人。

没注释，没缩进

楼主的图比代码好看多了


Question: 【求教】结构体带指针嵌套

引用 1 楼 paopaozai 的回复:不用数组的话可以每增加一个就分配一个student结构体需要的空间的内存，然后把指针指向这个分配的内存。 删除的时候记得把对应内存释放掉。这样的话具体应该如何实现呢？我写了一下总是出问题= =


Question: C语言的char *和string / Bus Error的问题

这里我想象了一下，不知道原因是不是因为C语言的stack结构，导致该string被其他的变量值“挤”在了中间？？？  是不是在C中，char *类型的变量基本不要拿来作为string，要用string需要用char a[100] 这种规定好了长度的char数组才行啊？？？(如果是这样的话，数组长度固定，为了满足需求，只能写一个很大的数字，造成空间上的浪费。。。。)  -------------------------------------- 必须分配空间，不过你可以预算下或者用程序计算下你需要分配的长度，然后再定义数组。

1 eg1 :helloworld是在常量区，p只是一个指针指向这一块常量区   eg2:必须为a分配内存，char a[10]，这样a分配了10个char字节，然后在接收你的输入 2 没什么问题，你是写错了吧，下面这样。  void getUsrName(char **p){ #ifdef WIN32     *p=getenv("USERNAME"); #else     *p=getenv("USER"); #endif }

void getUsrName(char **p){ #ifdef WIN32     *p=getenv("USERNAME"); #else     *p=getenv("USER"); #endif }    int functionXXX(....){     char *p;     getUsrName(&p)    //只是想在这列让p的值=系统用户名     ........// 接下来会有若干步操作,只要不修改p指向的内容     printf("%s",p)     return EXIT_SUCCESS; }  GETENV Section: POSIX Programmer's Manual (P) Updated: 2003  --------------------------------------------------------------------------------    NAME getenv - get value of an environment variable    SYNOPSIS #include <stdlib.h>    char *getenv(const char *name);      DESCRIPTION The getenv() function shall search the environment of the calling process (see the Base Definitions volume of IEEE Std 1003.1-2001, Chapter 8, Environment Variables) for the environment variable name if it exists and return a pointer to the value of the environment variable. If the specified environment variable cannot be found, a null pointer shall be returned. The application shall ensure that it does not modify the string pointed to by the getenv() function.   The string pointed to may be overwritten by a subsequent call to getenv(), setenv(), or unsetenv(), but shall not be overwritten by a call to any other function in this volume of IEEE Std 1003.1-2001.   If the application modifies environ or the pointers to which it points, the behavior of getenv() is undefined.   The getenv() function need not be reentrant. A function that is not required to be reentrant is not required to be thread-safe.     RETURN VALUE Upon successful completion, getenv() shall return a pointer to a string containing the value for the specified name. If the specified name cannot be found in the environment of the calling process, a null pointer shall be returned.   The return value from getenv() may point to static data which may be overwritten by subsequent calls to getenv(), setenv(), or unsetenv().   On XSI-conformant systems, the return value from getenv() may point to static data which may also be overwritten by subsequent calls to putenv().     ERRORS No errors are defined.   The following sections are informative.     EXAMPLES    Getting the Value of an Environment Variable The following example gets the value of the HOME environment variable.     #include <stdlib.h> ... const char *name = "HOME"; char *value;   value = getenv(name);      APPLICATION USAGE None.     RATIONALE The clearenv() function was considered but rejected. The putenv() function has now been included for alignment with the Single UNIX Specification.   The getenv() function is inherently not reentrant because it returns a value pointing to static data.   Conforming applications are required not to modify environ directly, but to use only the functions described here to manipulate the process environment as an abstract object. Thus, the implementation of the environment access functions has complete control over the data structure used to represent the environment (subject to the requirement that environ be maintained as a list of strings with embedded equal signs for applications that wish to scan the environment). This constraint allows the implementation to properly manage the memory it allocates, either by using allocated storage for all variables (copying them on the first invocation of setenv() or unsetenv()), or keeping track of which strings are currently in allocated space and which are not, via a separate table or some other means. This enables the implementation to free any allocated space used by strings (and perhaps the pointers to them) stored in environ when unsetenv() is called. A C runtime start-up procedure (that which invokes main() and perhaps initializes environ) can also initialize a flag indicating that none of the environment has yet been copied to allocated storage, or that the separate table has not yet been initialized.   In fact, for higher performance of getenv(), the implementation could also maintain a separate copy of the environment in a data structure that could be searched much more quickly (such as an indexed hash table, or a binary tree), and update both it and the linear list at environ when setenv() or unsetenv() is invoked.   Performance of getenv() can be important for applications which have large numbers of environment variables. Typically, applications like this use the environment as a resource database of user-configurable parameters. The fact that these variables are in the user's shell environment usually means that any other program that uses environment variables (such as ls, which attempts to use COLUMNS ), or really almost any utility ( LANG , LC_ALL , and so on) is similarly slowed down by the linear search through the variables.   An implementation that maintains separate data structures, or even one that manages the memory it consumes, is not currently required as it was thought it would reduce consensus among implementors who do not want to change their historical implementations.   The POSIX Threads Extension states that multi-threaded applications must not modify environ directly, and that IEEE Std 1003.1-2001 is providing functions which such applications can use in the future to manipulate the environment in a thread-safe manner. Thus, moving away from application use of environ is desirable from that standpoint as well.     FUTURE DIRECTIONS None.     SEE ALSO exec() , putenv() , setenv() , unsetenv() , the Base Definitions volume of IEEE Std 1003.1-2001, Chapter 8, Environment Variables, <stdlib.h>     COPYRIGHT Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html .  --------------------------------------------------------------------------------

1、直接初始化，a会被放在常量区，其内容不能被改写； 2、用之前可以现malloc分配内存，strcpy可以进行字符串赋值。  引用 楼主 soul376 的回复:CSDN论坛真是有爱啊， 小弟最近在写一个跟string有关的程序 对C语言中的string和char * / char[]有各种疑惑  第一个问题： C语言中，可以直接对指向char的指针变量进行赋值操作吗？  eg1:这个貌似正常  char *a="hello world";   eg2:这个一般来说会出现bus error  char *a; .........//中间若干步其他操作 scanf("%s",a)   这里我想象了一下，不知道原因是不是因为C语言的stack结构，导致该string被其他的变量值“挤”在了中间？？？  是不是在C中，char *类型的变量基本不要拿来作为string，要用string需要用char a[100] 这种规定好了长度的char数组才行啊？？？(如果是这样的话，数组长度固定，为了满足需求，只能写一个很大的数字，造成空间上的浪费。。。。)   问题2：这是我最近写的一个利用getenv()获得用户名的function，由于考虑到了Windows和Linux的兼容问题，我套用了外部函数，代码如下：  void getUsrName(char **p){ #ifdef WIN32     userName=getenv("USERNAME"); #else     (*userName)=getenv("USER"); #endif }   int functionXXX(....){     char *p;     getUsrName(&p)    //只是想在这列让p的值=系统用户名     ........// 接下来会有若干步操作     printf("%s",p)     return EXIT_SUCCESS; }   我现在很担心这个代码会不会也有类似的风险(BUS ERROR), 或者有其他的问题？ 求高人指点(真心不太想写一个长度很长的char p[xx] 数组，感觉浪费空间，而且长度上不好拿捏。。。。)

eg2这样写有问题吗？ char *a; char ca[10] = "123456"; a = ca; printf("%s\n",a);  是你没理解指针，不是这代码不行。

你第一个写法就有问题，编译器没警告？ 应当写成： const char* var = "XXXXX";  你第二个写法没有分配内存。 简单来说，楼主完全没有理解指针与内存分配的概念。


Question: Segmentation fault (core dumped) linux C编程，50分

引用 7 楼 hy09070422 的回复:[quote=引用 5 楼 hy09070422 的回复:] [quote=引用 3 楼 bijiaoben 的回复:] 百度了一下，函数原型int stat(const char *file_name, struct stat *buf); 所以感觉应该是用了野指针，先给ptr1申请一下内存再试试看呢。 我试试看，谢谢！[/quote]  引用 6 楼 user-2 的回复:[quote=引用 2 楼 bijiaoben 的回复:] struct stat *ptr1;，定义之后没看到给ptr1分配空间啊。 stat(from_file,ptr1)；这个函数原型是什么？如果要修改ptr1结构体成员的值的话，你的ptr1根本没有向系统申请有效的内存空间啊。如果是让ptr1指向另外一个结构体，应该传递&ptr1给stat函数吧？   应该是这个问题。[/quote] 谢谢 确实是这个问题 自己对指针理解有问题。太感谢了！[/quote] 结帖收分

引用 5 楼 hy09070422 的回复:[quote=引用 3 楼 bijiaoben 的回复:] 百度了一下，函数原型int stat(const char *file_name, struct stat *buf); 所以感觉应该是用了野指针，先给ptr1申请一下内存再试试看呢。 我试试看，谢谢！[/quote]  引用 6 楼 user-2 的回复:[quote=引用 2 楼 bijiaoben 的回复:] struct stat *ptr1;，定义之后没看到给ptr1分配空间啊。 stat(from_file,ptr1)；这个函数原型是什么？如果要修改ptr1结构体成员的值的话，你的ptr1根本没有向系统申请有效的内存空间啊。如果是让ptr1指向另外一个结构体，应该传递&ptr1给stat函数吧？   应该是这个问题。[/quote] 谢谢 确实是这个问题 自己对指针理解有问题。太感谢了！

引用 2 楼 bijiaoben 的回复:struct stat *ptr1;，定义之后没看到给ptr1分配空间啊。 stat(from_file,ptr1)；这个函数原型是什么？如果要修改ptr1结构体成员的值的话，你的ptr1根本没有向系统申请有效的内存空间啊。如果是让ptr1指向另外一个结构体，应该传递&ptr1给stat函数吧？   应该是这个问题。

引用 3 楼 bijiaoben 的回复:百度了一下，函数原型int stat(const char *file_name, struct stat *buf); 所以感觉应该是用了野指针，先给ptr1申请一下内存再试试看呢。 我试试看，谢谢！

引用 2 楼 bijiaoben 的回复:struct stat *ptr1;，定义之后没看到给ptr1分配空间啊。 stat(from_file,ptr1)；这个函数原型是什么？如果要修改ptr1结构体成员的值的话，你的ptr1根本没有向系统申请有效的内存空间啊。如果是让ptr1指向另外一个结构体，应该传递&ptr1给stat函数吧？ stat(from_file,ptr1)；这个函数就是基本函数 将ptr1指针指向from_file路径对应的文件。 因为如果没有子文件夹的递归访问 程序是可以实现功能，stat函数，ptr1也可以正常工作的。 我不太清楚是不是分配空间的问题，如果没有子文件夹，指针可以运行。谢谢！

在cs240文件夹里面有一个子文件夹，当访问子文件夹中的文件时，出错。如果直接访问，cs240文件夹中其他文件，则没有问题。 网上说的core方法，没用同，刚接触linux 只会gcc盲调，所以很纠结！谢谢了！


Question: 大神可以救救我么，我太笨了，看书也看不懂，就是谭浩强那本c语言，然后就来了个通天的作业

没办法，这是作业，而我的水平还在数组排序之类的，唉， 引用 4 楼 turingo 的回复:直接用C语言工作量太大了。  [quote=引用 2 楼 u013169337 的回复:] 可是我们不会数据库，只能用c,而且我连c都不怎么熟悉  [quote=引用 1 楼 turingo 的回复:] 直接用数据库啦，比如SQLite(http://www.sqlite.org/).  [quote=引用 楼主 u013169337 的回复:] 就是这个，会的大神一定要帮我啊，有源代码的可不可以发给我，邮箱547081377@qq.com   实现一个基于命令行的简单数据库系统  基本功能： 建立数据库表 能够对数据库中的单表进行数据导入 能够对数据库中的单表进行插入 能够对数据库中的单表进行查询 能够对数据库中的单表进行更新 能够对数据库中的单表进行删除  高级功能： 	当数据量比较大的时候，请大家建立索引，并通过索引加快查询速度（选作）  要求： 不能使用Cstring.h，string等类，只能使用char* 来处理字符串 能够动态的申请和分配内存  上交的内容： 	1、.cpp、.h、.exe文件 	2、文件命名规则：学号_[数字].cpp    学号_[数字].h	    学号.exe  程序具体要求： 在命令行下运行  学号.exe  出现界面如下   按输入参数	 –c 文件路径名		表示根据指定位置的文件内语句建立一个数据库表 文件格式如下： 　　CREATE TABLE   table_name     		(column_name    datatype(datalength)    [NULL／NOT NULL]; 　　… 　　 )   　　 　　参数说明 　　table_name：是新表的名称。表名最多可包含 128 个字符 　　column_name：是表中的列名。列名必须符合标识符规则，并且在表内唯一。 datatype：是表中的列的数据类型。要求支持以下两类：数字（float）和字符串(char) datalength：是表中的列的数据长度。如果datatype是数字，长度一律为4，如果是字符串，则表示允许的字符串的最大长度。 ［NULL／NOT NULL］：是表中列的取值是否能为空的标志。［］表明本项可不出现。如果不出现，默认为NULL，也就是可以为空。  　　参数之间以单个空格分开。多列之间以分号分隔。  				 –i 数据库表名 数据文件路径名		表示从指定文本文件中导入数据到数据库的表中 数据文件格式如下： 　　每条记录占一行，一行中的数据每列之间以逗号分隔。 			注意：实际提交后测试的数据文件中的数据量可能会比较大，几万条，上百兆。  　　举例：（上面建立的student表的数据） 　　1,aaa,97 　　2,bbb,87 　　3,ccc,56 　　 –s 文件路径名			表示从指定文本文件中读取语句执行查询操作 文件格式如下： 　　select [TOP n]	* | {column_name} from table_name [where  colume_name like | = column_value and | or … [order by column_name [ASC | DESC] ]  ]  　　参数说明： 　　TOP n：表示查询结果显示最多多少个，n为显示的记录条数；［］表明本项可不出现。 　　｜：表明｜的左边和右边为“或”的关系，只出现任一项即可； 　　＊：代表所有的列名； 　　｛column_name｝：是希望筛选的列名的表列，多个列名以逗号分隔，｛｝必须要有。 table_name：是数据库中待进行筛选操作的表名。 column_value：是表中该列的数据值。 like|=：字符串型的column_value用＝关键字，表明精确匹配；用like关键字，表明模糊匹配，即column_value应当是列中值的子串。 　　数值型的column_value用＝关键字，精确查询；不支持用like关键字。 and|or：表明多个筛选条件的逻辑关系。 order by： 表示按照后跟的column_name列进行排序，ASC表示升序，DESC表示降序，默认是升序排列。  查询后，将查询结果在屏幕上显示出来，应计算本次查询操作所花费的执行时间，并生成 学号_select_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　查询结果 　　 –u 文件路径名		表示从指定文本文件中读取语句执行更新操作 文件格式如下： 　　update table_name set colume_name = column_value  [where column_name = column_value and | or …]  　　参数说明 　　column_name：是表中的列名。 table_name：是数据库中的表名 column_value：是表中的列的数据值。  更新后，将更新结果在屏幕上显示出来， 应计算本次更新操作所花费的执行时间，并生成 学号_update_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　更新后的结果 　　 –d 文件路径名			表示从指定文本文件中读取语句执行删除操作 文件格式如下： delete from table_name [where column_name = column_value] 　　参数说明 　　column_name：是表中的列名。 Table_name：是数据库中的表名 Column_value：是表中的列的数据值。  删除后，将删除结果在屏幕上显示出来， 应计算本次删除操作所花费的执行时间，并生成 学号_delete_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　删除后的结果  –h						帮助信息，提示各个参数的格式和含义 –q						退出程序 –index 0/1				0表示关闭索引功能，1表示打开索引功能，即在接下来的查询、更新、删除操作中使用索引。    例如： 程序执行界面如下：   相关文件格式如下: create.txt create table Student ( 　　id float(4) NOT NULL； 	name char(100) NULL; 	grade float(4) NULL; )  data.txt 1,aaa,90 2,bbb,90 3,ccc,90 4,ddd,80 5,ddd,70  select1.txt select top 2 * from Student where grade = 90  09xxxx _select_1.txt execute time: 1ms execute result: 1,aaa,90 2,bbb,90  update1.txt update Student set grade = 80 where id = 5  09xxxx _update_1.txt execute time: 1ms execute result: 5,ddd,80  delete1.txt delete from Student where id = 4  09xxxx_delete_1.txt execute time: 1ms execute result: 1,aaa,90 2,bbb,90 3,ccc,90 5,ddd,80[/quote][/quote][/quote]

直接用C语言工作量太大了。  引用 2 楼 u013169337 的回复:可是我们不会数据库，只能用c,而且我连c都不怎么熟悉  [quote=引用 1 楼 turingo 的回复:] 直接用数据库啦，比如SQLite(http://www.sqlite.org/).  [quote=引用 楼主 u013169337 的回复:] 就是这个，会的大神一定要帮我啊，有源代码的可不可以发给我，邮箱547081377@qq.com   实现一个基于命令行的简单数据库系统  基本功能： 建立数据库表 能够对数据库中的单表进行数据导入 能够对数据库中的单表进行插入 能够对数据库中的单表进行查询 能够对数据库中的单表进行更新 能够对数据库中的单表进行删除  高级功能： 	当数据量比较大的时候，请大家建立索引，并通过索引加快查询速度（选作）  要求： 不能使用Cstring.h，string等类，只能使用char* 来处理字符串 能够动态的申请和分配内存  上交的内容： 	1、.cpp、.h、.exe文件 	2、文件命名规则：学号_[数字].cpp    学号_[数字].h	    学号.exe  程序具体要求： 在命令行下运行  学号.exe  出现界面如下   按输入参数	 –c 文件路径名		表示根据指定位置的文件内语句建立一个数据库表 文件格式如下： 　　CREATE TABLE   table_name     		(column_name    datatype(datalength)    [NULL／NOT NULL]; 　　… 　　 )   　　 　　参数说明 　　table_name：是新表的名称。表名最多可包含 128 个字符 　　column_name：是表中的列名。列名必须符合标识符规则，并且在表内唯一。 datatype：是表中的列的数据类型。要求支持以下两类：数字（float）和字符串(char) datalength：是表中的列的数据长度。如果datatype是数字，长度一律为4，如果是字符串，则表示允许的字符串的最大长度。 ［NULL／NOT NULL］：是表中列的取值是否能为空的标志。［］表明本项可不出现。如果不出现，默认为NULL，也就是可以为空。  　　参数之间以单个空格分开。多列之间以分号分隔。  				 –i 数据库表名 数据文件路径名		表示从指定文本文件中导入数据到数据库的表中 数据文件格式如下： 　　每条记录占一行，一行中的数据每列之间以逗号分隔。 			注意：实际提交后测试的数据文件中的数据量可能会比较大，几万条，上百兆。  　　举例：（上面建立的student表的数据） 　　1,aaa,97 　　2,bbb,87 　　3,ccc,56 　　 –s 文件路径名			表示从指定文本文件中读取语句执行查询操作 文件格式如下： 　　select [TOP n]	* | {column_name} from table_name [where  colume_name like | = column_value and | or … [order by column_name [ASC | DESC] ]  ]  　　参数说明： 　　TOP n：表示查询结果显示最多多少个，n为显示的记录条数；［］表明本项可不出现。 　　｜：表明｜的左边和右边为“或”的关系，只出现任一项即可； 　　＊：代表所有的列名； 　　｛column_name｝：是希望筛选的列名的表列，多个列名以逗号分隔，｛｝必须要有。 table_name：是数据库中待进行筛选操作的表名。 column_value：是表中该列的数据值。 like|=：字符串型的column_value用＝关键字，表明精确匹配；用like关键字，表明模糊匹配，即column_value应当是列中值的子串。 　　数值型的column_value用＝关键字，精确查询；不支持用like关键字。 and|or：表明多个筛选条件的逻辑关系。 order by： 表示按照后跟的column_name列进行排序，ASC表示升序，DESC表示降序，默认是升序排列。  查询后，将查询结果在屏幕上显示出来，应计算本次查询操作所花费的执行时间，并生成 学号_select_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　查询结果 　　 –u 文件路径名		表示从指定文本文件中读取语句执行更新操作 文件格式如下： 　　update table_name set colume_name = column_value  [where column_name = column_value and | or …]  　　参数说明 　　column_name：是表中的列名。 table_name：是数据库中的表名 column_value：是表中的列的数据值。  更新后，将更新结果在屏幕上显示出来， 应计算本次更新操作所花费的执行时间，并生成 学号_update_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　更新后的结果 　　 –d 文件路径名			表示从指定文本文件中读取语句执行删除操作 文件格式如下： delete from table_name [where column_name = column_value] 　　参数说明 　　column_name：是表中的列名。 Table_name：是数据库中的表名 Column_value：是表中的列的数据值。  删除后，将删除结果在屏幕上显示出来， 应计算本次删除操作所花费的执行时间，并生成 学号_delete_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　删除后的结果  –h						帮助信息，提示各个参数的格式和含义 –q						退出程序 –index 0/1				0表示关闭索引功能，1表示打开索引功能，即在接下来的查询、更新、删除操作中使用索引。    例如： 程序执行界面如下：   相关文件格式如下: create.txt create table Student ( 　　id float(4) NOT NULL； 	name char(100) NULL; 	grade float(4) NULL; )  data.txt 1,aaa,90 2,bbb,90 3,ccc,90 4,ddd,80 5,ddd,70  select1.txt select top 2 * from Student where grade = 90  09xxxx _select_1.txt execute time: 1ms execute result: 1,aaa,90 2,bbb,90  update1.txt update Student set grade = 80 where id = 5  09xxxx _update_1.txt execute time: 1ms execute result: 5,ddd,80  delete1.txt delete from Student where id = 4  09xxxx_delete_1.txt execute time: 1ms execute result: 1,aaa,90 2,bbb,90 3,ccc,90 5,ddd,80[/quote][/quote]

假设发贴的那人是个一B 那么,引用的那个人一定是二B

可是我们不会数据库，只能用c,而且我连c都不怎么熟悉  引用 1 楼 turingo 的回复:直接用数据库啦，比如SQLite(http://www.sqlite.org/).  [quote=引用 楼主 u013169337 的回复:] 就是这个，会的大神一定要帮我啊，有源代码的可不可以发给我，邮箱547081377@qq.com   实现一个基于命令行的简单数据库系统  基本功能： 建立数据库表 能够对数据库中的单表进行数据导入 能够对数据库中的单表进行插入 能够对数据库中的单表进行查询 能够对数据库中的单表进行更新 能够对数据库中的单表进行删除  高级功能： 	当数据量比较大的时候，请大家建立索引，并通过索引加快查询速度（选作）  要求： 不能使用Cstring.h，string等类，只能使用char* 来处理字符串 能够动态的申请和分配内存  上交的内容： 	1、.cpp、.h、.exe文件 	2、文件命名规则：学号_[数字].cpp    学号_[数字].h	    学号.exe  程序具体要求： 在命令行下运行  学号.exe  出现界面如下   按输入参数	 –c 文件路径名		表示根据指定位置的文件内语句建立一个数据库表 文件格式如下： 　　CREATE TABLE   table_name     		(column_name    datatype(datalength)    [NULL／NOT NULL]; 　　… 　　 )   　　 　　参数说明 　　table_name：是新表的名称。表名最多可包含 128 个字符 　　column_name：是表中的列名。列名必须符合标识符规则，并且在表内唯一。 datatype：是表中的列的数据类型。要求支持以下两类：数字（float）和字符串(char) datalength：是表中的列的数据长度。如果datatype是数字，长度一律为4，如果是字符串，则表示允许的字符串的最大长度。 ［NULL／NOT NULL］：是表中列的取值是否能为空的标志。［］表明本项可不出现。如果不出现，默认为NULL，也就是可以为空。  　　参数之间以单个空格分开。多列之间以分号分隔。  				 –i 数据库表名 数据文件路径名		表示从指定文本文件中导入数据到数据库的表中 数据文件格式如下： 　　每条记录占一行，一行中的数据每列之间以逗号分隔。 			注意：实际提交后测试的数据文件中的数据量可能会比较大，几万条，上百兆。  　　举例：（上面建立的student表的数据） 　　1,aaa,97 　　2,bbb,87 　　3,ccc,56 　　 –s 文件路径名			表示从指定文本文件中读取语句执行查询操作 文件格式如下： 　　select [TOP n]	* | {column_name} from table_name [where  colume_name like | = column_value and | or … [order by column_name [ASC | DESC] ]  ]  　　参数说明： 　　TOP n：表示查询结果显示最多多少个，n为显示的记录条数；［］表明本项可不出现。 　　｜：表明｜的左边和右边为“或”的关系，只出现任一项即可； 　　＊：代表所有的列名； 　　｛column_name｝：是希望筛选的列名的表列，多个列名以逗号分隔，｛｝必须要有。 table_name：是数据库中待进行筛选操作的表名。 column_value：是表中该列的数据值。 like|=：字符串型的column_value用＝关键字，表明精确匹配；用like关键字，表明模糊匹配，即column_value应当是列中值的子串。 　　数值型的column_value用＝关键字，精确查询；不支持用like关键字。 and|or：表明多个筛选条件的逻辑关系。 order by： 表示按照后跟的column_name列进行排序，ASC表示升序，DESC表示降序，默认是升序排列。  查询后，将查询结果在屏幕上显示出来，应计算本次查询操作所花费的执行时间，并生成 学号_select_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　查询结果 　　 –u 文件路径名		表示从指定文本文件中读取语句执行更新操作 文件格式如下： 　　update table_name set colume_name = column_value  [where column_name = column_value and | or …]  　　参数说明 　　column_name：是表中的列名。 table_name：是数据库中的表名 column_value：是表中的列的数据值。  更新后，将更新结果在屏幕上显示出来， 应计算本次更新操作所花费的执行时间，并生成 学号_update_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　更新后的结果 　　 –d 文件路径名			表示从指定文本文件中读取语句执行删除操作 文件格式如下： delete from table_name [where column_name = column_value] 　　参数说明 　　column_name：是表中的列名。 Table_name：是数据库中的表名 Column_value：是表中的列的数据值。  删除后，将删除结果在屏幕上显示出来， 应计算本次删除操作所花费的执行时间，并生成 学号_delete_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　删除后的结果  –h						帮助信息，提示各个参数的格式和含义 –q						退出程序 –index 0/1				0表示关闭索引功能，1表示打开索引功能，即在接下来的查询、更新、删除操作中使用索引。    例如： 程序执行界面如下：   相关文件格式如下: create.txt create table Student ( 　　id float(4) NOT NULL； 	name char(100) NULL; 	grade float(4) NULL; )  data.txt 1,aaa,90 2,bbb,90 3,ccc,90 4,ddd,80 5,ddd,70  select1.txt select top 2 * from Student where grade = 90  09xxxx _select_1.txt execute time: 1ms execute result: 1,aaa,90 2,bbb,90  update1.txt update Student set grade = 80 where id = 5  09xxxx _update_1.txt execute time: 1ms execute result: 5,ddd,80  delete1.txt delete from Student where id = 4  09xxxx_delete_1.txt execute time: 1ms execute result: 1,aaa,90 2,bbb,90 3,ccc,90 5,ddd,80[/quote]

直接用数据库啦，比如SQLite(http://www.sqlite.org/).  引用 楼主 u013169337 的回复:就是这个，会的大神一定要帮我啊，有源代码的可不可以发给我，邮箱547081377@qq.com   实现一个基于命令行的简单数据库系统  基本功能： 建立数据库表 能够对数据库中的单表进行数据导入 能够对数据库中的单表进行插入 能够对数据库中的单表进行查询 能够对数据库中的单表进行更新 能够对数据库中的单表进行删除  高级功能： 	当数据量比较大的时候，请大家建立索引，并通过索引加快查询速度（选作）  要求： 不能使用Cstring.h，string等类，只能使用char* 来处理字符串 能够动态的申请和分配内存  上交的内容： 	1、.cpp、.h、.exe文件 	2、文件命名规则：学号_[数字].cpp    学号_[数字].h	    学号.exe  程序具体要求： 在命令行下运行  学号.exe  出现界面如下   按输入参数	 –c 文件路径名		表示根据指定位置的文件内语句建立一个数据库表 文件格式如下： 　　CREATE TABLE   table_name     		(column_name    datatype(datalength)    [NULL／NOT NULL]; 　　… 　　 )   　　 　　参数说明 　　table_name：是新表的名称。表名最多可包含 128 个字符 　　column_name：是表中的列名。列名必须符合标识符规则，并且在表内唯一。 datatype：是表中的列的数据类型。要求支持以下两类：数字（float）和字符串(char) datalength：是表中的列的数据长度。如果datatype是数字，长度一律为4，如果是字符串，则表示允许的字符串的最大长度。 ［NULL／NOT NULL］：是表中列的取值是否能为空的标志。［］表明本项可不出现。如果不出现，默认为NULL，也就是可以为空。  　　参数之间以单个空格分开。多列之间以分号分隔。  				 –i 数据库表名 数据文件路径名		表示从指定文本文件中导入数据到数据库的表中 数据文件格式如下： 　　每条记录占一行，一行中的数据每列之间以逗号分隔。 			注意：实际提交后测试的数据文件中的数据量可能会比较大，几万条，上百兆。  　　举例：（上面建立的student表的数据） 　　1,aaa,97 　　2,bbb,87 　　3,ccc,56 　　 –s 文件路径名			表示从指定文本文件中读取语句执行查询操作 文件格式如下： 　　select [TOP n]	* | {column_name} from table_name [where  colume_name like | = column_value and | or … [order by column_name [ASC | DESC] ]  ]  　　参数说明： 　　TOP n：表示查询结果显示最多多少个，n为显示的记录条数；［］表明本项可不出现。 　　｜：表明｜的左边和右边为“或”的关系，只出现任一项即可； 　　＊：代表所有的列名； 　　｛column_name｝：是希望筛选的列名的表列，多个列名以逗号分隔，｛｝必须要有。 table_name：是数据库中待进行筛选操作的表名。 column_value：是表中该列的数据值。 like|=：字符串型的column_value用＝关键字，表明精确匹配；用like关键字，表明模糊匹配，即column_value应当是列中值的子串。 　　数值型的column_value用＝关键字，精确查询；不支持用like关键字。 and|or：表明多个筛选条件的逻辑关系。 order by： 表示按照后跟的column_name列进行排序，ASC表示升序，DESC表示降序，默认是升序排列。  查询后，将查询结果在屏幕上显示出来，应计算本次查询操作所花费的执行时间，并生成 学号_select_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　查询结果 　　 –u 文件路径名		表示从指定文本文件中读取语句执行更新操作 文件格式如下： 　　update table_name set colume_name = column_value  [where column_name = column_value and | or …]  　　参数说明 　　column_name：是表中的列名。 table_name：是数据库中的表名 column_value：是表中的列的数据值。  更新后，将更新结果在屏幕上显示出来， 应计算本次更新操作所花费的执行时间，并生成 学号_update_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　更新后的结果 　　 –d 文件路径名			表示从指定文本文件中读取语句执行删除操作 文件格式如下： delete from table_name [where column_name = column_value] 　　参数说明 　　column_name：是表中的列名。 Table_name：是数据库中的表名 Column_value：是表中的列的数据值。  删除后，将删除结果在屏幕上显示出来， 应计算本次删除操作所花费的执行时间，并生成 学号_delete_序号.txt的文本文件，在文件的开头写明:  	Execute Time: …ms 　　Execute Result: 　　删除后的结果  –h						帮助信息，提示各个参数的格式和含义 –q						退出程序 –index 0/1				0表示关闭索引功能，1表示打开索引功能，即在接下来的查询、更新、删除操作中使用索引。    例如： 程序执行界面如下：   相关文件格式如下: create.txt create table Student ( 　　id float(4) NOT NULL； 	name char(100) NULL; 	grade float(4) NULL; )  data.txt 1,aaa,90 2,bbb,90 3,ccc,90 4,ddd,80 5,ddd,70  select1.txt select top 2 * from Student where grade = 90  09xxxx _select_1.txt execute time: 1ms execute result: 1,aaa,90 2,bbb,90  update1.txt update Student set grade = 80 where id = 5  09xxxx _update_1.txt execute time: 1ms execute result: 5,ddd,80  delete1.txt delete from Student where id = 4  09xxxx_delete_1.txt execute time: 1ms execute result: 1,aaa,90 2,bbb,90 3,ccc,90 5,ddd,80


Question: c问他求教

楼主 说说你的需求吧！ 这个代码写的太水了，循环太多次，浪费时间了

目测不是死循环，只是计算的时间太长了，需要比较10*127^10次，估计能算到下一代计算机出现了

system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。

for(FileName[0]=1;FileName[0]!=-128;FileName[0]++) { for(FileName[1]=0;FileName[1]!=-128;FileName[1]++) { for(FileName[2]=0;FileName[2]!=-128;FileName[2]++) { for(FileName[3]=0;FileName[3]!=-128;FileName[3]++) { for(FileName[4]=0;FileName[4]!=-128;FileName[4]++) { for(FileName[5]=0;FileName[5]!=-128;FileName[5]++) { for(FileName[6]=0;FileName[6]!=-128;FileName[6]++) { for(FileName[7]=0;FileName[7]!=-128;FileName[7]++) { for(FileName[8]=0;FileName[8]!=-128;FileName[8]++) { for(FileName[9]=0;FileName[9]!=-128;FileName[9]++)  你这不就是在进行深层次循环吗？  这个计算时间应该会很长。  文件改小些测试一下。

引用 7 楼 baichi4141 的回复:楼主这段代码如果用每秒54.9千万亿次浮点计算能力的天河-2来执行，只需要2.3天就可以完成 高人，大神

楼主折腾啥呢？

需求是什么？  引用 楼主 u012690483 的回复:void OpenFile() { 	char FileName[15]={'\0'}; 	char Name[15]={'\0'}; 	FILE *file; 	system("cls"); 	for(FileName[0]=1;FileName[0]!=-128;FileName[0]++) 	{ 		for(FileName[1]=0;FileName[1]!=-128;FileName[1]++) 		{ 			for(FileName[2]=0;FileName[2]!=-128;FileName[2]++) 			{ 				for(FileName[3]=0;FileName[3]!=-128;FileName[3]++) 				{ 					for(FileName[4]=0;FileName[4]!=-128;FileName[4]++) 					{ 						for(FileName[5]=0;FileName[5]!=-128;FileName[5]++) 						{ 							for(FileName[6]=0;FileName[6]!=-128;FileName[6]++) 							{ 								for(FileName[7]=0;FileName[7]!=-128;FileName[7]++) 								{ 									for(FileName[8]=0;FileName[8]!=-128;FileName[8]++) 									{ 										for(FileName[9]=0;FileName[9]!=-128;FileName[9]++) 										{ 											for(int i=0;i<10;i++) 											{ 												if(FileName[i]==0) 												{ 													Name[i]='.'; 													Name[i+1]='l'; 													Name[i+2]='g'; 													Name[i+3]='f'; 													Name[i+4]='\0'; 													break; 												} 												else 												{ 													Name[i]=FileName[i]; 												} 											} 											//printf("%s\n",Name); 											if((fopen_s(&file,FileName,"r"))==false) 											{ 												printf("\s",FileName); 												fclose(file); 											} 										} 									} 								} 							} 						} 					} 				} 			} 		} 	} 	system("pause"); }  上面的代码想搜索.lgf的文件，可为什么它会是死循环呢？


Question: 求问VisualStudio一个解决方案中的两个项目的调试问题

第二个进程中断了，再绑定进程吧

感觉这种情况，用log 文件，可能更好

调试汇编。逆向追踪。

开两个vs. 第二个程序启动后，attch, 设置断点，调试。


Question: 函数的局部变量

这样做法确实很危险；毕竟tmp是局部变量；只不过你的运气好，暂时没有出错；

内存被回收了 只是数据没有清除而已  这样做是危险的  如果后面有数据入栈 那就无法预料了

只是暂时没有覆盖而已，实际上这片地址已经被操作系统回收了，只是未做他用 没有改变而已，对于未知的东西 你看到的没改变 只是暂时的而已

To break when the value at a specified memory address changes  1.	From the Edit menu, click Breakpoints. 2.	Click the Data tab of the Breakpoints dialog box. 3.	In the Expression text box, type the memory address for the byte.  For a word or doubleword memory address, enclose the address in parentheses, and precede it with a cast operator. For example, WO(21406036) for the word at memory location 21406036. Use the cast operator BY for a byte (optional), WO for a word, or DW for a doubleword. (The debugger interprets all integer constants as decimal unless they begin with zero (0) for octal or zero and x (0x) for hexadecimal.) 4.	In the Number Of Elements text box, type the number of bytes, words, or doublewords to monitor. If you used the BY operator in the Expression field, specify the number of bytes. If you used WO, specify the number of words. If you used DW, specify the number of doublewords.  5.	Click OK to set the breakpoint.

其实你的行为已经是非法操作了，编译器不够严谨的话是可以通过的，你返回了一个已经被释放的内存的地址，然后再主函数中访问这个地址，如果说在你在主函数访问这个地址之前这个内存的地址被重新分配并赋值了，那么子函数中返回的地址中的数据就会被覆盖掉。这种行为本身实不可取的，

这样是非常危险的，只不过暂时没有被其它数据覆盖而已。  引用 楼主 mousestuman 的回复:#include <stdio.h> #include <malloc.h> struct my {int a;};  struct my *f0() {struct my tmp;  tmp.a = 1;  return &tmp; }  void main() { 	struct my *tmpp; 	 	tmpp = f0(); 	printf("%d",tmpp->a);  } 在函数f0中定义了一个局部结构体变量tmp，然后返回其地址。在main函数中调用了f0，返回值赋值给了指针tmpp，我想问的是为什么下面的printf("%d",tmpp->a);能输出局部变量tmp的内部成员，为什么tmp这个局部变量在f0函数调用后没有被销毁？

有可能被其他数据覆盖


Question: 代码里有重复的函数定义,但是编译链接的时候不会报错,为什么

今天问了下同事，他说那些重复定义的函数有些没用到

是c语言，搜函数定义发现好几个函数体，我在不同的项目代码里碰到很多次了，有可能是楼上说的情况之一，我周一再去仔细看看，代码保密的，拷不出来～

这个上代码比较好 楼上说的条件编译情况下函数被忽略了也有可能

引用 9 楼 qq6680040 的回复:引用 8 楼 bijiaoben 的回复:[quote=引用 7 楼 qq6680040 的回复:] [quote=引用 3 楼 bijiaoben 的回复:] C语言有函数重载？LZ有说一定是C语言吗？ 这不是C语言版面吗？[/quote]我是从C/C++那进来的...[/quote] 那是大版，下面还有小版面，你把这帖子拉到顶上看看

引用 8 楼 bijiaoben 的回复:引用 7 楼 qq6680040 的回复:[quote=引用 3 楼 bijiaoben 的回复:] C语言有函数重载？LZ有说一定是C语言吗？ 这不是C语言版面吗？[/quote]我是从C/C++那进来的...

引用 7 楼 qq6680040 的回复:引用 3 楼 bijiaoben 的回复:C语言有函数重载？LZ有说一定是C语言吗？ 这不是C语言版面吗？

口说无凭，个人更相信编译器。

1. 条件编译只有一个生效 2. LZ把声明看成了定义? 3. 函数定义是static的 4. 函数实现完全一样, 某些编译器会允许.

引用 12 楼 A3872215 的回复:这个我也遇到过 ，例如  添加 #include <unistd.h>后， 再定义一个 link的变量，就会这样 l.c:5: error: ‘link’ redeclared as different kind of symbol /usr/include/unistd.h:806: note: previous declaration of ‘link’ was here make: *** [l.o] 错误 1 这应该是 说 #include <unistd.h> 中已经有了一个 link的变量。 不知道你的是否 也是这样的问题。 lz的问题是他看到函数重复定义但是编译器没报错。。。

会不会有什么预编译选项楼主没注意到，例如： #if #else #endif

感觉不太可能   除非编译器坑爹

C语言有函数重载？

“重复的函数定义”你确定没有不小心弄成函数重载了？

先上代码再说


Question: 两个 c 语言的小问题

第一个问题的解答： 在你的程序中添加一条语句，你就会明白了： #include<stdio.h>   int main() {     char c;       do     {      ;         c=getchar();         printf("3\n");         printf("%d\n", c);     }while(c=='y'||c=='Y'); } 当你输入y然后敲回车后，系统是认为你输入了两个字符：y和'\n'. 所以输出两个3, 然后程序结束。   PS:'\n'的ASCII值为10

#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

请检查scanf的返回值！

getchar 读了回车符 maybe

在scanf的格式化参数中加入空格    scanf(" %c %d %f",&name[i],&code[i],&price[i]);

你这两个问题都是没有清除 你输入时候 的 '\n'。 用getchar（）接收一下就好了。 1 #include<stdio.h>   2 #define N 2   3    4 int main()   5 {   6         int i,code[2];   7         char name[2];   8         float price[2];   9         for(i=0;i<N;i++)  10         {  11                 printf("Please input the name,code,price:");  12                 scanf("%c %d %f",&name[i],&code[i],&price[i]);  13                 getchar();  14         }  15   16         printf("Name   Code   Price\n");  17         for(i=0;i<N;i++)  18         {  19                 printf("%c   %d   %f \n",name[i],code[i],price[    i]);  20         }  21 }

你是输入的y加回车两个字符，第一次打印一个3然后判断是y继续循环，这时候c=getchar(); c=回车 ，打印一个3，然后while判断不是y或者Y，结束循环。  可以 看下我以前的测试， http://blog.csdn.net/terhack/article/details/5425915  因为getchar，scanf这些函数不自动清空输入输出缓冲区，必须人为手动清空，所以输入最好用cin不要用,你用cin就正确了。

#include<stdio.h> #define N 2 int main() {     int i,code[2];     char name[2];     float price[2];     for(i=0;i<N;i++)     { 	         printf("Please input the name,code,price:");         scanf("%c %d %f",&name[i],&code[i],&price[i]); 		getchar();     } 	     printf("Name   Code   Price\n");     for(i=0;i<N;i++)     {         printf("%c   %d   %f \n",name[i],code[i],price[i]);     } 		 }

#include<stdio.h> void  main() {  char c;     do     {    	c=getchar(); 	printf("3\n");   	getchar();     }while(c=='y'||c=='Y'); }

因为getchar是输入字符的，它吃字符；当你输入y的时候getchar是y，然后输出3，接着有个回车，getchar默认你输入的事回车，不是y就结束了

引用 1 楼 bijiaoben 的回复:因为你是先打印了3，然后才判断输入是否为y问题是为什么不继续执行？

1.你先去看看 DO WHILE的语法 2.你第二次FOR循环 的%c接受的是你上次一次的回车（换行符）剩下的你自己去看看书。

因为你是先打印了3，然后才判断输入是否为y


Question: getchar()怎样用？？

就是闲的 加上的 ，想看 打个断点不就行了，纯粹是为了F5调试的时候不想让命令行窗口消失，就这么点用途，价格断点就ok了

智者的梦再美，也不如愚人实干的步伐！ 讲一千遍理论，不如写一行代码！  任何语言不落实到实际行动上都等于白说， 没读过MSDN例子代码的程序员实在让人感到可怕！  用C语言1000行源码能完成的工作千万不要用C++重写， 整天把高级技术放在嘴边那是一种浮夸！  少年啊，千万要重视单步调试和设置断点， 用VC调试时记得按下Alt+5、Alt+6、Alt+7和Alt+8。   对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和 寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时 候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文 字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针 的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  进程都退出了，输入缓冲区刷不刷新都无关痛痒。  不要企图优雅的结束（因为这是不可能办到的） 而要在烂的不能再烂的摊子上也能重整河山！

谢谢大家的帮助。。。。

引用 2 楼 zhuobattle 的回复:等待输入，有输入后让循环继续，否则while(1)直接cpu冲满 谢了，最近学习Windows程序设计，一头雾水

引用 1 楼 truelance 的回复:就是停下来等使用者按一个键再继续. 谢谢了，最近在学习Windows程序设计。

等待用户输入一个字节！ 这里应该是通过用户控制循环输出而已！

等待输入，有输入后让循环继续，否则while(1)直接cpu冲满

就是停下来等使用者按一个键再继续.

引用 3 楼 max_min_ 的回复:等待用户输入一个字节！ 这里应该是通过用户控制循环输出而已！ 在此处程序利用输入一个任意键来实现停顿的功能。好观察输出量

getchar()函数的作用是从终端输入一个字符。 我想这里的意思是想看清每次的变化。


./configure -h

敢问带的参数在哪里看。。。。 make后生成的不是.a文件吧！

先./configure 后面带些参数 然后make 大部分的开源库都是这样的，具体你可以摸索摸索


Question: 求问怎么理解c语言这个语句typedef int (*a)();

引用 5 楼 stormier 的回复:[quote=引用 2 楼 modyaj 的回复:] a是个指针  指向一个函数  该函数的参数是0个 返回值是int的类型  至于怎么用 网上搜一下 函数指针和指针函数 彻底弄懂他们了就简单了 给个地址 http://www.programfan.com/blog/article.asp?id=6030 同上。 比如我自己写一个也行。  typedef int (*a)(); int b() {return 1;}  a c=b; c(); 绝对错误[/quote]  没有错误

定义函数指针！

typedef int (*a)();是定义一个函数指针；a是函数名称，*号在这里可有可无；只不过在应用的时候有所不同；

引用 13 楼 sinservice 的回复:诸位看下这个：     int * (* ( * a）（））[10]; 反正我就用左右法则来读  还是能理解的了

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

//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组指向了一个指针，该指针指向一个函数，该函数的无参数，返回一个指针，该指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*x000)[5];//返回值     char (*(x00)())[5];//函数原型，参数为空，返回值为指针     char (*(*x0)())[5];//数组的元素，是个函数指针     char (*(*x[3])())[5];//是个数组，大小为3      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]  #include <stdio.h> double A[300][100]; double valuex[300]; double valuey[300]; int i; double fun00(double x,double y) {return x  +   y  ;}; double fun01(double x,double y) {return x*x+ 3*y  ;}; double fun02(double x,double y) {return x  + 2*y*x;}; //...  fun03(double x,double y) {return ...+...   ;}; //... //...  fun98(double x,double y) {return ...+...   ;}; double fun99(double x,double y) {return x/2+20*y  ;}; double (*funNN[100])(double,double)={     fun00,     fun01,     fun02, //  fun03, //  ... //  fun98,     fun99, }; int main() {     double x,y;     int f,FN;      for (i=0;i<300;i++) {         valuex[i]=(double)i;         valuey[i]=(double)i;     }     FN=3;     for (i=0;i<300;i++) {          x=valuex[i];          y=valuey[i];          for (f=0;f<FN;f++) A[i][f]=funNN[f](x,y);     }     for (i=0;i<3;i++) {         for (f=0;f<FN;f++) printf("%lg ",A[i][f]);         printf("\n");     }     return 0; } //0 0 0 //2 4 3 //4 10 10

引用 10 楼 qdlgdx_lsy 的回复: #include <stdio.h>  int main() { 	typedef int (*a)(); 	int b() 	{return 1;}  	int (*d)() = &b; 	a c=b; 	printf("%d\n", (*c)());         printf("%d\n", c()); 	printf("%d\n", d()); } 都是1.谁能解释一下？？ 2楼哥们儿发的链接里面有你这个问题的答案

诸位看下这个：     int * (* ( * a）（））[10];

引用 5 楼 stormier 的回复:[quote=引用 2 楼 modyaj 的回复:] a是个指针  指向一个函数  该函数的参数是0个 返回值是int的类型  至于怎么用 网上搜一下 函数指针和指针函数 彻底弄懂他们了就简单了 给个地址 http://www.programfan.com/blog/article.asp?id=6030 同上。 比如我自己写一个也行。  typedef int (*a)(); int b() {return 1;}  a c=b; c(); 绝对错误[/quote]  绝对正确。

引用 25 楼 stormier 的回复:[quote=引用 12 楼 sinservice 的回复:] [quote=引用 5 楼 stormier 的回复:] [quote=引用 2 楼 modyaj 的回复:] a是个指针  指向一个函数  该函数的参数是0个 返回值是int的类型  至于怎么用 网上搜一下 函数指针和指针函数 彻底弄懂他们了就简单了 给个地址 http://www.programfan.com/blog/article.asp?id=6030 同上。 比如我自己写一个也行。  typedef int (*a)(); int b() {return 1;}  a c=b; c(); 绝对错误[/quote]  绝对正确。 [/quote] 你试过么就胡说八道。(*c)()才对。不懂就别说。OK？！[/quote]    这么简单的东西，你试试就知道。  虽然简单，我每天都用，但是为了准确回帖，我还是在回帖前就在编译器上实验了。

窃以为—— (*c)();  /*调用函数指针，正常*/ c();     /*函数名本身就是地址，与引用的地址相同，即地址c、&（c）和&（*c）一样，这是特殊点*/ d();     /*普通函数地址传递调*/

引用 24 楼 stormier 的回复:[quote=引用 20 楼 a345485527 的回复:] [quote=引用 5 楼 stormier 的回复:] [quote=引用 2 楼 modyaj 的回复:] a是个指针  指向一个函数  该函数的参数是0个 返回值是int的类型  至于怎么用 网上搜一下 函数指针和指针函数 彻底弄懂他们了就简单了 给个地址 http://www.programfan.com/blog/article.asp?id=6030 同上。 比如我自己写一个也行。  typedef int (*a)(); int b() {return 1;}  a c=b; c(); 绝对错误[/quote]  没有错误[/quote] 有错。(*c)()才对。不懂就别说。[/quote] 呵呵，难道lz试过？复制粘贴再运行一下，不麻烦  #include <stdio.h>  typedef int (*a)(); int b() {return 1;}  int main() { 	a c=b; 	//c(); 	printf("%d\n",c()); 	printf("%d\n",(*c)()); 	return 0; }

引用 12 楼 sinservice 的回复:[quote=引用 5 楼 stormier 的回复:] [quote=引用 2 楼 modyaj 的回复:] a是个指针  指向一个函数  该函数的参数是0个 返回值是int的类型  至于怎么用 网上搜一下 函数指针和指针函数 彻底弄懂他们了就简单了 给个地址 http://www.programfan.com/blog/article.asp?id=6030 同上。 比如我自己写一个也行。  typedef int (*a)(); int b() {return 1;}  a c=b; c(); 绝对错误[/quote]  绝对正确。 [/quote] 你试过么就胡说八道。(*c)()才对。不懂就别说。OK？！

引用 20 楼 a345485527 的回复:[quote=引用 5 楼 stormier 的回复:] [quote=引用 2 楼 modyaj 的回复:] a是个指针  指向一个函数  该函数的参数是0个 返回值是int的类型  至于怎么用 网上搜一下 函数指针和指针函数 彻底弄懂他们了就简单了 给个地址 http://www.programfan.com/blog/article.asp?id=6030 同上。 比如我自己写一个也行。  typedef int (*a)(); int b() {return 1;}  a c=b; c(); 绝对错误[/quote]  没有错误[/quote] 有错。(*c)()才对。不懂就别说。

使用的时候采用回调函数的方式

a就是一个函数指针

定义了一个类型a，类型为函数指针，对应的函数没有参数，返回int。

引用 5 楼 stormier 的回复:[quote=引用 2 楼 modyaj 的回复:] a是个指针  指向一个函数  该函数的参数是0个 返回值是int的类型  至于怎么用 网上搜一下 函数指针和指针函数 彻底弄懂他们了就简单了 给个地址 http://www.programfan.com/blog/article.asp?id=6030 同上。 比如我自己写一个也行。  typedef int (*a)(); int b() {return 1;}  a c=b; c(); 绝对错误[/quote] 什么错误？

引用 7 楼 stormier 的回复:[quote=引用 6 楼 bijiaoben 的回复:] [quote=引用 5 楼 stormier 的回复:] [quote=引用 2 楼 modyaj 的回复:] a是个指针  指向一个函数  该函数的参数是0个 返回值是int的类型  至于怎么用 网上搜一下 函数指针和指针函数 彻底弄懂他们了就简单了 给个地址 http://www.programfan.com/blog/article.asp?id=6030 同上。 比如我自己写一个也行。  typedef int (*a)(); int b() {return 1;}  a c=b; c(); 绝对错误[/quote] （*c）（）[/quote] 如果是函数指针，不需要(*c)（） 只要c()[/quote] Sorry，游戏更新出错，正在纠结中


Question: 求解一个算法！

假如是1000个数中有999个相同1个不同，那首先判断第一个第二个第三个中有没有和其它两个不同的，如果有那就是答案，如果没有那么这三个的值就是那个相同值，找后面不是这个值的数就行了 如果这999个数彼此之间也不同，那么需要定义要找的数到底哪里“与众不同”

引用 楼主 Nirvana_wzj 的回复:给定1000个数字，其中有一个数字不同与剩下999个都不同，怎样查找，能够迅速找到这个与众不同的数字？求大神指点~  老实说，我都没明白这需求。 “其中有一个数字不同与剩下999个都不同” 这两个不同分别指代的是什么呢？ 第一个不同是指代，有一个数字与剩下999个不同，第二个不同是指代剩下的999个也不同？  模糊！~~  嘿嘿！~~

引用 12 楼 yjz_uestc 的回复:[quote=引用 10 楼 Nirvana_wzj 的回复:] [quote=引用 9 楼 ForestDB 的回复:] 这题目没问题？没少条件啥的？ 0、1、2……999，每一个都与剩下的999个数字不同。 应该加上其他999个数字都相同，找出那个不同的[/quote]  你确定[/quote] 如果999个相同，1个不同，那怎么设计?

引用 17 楼 u012997273 的回复:就是其中一个与另外999个不同吗，另外999个是相同的吗，这就好办了 如果是相同的该怎么做？

建哈希表查找吧，如果数组变得很大，数据变成字符串，或者要找的目标改变，基本不用改变太多代码，通用点效率也高...

引用 楼主 Nirvana_wzj 的回复:给定1000个数字，其中有一个数字不同与剩下999个都不同，怎样查找，能够迅速找到这个与众不同的数字？求大神指点~  把1000个数存在数组里。计算1000个数的总和S1000。然后计算前500个数的总和，如果不是S1000的一半 说明那个数在前500里。如果是S1000的一半 说明那个数在后500里然后反复进行上述步骤，直到n=1为止。时间复杂度为对数级。

引用 9 楼 ForestDB 的回复:这题目没问题？没少条件啥的？ 0、1、2……999，每一个都与剩下的999个数字不同。 应该加上其他999个数字都相同，找出那个不同的

没太仔细想，同时不知道有多少个这样的数。一个比较简单但效率不是那么高的算法，定制一个红黑树，每个节点有个count。逐个进行插入，当比对冲撞的时候进行累加。从左向右看，count为1的就是你需要的所有的数。  可以稍微加速一点，rbnode上嵌入一个自删除链表节点。如果count从1到2就产生删除，从0到1就产生插入。最后遍历链表，避免树遍历的变相递归开销。

万一其中有数字长度超过1TB咋办？

把3楼的数组变成map就可以了

引用 4 楼 derekrose 的回复:哪里来的自信 这是最快的？ 哥们还有更好的算法吗，求指点

引用 10 楼 Nirvana_wzj 的回复:[quote=引用 9 楼 ForestDB 的回复:] 这题目没问题？没少条件啥的？ 0、1、2……999，每一个都与剩下的999个数字不同。 应该加上其他999个数字都相同，找出那个不同的[/quote]  你确定

这是计算频率的办法，但首先要确定数字的取值范围，题目未给  引用 3 楼 worldy 的回复:定义一个1000个单元的数组A， 将每个数据i做下标让A[i]++;  再次遍历，A[idx]=1就是要找的数据  ....这是最快的

当没说~~，看错

前两个相同(i)的话，累加是不是n*i?

快排行不。。。。。。。。。。。。

就是其中一个与另外999个不同吗，另外999个是相同的吗，这就好办了

3楼的做法基本靠谱，不过1000个有点少把，题目没说范围是0－999把？

引用 6 楼 worldy 的回复:[quote=引用 5 楼 Nirvana_wzj 的回复:] [quote=引用 3 楼 worldy 的回复:] 定义一个1000个单元的数组A， 将每个数据i做下标让A[i]++;  再次遍历，A[idx]=1就是要找的数据  ....这是最快的 如果另外999个数字都是相同的，假设相同的数为123，则A[123]的值为999，不是1[/quote]假设是1000个浮点数如何是好？


Question: C 语言读取HDF格式的数据

引用 7 楼 lihuiyu1314 的回复:你这是要弄遥感图像吗不是，就是要把数据导入到数据库里

你这是要弄遥感图像吗

有高手帮忙解决吗

还是不太懂，请高手推荐一个学习的资料

帮顶

二进制读取，按照格式自己分解

用 hdf 库 www.hdfgroup.org

这个跟读其他文件应该没有区别吧


Question: 无向图的建立与遍历

邻接链表 邻接矩阵来存储

使用邻接矩阵来表示啊。

http://www.indiastudychannel.com/resources/12983-C-Program-for-creation-adjacency-matrix.aspx  不要伸手

你需要定义一个数据结构来描述这个图, 最简单的方式是关联矩阵数组  #define INF 0x7fffffff int edge[6][6] = { {0, 800, 1000, INF, INF, 700},   {800, 0, 60, 200, INF, INF},   {1000, 60, 0, 300, 20, 50},   {INF, 200, 300, 0, INF, INF},   {INF, INF, 20, INF, 0, 20},   {700, INF, 50, INF, 20, 0} };


Question: Visual Studio Team System Test Editon 能对c语言进行单元测试么

引用 2 楼 SalmonRun 的回复:vs 2012 可以, 不知道什么版本, 用Ultimate一定行. 可以创建一个 Native Unit Test Project 进行单元测试. 用过, 还不错. 现在要用vs2010做 我现在不知道怎么得到要测试c文件的代码覆盖率  按照网上说的进行设置 跑完说覆盖率是0

不清楚 推荐一个 mutest


Question: c语言中int型数据转char

char* tmp[10]; int a = 16; int b = 17;  snprintf(tmp, sizeof(tmp), "%d/%d", a, b);  .....

sprintf

这些方法都可以啊

引用 6 楼 xjm199 的回复:[quote=引用 3 楼 max_min_ 的回复:]  #include <stdio.h>  char* work(char *test) {     int a = 16, b = 17;      sprintf(test, "%d/%d", a, b);      return test; }  int main() {     char test[10] = {0};      printf("%s \n", work(test)); }   由于程序原因，work里面无法带入test参数，怎么破[/quote] 华丽丽地把我的2楼跳过了。。。。2楼不就是给你work函数里面的方案吗？

引用 3 楼 max_min_ 的回复: #include <stdio.h>  char* work(char *test) {     int a = 16, b = 17;      sprintf(test, "%d/%d", a, b);      return test; }  int main() {     char test[10] = {0};      printf("%s \n", work(test)); }   由于程序原因，work里面无法带入test参数，怎么破

哦不对 是2楼的

3L的比较好

static char temp[100]; sprintf(temp, "%d/%d",a,b); return temp;

itoa  int a=10; char str[100];	 printf("%s",itoa(a,str,10));


Question: linux下用c语言如何实现ftp传输文件

这是个从客户端输入一段数据发送给服务器的程序 ， 你可以改改。 客户端的：argv【2】是服务器ip，argv【1】是你要输入的数据 。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h>  #define MAXLINE 80 #define SERV_PORT 8000  int main(int argc,char *argv[]) { 				struct sockaddr_in servaddr; 				char buf[MAXLINE] = {}; 				int sockfd, n; 				char *str;  				if (argc < 2) { 								fputs("usage:...../client message\n",stderr); 								exit(1); 				}  				str = argv[1]; 				sockfd = socket(AF_INET,SOCK_STREAM,0);  				bzero(&servaddr, sizeof(servaddr)); 				servaddr.sin_family = AF_INET; 				inet_pton(AF_INET,argv[2],&servaddr.sin_addr); 				servaddr.sin_port = htons(SERV_PORT);  				connect(sockfd, (struct sockaddr *) &servaddr,sizeof(servaddr));  				write(sockfd,str,strlen(str)); 				/* 					 n = read(sockfd,buf,MAXLINE); 					 printf("Response fron server:\n"); 					 write(STDOUT_FILENO,buf,n); 				 */ 				close(sockfd); 				return 0; } 服务器： #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h>   #define MAXLINE 80 #define SERV_PORT 8000  int main(void) { 				struct sockaddr_in servaddr, cliaddr; 				socklen_t cliaddr_len; 				int listenfd, connfd; 				char buf[MAXLINE] = {}; 				char str[INET_ADDRSTRLEN] = {}; 				int i, n; 				char buf1[100] = {0}; 				int fd; 				listenfd = socket(AF_INET,SOCK_STREAM,0);  				bzero(&servaddr, sizeof(servaddr)); 				servaddr.sin_family = AF_INET; 				servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 				servaddr.sin_port = htons(SERV_PORT);  				bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); 				listen(listenfd,20);  				printf("Accepting connections ...\n"); 				while(1) { 								cliaddr_len = sizeof(cliaddr); 								connfd = accept(listenfd,(struct sockaddr *) &cliaddr, &cliaddr_len); 								//	strcat(buf1,(void *)&cliaddr); 								//	strcat(buf1,"_"); 								//	strcat(buf1,(void *)&cliaddr.sin_port); 								sprintf(buf1,"%s_%d.txt",inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),ntohs(cliaddr.sin_port));  								fd = open(buf1,O_RDWR|O_TRUNC|O_CREAT,0644); 								while((n = read(connfd,buf,MAXLINE)) > 0) { 												write(fd,buf,n); 								} 								close(fd); 								//		n = read(connfd,buf,MAXLINE); 								printf("receive from %s at port %d\n",inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),ntohs(cliaddr.sin_port));  								/*		for (i = 0;i < n;i++) 											buf[i] = toupper(buf[i]); 								 */		write(connfd,buf,n); 								close(connfd); 				} }

用libcurl吧

随便一搜一大把，你都舍不得用下搜索引擎？


Question: 如何控制每行输出的个数

错了, 修改为:  #include<stdio.h> int main() { int n; int count_of_found; count_of_found = 0 for(n=100;n<=200;n++) { if (n%3!=0) {     printf("%d,",n);     count_of_found++;     if (count_of_found % 4 == 0) {         printf("\r\n");     } } } printf("\n"); }

#include<stdio.h> int main() { 	int n; 	int i=1; 	for(n=100;n<=200;n++) 	{ 		if(n%3!=0) 		{ 			printf("%d,",n); 			if(i++%4==0)printf("\n"); 		} 	} 	printf("\n"); }

if (n%3!=0) {     printf("%d,",n); } // 此处添加 if (n!=100 && n%4 = 0) {     printf("\r\n"); }


Question: C语言  新手问题   求大神相助

谢谢各位大神。亲，新手好吗？非得这样打击我，难得我有欲望写C.1L的大神，非得打击我。最可恶的5L，你还雪上加霜的抨击我。算了，每个都有分，谢谢其他L的好人，好人一生平安

这个代码我看了！你的问题出在 scanf（）上，不知道你的操作时怎样的，如果你先输入 数字然后 回车的话  那末 你的 '\n'就被 c接收了 。建议 在scanf后紧跟一个getchar（）；

1L正解

fflush(stdin);的作用是清空输入缓冲区，这么做是为了确保不影响后面的数据读取。 一般来说读完一个字符串后紧接着又要读取另一个字符，中间要加一句fflush(stdin);来情况缓冲区，否则上一次输入的字符可能会留在缓冲区。

scanf(" %c",&c); //%c前加空格就可以解决问题 否则此时读入的是你敲完数字后的回车，debug一下就可以看出来！

将 scanf("%c",&c); 改为 scanf(" %c",&c); 也就是格式字符串前加个空格。 空格在scanf中表示 忽略空白字符  BTW：printf/scanf这种C/C++最常用的函数都不会，还搞个毛呀？


Question: C语言名句解释

http://blog.chinaunix.net/uid-24774106-id-3053007.html http://www.ibm.com/developerworks/cn/java/j-cb11076.html

/** 举个例子，面向对象的实现过程中，可以用到函数绑定 */ #include <stdio.h>  struct point; typedef int (*dist_t)(struct point* this);  typedef struct point { 	int x; 	int y; 	dist_t dist; }point_t;  int dist(point_t* this) { 	return this->x * this->x + this->y * this->y; }  int main(int argc, char* argv[]) { 	point_t pt;  	pt.x = 10; 	pt.y = 20; 	pt.dist = dist;  	printf("%d\n", pt.dist(&pt));  	return 0; }  引用 楼主 celsnrt 的回复:函数延迟绑定：数据结构导致绑定 记住：在编程过程后期再结构化数据  上面的话，不是太懂，各位大神们解释解释，谢谢！

C 似乎没有这功能，只有函数指针，勉强可以实现这个东东.


Question: 字符串分段的组合Combine算法，紧急求救，高手快来！！！

引用 3 楼 uuuououlcz 的回复:考虑： （1）如果n < m，不行 （2）如果n >= m，先考虑最左边的第1段，则第1段的长度len1可以是[1,n-(m-1)]，这是因为后面至少要有m-1个字符用于分成m-1段，这样问题就化为长度为n-len1的字符串分成m-1段的子问题 以下代码仅供参考：  #include <stdio.h> #include <stdlib.h> #include <string.h>  void sliceUp(int segmentLength[], int index, const char* s, int remainingLength, int remainingPart) {     if(remainingPart == 1){         segmentLength[index++] = remainingLength;         int i, j, len;         for(i = 0; i < index; ++i){             if(i) putchar(' ');             for(j = 0, len = segmentLength[i]; j < len; ++j){                 putchar(s[j]);             }             s += segmentLength[i];         }         puts("");         return;     }     int len = 1, limit = remainingLength - (remainingPart-1);     for(; len <= limit; ++len){         segmentLength[index] = len;         sliceUp(segmentLength, index+1, s, remainingLength-len, remainingPart-1);     } }  int printCuts(const char* s, int parts) {     int len = strlen(s);     if(len < parts) return -1;      int* arr = (int*)malloc(parts * sizeof(int));     sliceUp(arr, 0, s, len, parts);     free(arr);      return 1; }  int main() {     printCuts("forum", 3);      return 0; }   完美的解决了我的问题，注释简明扼要，代码规范有效。。。。谢谢！！！

分成三段扩展两个char说错了

先将字符串进行扩展空间,比如分成3段就扩展一个char，然后插入2个空格  然后是第一个分段，第一个分段的长度需要确定，保证最后的字符至少是2个(3-1) 然后对剩下的字符进行分成2段  递归可以实现

仅供参考#include <stdio.h> #include <string.h> char *a="abcde"; int L,i,j,k; void main() {     L=strlen(a);     for (i=1;i<=L;i++) {         for (j=0;j<=L-i;j++) {             for (k=j;k<j+i;k++) {                 printf("%c",a[k]);             }             printf("\n");         }     } }

走楼梯+抽屉原理。

这个似乎和走楼梯,走台阶差不多。


Question: ftp sftp sch

读一读rfc吧 或者看一看http://curl.haxx.se/libcurl/ 行不行

可是我们不做C#啊，只做C。 关键是有没有对应的库？

用c#好一些

快来顶啊！！！！

是./configure 安装吗？     #include <libssh2.h>       int main()    {      return 0;    }   libssh2.h: No such file or directory  这个怎么搞啊？？？

我下载了libssh-.06.orc2  放到我linux中解压。怎么安装呢？

sftp 建议看 libssh http://www.libssh.org/

看FileZilla 源代码

busybox 这是个开源的可用的软件？ libftp 到底是干嘛的？ libcurl 这个是开源的可用的软件？ libncftp 又是什么？  现在要实现sftp  c语言版   到底该如何着手？


Question: 关于指针的冒泡排序问题。。。

眼神不好，看叉了。。。。要换眼镜了

引用 2 楼 bijiaoben 的回复:真没看出来循环控制条件i有什么作用啊。楼主在理一下自己的思路呢。。 sorry，我写错了，1楼正解

真没看出来循环控制条件i有什么作用啊。楼主在理一下自己的思路呢。。

#include<stdio.h>  void sort_out(int *p,int n)  {         int temp=0,i,j; 		for (int i=0;i<n;i++) 		{ 			for (int j=0;j<n-i-1;j++) 			{ 				if(*(p+j)>*(p+j+1))                 {                     temp = *(p+j+1);                     *(p+j+1) = *(p+j);                     *(p+j) = temp;                 } 			} 		}  }  int main() {     int a[9]={5,7,8,4,2,3,11,47,89},n=9;       sort_out(a,n);     for (n=0;n<9;n++)     {         printf("%3d",a[n]);     } 	printf ("\n");     return 0; }     楼主，你过界了....

引用 1 楼 AfterSeptember 的回复: if(*(p+j)>*(p+j+1))                 {                     temp = *(p+j);                     *p = *(p+j+1);                     *(p+j+1) = temp;                 }  *p应该是*(p+j) 哎呀！这么明显都没发现~~太感谢了！


Question: 关于移位操作

谢谢各位，我已经自己搞明白了。

自己多试验吧。

要看到本质  不然就是浪费时间

#include <stdio.h> unsigned char ui;   signed char si; char main() {     ui=(unsigned char)0x80u;     si=(  signed char)0x80;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=ui>>1;     si=si>>1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      printf("--------------\n");     ui=(unsigned char)0x80u;     si=(  signed char)0x80;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=((  signed char)ui)>>1;     si=((unsigned char)si)>>1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      printf("==============\n");      ui=(unsigned char)0x80u;     si=(  signed char)0x80;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=ui<<1;     si=si<<1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      printf("--------------\n");     ui=(unsigned char)0x80u;     si=(  signed char)0x80;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=((  signed char)ui)<<1;     si=((unsigned char)si)<<1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      return 0; } //ui=128 //si=-128 //ui=64 //si=-64 //-------------- //ui=128 //si=-128 //ui=192 //si=64 //============== //ui=128 //si=-128 //ui=0 //si=0 //-------------- //ui=128 //si=-128 //ui=0 //si=0

对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！

引用 楼主 a775992553 的回复:请教一下各位关于移位操作的问题。我现在被搞得有点晕了  1.C/C++和JAVA中的移位操作规则是不是不一样？ 2.关于算术移位和逻辑移位。 左移时候比较好理解，都是末尾补0.但是右移的时候我就有点晕了。 正常情况逻辑移位是不管符号位，直接高位补0；而算术移位是根据符号位来补高位的。 比如11001右移2位。逻辑移位结果是00110，而算术移位结果是11110。（这个应该对的吧？）  但是我好想隐约记得还有一种，就是符号位保持不变，剩余的位右移并且在符号位后面补0 。 比如11001右移两位变成10010。我不知道有没有记错，如果没有记错的话。那么这种移位规则是什么？  3.关于C语言中的>>运算符，执行的是逻辑移位还是算术移位？  4.C语言中有没有>>>这个运算符？如果没有那么这个运算符是属于那种语言的？  5.感觉我把C和JAVA学混了？如果可以的话，希望能有人帮我理一下： C语言中算术移位和逻辑移位的运算规则； C语言中>>运算符使用了哪种规则； JAVA语言中算术移位和逻辑移位的运算规则； JAVA语言中>>运算符和>>>使用了哪种规则； C语言的移位算符在不同的编译器下，对有符号数会有不同的行为。所以只应当对无符号数进行移位操作。

C语言中的>> 有符号数就是算数右移，无符号数就是逻辑右移


Question: C编程：找出一个整形数组中最大K个数的下标

楼主说的是找第k大的数吧 这是一个选择问题， 第一种方法 将给出的已知数组排好序后，输出第k大的值的下标  第二种就是利用快速排序去筛选

对数组进行排序，将排序结果用另一个数组暂存，然后从第二个数组取最大的K个值，然后在第一个数组中对应出下标

应该是再弄个数组存K 个数  即你要查找的最大数的下标。初始值0~K-1

引用 4 楼 bijiaoben 的回复:两个数组a和b，a里面存的是整数，b里面存a数组下标。b数组初始化1到n，然后对b数组按照a数组的值从大到小进行排序，规则如下 ：  if (a[b[i]] <= a[b[i+1]]) {     int temp = b[i];     b[i] = b[i+1];     b[i+1] = temp; }  详细代码可以自己去写，这里只写了比较大小的方法。 最终得到的b数组就是a数组的值从大到小排序的下表。然后随便你打印b里面的元素了。 写错了，b数组初始化从0到n-1

另一个方法，是创建指针或者下标数组。 每个不指针或者下标对应给出的数组中的元素。  对指针或者下标快速选择。 输出下标。

一个方法是： 创建一个结构，包含下标。 创建结构数组复制所有数据。 对结构数组，用快速选择，求出最大K个数。 输出结构中的下标。

什么叫最大K个数的下标？是找到最大数然后输出下标，如果有多个就输出多个下标，这个意思？


Question: 英雄会第二届在线编程大赛·线上初赛：AB数 超时

解题报告http://www.cnblogs.com/TenosDoIt/p/3496453.html


Question: 变量设置不同~~结果不同~~指针问题~~

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

有时候也不用malloc或者new，而是将指针指向一块已知的有效内存空间

指针使用之前必须为其向系统申请有效的内存空间，用malloc或者new。否则的话你访问的地址就不知道到哪里去了，野指针引发的问题千奇百怪。。。

修改成指针, 你就得为这个指针分配空间.

你没有为这个指针分配内存，它是一个野指针。向它指向的地方赋值，就会把其他的内容窜改掉，发生各种异常都是正常的。

int main(void) {     Family *member;     if(!(global.pfile=fopen(global.filename,"wb")))     {          printf("\nUnable to open %s for writing.\n",global.filename);         exit(1);     }     while(get_person(member)) // member使用前没有初始化         fwrite(member,sizeof(member),1,global.pfile);


Question: 大神求教,关于用c语言编写图书馆管理系统

何苦选计算机呢。

你这个几百行就搞定了。  学长吓唬你的。

没学过 [quote=引用 2 楼 turingo 的回复:] 改用数据库。

改用数据库。  引用 楼主 u010189427 的回复:如题,听计算机专业的学长说要用几万行代码,自己不是学计算机的但是报的课期末要交设计报告,所以求大神指导,最好能有简单的十几行代码

引用 1 楼 user-5 的回复:其实网上一堆 http://www.downloadprojects.in/download-c-projects.php 这个强大！