Question: 初学链表，不知道错误在哪里

楼主你的代码中，之所以输出的内容不是你输入的全部内容，是因为你在创建链表的时候，没有连接起来，从head指向的节点后出现了断层，  if (head == NULL)         {             p2=head = p1;         }         else         {             while (p2 != NULL)             {                 p2 = p2->p;             }             p2 = p1;         } 你的问题就出现在那块，致使head只指向了一个节点 因此在输出时，只会显示一个ID，可将代码改为  void _chain(chain* &pChain)     {           chain *pp=new chain;         pChain=pp;         cin>>pp->ID;         pp->p=NULL;         while(pp->ID!=0)             {             pp->p=new chain;             if(pp->p!=NULL)                 {                 pp=pp->p;                 cin>>pp->ID;                 pp->p=NULL;                 }             }         }

引用 5 楼 lming_08 的回复:while (0!=p1->ID)     {         p1 = (chain*)malloc(length);         if (p1 == NULL)         {             printf("apply for the new chain fail");             exit(1);         }         if (head == NULL)         {             p2=head = p1;         }         else         {             while (p2-p != NULL)             {                 p2 = p2->p;             }             p2->p = p1;         }         p1->p = NULL;         scanf_s("%d", &p1->ID);     } 你的这个 while (p2-p != NULL)       {           p2 = p2->p;       }           p2->p = p1; 跟我这个while (p2 != NULL)             {                 p2 = p2->p;             }             p2 = p1; 作用一样啊，没什么区别，为什么你的没有错误，我的错了？

引用 3 楼 logiciel 的回复:可如下修改: #include"iostream" struct chain {   long ID;   chain* p; }; #define length sizeof(chain) chain* _chain(chain* head); void _printf(chain* head); void main() {   chain* head=NULL;   printf("when the data you input is 0,the end!");   head=_chain(head);   _printf(head);  } chain* _chain(chain* head) {    chain *p1=NULL, *p2=head;   p1 = (chain*)malloc(length);   p1->ID = 10;   while (0!=p1->ID)   {     p1 = (chain*)malloc(length);     if (p1 == NULL)     {       printf("apply for the new chain fail");       exit(1);     }     if (head == NULL)     {       p2=head = p1;     }     else     {       p2->p = p1;//加       /*删       while (p2 != NULL)       {         p2 = p2->p;       }*/       p2 = p1;     }     p1->p = NULL;     scanf_s("%d", &p1->ID);   }    return head; } void _printf(chain* head) {   printf("\n");   while (NULL!=head)   {     printf("%d    ", head->ID);     head = head->p;   } } 有错误，提示：错误	1	error LNK2019: 无法解析的外部符号 _main，该符号在函数 ___tmainCRTStartup 中被引用。这是什么问题

你在看看代码吧，你写代码的时候逻辑思路不清晰，所以你都不知道写的是什么

大家帮帮我

楼主的逻辑好混乱啊， 链表的建立 基本上就是 “头插法” 和 “尾插法”，楼主的大概是想“尾插法”建立不带头结点的链表。 以下代码仅供参考。 #include <iostream> struct chain {     long ID;     chain* p; }; #define length sizeof(chain) chain* _chain(chain* head); void _printf(chain* head); void main() {     chain* head=NULL;     printf("when the data you input is 0,the end!");     head=_chain(head);     _printf(head); } chain* _chain(chain* _head) //尾插法建立链表,不带头结点的链表 {     chain *head ,*tail,*tmp;     head = (chain*)malloc(length);     tail = head ;     tail->p = NULL;     int tmp_id;     while (1)     {         scanf_s("%d", &tmp_id);         if(tmp_id == 0 )break;         tmp = (chain*)malloc(length);         if (tmp == NULL)         {             printf("apply for the new chain fail");             exit(1);         }         tmp->p = NULL;         tmp->ID = tmp_id;         tail->p = tmp ;         tail=tmp;     }     _head = head->p;     free(head);//防止内存泄露，删除没有值的头结点     return _head; } void _printf(chain* head) {     printf("\n");     while (NULL!=head)     {         printf("%d    ", head->ID);         head = head->p;     } }

引用 6 楼 u013497965 的回复:[quote=引用 5 楼 lming_08 的回复:] while (0!=p1->ID)     {         p1 = (chain*)malloc(length);         if (p1 == NULL)         {             printf("apply for the new chain fail");             exit(1);         }         if (head == NULL)         {             p2=head = p1;         }         else         {             while (p2-p != NULL)             {                 p2 = p2->p;             }             p2->p = p1;         }         p1->p = NULL;         scanf_s("%d", &p1->ID);     } 你的这个 while (p2-p != NULL)       {           p2 = p2->p;       }           p2->p = p1; 跟我这个while (p2 != NULL)             {                 p2 = p2->p;             }             p2 = p1; 作用一样啊，没什么区别，为什么你的没有错误，我的错了？[/quote] 我的那个p2是链表最后一个元素，然后再把新元素p1挂在p2后面，而你的那个p2则是最后一个元素的下一个，其值为NULL；你画下图就知道了


Question: 文件操作的重定向小白问题

#include <stdio.h>   #define LOCAL  #define INF 1000000000    int main()  {  #ifdef LOCAL      freopen("data.in","r",stdin);      freopen("data.out","w",stdout/*stdin*/);  #endif // LOCAL        int x,n=0,min=INF,max=-INF,s=0;      while(scanf("%d",&x)==1)      {          s+=x;          if(x<min)min=x;          if(x>max)max=x;                    //printf("x=%d,min=%d,max=%d\n",x,min,max);                    n++;      }      printf("%d %d %3.6f\n",min,max,(double)s/n);            return 0;  }  输入文件data.in: 12 34  57  输出文件data.out: 12 57 34.333333

谢谢你了~

引用 2 楼 u013036124 的回复:大神！就是不知道怎么输入文件data.in 因为代码把输入重定向到了文件data.in，所以现在不需要你在控制台输入了，而是要在当前路径下预先编写好data.in就行了。

大神！就是不知道怎么输入文件data.in


Question: 用C语言写一个方法，传一个char数组类型的参数，方法的返回值也为char数组

你的工作是挑战语言标准么？

改成数组也没作用，跟指针一样的

引用 1 楼 baichi4141 的回复:你的工作是挑战语言标准么？ 是这样的，我现在在wince上要调用C写的一个dll里的一个方法，这个方法是传一个字符串（char指针），返回一个字符串（char指针），wince的程序是C#写的，调用这个dll时，传一个String类型参数，用string接收，但接收的返回值是NULL，所以我觉得是C#的String类型接收不到dll里的指针类型，所以我想把dll的返回值改为char数组。


Question: 关于char 型的问题

引用 11 楼 u013594535 的回复:[quote=引用 7 楼 mujiok2003 的回复:] [quote=引用 5 楼 u013594535 的回复:] [quote=引用 4 楼 mujiok2003 的回复:] %c ----> char 我知道这个问题，但是这个程序在于char型的数据能用%s输出，而且这个程序是没有错的[/quote] 那不是没有错， 那是行为不确定。 谁敢用一个没有确定行为的软件？[/quote]这个地方没听明白，那为什么前面是%s呢？[/quote] 问题就在一个char* 可能指向一个缓冲区，也可能指向只是一个字符。当用%s的时候，期待一个缓冲区， 而%c只要一个字符的空间就好了。 %s的时候，缓冲区要足够长，否则缓冲区溢出， 变成了未定义行为。

引用 7 楼 mujiok2003 的回复:[quote=引用 5 楼 u013594535 的回复:] [quote=引用 4 楼 mujiok2003 的回复:] %c ----> char 我知道这个问题，但是这个程序在于char型的数据能用%s输出，而且这个程序是没有错的[/quote] 那不是没有错， 那是行为不确定。 谁敢用一个没有确定行为的软件？[/quote]这个地方没听明白，那为什么前面是%s呢？

引用 9 楼 zhao4zhong1 的回复:[quote=引用 6 楼 u013998151 的回复:] c中，汉字只能用字符串输入、出。 谬论！ //把“海中上国”排列成“中国上海”的形式输出 #include <stdio.h> #include <locale.h> int main() {     _wsetlocale(LC_ALL,L"chs");     wprintf(L"%c%c%c%c\n",L"海中上国"[1],L"海中上国"[3],L"海中上国"[2],L"海中上国"[0]);     return 0; } //中国上海 // [/quote]那那个输出地方是怎么回事啊？

引用 6 楼 u013998151 的回复:c中，汉字只能用字符串输入、出。 谬论！ //把“海中上国”排列成“中国上海”的形式输出 #include <stdio.h> #include <locale.h> int main() {     _wsetlocale(LC_ALL,L"chs");     wprintf(L"%c%c%c%c\n",L"海中上国"[1],L"海中上国"[3],L"海中上国"[2],L"海中上国"[0]);     return 0; } //中国上海 //

%s--char name[]; int char可以转换。 这是我的理解，有错请指出

%c ----> char

引用 2 楼 u011043553 的回复: 运行一下你的代码，有不小bug... 这个不是BUG，输入日期的时候按那个格式输入例如  1991/1/1

运行一下你的代码，有不小bug...

char name[10];这个应该是字符数组（字符串）

引用 5 楼 u013594535 的回复:[quote=引用 4 楼 mujiok2003 的回复:] %c ----> char 我知道这个问题，但是这个程序在于char型的数据能用%s输出，而且这个程序是没有错的[/quote] 那不是没有错， 那是行为不确定。 谁敢用一个没有确定行为的软件？

c中，汉字只能用字符串输入、出。

引用 4 楼 mujiok2003 的回复:%c ----> char 我知道这个问题，但是这个程序在于char型的数据能用%s输出，而且这个程序是没有错的


Question: 最近学习重定向~~不知道如何实现重定向

引用 3 楼 pokerLee 的回复:引用 2 楼 ypzhong 的回复:回过一个这样的贴。。cmd命令行运行exe程序。输入命令:  执行文件名 < 文本文件名。。如你生成的exe文件为 a.exe，文本文件a.txt，则在cd 到exe文件目录下执行 a.exe < a.txt  就完成标准输入字符终端重定向为文件。请问“cd到exe文件目录”是什么意思？ 你百度一下这个dos命令。

使用命令重定向操作符可以使用重定向操作符将命令输入和输出数据流从默认位置重定 向到不同的位置。输入或输出数据流的位置即为句柄。  下表将列出可用的句柄。  句柄      句柄的数字代号 描述 STDIN     0              键盘输入 STDOUT    1              输出到命令提示符窗口 STDERR    2              错误输出到命令提示符窗口 UNDEFINED 3-9            这些句柄由应用程序单独定义，并且是各个工具特定的。  数字 0 到 9 代表前 10 个句柄。可以使用命令 Cmd.exe 运行程序并将该程序前 10 个 句柄中的任何一个重定向。要指定想使用的句柄，可在重定向操作符前面键入该句柄的 数字。如果未定义句柄，则默认的 < 重定向输入操作符是 0，而默认的 > 重定向输出 操作符是 1。键入 > 或 < 操作符之后，必须指定要读取或写入数据的位置。可以指定 文件名或另一个现有的句柄。  要指定重定向到现有句柄，请使用与 (&) 字符，后面接要重定向的句柄号 （例如 &句柄#）。例如，下面的命令可以将句柄 2（即 STDERR）重定向到 句柄 1（即 STDOUT）：  2>&1  下表列出了可用于将输入和输出数据流进行重定向的操作符。  重定向操作符 描述 > 将命令输出写入到文件或设备（例如打印机）中，而不是写在命令提示符窗口或句柄中。 < 从文件中而不是从键盘或句柄中读入命令输入。 >> 将命令输出添加到文件末尾而不删除文件中的信息。 >& 将一个句柄的输出写入到另一个句柄的输入中。 <& 从一个句柄读取输入并将其写入到另一个句柄输出中。 | 从一个命令中读取输出并将其写入另一个命令的输入中。也称作管道。  默认情况下，可以从键盘将命令输入（即 STDIN 句柄）发送到 Cmd.exe，然后由 Cmd.exe 将命令输出（即 STDOUT 句柄）发送到命令提示符窗口。  重定向输入 (<) 要将键盘输入重定向到文件或设备，请使用 < 操作符。例如，要从 File.txt 获取 sort 命令的输入，请键入：  sort<file.txt  File.txt 的内容将以字母顺序列表的方式显示在命令提示符窗口中。  < 操作符可以打开具有只读访问的指定文件名。所以，不能使用该操作符向文件中写入 信息。例如，如果以 <&2 启动程序，则所有试图读取句柄 0 的操作都将失败，因为句 柄 2 最初是以只写访问打开的。   注意  0 是 < 重定向输入操作符的默认句柄。 重定向输出 (>) 几乎所有的命令都将输出发送到命令提示符窗口。即使将输出发送到驱动器或打印机的 命令也会在命令提示符窗口显示消息和提示。  要将输出从命令提示符窗口重定向到文件或设备，请使用 > 操作符。可以在许多命令中 使用该操作符。例如，要将 dir 输出重定向到 Dirlist.txt，请键入：  dir>dirlist.txt  如果 Dirlist.txt 不存在，Cmd.exe 将创建该文件。如果 Dirlist.txt 存在，Cmd.exe 将使用 dir 命令的输出替换文件中的信息。  要运行 netsh routing dump 命令，然后将输出发送到 Route.cfg，请键入：  netsh routing dump>c:\route.cfg  > 操作符可以打开具有只写访问属性的指定文件。所以，不能使用该操作符读取文件。 例如，如果使用重定向 >&0 启动程序，则所有试图写入句柄 1 的操作都将失败，因为 句柄 0 最初是以只读访问打开的。   注意  1 是 > 重定向输出操作符的默认句柄。 复制句柄 重定向操作符 & 可以将输出或输入从一个指定句柄复制到另一个指定的句柄。例如， 要将 dir 输出发送到 File.txt 并将错误输出发送到 File.txt，请键入：  dir>c:\file.txt 2>&1  复制句柄时，可以复制该句柄原状态的所有特性。例如，如果一个句柄具有只写访问的 属性，则该句柄的所有副本都具有只写访问属性。不能将一个具有只读访问属性的句柄 复制到另一个具有只写访问属性的句柄。  使用 & 操作符重定向输入和副本 要将重定向输入操作符 (<) 与复制操作符 (&) 一起使用，指定的文件必须已经存在。 如果输入文件存在，Cmd.exe 将以只读方式打开该文件，然后将文件中包含的字符作为 输入发送到此命令（如同从键盘输入一样）。如果指定了句柄，Cmd.exe 将指定的句柄 复制到系统现有的句柄中。  例如，要以句柄 0 输入读取（即 STDIN）的方式打开 File.txt，请键入：  <file.txt  要打开 File.txt，并在内容排序后将输出发送到命令提示符窗口（即 STDOUT），请键入：  sort<file.txt  要查找 File.txt，然后将句柄 1（即 STDOUT）和句柄 2（即 STDERR）重定向到 Search.txt，请键入：  findfile file.txt>search.txt 2<&1  要以句柄 0 输入读取（即 STDIN）的方式复制用户定义句柄 3，请键入：  <&3  使用 & 操作符重定向输出和复制 如果将输出重定向到文件且指定了现有的文件名，Cmd.exe 将以只写方式打开文件并覆 盖该文件内容。如果指定了句柄，Cmd.exe 将文件复制到现有句柄中。  要将用户定义句柄 3 复制到句柄 1，请键入：  >&3  要将包括句柄 2（即 STDERR）的所有输出从 ipconfig 命令重定向到 句柄 1（即 STDOUT），然后将输出重定向到 Output.log，请键入：  ipconfig.exe>>output.log 2>&1  使用 >> 重定向操作符追加输出 要从命令中将输出添加到文件末尾而不丢失文件中已存在的任何信息，请使用两个连续 的大于号（即 >>）。例如，下面的命令可以将由 dir 命令生成的目录列表追加到 Dirlist.txt 文件：  dir>>dirlist.txt  要将 netstat 命令的输出追加到 Tcpinfo.txt 的末尾，请键入：  netstat>>tcpinfo.txt  使用管道操作符 (|) 管道操作符 (|) 可以提取一个命令的输出（默认情况下是 STDOUT），然后将其导入另 一个命令的输入中（默认情况下是 STDIN）。例如，下面的命令将对目录分类：  dir | sort  在本例中，将同时启动两个命令，但随后 sort 命令会暂停，直到它接收到 dir 命令 的输出为止。sort 命令使用 dir 命令的输出作为输入，然后将输出发送到 句柄 1（即 STDOUT）。  合并带重定向操作符的命令 可以通过合并带有其他命令和文件名的筛选器命令创建自定义命令。例如，可以使用以 下命令存储包含“LOG”字符串的文件名:  dir /b | find "LOG" > loglist.txt  dir 命令的输出通过 find 筛选器命令发送。包含字符串 "LOG" 的文件名作为文件名 列表（例如，NetshConfig.log、Logdat.svd 和 Mylog.bat）存储在文件 Loglist.txt 中。  要在相同命令中使用多个筛选器，请使用管道 (|) 分隔筛选器。例如，下面的命令将 搜索 C 盘上的每个目录以查找包含 "LOG" 字符串的文件名，并且在命令提示符窗口中 每次显示一屏：  dir c:\ /s /b | find "LOG" | more  利用管道 (|) 可以将 Cmd.exe 导向为通过 find 筛选器命令发送 dir 命令输出。 find 命令只选择包含字符串 "LOG" 的文件名。more 命令可以显示由 find 命令选择 的文件名（在命令提示符窗口中每次显示一屏）。有关筛选器命令的详细信息，请参阅 使用筛选器。

就是将某个文件作为程序的输入读取，或者将程序的输出写入某文件

lz看看这个对你有帮助没——http://zhidao.baidu.com/link?url=kK6uYFxwqw5WzjsXv_Mmtq5oK7Jjc3Jao-_3ATuEbvGIphtXhR8vXWBsUWbmhWmapgMUUaMQWKH5AQGN0qC1ca


Question: [SWU]如何求取变量所在的字节

sizeof(）；/*括号内为要求的字节的名称*/

printf("%p",&k);

sizeof(int)

偶！希望我可以早点吃到这道菜

遇到的时候自然就知道了。光看资料是很难明白的。你想一想食谱就明白了，如果看食谱就可以替代品尝的话...

1、在网上查看了一下Big Endian 和 Little Endian的区别，Big Endian 是从小到大，Litle Endian  是从大到小。c/c++和编译平台的CPU有关，我们一般用的电脑都是Intel X86的处理器，他是由低到高也就是Litle Endian.但还是不是很清楚的干活！！！ 2、big endian：最高字节在地址最低位，最低字节在地址最高位，依次排列。 little endian：最低字节在最低位，最高字节在最高位，反序排列。 更是不是很明白了。 哎！可爱又可恨的计算机啊！！！！

需要注意的是，有个字节序的问题：big indian和little indian。你可以自己搜索一下。

楼上的理解正确。

基地址是指从那个地址开始，一直往后计算多少个字节吗？比如说我用的编译器对于整形分配四个字节，也就是说从基地址开始往后数四个字节都是用来存放整形变量吗？

占用哪两个字节是在运行时决定的。不过你可以看到： int a;  printf("%p", &a); 将打印a所占空间（两个字节）的基地址。

针对你的： 2、0xff91470c是一串16进制数，这个就是它的地址。 3、sizeof就是用来求一个对象或者类型所占的内存字节数。

1、我执行这条语句printf("%d\n", sizeof(int));的输出结果是4，在网上查了一下，针对不同的编译器对整形变量分配的字节数不同， 我用的是Linux下的编译器，所以不同于turboC是分配2个字节，这点我明白了。  2、执行这两条语句的输出结果是         int k;         printf("%p", &k); 0xff91470c，那这个结果（0xff91470c）又是什么意思呢？其中p又是什么意思？  3、针对三楼回复sizeof（）；/*括号内为要求的字节的名称*/，能将清楚一点吗？ 先谢过大家了。


Question: [求助]关于字符串和位操作符右移的问题

连不连续是由设计决定的，没有“应该”“理所当然”，只有“规定” 在某些存储结构中，两个字节的第一位位于同一个存储芯片中，同一个字节内的不同位位于不同存储芯片中，你觉得哪些位是连续的？  数据的左移和右移只和这个数据本身有关，不影响其他数据 一个char进行左右移只影响一个字节，一个int进行左右移就影响四个字节

这么说吧，像>>这些运算操作都是在CPU的寄存器中进行的，而变量都保存在存储器中。c = c >> 8 实际的操作过程是： 1 把变量c读入寄存器 2 在寄存器中把数据右移8位 3 把结果写入存储器中的c变量处  所以单纯执行 c>>8 你看不到任何效果，因为存储器没有变 字符数组是一组字符变量组织在一起，c[0]=c[0]>>8；所做的就是把c[0]右移后写回c[0]。注意，只写了c[0]，所以其它字符都不会变  union 的例子可以是因为操作的int变量（两个字节），所以写回去时改变了两个字符。如果改成u.c[0]=u.c[0]>>8 你再试试

谢谢，我的意思是>>和空间之间应该是有联系的。 比如 union U { 	char c[2]; 	int i; };  	U u = {'a','b'}; 	cout << u.c[0];//输出是a 	 	u.i = u.i >> 8; 	cout << u.c[0];//输出是b  那么字符数组为什么不可以右移，变为字符右移？

c赋值为'a'，因为char占用一个字节，就是8个二进制位，右移8位，就会把a的二进制码全部移走，而每移一位高位的空缺都由0来补上。所以这时c的数值是0. 右移移位是电路操作，而指针移位是逻辑操作，这是两码事。


Question: C语言中文件输出问题

while(!feof(fb)) { ch=fgetc(fb); putchar(ch);  }  这种写法是比较典型的错误，很多书都在误导。  没有执行fgetc之前，FILE是不知道是否eof的，所以应该改为先fgetc，然后判断fgetc返回值。

不要使用 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;  //... } 类似的例子还可以举很多。

fb=fopen("F:\新建文本文档.txt","r");中'\'改为'\\'

#include <stdio.h> #include <stdlib.h> int main() {     int ch;     FILE *fb;     fb=fopen("F:\\新建文本文档.txt","r");     if (NULL==fb) {         printf("找不到文件[F:\\新建文本文档.txt]!\n");         return 1;     }     while(1) {         ch=fgetc(fb);         if (EOF==ch) break;         putchar(ch);     }     fclose(fb);     return 0; }

没有问题啊，我用vs2010编译执行没有问题。代码稍微修改了一点，应该是不会有影响的。 #include "stdafx.h" #include <stdio.h> #include <stdlib.h> int test_32() { 	char ch; 	FILE*fb; 	fb=fopen(".\\ReadMe.txt","r"); 	while(!feof(fb)) 	{ 		ch=fgetc(fb); 		putchar(ch);  	} 	fclose(fb); 	return 0; }


Question: c函数返回为void*指针，在cpp文件中无法识别

跟C和C++没有关系的，看看错误的具体提示吧。  引用 楼主 luoyanghero 的回复:在Image.c文件中有函数 void* MaPU_Malloc(int SIZE) { 	return (void*)malloc(SIZE); } 在ImgProc.cpp中调用，无法识别该函数，请问是什么原因？（该函数在同一文档中调用能识别，*.cpp文件中调用其他*.c的函数可以。已包含extern“C”）

估计没将Image.c和ImgProc.cpp放在一个项目中。

无法识别是什么报错


StaticProc=(WNDPROC)SetWindowLong(GetDlgItem(hDlg,IDC_STC8),GWL_WNDPROC,(LONG)ProcLink); 编译器没找到 StaticProc 的声明。

代码是从网上搜到的，然后再加到自己代码里的，我只想实现静态文本框的超链接功能，有人能直接上代码吗？ 注：mingw编译的

引用 2 楼 zxh707wk 的回复:具体怎么改？ 那要看代码有没有定义StaticProc： 如果有，就要在引用的文件里面声明下,extern ... StaticProc； 如果没有，就要先定义，然后再在引用的地方声明。

你没定义staticproc吧

具体怎么改？


Question: 二叉树的竖向显示

所谓的竖向打印是啥 像树的结构打印成图形样式? 那你用层次遍历试一下


Question: 关于浦风投针的C语言

lz代码本身有问题啊——   这是我随便输的数得到的结果，你的两个答案是怎么得出来的啊 关于浦风投针，lz可以看看这个——http://blog.csdn.net/zmazon/article/details/8199357（这个我是真看不懂）


Question: 异或后 还原不回去 大家帮忙看看啊

引用 6 楼 Automation_dmu 的回复:将descrypt_file（）中的key ^= ch 改成 key ^= x 这个好像正解

将descrypt_file（）中的key ^= ch 改成 key ^= x

key ^= ch; 每次改变key的值啊

key ^= ch;  是不是把key的值改变了？

完全不对？还是有些地方不对？ 跟踪一下应该很容易查的。

'a' - 256 = -1不等于-1，反正就是这意思

while( (ch=fgetc(fp_dstTxt)) != EOF )     {         x = (ch - i) ^ key;         fputc(x, fp_srcTxt);         key ^= ch;         i++;     }    while( (ch=fgetc(fp_srcTxt)) != EOF )     {         x = (ch ^ key) + i;         fputc(x, fp_dstTxt);         key ^= ch;         i++;     }   i如果大于255怎么办？ 例如： 'a' - 256 = -1，你写的文件里是什么？ 可以改成： i = i %255


Question: 关于管道echo的小白问题

1)echo 20|abc 应该没问题，可能是没有生成 可执行程序 2）试试 echo 20|abc.exe 3）编译了没有，看到可执行文件了么 4）abc.cbp 貌似 code::block 项目文件，不是可执行程序

可以把n的值打印出来看下


Question: C语言按顺序执行写入文本语句,但写入文本的内容却不按顺序（有时顺序对，有时不对）

file1文件不用考虑

引用 2 楼 czarten 的回复:贴代码 六个字补丁 就是一抓包程序，每抓一包分析，将分析信息写入文本txt中，vc++,winpcap抓包 部分代码 void ethernet_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)      {         u_short ethernet_type;          /* 以太网类型 */          struct ether_header *ethernet_protocol;          /* 以太网协议变量 */          u_char *mac_string;          /* 以太网地址 */          static int packet_number = 1;          /* 数据包个数，静态变量 */       file1=fopen("H:\\example1.txt","at+"); 	file=fopen("H:\\example.txt","at+");     printf("**************************************************\n");          printf("捕获第%d个网络数据包\n", packet_number);  	fprintf(file1,"%d,",packet_number); 	fprintf(file,"捕获第%d个网络数据包\n",packet_number);     printf("捕获时间:\n");          printf("%s", ctime((const time_t*) &packet_header->ts.tv_sec));          /* 获得捕获数据包的时间 */          printf("数据包长度:\n");          printf("%d\n", packet_header->len);          printf("--------   以太网协议    --------\n");     ethernet_protocol = (struct ether_header*)packet_content;          /* 获得以太网协议内容 */          printf("类型:\n");          ethernet_type = ntohs(ethernet_protocol->ether_type);          /* 获得以太网类型 */          printf("%04x\n", ethernet_type);          switch (ethernet_type) /* 根据以太网类型判断 */          {      	case 0x0800:      		printf("上层协议为IP协议\n");  		break;      	case 0x0806:      		printf("上层协议为ARP协议\n"); 		break;      	case 0x8035:      		printf("上层协议为RARP协议\n");  		break;      	default:      		break;          }          printf("源MAC地址: \n");      mac_string = ethernet_protocol->ether_shost;  	printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5)); 	fprintf(file,"源MAC地址:%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5)); 	/* 获得源以太网地址 */          printf("目的MAC地址: \n");      mac_string = ethernet_protocol->ether_dhost;          printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));  	fprintf(file,"目的MAC地址: %02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));     /* 获得目的以太网地址 */          switch (ethernet_type)          {      	case 0x0806:      		arp_protocol_packet_callback(argument, packet_header, packet_content);      		break;      		/* 上层协议为ARP协议，调用分析ARP协议的函数，注意参数的传递 */      	case 0x0800:      		ip_protocol_packet_callback(argument, packet_header, packet_content);      		break;      		/* 上层协议为IP协议，调用分析IP协议的函数，注意参数的传递 */      	default:      		break;          }          printf("**************************************************\n");          packet_number++;       printf("捕获数据包内容:\n"); 	for(int i=0;i<packet_header->len;i++) 	{ 		printf("%02x ",*(packet_content+i)); 		fprintf(file,"%02x",*(packet_content+i)); 	}  	fprintf(file,"\n\n",sizeof("\n\n")); 	printf("\n"); 	fclose(file1); 	fclose(file); } main() { 	const char user[] = "root";         //username       const char pswd[] = "123456";    //password       const char host[] = "localhost";    //or"127.0.0.1"       const char table[] ="test";       //database       unsigned int port = 3306;           //server port               mysql_init(&myCont);       if(mysql_real_connect(&myCont,host,user,pswd,table,port,NULL,0))       {           cout<<"connect succeed!"<<endl;           mysql_query(&myCont, "SET NAMES GBK");     //设置编码格式,否则在cmd下无法显示中文  	 	}	  	pcap_if_t *alldevs;//设备列表 	pcap_if_t *d; 	int inum; 	int i=0; 	pcap_t *adhandle;//PCAP源口 	char errbuf[PCAP_ERRBUF_SIZE];     /* 获取本机设备列表 */     if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)     {         fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);         exit(1);     }     /* 打印列表 */     for(d=alldevs; d; d=d->next)     {         printf("%d. %s\n", ++i, d->name);         if (d->description)             printf(" (%s)\n", d->description);         else             printf(" (No description available)\n");     }     if(i==0)     {         printf("\nNo interfaces found! Make sure WinPcap is installed.\n");         return -1;     }     printf("Enter the interface number (1-%d):\n",i);     scanf("%d", &inum);     if(inum < 1 || inum > i)     {         printf("\nInterface number out of range.\n");         /* 释放设备列表 */         pcap_freealldevs(alldevs);         return -1;     }     /* 跳转到选中的适配器 */     for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);     /* 打开设备 */ 	if ( ( 		adhandle= pcap_open(d->name,          // 监听的适配器名称 		65536,            // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 		PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式 		1000,             // 读取超时时间 		NULL,             // 远程机器验证 		errbuf       // 错误缓冲池 		) ) == NULL) 	{ 		fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); 		/* 释放设备列表 */ 		pcap_freealldevs(alldevs); 		return -1; 	}     printf("\n正在监听 %s...\n", d->description);     /* 释放设备列表 */     pcap_freealldevs(alldevs);     /* 开始捕获 */     pcap_loop(adhandle,5, ethernet_protocol_packet_callback,NULL);//用pcap_open监听的抓包端口      pcap_close(adhandle); /*	int res; 	res=mysql_query(&myCont,"LOAD DATA LOCAL INFILE 'H://example1.txt' INTO  table packet1  FIELDS TERMINATED BY ',' ENCLOSED BY '' LINES TERMINATED BY '\n';"); 	if(!res) 	{ 		printf("Inserted id number %lu rows\n",(unsigned long)mysql_affected_rows(&myCont)); 	}else 	{ 		fprintf(stderr,"Insert error %d: %s\n",mysql_errno(&myCont),mysql_error(&myCont)); 	} 	mysql_close(&myCont);//断开连接*/     return 0; }

引用 2 楼 czarten 的回复:贴代码 六个字补丁 代码太大了 传不上去

贴代码 六个字补丁

先去google “提问的智慧”


Question: 求高手指点一下小弟一个关于星期几的问题

不好意思！我对这个网站不是很熟悉，所以结了零分给你！你重新给我回复我再把结贴分给你吧。

谢谢您的指点！我知道我错在什么地方了！if (totaldays == 1) printf("星期四");我这个是从八月十号算起的所以是星期六

求每月天数我做了一点优化，也可以在全局弄一个每个月的数组： int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int getMonthDay(int year, int month){ 	if (month == 2 && isLeapYear(year)) 		return 29; 	return day[month - 1]; }

你的代码格式为什么空行这么多，还有，语块里如果只有一条语句，那么没有用花括号的必要。 2009年第一天是周四，循环计算日期中有错误。  #include<stdio.h> //判断是否是闰年 int isLeapYear(int year) { 	int flag = 0; 	if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) 		flag = 1; 	else 		flag = 0; 	return flag; } //求出该月的天数 int getMonthDay(int year, int month) { 	int day; 	if (month % 2) 		day = 31; 	if (!month % 2) 		day = 30; 	if (month == 2){ 		if (isLeapYear(year)) 			day = 29; 		else 			day = 28; 	} 	return day; } //求出距离2008年的总天数 int gettotalDays(int year, int month, int day) { 	int totaldays = 0, i, j; 	if (year>2008){ 		for (i = 2009; i<year; i++){ 			if (isLeapYear(year) == 1) 				totaldays += 366; 			else 				totaldays += 365; 		}  		for (j = 1; j<month; j++) 			totaldays += getMonthDay(year, j);    //totaldays += getMonthDay(year, month);  		totaldays += day; 		printf("总天数为%d:\n", totaldays); 	} 	else if (year == 2008){ 		if (month>8) 		{ 			for (i = 8; i<month; i++) 				totaldays += getMonthDay(year, month);  			totaldays += day - 8; 			printf("总天数为%d:\n", totaldays); 		} 		else if (month == 8){ 			if (day>8){ 				totaldays += day - 8; 				printf("总天数为%d:\n", totaldays); 			} 			else 				printf("您输入有误!请重新输入!\n"); 		} 		else 			printf("请重新输入!您输入的月份小于8月!\n"); 	} 	else 		printf("请您重新输入!您输入的年份小于2008年!\n");  	return totaldays; }  void main(){ 	int year, month, day, totaldays, monthday, week; 	printf("请您输入年月日:"); 	scanf("%d%d%d", &year, &month, &day); 	printf("您输入的是%d年%d月%d日", year, month, day);  	if (isLeapYear(year) == 1) 		printf("该年是闰年\n"); 	else 		printf("该年是平年\n");  	totaldays = gettotalDays(year, month, day);  	if (totaldays == 1) 		printf("星期四");   //printf("星期六"); 	else{ 		week = totaldays% 7;  		switch (week){ 		case 3: printf("星期日\n"); 			break;  		case 4: printf("星期一\n"); 			break;  		case 5: printf("星期二\n"); 			break;  		case 6: printf("星期三\n"); 			break;  		case 0: printf("星期四\n"); 			break;  		case 1: printf("星期五\n"); 			break;  		case 2: printf("星期六\n"); 			break; 		} 	} }


Question: 求解一个算法问题。。

double x = 0; unsigned char * p =&x; //先这样试试 p[0]=1,p[1]=2,p[2]=3,p[3]=4; //再这样试试 p[4]=1,p[5]=2,p[6]=3,p[7]=4; //不然可以反序  //另外也可以这样 union ｛ double a; unsigned int b[2]; };   b[0] =0x04030201; b[1]=0; //或者反过来。  b[0] =0x01020304; b[1]=0; //不然 b[0]=0; b[1] =0x04030201; ///或者反过来。 b[0]=0; b[1] =0x01020304; //总之，不过是个字节顺序的问题。

在计算机中，double型的数据编码和int型char型是不同的，double y=0x04030201，占8个字节，这个值的在内存中的表示为：00 00 00 04 08 0c 90 41（我的计算机得到的值是这个，不同的计算机可能不同）。而int y=0x04030201在内存中的表示为 01 02 03 04（这个结果表示我使用的计算机是小端型的），要想得到楼主想要的结果可参考二楼的程序，让后将结果int强制转换成double

4楼正解，只不过打印时出现指数形式，需要改成16进制形式 unsigned char Y1[8];     Y1[0]=0x01;     Y1[1]=0x02;     Y1[2]=0x03;     Y1[3]=0x04;          double y = *(double *)Y1;     printf("%x", y);

现在是要把double d=0x01020304;  怎么成为 unsigned char[4]={0x01,0x02,0x03,0x04} 得到的结果就是一个char数组。  不支持long long类型的。。如果用int或者long类型的时候，long  d=0x01020304;这样已经溢出了吧。。

用long long类型，然后注意一下大小端问题

printf("y=0x%08x.\n", y); 打印这样更清楚些

int main(int argc, char* argv[]) {     unsigned char x[4] = {0x01, 0x02, 0x03, 0x04};      unsigned int y = (unsigned int)(*(int*)x);  	printf("y=%d.\n", y); 	return 0; }

为什么不用unsigned int呢

再请问一下double d=0x01020304; 怎么转换的到 unsigned char[4]={0x01,0x02,0x03,0x04} 通过什么算法可以进行转换呢

double  y永远也不会等于0x04030201

引用 2 楼 lslvxy 的回复:[quote=引用 1 楼 u013595256 的回复:] #include<stdio.h>  int main(void) {  	unsigned char Y1[4]; 	int y = 0;     int i;  	Y1[0]=0x01;     Y1[1]=0x02;     Y1[2]=0x03;     Y1[3]=0x04; 	 	for(i = 3; i>=0; i--) 		y = (y << 8) + Y1[i]; 	printf("y=%#x\n", y); 	return 0; }仅供参考，y用的int型  这样虽然可以，但是如果Y1中的数据比较大的话计算后会超出int的范围的吧。。所以我才想是用double类型来接收的。[/quote]我觉得你可以根据你的数据数量，malloc一块内存，然后用memcpy把相应的数据拷贝到那块内存区域中，我没写代码，你可以试试。

已经是了。

#include <iostream> using namespace std;  int main() {     unsigned char Y1[4];     Y1[0]=0x01;     Y1[1]=0x02;     Y1[2]=0x03;     Y1[3]=0x04;          double d = *(double *)Y1; 	cout << d << endl; 	return 0; }

如果使用double型，就没法使用左移，而且数据会丢失。如果数位相对较少，最大用到long long int，再长，就用数组直接输出。 #include<stdio.h>  int main(void){ 	unsigned char Y1[4]; 	int i;  	Y1[0] = 0x01; 	Y1[1] = 0x02; 	Y1[2] = 0x03; 	Y1[3] = 0x04;  	printf("y=0x"); 	for (i = 3; i >= 0; --i){ 		if (Y1[i] <= 0xF)putchar('0'); 		printf("%x", Y1[i]); 	} 	putchar('\n'); 	return 0; }

引用 1 楼 u013595256 的回复:#include<stdio.h>  int main(void) {  	unsigned char Y1[4]; 	int y = 0;     int i;  	Y1[0]=0x01;     Y1[1]=0x02;     Y1[2]=0x03;     Y1[3]=0x04; 	 	for(i = 3; i>=0; i--) 		y = (y << 8) + Y1[i]; 	printf("y=%#x\n", y); 	return 0; }仅供参考，y用的int型  这样虽然可以，但是如果Y1中的数据比较大的话计算后会超出int的范围的吧。。所以我才想是用double类型来接收的。


Question: 关于鸡尾酒排序。。。

不明白楼主什么意思，那个for循环的用法是对的。


Question: 求大神帮忙，怎么用C 语言编写一个登陆界面

一定要用C？我觉得用C#更简单点。

引用 楼主 u013995628 的回复:刚开学大2老师要求我们做一个管理系统的项目，求大神帮忙登陆界面怎么制作，大一开学第一节课老师讲解了下，都这么久了已经忘了T T     RT就像这种的  随便找个前端做个界面 然后用C写实现啊

最好还是学系较新的技术，现在还用c+win32是不是有点……浪费时间

搜索C 语言WIN32编程

你们的老师肯定也没有教过用C语言写界面这种东西。你真得好好反省大一时你听了什么课。

用MFC不就搞定了  用c写...

找MFC看看吧 一看这样子就是MFC做的

MFC容易。。。。

引用 2 楼 u013995628 的回复:额这倒不是，只是我们小组让我做登陆界面。我想做到那种程度。 怎么用C语言写windows界面啊？  你可以去找那种特别的老的Win32程序设计的书，基本就是你要的东西 （C语言+系统API）。

你去百度文库看看。。

用C语言写Windows界面，你确定这是你们老师的要求？


Question: 救命！！！帮我看看哪错了，找不出来我就自杀去了

引用 28 楼 nadleeh123 的回复:[quote=引用 楼主 u013995559 的回复:] #include<stdio.h> #include<stdlib.h> #include<string.h> #include"h.h"  extern void enter_m();  extern void see_m();  void see_m()   /********查找函数********/ {    int i;    system("cls");    printf("请输入要查询的房间号码:\n");    scanf("%d",&i);    if(Room[i].Room_ID==i)    {      printf("\n姓名:%s\n",Room[i].name); 	 printf("\n性别（0表示男，1表示女）%d：",Room[i].sex);      printf("\n年龄：%d",Room[i].age);      printf("\n入住时间（年/月/日）%d%d%d：",Room[i].year,Room[i].month,Room[i].date); 	 printf("\n电话：%d",Room[i].tel); 	 printf("\n居民身份证：%s",Room[i].ID_card);      printf("\n房间号：%d",Room[i].Room_ID);      printf("\n房间价格：%d",Room[i].price); 	 printf("\n是否入住:（1表示入住，0表示不入住）%d",Room[i].sign);    }     else 	{      printf("很抱歉,没有找到该身份证登记的相关信息!!"); 	} }  你的入口函数main呢？ 吃了？[/quote]+1

如果用的是vs的话，建议你重新建一个工程。应该是工程问题

没有 main 函数

估计是今天要交课程设计了，晚上不知道在哪里copy了一段代码，一编译，出问题了。自己平时又没有学过，明天就要交货了，怎么办，又要不及格了。于是在这里哭生哭死，小刀插大腿的。过了这个关， 又天天玩游戏去了。对于你这种人，说多无谓。

引用 29 楼 u013061236 的回复:[quote=引用 14 楼 u013995559 的回复:] 哪位大神帮我把查询的那段写下吧，跪求 程序并没有错，你只是缺少main函数，那个直接写个 int main() { } 就搞定了[/quote] int main() {  see_m();  return 0; }

人命关天....  居然没有main.... 汗

引用 8 楼 dbzhang800 的回复:你连main函数都没有？？ 引用 8 楼 dbzhang800 的回复:你连main函数都没有？？ 正解

引用 楼主 u013995559 的回复:#include<stdio.h> #include<stdlib.h> #include<string.h> #include"h.h"  extern void enter_m();  extern void see_m();  void see_m()   /********查找函数********/ {    int i;    system("cls");    printf("请输入要查询的房间号码:\n");    scanf("%d",&i);    if(Room[i].Room_ID==i)    {      printf("\n姓名:%s\n",Room[i].name); 	 printf("\n性别（0表示男，1表示女）%d：",Room[i].sex);      printf("\n年龄：%d",Room[i].age);      printf("\n入住时间（年/月/日）%d%d%d：",Room[i].year,Room[i].month,Room[i].date); 	 printf("\n电话：%d",Room[i].tel); 	 printf("\n居民身份证：%s",Room[i].ID_card);      printf("\n房间号：%d",Room[i].Room_ID);      printf("\n房间价格：%d",Room[i].price); 	 printf("\n是否入住:（1表示入住，0表示不入住）%d",Room[i].sign);    }     else 	{      printf("很抱歉,没有找到该身份证登记的相关信息!!"); 	} }  你这个代码，还是把格式规整一下，看着都头疼，格式要统一，不要一会这样，一会又那样

引用 14 楼 u013995559 的回复:哪位大神帮我把查询的那段写下吧，跪求 程序并没有错，你只是缺少main函数，那个直接写个 int main() { } 就搞定了

引用 楼主 u013995559 的回复:#include<stdio.h> #include<stdlib.h> #include<string.h> #include"h.h"  extern void enter_m();  extern void see_m();  void see_m()   /********查找函数********/ {    int i;    system("cls");    printf("请输入要查询的房间号码:\n");    scanf("%d",&i);    if(Room[i].Room_ID==i)    {      printf("\n姓名:%s\n",Room[i].name); 	 printf("\n性别（0表示男，1表示女）%d：",Room[i].sex);      printf("\n年龄：%d",Room[i].age);      printf("\n入住时间（年/月/日）%d%d%d：",Room[i].year,Room[i].month,Room[i].date); 	 printf("\n电话：%d",Room[i].tel); 	 printf("\n居民身份证：%s",Room[i].ID_card);      printf("\n房间号：%d",Room[i].Room_ID);      printf("\n房间价格：%d",Room[i].price); 	 printf("\n是否入住:（1表示入住，0表示不入住）%d",Room[i].sign);    }     else 	{      printf("很抱歉,没有找到该身份证登记的相关信息!!"); 	} }  你的入口函数main呢？ 吃了？

好痛苦啊，很同情

提示找不到入口函数

引用 17 楼 angel_su 的回复:认真看错误信息，都在link了，说明代码没问题，只是你的工程应该是要构建执行文件，那么需要提供一个main函数，不然只能先个别compile不能整体build... 顶

引用 5 楼 u013995559 的回复: 我看这个error 报的不是代码的逻辑问题，而是debug 的方式有问题

看的头疼，晕了

引用 17 楼 angel_su 的回复:认真看错误信息，都在link了，说明代码没问题，只是你的工程应该是要构建执行文件，那么需要提供一个main函数，不然只能先个别compile不能整体build... 莫有main

看的头疼，晕了

浮夸

自杀了没？？？？？？？？？

1.C程序默认从main开始执行, 所以一定要有一个main函数. 2.要从main里面去处理你的事件. 3.你可以做成一个库, 然后做为查询系统的一个部件,等系统编码时连接


Question: 新手求助！！求大神解答！！

引用 5 楼 u012928672 的回复:[quote=引用 1 楼 u012421456 的回复:] lz你代码从哪儿弄来的啊？ 第4行已经给 n 赋值为 0，而第9行i的值被赋为1，for循环的条件又是i<=n,结果根本没有一次循环啊，还有第10行的len从哪儿来的啊？上面没有啊这个代码是我自己写的，n第一遍的时候是不进循环的，后面不是有个n+=2么，等第二遍的时候n就等于2了，然后1en是xen就是x的n次方的意思，我看书上写的e前面必须有个数字，然后我就乘了个1。[/quote] 看错了

引用 1 楼 u012421456 的回复:lz你代码从哪儿弄来的啊？ 第4行已经给 n 赋值为 0，而第9行i的值被赋为1，for循环的条件又是i<=n,结果根本没有一次循环啊，还有第10行的len从哪儿来的啊？上面没有啊这个代码是我自己写的，n第一遍的时候是不进循环的，后面不是有个n+=2么，等第二遍的时候n就等于2了，然后1en是xen就是x的n次方的意思，我看书上写的e前面必须有个数字，然后我就乘了个1。

lz还是参考一下别人的吧——http://bbs.bccn.net/thread-335083-1-1.html http://zhidao.baidu.com/link?url=0rtQKG_fEjDF1hUwJYz62NQ9zg-wraSeJNioP1aYRVVIhg7aWxkq0UpsF1wmLOka8OUArvUmoFXIGAnjVmgYsa

首先你前面已经将n初始化为0，你在for循环的时候，条件是i<=n;这样for循环是不能运行的，而且你的for循环是{b=b*i}，后面的代码根本没有参与循环运算，总的来说，这段程序的算法不对，而且差好多

仅供参考：  #include <iostream> using namespace std ; //get the an  double x_an(double x,int i) {     double res = 1.0;     for(int t = i ; t > 0; t--)     {         res*=(x/t) ;     }     return res ; }  //cos(x)=1-(x^2/2!)+(x^4/4!)-(x^6/6!).. double x_cos(double x,double rate = 1e-6) {     int i = 2 ;     int ct = 1 ;     double res = 1 ;     double sig = -1;     double an = 0 ;     while(1)     {         sig = (ct%2 == 0 ? 1.0 : -1.0);         i=2*ct;         an = x_an(x,i);         if(an < rate)break;         an *= sig;         res += an ;         ct++;     }     return res; } int main() {     double x ;    while(cin>>x){         cout<<x_cos(x)<<endl;    }    return 0; }


Question: 纯新手求解三道题

请问第一题的正确是什么...他给的有c和c++，怎么编译呢？

第二题  #include <iostream> #include<conio.h> using namespace std;  void main() { 	int t=0; 	cout<<"请输入要输出的组数T："<<endl; 	cin>>t; 	char **hit; 	hit=(char**)malloc(sizeof(char*)*t); 	for (int j=0;j<t;j++) 	{ 		hit[j]=(char*)malloc(sizeof(char)*100); 		memset(hit[j],0,100); 		cout<<"请输入第"<<j+1<<"组数据'g'或'l'，否则退出："<<endl; 		int i=0; 		while(1) 		{ 			char str; 			str=getche(); 			if (str!='g'&&str!='l') 			{ 				break; 			} 			hit[j][i]=str; 			i++; 		} 		cout<<endl; 	}  	for (int j=0;j<t;++j) 	{ 		int recordg=0; 		int maxg=0; 		for (int i=0;i<strlen(hit[j]);++i) 		{ 			if ('g'==hit[j][i]) 			{ 				recordg++; 				if (maxg<recordg) 				{ 					maxg=recordg; 				} 			}else 			{ 				recordg=0; 			} 		}  		cout<<"第"<<j+1<<"组最大连击数："<<maxg<<endl; 	} 	system("pause"); }

第一个题，会10,100会超过int的最大存储范围，用浮点数表示不了这么长的数位，可以把数字转化为字符串比较。下面写的是直接计算的  #include <iostream> #include <iomanip> using namespace std;  int linknum(int num1,int num2) { 	int len=1; 	while(num2%10>10) 	{ 		len++; 		num2/=10; 	} 	for (int i=0;i<len;++i) 	{ 		num1*=10; 	} 	num1+=num2; 	return num1; }  void main() { 	int t,*n,*k; 	cout<<"请输入组数T:"; 	cin>>t; 	n=(int *)malloc(sizeof(int)*t); 	k=(int *)malloc(sizeof(int)*t); 	for (int i=0;i<t;i++) 	{ 		cout<<"请输入第"<<i+1<<"组n,k:"<<endl; 		cin>>n[i]>>k[i];cout<<endl; 	}  	for (int i=0;i<t;i++)//遍历组数 	{ 		int **array; 		int re=1; 		array=(int **)malloc(sizeof(int*)*n[i]);//分配矩阵空间 		for (int x=0;x<n[i];++x) 		{ 			array[x]=(int *)malloc(sizeof(int)*n[i]); 		} 		for (int j=0;j<n[i];++j)//矩阵赋值 		{ 			for (int l=0;l<n[i];++l) 			{ 				array[j][l]=re; 				re++; 				if (k[i]<re) 				{ 					re=1; 				} 			} 		}  		int **arraytotal;; 		arraytotal=(int **)malloc(sizeof(int*)*2); 		for (int x=0;x<n[i];++x) 		{ 			arraytotal[x]=(int *)malloc(sizeof(int)*n[i]); 			memset(arraytotal[x],0,sizeof(int)*n[i]); 		} 		for (int j=0;j<n[i];++j) 		{ 			for (int l=0;l<n[i];++l) 			{ 				arraytotal[0][j]=linknum(arraytotal[0][j],array[j][l]); 				arraytotal[1][l]=linknum(arraytotal[1][l],array[j][l]); 			} 		}  		int maxnum=0; 		for (int j=0;j<2;++j) 		{ 			for (int l=0;l<n[i];++l) 			{ 				if (maxnum<arraytotal[j][l]) 				{ 					maxnum=arraytotal[j][l]; 				} 			} 		} 		cout<<"第"<<i+1<<"组最大数为："<<maxnum<<endl; 	}; 	system("pause"); }


Question: Android屏幕解锁图案有多少种？

不好意思，不知道怎么给分。点了无满意结贴然后就这样了。。。。。

学习了楼上大神的程序，向你学习，向你致敬！ 但效率上还是和第二个程序差不多，看来有时还是简单方法效率高一点！ 非常感谢！

// 389112 // 65 #include <cstdio> #include <iostream> #include <ctime> #include <algorithm> using namespace std; #define X first #define Y second typedef pair<int, int> Pt; int solve(Pt* data, int n) { 	int ret = 0; 	do 	{ 		int ok = 1; 		int used[9] = {0}; 		for (int i = 0; i + 1 < n; ++i) 		{ 			if ((data[i].X+data[i+1].X) % 2 == 0 && (data[i].Y+data[i+1].Y) % 2 == 0) 			{ 				int a = data[i].X+data[i+1].X >> 1; 				int b = data[i].Y+data[i+1].Y >> 1; 				int id = a*3+b; 				if (used[id] == 0) 				{ 					ok = 0;  					break; 				} 			} 			used[data[i].X*3+data[i].Y] = 1; 		} 		ret += ok; 	} while (next_permutation(data, data+n)); 	return ret; } int main() { 	int ans = 0; 	for (int i = 1; i < 1 << 9; ++i) 	{ 		if (__builtin_popcount(i) < 4) continue; 		Pt data[9]; 		int top = 0; 		for (int j = 0; j < 9; ++j) 		if (i & 1 << j) data[top].X = j / 3, data[top++].Y = j % 3; 		ans += solve(data, top); 	} 	cerr << ans << endl; 	cerr << clock() << endl; 	return 0; }


Question: 吃回车问题

scanf(" %c" ,xxxx);// %c前面加个空格，可以过滤掉空白符

使用getchar()，scanf()来读取一个字符之前，最好使用getchar()来接收之前输入时的回车，如果不确定之前是否有输入，最保险的就是使用fflus(stdin);来清空缓存区


Question: 我用Ubuntu 下的vim 遇到一个诡异的问题

引用 2 楼 zmlovelx 的回复:好像这个跟ub vim没有半毛钱的关系。我还以为是我的编译器有问题

改成这样就行了 #include<stdio.h> #include<stdlib.h>    void arr_print(int *arr, int len) {     int i;         for (i=0;i<len;i++)     printf("%d ", arr[i]);           printf("\n"); } void swap(int *p, int *q) {     int temp=*p;     *p=*q;     *q=temp; }   void bubble_sort( int *arr, int len) {     int i, j;      //for (i=0;i<9;i++)//这里如果改成  	for(i=0;i<len-1;i++)                   //for(j=0; j<9-i; j++)//这里改成  		for(j=0; j<len-1-i; j++)         {             if (arr[j]>arr[j+1])             {                 swap(&arr[j], &arr[j+1]);                 }             }             }   int main() {     int arr[] = {2, 10, 3, 5, 6, 9, 4, 7, 8, 1};     bubble_sort(arr, sizeof(arr)/sizeof(int));           arr_print(arr, sizeof(arr)/sizeof(int));               return 0; }

好像这个跟ub vim没有半毛钱的关系。

因为LEN计算有问题  (sizeof(arr))/(sizeof(arr[0]))这个计算对数组来说是没问题的，但是对指针来说就没用了  arr在传递前是数组，这样计算是没问题的。但把数组做参数传递时，会退化成指针，只有地址，长度会被丢弃。所以(sizeof(arr))/(sizeof(arr[0]))算出来的就是(sizeof(int*))/(sizeof(int))也就是4/4=1，排序当然就没用了。  在C里，数组做函数参数，还是手动传递一个长度比较好


Question: 从一个数组中搜到一个关键的数字，并返回该数组的下标

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

打印int要使用 %d.我感觉你这个数组没越界，只是循环不到索引为0的元素

重点是%d,不是%c

长度为5，n最大只能为4

编译器是不检查数组越界。

刚发上去，就看到问题了，编译器也不报错 哎  ~~


Question: 这个单链表程序在visual C++上有错误，还是我的visual C++编译器有问题，求大神指点

楼主，不是建立一个头结点就建立链表的，最后用一个单独函数建立

我看不懂，你的链表是怎么建立的啊

你的程序很有问题..insert函数明明有返回值,却用的是void ..返回的是head,  那么前面函数的返回值应该是node型 继续的下面就没法看了..main函数里面的head让人不知道怎么回事.. 比较粗糙很粗糙,都得改...


Question: 刚接触C语言，在编写的时候遇到问题，不懂得如何修改，希望大家能帮帮忙，谢谢 ~

1.char ch[]; 2.char ch[]=a+b>c&&a+c>b&&b+c>a?"yes":"no"; 这两句是错的： 1.重复定义了一个变量ch。 2.第一句看起来你是想定义一个数组，但是你没有指定数组元素的个数，语法错误。 3.第二句给字符串变量赋初值的时候，等号后面只能跟字符串。  ———————— 按照你的意思，这两句修改成下面的语句，应该就对了： char * ch=a+b>c&&a+c>b&&b+c>a?"yes":"no";

另外，我想问一下lz，你觉得这里的sqrt合适吗？

除了楼上说的，还有就是scanf中最好不要加非输入控制符（这里指的是逗号），因为非输入控制符必须原样输出，关于scanf，lz可以看看这个——http://blog.csdn.net/u012421456/article/details/18501309

char ch[]=a+b>c&&a+c>b&&b+c>a?"yes":"no";  这个地方，重复定义，而且赋值不能这样赋。 "yes":"no"在编译器看来是个指向"yes"或“no”的字符串指针，所以不能赋值给字符串数组，如果用指针接收的话，可以这样char* p; p=a+b>c&&a+c>b&&b+c>a?"yes":"no";  如果非要用字符串数组接收的话，可以拷贝到字符串数组，比如： char ch[16]; a+b>c&&a+c>b&&b+c>a?strcpy_s(ch,"yes"):strcpy_s(ch,"no");

引用 2 楼 PDD123 的回复:char * ch=a+b>c&&a+c>b&&b+c>a?"yes":"no";  这句中，是定义了一个字符型指针ch。 "yes"和"no"在编译的时候实际上是存储在程序中的，（a+b>c&&a+c>b&&b+c>a?"yes":"no"）返回的是这两个字符串的首地址。 还有，这个似乎是根据三个边长判断三角形的，应该放在scanf语句给a,b,c赋值以后


Question: scanf 和gets吃回车问题

查看MSDN和调试吧

gets()会将回车一起读进字符数组里 scanf("%s")不会读回车 scanf("%c")会将空格和回车留在输入流里，下一次读取，读输入流里的下一个字符

第一个输入读取一个整数，输入时你会输入（例如）： 3 \n(回车)，此时这两个输入会被放在输入缓冲区中，第一个3被 scanf("%d",&a) 获取，第二个回车 被 gets(str1)获取，当再一次输入时（例如）：asdjfsdjf \n 会被 gets(str3)全部读取,因为gets()读取的是字符串以\n为结尾的，总结即为楼上所说。

gets函数会吃掉输入字符串的回车符 scanf %d 会将回车符留在输入字符串中


Question: PKU北大ACM 1007 DNA Sorting

我重新改了代码，还是不行，求助啊 #include<stdio.h> #include<string.h> int main() { 	char a[101][52]; 	int c[51]; 	int m,n,i,j,s,b,k; 	scanf("%d%d",&m,&n); 	for(i=0;i<n;i++) 	{	 			scanf("%s",a[i]); 			a[i][m]='\0'; 	} 	for(s=0;s<n;s++) 	{ 		c[s]=0; 		for(i=0;i<m-1;i++) 			for(j=i+1;j<m;j++) 			{	 			if(a[s][i]>a[s][j]) 				c[s]++; 			} 	} 	for(i=0;i<n;i++) 	{ 	    b=c[0]; 		s=0; 		if(c[0]==-1) 		{     			k=1; 			while(c[k]==-1) 			{ 				if(k==n) return 0; 				k++; 			} 			b=c[k]; 			s=k; 		} 		for(j=0;j<n;j++) 		{	 			if(b >c[j] && c[j]!=-1) 			{ 				b=c[j]; 				s=j; 			} 		} 		c[s]=-1; 		//for(j=0;j<m;j++) 		//	printf("%c",a[s][j]); 		printf("%s\n",a[s]); 	 	 	} return 0; }

谢谢各位的帮助 错误的原因 int c[51];要改成int c[101]; 看来太粗心了 谢谢

是的，用char会溢出，我的算法确实不好，但是我还是想知道我的算法错误的原因 我已经有修改了，但是还是不能，wrong answer 我没有找到错误的原因，求大家帮帮忙  #include<stdio.h> #include<string.h> int main() { 	char a[101][52]; 	long c[51]={0}; 	int m,n,i,j,s,b,k; 	scanf("%d%d",&m,&n); 	for(i=0;i<n;i++) 	{	 			scanf("%s",a[i]); 			a[i][m]='\0'; 	} 	for(s=0;s<n;s++) 		for(i=0;i<m-1;i++) 			for(j=i+1;j<m;j++) 			{	 			if(a[s][i]>a[s][j]) 				c[s]++; 			} 	for(i=0;i<n;i++) 	{ 	    b=c[0]; 		s=0; 		if(c[0]==-1) 		{     			k=1; 			while(c[k]==-1) 			{ 				if(k==n) return 0; 				k++; 			} 			b=c[k]; 			s=k; 		} 		for(j=0;j<n;j++) 		{	 			if(b >c[j] && c[j]!=-1) 			{ 				b=c[j]; 				s=j; 			} 		} 		c[s]=-1; 		//for(j=0;j<m;j++) 		//	printf("%c",a[s][j]); printf("%s\n",a[i]); 	 	}											 return 0; }    谢谢各位的帮助了

这么一堆for,即使正确也超时，想想算法。。。

a[s][m]++;感觉char当数字用不牢靠吧，测试数据较大会溢出，最好改用int...

#include <iostream> #include <vector> #include <string> #include <algorithm> #include <windows.h> using namespace std;  size_t countUnsortedness(const string &s) {     int sum = 0;     for(int i = 0;i < s.size();i++)         for(int j = i+1; j <s.size(); j++)             if (s[j] < s[i] )                 sum++;     return sum; }  bool comp(const string &s1,const string &s2) {     return countUnsortedness(s1) < countUnsortedness(s2) ? true : false; }  int main() {     vector< string > DNAs;     int n,m;     cin >> n >> m;     for(string s;m--;cin>>s,DNAs.push_back(s));     stable_sort(DNAs.begin(),DNAs.end(),comp);     for(int i = 0; i < DNAs.size(); i++)         cout << DNAs[i] << endl;     system("pause");     return 0; }


Question: 不用指针编写出顺序线性表的输入输出，以及排序，插入，删除。 可以用学生信息系统来存放数据。 用C编译

数据结构好像都是用指针实现的吧，不用指针有意义吗？非要的话用动态数组吧，也可以实现


Question: 不用指针实现顺序线性表的输入输出，以及排序，插入，删除功能。

引用 楼主 u013465397 的回复:不用指针编写出顺序线性表的输入输出，以及排序，插入，删除。 可以用学生信息系统来存放数据。 用C编译 都顺序表了，malloc一块内存，把那块内存当数组来用

用动态数组，应该行吧

数组可以解决的

写一个结构体数组，利用下标访问。


Question: 刚学习C语言，编写的这个程序，自己找不出 错误，希望大家能指教指教，谢谢~

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

#include <stdio.h>  void main () { float a,b,c,d; printf("a,b,c="); scanf("%f,%f,%f",&a,&b,&c);  /* d=a>b?b:a; //首先对这种语句结构进行批判，一行语句应该只写一个操作运算，否则容易引起错误而且难以调试，所以?:这种操作符一般都是不推荐使用的 d>c?c:d ;   //错误在这里没有赋值 */  printf ("min=%f\n",d);  }  改成 #include <stdio.h> #include <math.h>  void main () { float a,b,c,d; printf("a,b,c="); scanf("%f,%f,%f",&a,&b,&c);  d=min(a, b); d=min(d, c); printf ("min=%f\n",d);  }

d>c?c:d ; 这句没有要干啥？

引用d=（a>b?b:a）； d=(d>c?c:d) ; 赞同这个！

这句话d>c?c:d ;  没有意义

#include <stdio.h>  void main () { float a,b,c,d; printf("a,b,c="); scanf("%f,%f,%f",&a,&b,&c);  d=a>b?b:a; d>c?c:d;//这句话应该修改为d=d>c?c:d;三目表达式的结果应该赋值给一个变量，由变量b接收该值 printf ("min=%f\n",d);  }

d=（a>b?b:a）； d=(d>c?c:d) ;

关于scanf的用法，lz可以看看这个——http://blog.csdn.net/u012421456/article/details/18501309

注释的释打错了

#include <stdio.h>  void main () { 	float a, b, c, d, min;      // 	printf("a,b,c="); 	scanf("%f,%f,%f",&a,&b,&c); 	 	d = a>b?b:a; 	min = d>c?c:d;              // 这里  	printf ("min = %f\n", min);	//还有这里  lz看看注视的地方，看能明白不 } /*另外，最好输入时输入小数，毕竟你定义的都是float 还有就是尽量不要在scanf中使用非输入控制符（这里指的是逗号）*/


Question: [SWU]自己定义连接字符串的函数的思路

引用 6 楼 u013990248 的回复:1 #include<stdio.h>   2   3 void main()   4 {   5         char *str1      = "cs";   6         char *str2      = "dn";   7         char str3[10];   8         int i, j;   9         for(i=0; *(str1+i)!='\0'; i++){  10                 str3[i] = str1[i];  11         }  12         for(j=0; *(str2+j)!='\0'; j++){  13                 str3[j+i]       = str2[j];  14         }  15         str3[j+i]       = '\0';  16         for(i=0; str3[i]!='\0'; i++){  17                 printf("%c", str3[i]);  18         }  19         putchar('\n');  20 } 针对楼上说的解决数据溢出，我采用的字符型指针的方法，这样似乎简单了一点，但是为什么，我把str3也定义为char *str3就不行了呢？求解释！！！ 只定义指针没有分配内存，要再加一句 str3 = malloc(10); 你才有空间放数据啊

比我强我都不喜欢做注释的

1 #include<stdio.h>   2 #include<string.h>   3   4 void main()   5 {   6         char str1[]     = "cs";   7         char str2[]     = "dn";   8         char str3[10];   9         int i, j;  10         int len1, len2;  11         len1    = strlen(str1);  12         len2    = strlen(str2);  13         for(i=0; i<len1; i++){  14                 str3[i] = str1[i];  15         }  16         for(j=0; j<len2; j++){  17                 str3[j+len1]    = str2[j];  18         }  19         str3[j+len1]    = '\0';  20         for(i=0; str3[i]!='\0'; i++){  21                 printf("%c", str3[i]);  22         } 楼上的同学，你觉得有解决你的问题吗？

楼上这种代码风格是非常反人类的，即使正确，也会被团队所厌恶的，道理很简单：大家看起来不容易懂。

void String_Catenate(char *p1, char *p2) { 	while(*p1++); 	p1--; 	while(*p1++ = *p2++); }

没明白楼主想问什么问题啊？ 是说怎么实现strcat吗？ 要将两个字符串连接起来，至少要给出这两个字符串的地址吧，假设为str1和str2，那么函数返回时，生成的连接后字符串放在哪里？str2吗？那么调用此函数时必须保证str2指向足够大的缓存，否则就会溢出。 也可以动态分配内存来存放，返回时将传入的指针指向分配的内存，但这种方式必须手动释放动态分配的内存。 所以，strcat选择了前者，而且还有一个strncat，限定长度。 请man strcat

Strcat函数原型如下：  //将源字符串加const，表明其为输入参数 char *strcat(char *strDest, const char *strSrc)  {   // 后文return address，故不能放在assert断言之后声明address   char *address = strDest;   assert((strDest != NULL) && (strSrc != NULL)); //对源地址和目的地址加非0断言   while(*strDest)             //是while(*strDest!=’\0’)的简化形式   {     //若使用while(*strDest++)，则会出错，因为循环结束后strDest还会执行一次++,     //那么strDest将指向'\0'的下一个位置。/所以要在循环体内++；因为要是*strDest最后指     //向该字符串的结束标志’\0’。     strDest++;   }     while(*strDest++ = *strSrc++)   {     NULL;             //该循环条件内可以用++，   }                   //此处可以加语句*strDest=’\0’;无必要   return address;     //为了实现链式操作，将目的地址返回 } 百度百科里面就有


Question: 字符指针变量与字符数组

数组和指针都可以进行[]来操作。 数组名，在很多情况下，你都可以当作一个指针来操作。 指针，在很多情况下，你也可以把他作为一个数组来操作。 sizeof 对数组和指针的操作是不一样的。  在使用[]时，数组和指针都是一样的，比如： int a[100];a[2]=12; int * a=new int[100];a[2]=12; 这两句都是正确的，其中的a[2]=12，都等效于 *(a+2)=12;

5 int main(int argc,char* argv[])   6 {   7     char* arr[]={   8         "11111111\n",   9         "222222222\n",  10         "333333333\n",  11         NULL  12     };  13   14     if(arr[0])  15     {  16         int i=0;  17         int len=sizeof(arr)/sizeof(arr[0]);  18         int num=len;  19           20         while(num--)  21         {     22             if(arr[i] /*使用前做指针有效性检查*/  23                     &&(*(arr+i))[strlen(arr[i])-1]=='\n')  24             {     25                 /*如果是字符串字面值则不能修改  输入的数据可以修改*/  26 //              (*(arr+i))[strlen(arr[i])-1]=0;  27                 int j=0;  28                 for(j=0;j<strlen(arr[i]);j++)  29                 {     30                     printf("%c",(*(arr+i))[j]);  31                 }  32             }  33             i++;  34         }  35       36     }  37       38     return 0;  39 } 08ptr.c

1：char* sMessage[]   是字符指针数组   而一般的字符指针数组最后是指向NULL作为结束的   比如       char*  sMessage[]={ "1","2","3",NULL}    if(sMessage[0]) 就是判断这个字符指针数组里面是不是有元素   如果sMessage[0]=NULL   就是没有数据  那么后续的比较就没意义  2   你这程序完全错误   不知道你哪里搞得  ：           (1) strlen(sMessage)    sMessage是二级指针   不能调用strlen      char* strlen(const char* s);           (2) if ( sMessage[strlen(sMessage)-1] == '\n' )     你想修改的是那一个字符串？          如果要把sMessage[1]中这个'\n'改成0   要这么写：          if(*（sMessage+1）[strlen(sMessage[1])-1)]=='\n')

看看<<c与指针>>，里面会有详细介绍 数组和指针的区别和联系

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

#include<stdio.h> int main() { 	char *p = "asdfgh"; 	printf("%c\n",p[3]); 	printf("%c\n",*(p+3)); 	return 0; } 既然把p申明为指针，那么不管p原先是定义为指针还是数组，都会按照下面三个步骤进行操作; 1.取得符号表中p的地址，提取存储在此处的指针。 2.把下表所表示的偏移量值指针的值相加，产生一个地址。 3.访问上面那个地址，取得字符.

[]的定义就是a[b]==*(a+b)==b[a]，本来就是指针相关 数组使用[]也是通过先转化为指向首元素的临时指针再执行[]的

引用 2 楼 u013163178 的回复:但你数组名单独出现的时候一般被编译器理解为指针，指向数组的第一个元素的地址。一种情况除外，就是char a[2]; int b; b = sizeof(a);遇到sizeof()的时候，数组名表示所有成员。   谢谢回答！ 但这个例子中sMessage已经在函数中作为形参被定义为字符指针变量了，怎么会在函数体中又以数组名出现了呢？

数组的本质就是指针。


Question: [swu]sprt函数不能直接用吗？是否需要定义？

在程序开始申明文件#include<math.h> 并且在编译时加上  -lm 如gcc -lm 文件名

#include "math.h"


Question: C语言 二进制文件存储读取数据结构的一个疑问

debug模式中调试器会在内存中加入一些调试信息

为什么两个连续结构体数组就无法读取？

引用 2 楼 user-2 的回复:2进制读取用模式"rb"... 打错。。。

求解答。。。


Question: 一个typedef看不懂

确实比较难 看懂, 请高手来解释一下吧，全面的，不能只说个大概，我觉得PFUN有两层括号就比较难懂了。

typedef int (*(*PFUN)(int a[2],int (*(*)(int [2]))[2]))[2] ; PFUN是一个返回值为指向一个 int[2]的数组指针的函数指针。它拥有两个参数，第一个是 int [2], 另一个也是一个返回值为指向一个 int[2]的数组指针的函数指针，不过它只有一个参数，即 int [2]. 这个蹩脚的声明，估计只能出现在面试题中吧。


Question: 最短路算法求助

引用 10 楼 buyong 的回复:引用 8 楼 M173475237 的回复:[quote=引用 7 楼 M173475237 的回复:] [quote=引用 6 楼 u012421456 的回复:] [quote=引用 5 楼 h15757160454 的回复:] [quote=引用 4 楼 u012421456 的回复:] 这个。。。lz代码问题太多啊！远的不说，先说你代码的第四五行，在C 语言中数组的长度能是这样吗？（个人见解，如有错误，敬请指正）可以啊，我记得这样好像是叫做 变长数组，C99标准定义的C语言新特性。 这个。。。lz用的什么编译器啊？ 这是VS2012的情况——  这是VC6.0的情况——[/quote]  变长数组不能是二维的。[/quote]  微软做的编译器是不支持的。。GCC阔以~[/quote]  gcc是神仙？[/quote] 你可能理解错了，gcc支持一维的边长数组。但数组在定义了以后长度就固定了，只是可以用变量定义长度而已。

引用 8 楼 M173475237 的回复:引用 7 楼 M173475237 的回复:[quote=引用 6 楼 u012421456 的回复:] [quote=引用 5 楼 h15757160454 的回复:] [quote=引用 4 楼 u012421456 的回复:] 这个。。。lz代码问题太多啊！远的不说，先说你代码的第四五行，在C 语言中数组的长度能是这样吗？（个人见解，如有错误，敬请指正）可以啊，我记得这样好像是叫做 变长数组，C99标准定义的C语言新特性。 这个。。。lz用的什么编译器啊？ 这是VS2012的情况——  这是VC6.0的情况——[/quote]  变长数组不能是二维的。[/quote]  微软做的编译器是不支持的。。GCC阔以~[/quote]  gcc是神仙？

引用 5 楼 h15757160454 的回复:引用 4 楼 u012421456 的回复:这个。。。lz代码问题太多啊！远的不说，先说你代码的第四五行，在C 语言中数组的长度能是这样吗？（个人见解，如有错误，敬请指正）可以啊，我记得这样好像是叫做 变长数组，C99标准定义的C语言新特性。  从这回答看lz有当政治家的潜质。但不适和程序员。程序员都是先编译看是否出错。然后查C99标准里在哪说可以这样写了。 lz这一句，楼下的把这些都给做了。

引用 7 楼 M173475237 的回复:引用 6 楼 u012421456 的回复:[quote=引用 5 楼 h15757160454 的回复:] [quote=引用 4 楼 u012421456 的回复:] 这个。。。lz代码问题太多啊！远的不说，先说你代码的第四五行，在C 语言中数组的长度能是这样吗？（个人见解，如有错误，敬请指正）可以啊，我记得这样好像是叫做 变长数组，C99标准定义的C语言新特性。 这个。。。lz用的什么编译器啊？ 这是VS2012的情况——  这是VC6.0的情况——[/quote]  变长数组不能是二维的。[/quote]  微软做的编译器是不支持的。。GCC阔以~

引用 6 楼 u012421456 的回复:引用 5 楼 h15757160454 的回复:[quote=引用 4 楼 u012421456 的回复:] 这个。。。lz代码问题太多啊！远的不说，先说你代码的第四五行，在C 语言中数组的长度能是这样吗？（个人见解，如有错误，敬请指正）可以啊，我记得这样好像是叫做 变长数组，C99标准定义的C语言新特性。 这个。。。lz用的什么编译器啊？ 这是VS2012的情况——  这是VC6.0的情况——[/quote]  变长数组不能是二维的。

引用 9 楼 buyong 的回复:引用 5 楼 h15757160454 的回复:[quote=引用 4 楼 u012421456 的回复:] 这个。。。lz代码问题太多啊！远的不说，先说你代码的第四五行，在C 语言中数组的长度能是这样吗？（个人见解，如有错误，敬请指正）可以啊，我记得这样好像是叫做 变长数组，C99标准定义的C语言新特性。  从这回答看lz有当政治家的潜质。但不适和程序员。程序员都是先编译看是否出错。然后查C99标准里在哪说可以这样写了。 lz这一句，楼下的把这些都给做了。[/quote] 我是用C-FREE的。。它没报错。。我还以为这样就是可以的说。。

引用 5 楼 h15757160454 的回复:引用 4 楼 u012421456 的回复:这个。。。lz代码问题太多啊！远的不说，先说你代码的第四五行，在C 语言中数组的长度能是这样吗？（个人见解，如有错误，敬请指正）可以啊，我记得这样好像是叫做 变长数组，C99标准定义的C语言新特性。 这个。。。lz用的什么编译器啊？ 这是VS2012的情况——  这是VC6.0的情况——

不开心

1111肯定不对。1e9不行是说明其他地方有问题。 算法也不用看了。你这个就算写对了也肯定是超时/爆内存的。

把缩放循环中的min变量初始化为1e9也不行.


Question: c初学者，请大家帮忙下，关于哥德巴赫猜想的问题。谢谢。

引用 4 楼 Falleyes 的回复:在这里要简单地组织逻辑就要使用goto  #include <stdio.h> #include<math.h>  int main(void) { 	int m, i,j;  	for (m = 6; m <= 100; m = m + 2) 	for (i = 2; i < m - 1;){ 		for (j = 2; j <= sqrt(i); j++){ 			if (i%j == 0){ 				goto next; 			} 		} 		for (j = 2; j <= sqrt(m - i); j++){ 			if ((m - i) % j == 0) 				goto next; 		} 		printf("%d=%d+%d\n", m, i, m - i); 		break; 	next:++i; 	} 	return 0; }谢谢你，终于不用纠结了。

引用 2 楼 Falleyes 的回复:为什么要改成纯嵌套循环呢？一般都是把多层嵌套改成函数调用来简化错误检查，你这是背道而驰，练习不是这样练的。只是想这样弄下，以及知道错在哪里。

哥们，你和我一样，我也是小白，也是来学习的。


Question: 语法错误

引用 4 楼 zhao4zhong1 的回复:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉  这个对我来说水平太高端大气上档次了。。

引用 3 楼 zhao4zhong1 的回复:偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。恩恩，是个不错的方法，以前有过这种记忆，不过印象不深，今后一定谨记此方法。

引用 2 楼 truelance 的回复:char *s2 = ""; //没有为s2分配空间, s2指向一个空字串, 可能在常量区.  s2 += "0000"; 字符串不支持加法, 字符串拼接要使用strcat. 而且因为s2没有分配空间, 这里会导致内存异常  其他的语法错误, 你要拿编译器检查. 靠人眼代替已有的工具, 只有书呆子才会干.这个错误我知道，可是我就是一时不知道如何改正这个问题。

引用 楼主 u012523688 的回复:#include<stdio.h> #include<string.h> //十六进制转为八进制  int main() { 	int n,i; 	int flag = 0; 	char s1[16]; 	scanf("%d",&n); 	for( i = 0; i <= n; i++ ) 	{ 		gets(s1); 		char *s2 = ""; 		for( i = 0; i < strlen(s1); i++ )//十六进制转为二进制  		{ 			switch(s1[i]) 				{ 					case '0':s2 += "0000";break; 					case '1':s2 += "0001";break; 					case '2':s2 += "0010";break; 					case '3':s2 += "0011";break; 					case '4':s2 += "0100";break; 					case '5':s2 += "0101";break; 					case '6':s2 += "0110";break; 					case '7':s2 += "0111";break; 					case '8':s2 += "1000";break; 					case '9':s2 += "1001";break; 					case 'A':s2 += "1010";break; 					case 'B':s2 += "1011";break; 					case 'C':s2 += "1100";break; 					case 'D':s2 += "1101";break; 					case 'E':s2 += "1110";break; 					case 'F':s2 += "1111";break; 					default : break;  				} 		} 	} 	len = strlen(s2)%3; 	if( len == 1 ) 	{ 		s2 += "00"; 	}     if( len == 2) 	{ 		s2 += "0";	 	} 	for( i = 0; i <= strlen(s2) - 3; i += 3 )//二进制转为八进制  	{ 		sum = 4 * ( s[i] - '0' ) + 2 * ( s[i+1] - '0' ) + 1 * ( s[i+2] - '0' ); 		if( sum ) 		{ 			flag = 1;	 		}  		if( flag ) 		{ 			printf("%o",sum);	 		} 	}     return 0;  }不知道语法上哪里错了，求指教一下！

1、s2=s2+"0000"; 这种肯定是不行的； 2、发现你里面好多变量都没定义就直接用了，如 len 3、还有s2是你放在了for里面成了局部变量，外面是不能用的。  建议找一本语法书好好先看看

s2 += "0000";break;  s2=s2+"0000"; 能把一个指针和一个字符串相加，肯定编译不过的～


Question: C语言问题新手求助

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

建议lz去看看C语言基础方面的视频，推荐一个： www.tudou.com/home/93506222/

play.c:34:9: warning: too many arguments for format [-Wformat-extra-args]          printf("age=",pArr);          ^ play.c:37:9: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat=]          scanf("%s",&pArr[k].name);          ^ 你的scanf没有设置读取长度  还有你有个printf后面的量也不对

#include <stdio.h> #include <malloc.h> struct stu {     int age;     char name[20];     float score; };   int main() {     int k,len;     struct stu * pArr;     struct stu student;       //动态的构造一维数组     printf("请输入学生的个数:\nlen=");     scanf("%d",&len);     pArr = (struct stu *)malloc(len*sizeof(struct stu));           for(k=0; k<len; k++)     {         printf("请输入学生的基本信息：\n");         printf("age=");         scanf("%d",&pArr[k].age);         printf("name=");         scanf("%s",pArr[k].name);         printf("score=");         scanf("%f",&pArr[k].score);     }     for(k=0; k<len; k++)     {         printf("\n\n第%d学生的基本信息：",k+1);         printf("age=");         printf("%d\n",pArr[k].age);         printf("name=");         printf("%s\n",pArr[k].name);         printf("score=");         printf("%f\n",pArr[k].score);     }         free(pArr);           return 0;   }

引用 2 楼 iamkconghua 的回复:#include <stdio.h> #include <malloc.h>  struct stu { 	int age; 	char name[20]; 	float score; };  int main() { 	int k,len; 	struct stu * pArr;  	//动态的构造一维数组 	printf("请输入学生的个数:\nlen = "); 	scanf("%d", &len); 	pArr = (struct stu *)malloc(len * sizeof(struct stu)); 	 	for (k = 0; k < len; k++) 	{ 		printf("请输入第%d个学生的基本信息：\n", k + 1); 		printf("age = "); 		scanf("%d", &pArr[k].age);  		printf("name = "); 		scanf("%s", pArr[k].name);  		printf("score = "); 		scanf("%f", &pArr[k].score); 		float fx = pArr[k].score;//使用一下pArr[k].score 	}  	for (k = 0; k < len; k++) 	{ 		printf("\n第%d学生的基本信息：\n", k + 1); 		printf("age = %d ", pArr[k].age); 		printf("name = %s ", pArr[k].name); 		printf("score = %f\n", pArr[k].score); //		float fx = pArr[k].score; 	}  	free(pArr); 	return 0; }  我刚刚把你加的那个代码注释后程序又可以正常运行了，睡了一觉又好了？这编译器太郁闷了

引用 2 楼 iamkconghua 的回复:#include <stdio.h> #include <malloc.h>  struct stu { 	int age; 	char name[20]; 	float score; };  int main() { 	int k,len; 	struct stu * pArr;  	//动态的构造一维数组 	printf("请输入学生的个数:\nlen = "); 	scanf("%d", &len); 	pArr = (struct stu *)malloc(len * sizeof(struct stu)); 	 	for (k = 0; k < len; k++) 	{ 		printf("请输入第%d个学生的基本信息：\n", k + 1); 		printf("age = "); 		scanf("%d", &pArr[k].age);  		printf("name = "); 		scanf("%s", pArr[k].name);  		printf("score = "); 		scanf("%f", &pArr[k].score); 		float fx = pArr[k].score;//使用一下pArr[k].score 	}  	for (k = 0; k < len; k++) 	{ 		printf("\n第%d学生的基本信息：\n", k + 1); 		printf("age = %d ", pArr[k].age); 		printf("name = %s ", pArr[k].name); 		printf("score = %f\n", pArr[k].score); //		float fx = pArr[k].score; 	}  	free(pArr); 	return 0; }  确实没问题了，可是我想知道这是为什么呢？

在scanf("%f",&pArr[k].score);后加入如下代码试试： scanf("%f",&pArr[k].score); float fTemp = pArr[k].score; //使用一下pArr[k].score


Question: 新人小问：关于the c programming language和 c primer plus

The C++ Programming Language太厚， 如果是纯粹学习c语言，还是看看 The C Programming Language.

the c++ programmming language 不建议初学者看，建议先看c++ primer


Question: 指针指向的地址与内存中实际的地址不符，很诡异

谢谢楼上的几位，虽然第二个问题还是没完全明白，不过还是学到了不少东西！

引用 10 楼 u011303711 的回复:你把你的结构体大小打印出来，就明白了，他分配的时候就已经对齐了，也就是说，内分配的时候比你预想多分配了，  谢谢回复，能否详细说明下你的理解，我打印过sizeof(TNE_NODE)，从我的打印来看，我个人的感觉是结构体的大小是对的，只是地址不对，Data的地址Data 03D70010,比预想的03D70014少4，不知道为什么

谢谢楼上的几位，学到了不少新的东西

引用 6 楼 yanran_hill 的回复: #pragma pack(push) #pragma pack(1) typedef struct... #pragma pack(pop)   谢谢回复，这段代码的意思是否是这个结构体按byte对齐？我看了下我默认的编译器设置，Data alignment是Quad Word

引用 2 楼 richyhuang 的回复:在vs里面有没有问题啊？ 如果有你发个程序片段出来，不然你这样人家会以为你信口开河哦  谢谢回复，我之前回复不对，又没法编辑，请看这个～  代码的话，主要就是下面几句，sprintf是为了调试加： PNode = (TNODE *)malloc(sizeof(TNODE)); char buf[100]; sprintf(buf, "%p,%d",PNode,offsetof(TNODE,Data));  //打印出来为"03D70004,16" sprintf(buf, "%p",&(PNode->Data));              //打印出来为"03D70014" sprintf(buf, "%p",&(PNode->Data.ID));           //打印出来为"03D70014" PNode->Data.ID = 1; Data是Com_Attributes类型，Com_Attributes定义如下： typedef struct {     int ID;     in_addr IP; }Com_Attributes; ID是Com_Attributes的第一个成员，int类型，PNode->Data与PNode->Data.ID的地址是相等的，都是03D70014 但在内存里Data和Data.ID的地址是03D70010，相对于03D70004，偏移量为12 所以造成了赋值不成功。所以我才会有那两个疑问： 1.这个偏移量16怎么理解，为何会是16？ 2.既然通过offsetof得知偏移量为16，为何malloc的时候，偏移变成了12

引用 2 楼 richyhuang 的回复:在vs里面有没有问题啊？ 如果有你发个程序片段出来，不然你这样人家会以为你信口开河哦  代码的话，主要就是下面几句，sprintf是为了调试加： PNode = (TNODE *)malloc(sizeof(TNODE)); char buf[100]; sprintf(buf, "%p,%d",PNode,offsetof(TNODE,Data));  //打印出来为"03D70004,16" sprintf(buf, "%p",&(PNode->NE_Data));              //打印出来为"03D70014" sprintf(buf, "%p",&(PNode->NE_Data.ID));           //打印出来为"03D70014" PNode->Data.ID = 1; Data是Com_Attributes类型的结构体，定义如下： typedef struct {     int ID;     in_addr IP; }Com_Attributes; ID是Com_Attributes的第一个成员，int类型，PNode->NE_Data与PNode->NE_Data.ID的地址是相等的，都是03D70014 但在内存里Data和Data.ID的地址是03D70010，相对于03D70004，偏移量为12 所以造成了赋值不成功。所以我才会有那两个疑问。

引用 1 楼 czarten 的回复:没太看明白你的叙述，不过应该是内存对齐的问题，搜索一下“内存对齐” 谢谢，我搜搜看

没太看明白你的叙述，不过应该是内存对齐的问题，搜索一下“内存对齐”

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

谢谢楼上几位，试了下，应该就是内存对齐的问题，对齐方式按byte，word，double word对齐都没问题，而默认的设置Quad Word就有问题。所以第一个问题就清楚了。之所以偏移量为16，是因为按Quad Word（8字节）对齐 typedef struct {     TTreeNode *Nd;   //占4个字节     TIdTCPServer *Srv; //占4个字节，和Nd共用8字节     int Disconnects;   //int是4个字节，对齐到8字节     Com_Attributes Data; //所以Data的偏移量就成了16 }TNODE, *P_NODE;  不过第二个问题还不是太明白，既然默认是按Quad Word（8字节）对齐的，那malloc分配内存的时候，应该也考虑到对齐的问题，但似乎地址没有进行对齐 PNode 03D70004 Nd 03D70004   Srv 03D70008  Disconnects 03D7000C  Data 03D70010   //按对齐到8个字节计算，地址应该为03D70004 + 4 + 4 + 8 = 03D70014，但从这个地址看，Disconnects并没有对齐到8字节，而且还是4个字节，03D70004 + 4 + 4 + 4 = 03D70010，好奇怪 而指针的地址PNode->Data 03D70014，则则已经指向了按8字节对齐之后的地址。。。


Question: 新手，求大神帮忙，急急急急急~~！

嗯，这应该是自带的，你按一楼的话试试吧，二楼的怕是不行，有可能会出现更多错误

找到这两个函数的位置，全部注释或者删除掉就可以了。

这两个函数应该是别人自己写的，你需要包含他的C/C++源文件或者是库文件。  引用 楼主 z356675143 的回复:c:(.text+0x87a): undefined reference to `DebugHex' c:(.text+0x8b4): undefined reference to `Debug'  linux环境下编译报错， 是这个函数没有包含头文件吗？   DebugHex和Debug我在C语言里从来没见到过，麻烦大神告诉我这个是要包含哪个头文件？ 或者是被的错误，急急急~~！


Question: 问了一群人都没搞定的蛋疼socket

主线程 listen（s，5） 创建线程传入s，将线程置为挂起 将线程恢复   第一个记录得到000，去GetLastError  看下是什么错误

accept以后用newfd工作, 那个self里的值不代表新接入的连接.

放到线程里 accept 就有这个问题，但是放到主进程里 界面会卡死。。。 求大神解决下

问题解决 我再主进程先accept了一次  后来开线程出的问题  不能这么干 谢谢大家！

user-3 我只单独开辟了一个线程循环accept 新来的链接 怎么会产生惊群现象呢？ 而且我查看了accept返回值 0000:0的也是正常的。。。唯独这个含对方ip信息的结构体是空的。。

多线程accept一个fd会惊群，而你没有检查accept的返回值。


Question: 代码看不懂啊, 求助!

应该是初始化这个结构体数组所有值都为0

猜一猜也能猜出来是什么意思吧

引用 1 楼 zmlovelx 的回复:初始化整个数组中的结构体成员为0 第一次见到，学习了

看不懂没办法。

引用 16 楼 JiMoKuangXiangQu 的回复:gcc编译器提供的支持。如果使用内嵌在Dev C++，或mSys，minGW之类的环境也包含由gcc的支持。 只是编译器一种实现，未必只有gcc支持，不过我所知道的编译器里面，暂时还只有gcc支持，可能一些我不知道的编译器也提供这样的语法支持，得参看编译器的文档，呵呵。高手啊

共同关注~~~

嵌入式语言的某种扩展吧

引用 13 楼 JiMoKuangXiangQu 的回复:gnu c对c90的扩充语法。在这里的作用就把0~NUM_MEM_AREAS-1范围内的数组元素初始化为{.start...}的值，即全为0。  看参考gcc编译器手册获取更多细节，或者网络搜索“Designated Initializers”关键字获取帮助信息。 高手这个是不是只用于linux上啊?windows可以吗?

楼主，这种写法能通过编译么？

不能直接翻译的描述性语言吧 意思是在声明定义变量的时候，同时对它进行初始化整个数组中的结构体成员为0

在声明定义变量的时候，同时对它进行初始化

我也第一次见这样的写法

初始化整个数组中的结构体成员为0

楼主，哪抄来的代码啊。。。  memory_map.used = 0;  这句明显也有错啊

引用 楼主 winnerid 的回复:memory_area_t memory_map[NUM_MEM_AREAS] = {     [0 ... (NUM_MEM_AREAS - 1)] = {              .start = 0,                            .size = 0,                            .used = 0       },}; 还真没见过这种情况 不过，我引用lz的话的最后面的两个大括号中间是个逗号，这个。。。这样怕是不行吧（个人见解）

[0 ... (NUM_MEM_AREAS - 1)]  这么写还真没见过，不一定能编译

引用 5 楼 PDD123 的回复:楼主，这种写法能通过编译么？ 书上写的应该是可以的,这个是嵌入式里面的代码,难道这个是C语言新支持的写法? 我也头一次见,意思能懂,但真不知道还有这种怪语法


Question: 有时间的请帮我看下这个程序  谢谢    错误我不会找了

楼主，建议你发完贴子后看一下排版。。。有点乱。。。一般看到这么乱，没人看的。这道题是去年的蓝桥杯预赛的题，我做到过，建议你可以搜搜看

这错误。。。 lz还是看看这个吧——http://www.cnblogs.com/shendiao/archive/2013/05/05/3061340.html


Question: pthread 消费者 生产者问题

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

#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h>  #define QUEUESIZE 10 #define LOOP 20  void *producer (void *args); void *consumer (void *args);  typedef struct { 	int buf[QUEUESIZE]; 	long head, tail; 	int full, empty; 	pthread_mutex_t *mut; 	pthread_cond_t *notFull, *notEmpty; } queue;  queue *queueInit (void); void queueDelete (queue *q); void queueAdd (queue *q, int in); void queueDel (queue *q, int *out);  int main () { 	queue *fifo; 	pthread_t pro, con;  	fifo = queueInit (); 	if (fifo ==  NULL) { 		fprintf (stderr, "main: Queue Init failed.\n"); 		exit (1); 	} 	pthread_create (&pro, NULL, producer, fifo); 	pthread_create (&con, NULL, consumer, fifo); 	pthread_join (pro, NULL); 	pthread_join (con, NULL); 	queueDelete (fifo);  	return 0; }  void *producer (void *q) { 	queue *fifo; 	int i;  	fifo = (queue *)q;  	for (i = 0; i < LOOP; i++) { 		pthread_mutex_lock (fifo->mut); 		while (fifo->full) { 			printf ("producer: queue FULL.\n"); 			pthread_cond_wait (fifo->notFull, fifo->mut); 		} 		queueAdd (fifo, i); 		pthread_mutex_unlock (fifo->mut); 		pthread_cond_signal (fifo->notEmpty); 		usleep (100000); 	} 	for (i = 0; i < LOOP; i++) { 		pthread_mutex_lock (fifo->mut); 		while (fifo->full) { 			printf ("producer: queue FULL.\n"); 			pthread_cond_wait (fifo->notFull, fifo->mut); 		} 		queueAdd (fifo, i); 		pthread_mutex_unlock (fifo->mut); 		pthread_cond_signal (fifo->notEmpty); 		usleep (200000); 	} 	return (NULL); }  void *consumer (void *q) { 	queue *fifo; 	int i, d;  	fifo = (queue *)q;  	for (i = 0; i < LOOP; i++) { 		pthread_mutex_lock (fifo->mut); 		while (fifo->empty) { 			printf ("consumer: queue EMPTY.\n"); 			pthread_cond_wait (fifo->notEmpty, fifo->mut); 		} 		queueDel (fifo, &d); 		pthread_mutex_unlock (fifo->mut); 		pthread_cond_signal (fifo->notFull); 		printf ("consumer: recieved %d.\n", d); 		usleep(200000); 	} 	for (i = 0; i < LOOP; i++) { 		pthread_mutex_lock (fifo->mut); 		while (fifo->empty) { 			printf ("consumer: queue EMPTY.\n"); 			pthread_cond_wait (fifo->notEmpty, fifo->mut); 		} 		queueDel (fifo, &d); 		pthread_mutex_unlock (fifo->mut); 		pthread_cond_signal (fifo->notFull); 		printf ("consumer: recieved %d.\n", d); 		usleep (50000); 	} 	return (NULL); }  #ifdef 0 typedef struct { 	int buf[QUEUESIZE]; 	long head, tail; 	int full, empty; 	pthread_mutex_t *mut; 	pthread_cond_t *notFull, *notEmpty; } queue; #endif  queue *queueInit (void) { 	queue *q;  	q = (queue *)malloc (sizeof (queue)); 	if (q == NULL) return (NULL);  	q->empty = 1; 	q->full = 0; 	q->head = 0; 	q->tail = 0; 	q->mut = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); 	pthread_mutex_init (q->mut, NULL); 	q->notFull = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); 	pthread_cond_init (q->notFull, NULL); 	q->notEmpty = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); 	pthread_cond_init (q->notEmpty, NULL); 	 	return (q); }  void queueDelete (queue *q) { 	pthread_mutex_destroy (q->mut); 	free (q->mut);	 	pthread_cond_destroy (q->notFull); 	free (q->notFull); 	pthread_cond_destroy (q->notEmpty); 	free (q->notEmpty); 	free (q); }  void queueAdd (queue *q, int in) { 	q->buf[q->tail] = in; 	q->tail++; 	if (q->tail == QUEUESIZE) 		q->tail = 0; 	if (q->tail == q->head) 		q->full = 1; 	q->empty = 0;  	return; }  void queueDel (queue *q, int *out) { 	*out = q->buf[q->head];  	q->head++; 	if (q->head == QUEUESIZE) 		q->head = 0; 	if (q->head == q->tail) 		q->empty = 1; 	q->full = 0;  	return; }


Question: 以下产生的效果，是什么原因造成的

i是unsigned char 类型，最大为255,二进制表示是1111 1111,255+1=256，二进制表示是1 0000 0000，i占8位，有成了 0000 0000，继续循环，这样就无限循环了 把i改成int就好了


Question: 请看下面的代码，运行Test之后是否存在问题？为什么？

第二个是局部变量吧

GetMemory的参数的是二级指针。即GetMemory(char** p).在main函数调用时用GetMemory(&str).当然GetMemory函数内部还要改动一下。 GetMemory2函数里面的p2指向的内存是不可修改的。所以也不正确。要使用static char p2[20]这样的定义。

引用 3 楼 u013085807 的回复:引用 2 楼 user-4 的回复:GetMemory2类型也不对。那里不对，我看没错啊 char* GetMemory2(void) {    const char p[] = "hello world";    return *p } 噗... *p返回的是p[0]也就是h，不是整个字符串 而且p是局部变量，返回时被销毁了，另一边使用了一个无效的地址（假设你正确的返回p，不是*p），是很危险的

引用 5 楼 Adol1111 的回复:引用 3 楼 u013085807 的回复:[quote=引用 2 楼 user-4 的回复:] GetMemory2类型也不对。那里不对，我看没错啊 char* GetMemory2(void) {    const char p[] = "hello world";    return *p } 噗... *p返回的是p[0]也就是h，不是整个字符串 而且p是局部变量，返回时被销毁了，另一边使用了一个无效的地址（假设你正确的返回p，不是*p），是很危险的[/quote]是的，以前我做过这样的，那个时候我写对了，今年忘了很多东西

Void GetMemory(char* p) {     p=(char*)malloc(100);//编译器分配内存后，函数执行后，就销毁了 }  错了，应该使用 Void GetMemory(char** p) {     *p=(char*)malloc(100);//编译器分配内存后，函数执行后，就销毁了 } 或者 char* GetMemory() {     return malloc(100);//编译器分配内存后，函数执行后，就销毁了 }


Question: 小白，请问队列顺序存储结构这两种表述方法的区别

3楼正解！！！！！！！！！

第一种：因为数据项给的是指针（int *Base）所以可以动态分配 SqQuence q; q.base = (int *)malloc(?); 第二种：数据项是一个固定的数组，所以只要确定了int data[maxsize]中maxsize大小就固定了 两种情况没有优劣之分，只是应用的情况不同罢了，第一种一般是不清楚实际队列大小，可以动态的规划，所以不存在满队的情况

各位大神，求指导

在数据结构区没人回答，特来这里问问~~


Question: C语言先序建立二叉树 问题

1 楼主的意思应该是结构体节点的指针吧，应该不是二级指针吧 2 同楼上，实际为递归调用，把自己有调用了一次，效果就是创建了右子树

1.对，指针的指针 2.CreateBinTree(&(*T->rchild)); T的类型是BiTree指针，*T是BiTree，*T->rchild就是这个BiTree的右孩子，其类型也是BiTree，最后加上&，就是指向BiTree的指针了，这样才符合CreateBinTree函数的参数类型


Question: 用变量a 给出下面的定义

struct S_DEM* a[10];


Question: C语言，栈的初始化失败

接2楼的,也可以采用下面的写法： SeqStack *s; s = (SeqStack *)malloc(sizeof(SeqStack));

SeqStack *s; 你在这里只是定义了一个指针，并没有真正的分配内存，所以当你把这个变量传给初始化函数的 时候在进行 s->base=(ElemType *)malloc(stack_size*sizeof(ElemType)); 这一步是 s->base是不能找到任何地址的，所有这次赋值操作就会失败  改成这样就好了 SeqStack s; Initial(&s);/*此处调用初始化函数失败*/

Initial(s);/*此处调用初始化函数失败*/ 这个s传进去是空指针，然后 s->base 这样肯定会出错吧


Question: 用宏定义写出swap xy,

引用 6 楼 u013085807 的回复:[quote=引用 1 楼 JiMoKuangXiangQu 的回复:] #define swap(x, y) \ 	x = x + y; \ 	y = x - y; \ 	x = x - y; 是的，刚才那个是从网上复制的，别人写的，这个是反斜杠持续符，但是vim 编译说有游离的'\'的错误[/quote]  编译一下看看，不应该有什么错误，要注意直接复制。在'\'不能有任何字符（包含空格，TAB）。

引用 1 楼 JiMoKuangXiangQu 的回复:#define swap(x, y) \ 	x = x + y; \ 	y = x - y; \ 	x = x - y; 是的，刚才那个是从网上复制的，别人写的，这个是反斜杠持续符，但是vim 编译说有游离的'\'的错误

引用 3 楼 greatchina01 的回复:#define swap(x,y){y^=x^=y^=x;}

+-法的宏有可能会溢出的。

#define swap(x,y){y^=x^=y^=x;}

引用 1 楼 JiMoKuangXiangQu 的回复:#define swap(x, y) \ 	x = x + y; \ 	y = x - y; \ 	x = x - y; 正解。


Question: C语言疑问 当函数参数是2个数组时

引用 9 楼 Adol1111 的回复:引用 8 楼 Automation_dmu 的回复:[quote=引用 6 楼 wq_vincent 的回复:] 上面那个程序自定义函数出现主调函数之前，所以在主调函数里面不需要对其作声明。我想请问的是，如果要对其作声明，该怎么做？？？麻烦自己调试下再说话，我在CB下总是出现错误。。。。。郁闷死了在函数体内是不允许声明函数，需放在全局域进行声明。 谁跟你说C中不能在函数体内声明函数的？？ 函数不能嵌套定义，但允许函数中包含其他函数的声明[/quote]我表述有误吧！

你可以将函数定义放在主函数之前，这样就不用声明了，不然可以这样声明 vod fun(int arr1[] int arr2[])；

#include<stdio.h> #include<string.h>   int main() {     void constr(char *a,char *b);     char str1[50],str2[50];     gets(str1);     gets(str2);     constr(str1,str2);     puts(str1); }  void constr(char *a,char *b) {     strcat(a,b); }

引用 8 楼 Automation_dmu 的回复:引用 6 楼 wq_vincent 的回复:上面那个程序自定义函数出现主调函数之前，所以在主调函数里面不需要对其作声明。我想请问的是，如果要对其作声明，该怎么做？？？麻烦自己调试下再说话，我在CB下总是出现错误。。。。。郁闷死了在函数体内是不允许声明函数，需放在全局域进行声明。 谁跟你说C中不能在函数体内声明函数的？？ 函数不能嵌套定义，但允许函数中包含其他函数的声明

引用 5 楼 wq_vincent 的回复:我有个程序 是关于字符串连接的。  constr(a,b) char a[50],b[50]; {     strcat(a,b); }   int main() {     char str1[50],str2[50];     gets(str1);     gets(str2);     constr(str1,str2);     puts(str1); } K&R的声明风格，兼容性不好，还是乖乖的用ANSI的风格吧

void fun1(int arr1[],int arr2[]);//函数形参为数组 参见《C primer plus》266页 把数组当做函数的参数的时候要注意保护数据，如果你不想数字里面的人数据被修改，你还可以这样申明void fun1(const int arr1[],const int arr2[]);//函数形参为数组

这个简单 你实在不行可以声明成void* 你想怎么着都行  void func(void *array1, int size1, void *array2, int size2); 你到函数里可以进行强制类型转换。具体转成什么你就自己看着办吧。  搞定，给分！

数组形参可以声明为指针类型

void Function(int *a,size_t aSize,int *b size_t bSize);


Question: 递归问题

引用 6 楼 u013163178 的回复:[quote=引用 3 楼 mujiok2003 的回复:] [quote=引用 2 楼 mujiok2003 的回复:] #include<stdio.h> int main() { int n; int i; int Fib(int); printf("请你输入n值:"); scanf("%d",&n);  for(i=0;i<=n;i++) {    printf("%d ",Fib(i)); } return 0; }   int Fib(int n) { if(0==n|1==n)   return 1; else return Fib(n-1)+Fib(n-2);  }  //if(0==n|1==n) if(0==n||1==n) [/quote]#include<stdio.h> int main() { int n; int i; int Fib(int); printf("请你输入n值:"); scanf("%d",&n); for(i=0;i<=n;i++) { printf("%d",Fib(i)); } return 0; }   int Fib(int n) { if(1==n|2==n)   Fib(n)=1; else Fib(n)= Fib(n-1)+Fib(n-2); return Fib(n); } 这有为什么不对呢[/quote]  能编译吗？

引用 8 楼 czarten 的回复:[quote=引用 7 楼 u013163178 的回复:] [quote=引用 1 楼 czarten 的回复:] 你看看你return x之前，有任何一句语句和x有关吗  去掉x变量，倒数第二句改成return Fib(n-1)+Fib(n-2) ; 就好了  顺便，除非题目要求，或者练习递归思想，否则斐波那契慎用递归啊为什么不能写Fib(n)=Fib(n-1)+Fib(n-n); return Fib(n);[/quote]  Fib(n)=Fib(n-1)+Fib(n-n)这是数学上的写法 你在程序里这么写，Fib(n)是什么意思，Fib(n)就是把n代入函数Fib()所得到的值，它是个值，而不是变量，只有变量才能赋值 “=”不是等号，而是赋值 这个你要仔细体会 就像3=1+2，是数学上的写法，而在程序中毫无意义  你倒是可以写int x=Fib(n-1)+Fib(n-n);return x;[/quote]有道理啊

你会写Fib(n)=Fib(n-1)+Fib(n-n)说明你还没有弄明白最基础的变量和赋值的概念，建议先弄明白这个，加上递归只会更乱

引用 7 楼 u013163178 的回复:[quote=引用 1 楼 czarten 的回复:] 你看看你return x之前，有任何一句语句和x有关吗  去掉x变量，倒数第二句改成return Fib(n-1)+Fib(n-2) ; 就好了  顺便，除非题目要求，或者练习递归思想，否则斐波那契慎用递归啊为什么不能写Fib(n)=Fib(n-1)+Fib(n-n); return Fib(n);[/quote]  Fib(n)=Fib(n-1)+Fib(n-n)这是数学上的写法 你在程序里这么写，Fib(n)是什么意思，Fib(n)就是把n代入函数Fib()所得到的值，它是个值，而不是变量，只有变量才能赋值 “=”不是等号，而是赋值 这个你要仔细体会 就像3=1+2，是数学上的写法，而在程序中毫无意义  你倒是可以写int x=Fib(n-1)+Fib(n-n);return x;

引用 1 楼 czarten 的回复:你看看你return x之前，有任何一句语句和x有关吗  去掉x变量，倒数第二句改成return Fib(n-1)+Fib(n-2) ; 就好了  顺便，除非题目要求，或者练习递归思想，否则斐波那契慎用递归啊为什么不能写Fib(n)=Fib(n-1)+Fib(n-n); return Fib(n);

引用 3 楼 mujiok2003 的回复:[quote=引用 2 楼 mujiok2003 的回复:] #include<stdio.h> int main() { int n; int i; int Fib(int); printf("请你输入n值:"); scanf("%d",&n);  for(i=0;i<=n;i++) {    printf("%d ",Fib(i)); } return 0; }   int Fib(int n) { if(0==n|1==n)   return 1; else return Fib(n-1)+Fib(n-2);  }  //if(0==n|1==n) if(0==n||1==n) [/quote]#include<stdio.h> int main() { int n; int i; int Fib(int); printf("请你输入n值:"); scanf("%d",&n); for(i=0;i<=n;i++) { printf("%d",Fib(i)); } return 0; }   int Fib(int n) { if(1==n|2==n)   Fib(n)=1; else Fib(n)= Fib(n-1)+Fib(n-2); return Fib(n); } 这有为什么不对呢

引用 1 楼 czarten 的回复:你看看你return x之前，有任何一句语句和x有关吗  去掉x变量，倒数第二句改成return Fib(n-1)+Fib(n-2) ; 就好了  顺便，除非题目要求，或者练习递归思想，否则斐波那契慎用递归啊#include<stdio.h> int main() { int n; int i; int Fib(int); printf("请你输入n值:"); scanf("%d",&n); for(i=0;i<=n;i++) { printf("%d",Fib(i)); } return 0; }   int Fib(int n) { if(1==n||2==n)   Fib(n)=1; else Fib(n)= Fib(n-1)+Fib(n-2); return Fib(n); } 我其实是这么写的，后来才改成那样，这样有为什么不对呢

引用 2 楼 mujiok2003 的回复:#include<stdio.h> int main() { int n; int i; int Fib(int); printf("请你输入n值:"); scanf("%d",&n);  for(i=0;i<=n;i++) {    printf("%d ",Fib(i)); } return 0; }   int Fib(int n) { if(0==n|1==n)   return 1; else return Fib(n-1)+Fib(n-2);  }  //if(0==n|1==n) if(0==n||1==n)


Question: 图示 指针与内存

哈哈，赵大侠都出来了。 一幅图就想让新手搞懂所有的内存知识，我估计够呛。期盼高手出幅这样的内存图，就一幅，别整成蚊子大小的字啊。 从本质上讲，所有内存都是可读可写的。否则，某个内存中的值当初是如何写入的呢？只是有不同的权限限制而已。

呵呵，当然是Debug环境啊，上图标的不是清清楚楚嘛, Win32 Debug，你要是换个环境，如BC, TC啥的，内存的值可能就变了，跟编译器密切相关。

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

引用 7 楼 iamkconghua 的回复:另外，针对XP + VC6.0， “p1没有初始化,其值是不定的,是随机的” 这句话是不对的。 对上述环境而言，p1不是随机的，就是0xCCCCCCCC。 之所以将其初始化为许多CC，是因为0xCC是对应的汇编代码是3号中断即int 3，逆向工程中常用int 3来进行跟踪二进制代码。 不对。你还得指出是Debug。否则别指望烫烫烫烫。

这些知识都知道。我是问针对上图的具体环境，XP + VC6.0，上图的具体错误在哪？谢谢。

简单的说就是: 一个进程中有从地址 0x0000 ~~  0xfff..fff (2^32 即4GB)大小的内存空间 粗略的可以认为这些内存一部分是空的,假的,没有对应实际的物理内存.另一部分是已经分配了的,比如装在了我们程序的内存. 在分配了的内存中,又有几种,有些内存只能读,有些内存只能写,有些内存可读写,还有一些内存可以执行代码,这些是对内存权限的设置,并且是可以修改的.   p1没有初始化,其值是不定的,是随机的,是历史上遗留下来的过期数据,可以指向任何一个地址,比如未分配的内存,或者只写的内存等.  我们的程序在编译生成时,会把字符串常量默认存储在只读的内存区域中,所以p2指向的是只读的,写会发生错误,但是可以修改这个内存变成可读写  p3是 栈内存,默认是可读写

上述代码本身是有错误的，图中已经说过了。请指出其他错误。谢谢。

引用 2 楼 u013573183 的回复:虽然1个小时弄完了,但是不得不告诉你,是错的... 请指教！

虽然1个小时弄完了,但是不得不告诉你,是错的...

good，很直观~~~~~


Question: 请教大神们的一个二级程序问题

各位大神，，这个我已经用tc编译过了，，，结果正确，是6，，，我也好疑惑那个，p【i】=i+1，，

引用 6 楼 u013410838 的回复:1. 你那个for循环应该是for(i=0;i<9;i++) 吧 2. P为int*类型的，因此p指向二维数组的首地址时候，小标每加一，指针向后移动一个int大小的内存，举个例子：p[0]就是array[0][0],  p[1]就是array[0][1], p[2]就是array[0][2], p[3]就是array[1][0]  3. 数组结果如图     sorry！！！！ 行号和列号标反了

int array[3][3] 3*3数组 下标分别是[0-2][0-2]

引用 2 楼 zhccl 的回复: for(i=p;i<9;i++) 这句代码应该编译不过吧，把一个 指针赋值给 int ？？你确认你编译器能编过？ ++, p 是int * 类型数据，i 是int型数据，这里会报错

void main() {    int array[3][3],*p,i;    p=&array[0][0];    for(i=0;i<9;i++)//感觉这里应该是i=0吧，怎么能把p指针赋值给i    {      p[i]=i+1;    }    printf("%d\n",array[1][2]); } p指针指向array数组的首地址，然后for循环为数组的9个元素依次赋值，(1,2,3),(4,5,6),(7,8,9) 之后输出array[1][2]，所以是6

1 2 3 4 5 6 7 8 9


Question: 本人做了一个俄罗斯方块程序,但玩着玩着就变白了希望有大神帮调试或指点迷津

我的出成绩了 就会解决滴

引用 3 楼 u013670102 的回复:我也是 惶恐ING 引用 3 楼 u013670102 的回复:我也是 惶恐ING 你的跟我的也一样,有解决办法吗?

我也是 惶恐ING

引用 1 楼 derekrose 的回复: 新人出来咋到什么都不懂

引用 6 楼 zhao4zhong1 的回复:检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！谢谢了,我太粗心了,终于解决这个问题啦


Question: 新人求解：求大神们教教我怎样用c语言做界面？

引用 1 楼 user-2 的回复:推荐Qt，语句简单 Qt用C？连标准C++都算不上。 纯C就GTK+，如果不想艹xlib之类。虽然没多少意思。

那用qt时怎么在mainwindow里添加widget函数？？

推荐Qt，语句简单


Question: 指向字符串的指针为何不能用来修改此字符串

常量数据时无法修改的，只能先开辟内存并复制到开辟的内存内才行。

不喜欢抠字眼，不过遇到抠字眼的，还是要更精确点说“常量字符串存放在静态存储区”,并没说他就是静态对象，也没说完全不能修改，通过某些手段也是可以的。只是不想扯太远。 引用 11 楼 KenZhang1031 的回复:我说常量对象位于静态存储区，没说它是静态对象。 [quote=引用 5 楼 FrankHB1989 的回复:] [quote=引用 1 楼 twhold 的回复:] char pa[50]="ABCDE";  "ABCDE"存储在常量区,pa指向常量区所以不能修改. 要改你可以给Pa申请一个空间,然后在COPY. pa = (char*)malloc(50 * sizeof(char)); 引用 3 楼 u012586257 的回复:char *pb="EFG" 我觉得问题是在这句。改成 char *pb; 或者 char pb[4]="EFG"；应该就好了 C什么时候告诉你们就放在“常量区”了。 GCC的-fwritable-strings是干什么吃的？  引用 4 楼 KenZhang1031 的回复:"ABCDE"常量字符串在静态数据区，无法修改。只能复制到栈或堆中，再做修改。  扯蛋。静态对象没法修改？唬谁呢？  修改字符串字面量的C程序行为未定义。 因此实现可以假定用户不修改这些字面量，可以作为常量对待（虽然没这个保证）。 要改就自己复制出来。 [/quote][/quote]

我说常量对象位于静态存储区，没说它是静态对象。 引用 5 楼 FrankHB1989 的回复:[quote=引用 1 楼 twhold 的回复:] char pa[50]="ABCDE";  "ABCDE"存储在常量区,pa指向常量区所以不能修改. 要改你可以给Pa申请一个空间,然后在COPY. pa = (char*)malloc(50 * sizeof(char)); 引用 3 楼 u012586257 的回复:char *pb="EFG" 我觉得问题是在这句。改成 char *pb; 或者 char pb[4]="EFG"；应该就好了 C什么时候告诉你们就放在“常量区”了。 GCC的-fwritable-strings是干什么吃的？  引用 4 楼 KenZhang1031 的回复:"ABCDE"常量字符串在静态数据区，无法修改。只能复制到栈或堆中，再做修改。  扯蛋。静态对象没法修改？唬谁呢？  修改字符串字面量的C程序行为未定义。 因此实现可以假定用户不修改这些字面量，可以作为常量对待（虽然没这个保证）。 要改就自己复制出来。 [/quote]

认罪..误导LZ了,感谢教育`!`

char pa[50]="ABCDE"; char *pb="EFG"; pb[1]='A';  pb只是一个指针，指向一个字符串，在这里pb指向的是字符串常量 LZ最好了解下微机原理和编译原理

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

pb=pa; pb[1]='A'; 这样就可以了

引用 5 楼 FrankHB1989 的回复:[quote=引用 1 楼 twhold 的回复:] char pa[50]="ABCDE";  "ABCDE"存储在常量区,pa指向常量区所以不能修改. 要改你可以给Pa申请一个空间,然后在COPY. pa = (char*)malloc(50 * sizeof(char)); 引用 3 楼 u012586257 的回复:char *pb="EFG" 我觉得问题是在这句。改成 char *pb; 或者 char pb[4]="EFG"；应该就好了 C什么时候告诉你们就放在“常量区”了。 GCC的-fwritable-strings是干什么吃的？  引用 4 楼 KenZhang1031 的回复:"ABCDE"常量字符串在静态数据区，无法修改。只能复制到栈或堆中，再做修改。  扯蛋。静态对象没法修改？唬谁呢？  修改字符串字面量的C程序行为未定义。 因此实现可以假定用户不修改这些字面量，可以作为常量对待（虽然没这个保证）。 要改就自己复制出来。 [/quote]  引用错了。  引用 2 楼 ganpengjin1 的回复:char *pb="EFG";  因为指向了一个常量区，数据不能被修改 ↑3L不算，替换。

引用 1 楼 twhold 的回复:char pa[50]="ABCDE";  "ABCDE"存储在常量区,pa指向常量区所以不能修改. 要改你可以给Pa申请一个空间,然后在COPY. pa = (char*)malloc(50 * sizeof(char)); 引用 3 楼 u012586257 的回复:char *pb="EFG" 我觉得问题是在这句。改成 char *pb; 或者 char pb[4]="EFG"；应该就好了 C什么时候告诉你们就放在“常量区”了。 GCC的-fwritable-strings是干什么吃的？  引用 4 楼 KenZhang1031 的回复:"ABCDE"常量字符串在静态数据区，无法修改。只能复制到栈或堆中，再做修改。  扯蛋。静态对象没法修改？唬谁呢？  修改字符串字面量的C程序行为未定义。 因此实现可以假定用户不修改这些字面量，可以作为常量对待（虽然没这个保证）。 要改就自己复制出来。

"ABCDE"常量字符串在静态数据区，无法修改。只能复制到栈或堆中，再做修改。

char *pb="EFG";  因为指向了一个常量区，数据不能被修改


Question: 强制类型转换的疑问

多谢提点，确实是我没搞清楚，小整型向大整型拓展时候的位拓展和它原本的有无符号有关系，这一点我之前没有弄清楚，多谢！所以(unsigned int)(signed short)y 会变成0xffffffff

#include <stdio.h>  int main(){ 	unsigned int x = 0xdeadbeef; 	unsigned short y = 0xffff; 	signed int z = -1;  	printf("0x%hx\n", y); 	printf("0x%hx\n", (signed short)y); 	return 0; }   格式描述符与实参类型要一一对应。

printf自作主张给你看转成int的结果了 y是unsigned short 的正数 转int 前面补全零 实际是把0x0000ffff输出了 y为unsigned short 的正数 0xffff 转short int 就成为 负数 再转int 前面就补全1.... 补码表示+小整形向大整形扩展的特点 你还是下断点、单步调试，看内存吧

多谢指教啊，我把程序又改了下，变成了：  #include <stdio.h>  int main(){ 	unsigned int x = 0xdeadbeef; 	unsigned short y = 0xffff; 	signed int z = -1;  	printf("0x%x\n", y); 	printf("0x%x\n", (unsigned int)(signed short)y); 	return 0; }  得到的结果是一样的 但是我就不懂了 第二个printf输出的为什么不是0x0000ffff呢？

printf 把输入的参数中小域32bit的参数提升为 int进行处理， 无符号的0xffff执行0扩展即提升为 0x0000ffff ， 而有符号的0xffff执行符号位扩展则会提升为 0xffffffff


Question: linux c 5s动态抓/proc/kmsg问题~

来个高手帮帮忙吧。。。


Question: 自己最近《学数据结构与算法》的一些笔记<一>----------连载（不定期更新）

学习数据结构的目的是：怎么将数据存储在内存当中！ 目的是为算法服务，不是将数据存在内存中。

写博客是首选！这里问问题解答问题为主战场

长期占座，跟楼主一起学习数据结构~

《数据结构（C语言版）》 《算法精解（C语言实现）》

为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

我们也是刚开数据结构课 lz，建议你还是写博客吧！，那样效果应该会更好


Question: 求C语言高手指教

lz你37、38行输入的m n 就相当于第4行的 m 和 k， 第9行到18行是判断是否为素数；19行到28行表示你输入的素数后边（这里你输入的是17）还要几个（这里你输入的是5）素数，然后将这些素数放到数组里，这样lz应该能看懂了吧？（如果我哪里说的不对，就请点出来，感激不尽，不说了，睡觉啊）

if (flag==1&&j>=i) 为什么这部分要j>=i? 因为正常循环结束时 j>=i,否则是break中断出来的 当然这里flag==1 j>=i 两个条件重复了，只判断一个应该也够了

关于scanf的用法lz可以看看这个——http://blog.csdn.net/u012421456/article/details/18501309

#include <conio.h> #include <stdio.h>  void fun(int m, int k, int xx[]) { 	int g = 0, i, j, flag = 1; 	for(i=m+1; i<m*m; i++) 	{ 		for(j=2; j<i; j++) 		{ 			if (i%j != 0) 				flag = 1; 			else 			{  				flag = 0; 				break; 			}  		} 		if (flag==1 && j>=i) 		{ 			if (k >= 0) 			{ 				xx[g++] = i; 				k--; 			} 			else 				break; 		} 	} }  int main() {     int m, n, zz[1000];     FILE *out; 	printf("\nPlease enter two integers:"); 	scanf("%d %d",&m, &n);    //  scanf中不要加非输入控制符（这里指的是逗号），加了必须原样输出 	fun( m, n, zz); 	 	for(m=0; m<n; m++) 		printf("%d ", zz[m]); 	printf("\n"); 	fun(28, 20, zz); 	out = fopen("out.dat", "w"); 	 	for (m = 0; m < 20; m++) 		fprintf(out, "%d\n", zz[m]); 	fclose(out);	 	return 0; }