Mxode/CSDN-C_Language-2013_2023 huggingface dataset:
user-0 提问: 二维数组

回复:
user: user-1
content: 警告说的是cp的第二个参数期望的是conts double (*)[]类型，但是实际传入的参数是double (*)[5]类型的，这个可以不用理会。 第一个函数没有输出，还有就是k为int型，k*1/3的结果肯定是int型。最后赋值只是把int型转换为了double。 其他的暂时没有看出问题。

user: user-2
content: C99的东西，一些编译器处理起来并一定符合标准 还是用C89吧，在main()构建一个指针数组来向函数传递数组行的首址

user: user-3
content: 哦，再多句嘴，函数参数是二维数组的时候，必须要知道列的元素个数 也就是说 void cp(int h,int g,const double sar[*],double lar[*][*]); void pri(int a,int b,const double [*][*]);  改成 void cp(int h,int g,const double sar[*][5],double lar[*][5]); void pri(int a,int b,const double [*][5]);  你的这种用法我没用过，也不知道是啥意思，我在Windows上编译是过不去的 建议你还是用最容易看懂的方式写代码

user: user-3
content: 还有个就是。。你打印出来很难看 void pri(int a,int b,const double ar[a][b]) {         int k,i;         for(k=0;k<a;k++)         {                 for(i=0;i<b;i++)                         printf("%d*%d=%.2f",k,i,ar[k][i]);//这里打印的时候加个分隔符                 putchar('\n');         } }

user: user-3
content: void cp(int h,int g,const double sar[h][g],double lar[h][g]) {         int j,k;         for(j=0;j<h;j++)         {                 for(k=0;k<g;j++) //这里应该是k++，你把j++数组都越界了，肯定报段错误                         lar[j][k]=sar[j][k];         } }

user: user-0
content: 我那个警告是什么意思？

user: user-4
content: 仅供参考#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //
user-0 提问: readdir为什么是非线程安全的

回复:
user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:加锁。感谢赵老师的回复，不过在我看来，即使不加锁，也不影响其使用效果。如果两个线程操作同一个directroy stream，确实会影响扫描的目录集合；其他情况的话，就没有必要加锁了。不知我这样理解对吗？

user: user-0
content: 引用 3 楼 user-2 的回复:官网文档的解释用了可能（may）一词，说明 readdir 的具体实现不必是线程安全的。当然，具体的库开发者可以将其实现为线程安全的，也可以实现为非线程安全的。作为程序调用者，尤其是遇到跨平台的情况，应该不能依赖于具体的实现机制，而只能因为readdir 不是线程安全的。收益，感谢

user: user-1
content: 参考readdir的源代码。

user: user-2
content: 官网文档的解释用了可能（may）一词，说明 readdir 的具体实现不必是线程安全的。当然，具体的库开发者可以将其实现为线程安全的，也可以实现为非线程安全的。作为程序调用者，尤其是遇到跨平台的情况，应该不能依赖于具体的实现机制，而只能因为readdir 不是线程安全的。

user: user-1
content: 加锁。
user-0 提问: C语法

回复:
user: user-1
content: 我觉得二楼说的在理

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

user: user-3
content: input !=NULL表示分配了内存空间； input [0] !='\0'数组的内容不为空

user: user-4
content: 1.input != NULL 是确保已给input分配了空间 2.input[0] !='\0' 是判定input的内容不为空

user: user-5
content: nput ！=NULL 是指数组的指针不为空，input[0]!=‘\0’是指数组的第一个元素不为空.
user-0 提问: 新手求教

回复:
user: user-0
content: 引用 7 楼 u010236550 的回复:http://blog.csdn.net/u010236550/article/details/19005909感谢，，虽然没有找到我想要的书

user: user-1
content: http://blog.csdn.net/u010236550/article/details/19005909

user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:《数据结构（C语言描述）》 《算法精解（C语言描述）》 请问是谁写的书？

user: user-0
content: 感谢楼上的帮忙

user: user-2
content: 别的数据结构太枯燥了，可以看看《大话数据结构》再看其它的书进阶。

user: user-3
content: 《数据结构与算法分析（C语言描述）》

user: user-4
content: 《数据结构与算法分析（C语言描述）》

user: user-5
content: 《数据结构（C语言描述）》 《算法精解（C语言描述）》
user-0 提问: 关于CreateProcess（）函数的一点疑惑，请指教

回复:
user: user-1
content: CreateProcess("c:\\Program File\\Internet Explorer\\IEXPLORE.EXE",NULL,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi); 路径Program File中少了一个s，应该是Program Files  CreateProcess("c:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",NULL,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi);

user: user-2
content: 你都不看看CreateProcess是不是创建进程是否成功了？
user-0 提问: 用c语言编写一个年历系统

回复:
user: user-1

user: user-2
content: 引用 7 楼 qq_17153977 的回复:引用 4 楼 u010957746 的回复:引用 1 楼 user-7 的回复:看看Linux cal 源码+++++++++++++111111111111111啥意思？Linux 中的 cal功能很强大的

user: user-3
content: 引用 9 楼 qq_17153977 的回复:[quote=引用 8 楼 yangyangsnr 的回复:] [quote=引用 6 楼 qq_17153977 的回复:] [quote=引用 2 楼 yangyangsnr 的回复:] http://blog.csdn.net/yangyangsnr/article/details/29220581 N久之前写的，写的太复杂的，能用就凑合着用吧。 而且，写这么复杂都用不了250行，你们老师有必要搞个长度要求么？就是不知道老师怎么想的，哭了都，大神你能不能帮帮忙，[/quote] http://blog.csdn.net/yangyangsnr/article/details/29220581 打开链接，复制，粘贴，编译，完事。[/quote]好吧，谢谢大神，我试了一下，真的可以也。只是我要把它在加加改改成250行代码。[/quote]各种空格 换行  空白行

user: user-4
content: 一个简单算法： 取得那一年第一天零时的time_t值t0 （调用time.h中的mktime） 然后每次在t0上累加24小时 （24*60*60秒），然后调用localtime就可以获得星期/月份/日期数据 依次累加至年份变化为止  当然效率高些的算法也有，只调用一次mktime，获得那一天第一天星期几 然后接下来的365天或者364天的星期数据就是基于累加值对7取模的线性计算 至于日期数据，根据年份你能知道每个月有几天，所以每天几月几号都可以算下来 这种算法，用两重的for循环就可以实现了  代码不写了，建议根据第二种算法来，呵呵

user: user-0
content: 引用 8 楼 yangyangsnr 的回复:[quote=引用 6 楼 qq_17153977 的回复:] [quote=引用 2 楼 yangyangsnr 的回复:] http://blog.csdn.net/yangyangsnr/article/details/29220581 N久之前写的，写的太复杂的，能用就凑合着用吧。 而且，写这么复杂都用不了250行，你们老师有必要搞个长度要求么？就是不知道老师怎么想的，哭了都，大神你能不能帮帮忙，[/quote] http://blog.csdn.net/yangyangsnr/article/details/29220581 打开链接，复制，粘贴，编译，完事。[/quote]好吧，谢谢大神，我试了一下，真的可以也。只是我要把它在加加改改成250行代码。

user: user-5
content: 引用 6 楼 qq_17153977 的回复:[quote=引用 2 楼 yangyangsnr 的回复:] http://blog.csdn.net/yangyangsnr/article/details/29220581 N久之前写的，写的太复杂的，能用就凑合着用吧。 而且，写这么复杂都用不了250行，你们老师有必要搞个长度要求么？就是不知道老师怎么想的，哭了都，大神你能不能帮帮忙，[/quote] http://blog.csdn.net/yangyangsnr/article/details/29220581 打开链接，复制，粘贴，编译，完事。

user: user-0
content: 引用 4 楼 u010957746 的回复:引用 1 楼 user-7 的回复:看看Linux cal 源码+++++++++++++111111111111111啥意思？

user: user-0
content: 引用 2 楼 yangyangsnr 的回复:http://blog.csdn.net/yangyangsnr/article/details/29220581 N久之前写的，写的太复杂的，能用就凑合着用吧。 而且，写这么复杂都用不了250行，你们老师有必要搞个长度要求么？就是不知道老师怎么想的，哭了都，大神你能不能帮帮忙，

user: user-6
content: http://bbs.csdn.net/topics/380172915

user: user-2
content: 引用 1 楼 user-7 的回复:看看Linux cal 源码+++++++++++++111111111111111

user: user-7
content: http://www.oschina.net/code/explore/php-5.2.15/ext/calendar

user: user-5
content: http://blog.csdn.net/yangyangsnr/article/details/29220581 N久之前写的，写的太复杂的，能用就凑合着用吧。 而且，写这么复杂都用不了250行，你们老师有必要搞个长度要求么？

user: user-7
content: 看看Linux cal 源码
user-0 提问: TC伪随机数加密

回复:
user: user-1
content: 实在没分了只能靠回复了,求大神帮助啊. 需求就是从一个站点A开始,获取A站点上所有的链接,把获取到的链接存到domain_data数据表里,同时把A站点 存到domain_exist表里用来判断是否获取过. 从A站点获取到链接后存到一个数组中,然后从这个数组中取一个链接,判断这个链接是否在domain_exist出现过, 如果没有就插入到domain_exist表中.然后获取这个新插入的链接页面中的所有链接,如果当前链接无法访问,就取数组中下一个下标,造成一个循环,两个表中都不允许有重复数据. 获取链接的格式限制是:data表中不能有exist表中的链接以免造成重复获取, 存储格式统一为www.baidu.com,或者baidu.com,XXX.baidu.com. 不能有http://XXX.XXX/ 无限制循环,程序不崩就成功了. 求大神帮小弟改下程序,现在总是会崩掉. http://pan.baidu.com/s/1bnw7zMR

user: user-0
content: 引用 3 楼 cbzjzsb123 的回复:[quote=引用 2 楼 rand_srand 的回复:] [quote=引用 1 楼 lovesmiles 的回复:] k1是用来生成随机种子的，k2是用来将这个随机种子所生的伪随机数列移动到第k2位。  使得下一个rand()函数是第k2+1的伪随机数。  k3没有用，k4没有用，k5也没有用。就这样..................................... 没用那为什么还要写它呢？[/quote] 谁写的代码你去问谁啊，又不是他写的，你问他为什么要写有什么用[/quote] 书上写的，我以为肯定有用，只是自己没搞明白，所以想问问

user: user-2
content: 引用 2 楼 rand_srand 的回复:[quote=引用 1 楼 lovesmiles 的回复:] k1是用来生成随机种子的，k2是用来将这个随机种子所生的伪随机数列移动到第k2位。  使得下一个rand()函数是第k2+1的伪随机数。  k3没有用，k4没有用，k5也没有用。就这样..................................... 没用那为什么还要写它呢？[/quote] 谁写的代码你去问谁啊，又不是他写的，你问他为什么要写有什么用

user: user-0
content: 引用 1 楼 lovesmiles 的回复:k1是用来生成随机种子的，k2是用来将这个随机种子所生的伪随机数列移动到第k2位。  使得下一个rand()函数是第k2+1的伪随机数。  k3没有用，k4没有用，k5也没有用。就这样..................................... 没用那为什么还要写它呢？

user: user-3
content: k1是用来生成随机种子的，k2是用来将这个随机种子所生的伪随机数列移动到第k2位。  使得下一个rand()函数是第k2+1的伪随机数。  k3没有用，k4没有用，k5也没有用。就这样.....................................
user-0 提问: 欲读《数据结构与算法分析》，求前提知识提点

回复:
user: user-1
content: 额。。。这个貌似是大学开的课程里面的《高等数学》。不知道现在课改高中课程有没有。不过这个基础不会的话编程以后会有很大阻力滴。。

user: user-2
content: 楼主应该去听高中数学。  早知道吃完第七个包子就饱了，我为什么还要吃前六个包子呢？！  希望楼主不要犯这种低级错误。

user: user-2
content: 《高中数学》
user-0 提问: 用c语言编写一个魔方矩阵

回复:
user: user-1
content: 在http://www.codeproject.com搜“Magic Cube” ？

user: user-2
content: 这年头伸手党怎么这么多。。。

user: user-3
content: 百度知道里的伸手党更多,且个别道德败坏...

user: user-4
content: 只说思路： 先实现输出N*N魔方矩阵，然后再考虑其他条件
user-0 提问: 整数转换为字符型数据

回复:
user: user-0
content: 主要是不使用标准库函数。

user: user-1
content: 这都隔了快两年了！ #include<stdio.h> #include<conio.h>  char *int_char(char str[],int num) {     char string[11] = "0123456789";  //查询对应字符     char temp = 0;     int denum = 0;     int count = -1;     int i = 0,j = 0;      while(num >= 10) {         denum = num % 10;         num /= 10;         str[i] = string[denum];         i++;         count++;     }     str[i] = string[num];     count++;     i++;     str[i] = '\0';     j = count;     //ptr=ptr-count-1;     for(i = 0,j=count;i < j;i++,j--) {         temp = str[i];         str[i] = str[j];         str[j] = temp;     }     return str; }  //主函数 int main() {     int num = 0;     char ch = 0;     char str[20] = {0};     do {         printf("Please input num:\n");         scanf("%d",&num);         int_char(str,num);         printf("%s\n",str);         ch = getch();     } while(ch == 'y');     return 0; }

user: user-1
content: #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汉

user: user-2
content: 接分。。是这个节奏恶魔

user: user-3
content: sprintf（temp，"%d",i);

user: user-4
content: do{ printf("Please input num:\n"); scanf("%d",&num); //int_char(str,num); sprintf(str, "%d", num); printf("%s\n",str); ch = getch(); }while(ch == "y");

user: user-5
content: 引用 1 楼 u013470052 的回复:你能把你的问题问出来吗？  是来散分的吗？

user: user-6
content: 你能把你的问题问出来吗？
user-0 提问: 关于OC的release的问题

回复:
user: user-1
content: 请看错误提示，release在自动引用计数模式中是无效的，ARC已经自动添加了retain和release在自动释放池(@autoreleasepool)

user: user-2
content: “OC和C不是一回事。” 怎么讲，这里面哪儿用到C了吗？

user: user-3
content: OC和C不是一回事。
user-0 提问: 鼠标移动，在窗口标题中显示鼠标的坐标，字符数组输出问题

回复:
user: user-1
content: 引用 5 楼 u010306834 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] printf,wprintf,_tprintf sprintf,swprintf,_stprintf fprintf,fwprintf,_ftprintf 不是一回事！ 能简单说一下么？[/quote] 最好自己在MSDN里面查。

user: user-0
content: 引用 3 楼 Intel0011 的回复:[quote=引用 1 楼 Intel0011 的回复:] wprintf(szTitle,"%d,%d",point.x,point.y); ----> wprintf(szTitle,L"%d,%d",point.x,point.y); //宽字符 格式化数组用swprintf swprintf(szTitle,L"%d,%d",point.x,point.y); //宽字符 [/quote] 感谢

user: user-0
content: 引用 4 楼 zhao4zhong1 的回复:printf,wprintf,_tprintf sprintf,swprintf,_stprintf fprintf,fwprintf,_ftprintf 不是一回事！ 能简单说一下么？

user: user-1
content: printf,wprintf,_tprintf sprintf,swprintf,_stprintf fprintf,fwprintf,_ftprintf 不是一回事！

user: user-2
content: 引用 1 楼 Intel0011 的回复:wprintf(szTitle,"%d,%d",point.x,point.y); ----> wprintf(szTitle,L"%d,%d",point.x,point.y); //宽字符 格式化数组用swprintf swprintf(szTitle,L"%d,%d",point.x,point.y); //宽字符

user: user-0
content: 引用 1 楼 Intel0011 的回复:wprintf(szTitle,"%d,%d",point.x,point.y); ----> wprintf(szTitle,L"%d,%d",point.x,point.y); //宽字符  我试了一下结果是一样的 乱码，谢谢

user: user-2
content: wprintf(szTitle,"%d,%d",point.x,point.y); ----> wprintf(szTitle,L"%d,%d",point.x,point.y); //宽字符

user: user-3
content: LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)  {        char szTitle[100];//存放鼠标位置的数组      POINT point;//当前鼠标的位置      switch(message)      {      case WM_MOUSEMOVE:          point.x=LOWORD(lParam);          point.y=HIWORD(lParam);          sprintf(szTitle,"%d,%d",point.x,point.y);//格式化数组szTitle SetWindowTextA(hwnd,szTitle);//设置windows标题          break;       case WM_DESTROY:          PostQuitMessage(0);          break;        default:          return DefWindowProc(hwnd,message,wParam,lParam);      }      return 0;    或者修改工程的字符集配置。
user-0 提问: 大神进来帮忙解决一下，新手问题求教

回复:
user: user-1
content: =是用来赋值，==是判断相等关系

user: user-2
content: http://blog.csdn.net/u010236550/article/details/19005909

user: user-3
content: 从其它的语言转过来的初学者真得好好看完基础书再来问这样的问题。

user: user-4
content: 卤煮 的基本知识还是有待提高哦

user: user-5
content: C语言中 逻辑运算符有 > (大于)，<(小于)，==（等于）等等，简单的说就是比较两个数的大小。当你要判断两个数是否相等的时候就需要用 ==。  而 = 是赋值运算符。比如说 x=1 的意思就是将x的值设为1。   比如： int x =1;  //将x的值设为1 if(x == 2) // 比较x的值是否和 2相等，如果相等输出1 ，否则输出0. printf("1"); else printf("0");

user: user-6
content: 基础不牢靠，用啥是由你决定，看你想用来干嘛

user: user-7
content: 书上不是都有吗

user: user-8
content: 楼主如果用Pascal或Delphi的话，就会问：为什么一会用=,一会用:=

user: user-9
content: 引用 1 楼 user-13 的回复:=是赋值 ==是判断 它们之间的关系，就像东（方向）和东东（物品的口语说法）的关系一样  这不是新手问题，这是根本不看书问题 就是没看书的问题

user: user-10
content: 楼主该好好看书。这是最好的建议。

user: user-11
content: 引用 楼主 l964772215 的回复:main（） ｛ int x； scanf（“%d”，&x） if （x《0） printf（“-1”）； else if （x==0） printf（“0”）； else printf（“1”）； ｝     为什么else if处要用两个等号，什么时候用两个，什么时候用一个 1. 如果你只是判断一下x是否等于0，用 x == 0 2. 如果你想让x等于0，用x = 0

user: user-12
content: x == 0 是判断x是否为0，是的话就返回ture否则返回false      x = 0  是赋值

user: user-13
content: =是赋值 ==是判断 它们之间的关系，就像东（方向）和东东（物品的口语说法）的关系一样  这不是新手问题，这是根本不看书问题
user-0 提问: C语言中布尔值的候选类型是什么？

回复:
user: user-1
content: 引用 5 楼 u014444402 的回复:stdbool.h C语言的标准函数库中的头文件stdbool.h包含了四个用于布尔型的预定义宏。本头文件是在C99标准中引入的 ++

user: user-2
content: #include<stdbool.h>   这个头文件定义了bool,true,false等宏。  #ifndef__cplusplus  如果不是C++,是纯C，那么，定义宏bool相当于_Bool类型。  #definebool _Bool  #definetrue 1  #definefalse 0   #else/* __cplusplus */  如果是C++,那么定义_Bool类型为bool类型。  /*Supporting <stdbool.h> in C++ is a GCC extension. */  #define_Bool bool  #definebool bool  #definefalse false  #definetrue true   #endif/* __cplusplus */   /*Signal that all the definitions are present. */  #define__bool_true_false_are_defined 1

user: user-2
content: _Bool, C99标准定义了一个新的关键字

user: user-3
content: stdbool.h C语言的标准函数库中的头文件stdbool.h包含了四个用于布尔型的预定义宏。本头文件是在C99标准中引入的

user: user-4
content: 使用整形 int  就可以了

user: user-5
content: int

user: user-6
content: 我更喜欢 typedef enum {false, true} bool ;  bool a = false; bool b = true;

user: user-7
content: 你到底想问什么？
user-0 提问: 关于字符串复制语句while ((*a++=*b++)!='\0’)；的问题

回复:
user: user-1
content: 计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

user: user-2
content: 引用 15 楼 zyb050607 的回复:[quote=引用 12 楼 u013171165 的回复:] 引用嗯嗯，还有一个问题不明白啊，判断*b指向的元素为'\0'则停止循环，此时b中的'\0'还为复制到a中，是不是？实测'\0'会复制过去，如果不复制过去函数本身就是错的。 这个是怎么测试的？首先a的长度比b要长，如果b有5个字符，a的长度为10，那么不管b中的'\0'有没有复制过去，a[5]到a[9]应该都是'\0'.[/quote]你还是没理解代码的意思，我把我测试的代码给你吧，如果你有兴趣，可以参与这个过程。私信发给你。

user: user-0
content: 引用 12 楼 u013171165 的回复:引用嗯嗯，还有一个问题不明白啊，判断*b指向的元素为'\0'则停止循环，此时b中的'\0'还为复制到a中，是不是？实测'\0'会复制过去，如果不复制过去函数本身就是错的。 这个是怎么测试的？首先a的长度比b要长，如果b有5个字符，a的长度为10，那么不管b中的'\0'有没有复制过去，a[5]到a[9]应该都是'\0'.

user: user-0
content: 引用 6 楼 u013470052 的回复:明显是strcpy函数的实现源码。 a++不能做左值。 还有你得搞清楚*a++ = *b++，和a++ = b++的区别。*a++ = *b++是先将b指向地址的值取出来赋值给a纸箱地址的值，然后a指针指向下一个元素的地址，b指针也只想下一个元素的地址。a++ = b++欲使a++做左值，肯定是错的。 确实是strcpy的源码 ，好眼力

user: user-3
content: 后++不能做左值

user: user-2
content: 引用嗯嗯，还有一个问题不明白啊，判断*b指向的元素为'\0'则停止循环，此时b中的'\0'还为复制到a中，是不是？实测'\0'会复制过去，如果不复制过去函数本身就是错的。

user: user-0
content: 引用 3 楼 czarten 的回复:你漏掉了那两个 * 号  其实就是想知道a++为什么不能在左边，以前不知道左值这个感念，学习了

user: user-0
content: 引用 2 楼 tujiaw 的回复:a++不能放在等号左边 正解！

user: user-0
content: 引用 3 楼 czarten 的回复:你漏掉了那两个 * 号加上  引用 5 楼 u013171165 的回复:[quote=引用 4 楼 u013171165 的回复:] 楼主可能没懂这句的意思： while((*a++=*b++)!='\0')表示1、*a=*b;  2、a++;b++; 判断*b（此时b已经加了一次了，指向下一个元素）所指向元素是否为'\0'，是的话就退出循环，不是（!=）则继续复制b所指数组中元素到a数组中。 你说的 (a++)=(b++))!=4 这意思就完全变了，a++返回的是自身的值副本 (++a)=(++b)!=4; 这个却可以，因为：++a 返回的是a加1后自身的引用！不信你试下。 真心感谢楼主，如果不是你这个问题，我也不会去查书，也就不会注意这个细节。我也是初学C++：与其问人，不如查书，与楼主共勉，另外，欢迎私信微博各种交流。有问题问对其他人也是有好处的。[/quote] 嗯嗯，还有一个问题不明白啊，判断*b指向的元素为'\0'则停止循环，此时b中的'\0'还为复制到a中，是不是？

user: user-4
content: 指针和数值要分清楚

user: user-5
content: 你漏掉了那两个 * 号   !=4是不是也有问题？这个表达式没看懂想干嘛。

user: user-6
content: 明显是strcpy函数的实现源码。 a++不能做左值。 还有你得搞清楚*a++ = *b++，和a++ = b++的区别。*a++ = *b++是先将b指向地址的值取出来赋值给a纸箱地址的值，然后a指针指向下一个元素的地址，b指针也只想下一个元素的地址。a++ = b++欲使a++做左值，肯定是错的。

user: user-2
content: 引用 4 楼 u013171165 的回复:楼主可能没懂这句的意思： while((*a++=*b++)!='\0')表示1、*a=*b;  2、a++;b++; 判断*b（此时b已经加了一次了，指向下一个元素）所指向元素是否为'\0'，是的话就退出循环，不是（!=）则继续复制b所指数组中元素到a数组中。 你说的 (a++)=(b++))!=4 这意思就完全变了，a++返回的是自身的值副本 (++a)=(++b)!=4; 这个却可以，因为：++a 返回的是a加1后自身的引用！不信你试下。 真心感谢楼主，如果不是你这个问题，我也不会去查书，也就不会注意这个细节。我也是初学C++：与其问人，不如查书，与楼主共勉，另外，欢迎私信微博各种交流。有问题问对其他人也是有好处的。

user: user-2
content: 楼主可能没懂这句的意思： while((*a++=*b++)!='\0')表示1、*a=*b;  2、a++;b++; 判断*b（此时b已经加了一次了，指向下一个元素）所指向元素是否为'\0'，是的话就退出循环，不是（!=）则继续复制b所指数组中元素到a数组中。 你说的 (a++)=(b++))!=4 这意思就完全变了，a++返回的是自身的值副本 (++a)=(++b)!=4; 这个却可以，因为：++a 返回的是a加1后自身的引用！不信你试下。

user: user-7
content: 你漏掉了那两个 * 号

user: user-8
content: a++不能放在等号左边

user: user-9
content: a++ 结果不是左值 不能作为 =左操作数
user-0 提问: 初始化数组的时候时候内存是否开辟了存贮指针的空间？

回复:
user: user-1
content: 计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

user: user-2
content: 你定义一个变量a，是不是应该另外分配一个空间存a的地址了？肯定不用嘛。

user: user-3
content: 引用 楼主 u013491662 的回复:int a[3][4]={0}; 这个数组占内存的字节数为12*sizeof(int) 我有一个问题 在程序中有没有开辟单独的4字节的指针数据空间 存数组a的地址？ 这个疑问是这么来的 a = (int (*)[4])0; 报错：做操作数必须为左值 也就是说a是常量？ 那初始化数组的时候有没有单独开辟4字节空间存a呢？ 相应的，有没有开辟4字节空间存a[0]、a[1]、a[2]呢？ 当然没有，如果有那必须声明另外的指针变量  其实程序编译后，所有的a都会变成数组的基址，数组元素是通过基址+偏移来寻址的 一般是ebp+某个偏移
user-0 提问: 关于变量的生命周期问题，在一个大括号里的变量何里销毁？

回复:
user: user-0
content: 谢谢楼上各位的回复

user: user-1
content: index事实上离开大括号就已经被释放了，它的值不值有意义，你看到它还是原来的似乎正确的值，只是因为os暂时没有用到它而已。

user: user-2
content: 引用 2 楼 test_lockxxx 的回复:引用确实就从[栈]上被释放了，但只是栈指针esp变动了，栈中的内容还在那里成为了垃圾值，如果又有栈操作的话，就会改变，所以用p引用那个位置的值是不可信的  看到楼上的回复，确定了我之前的认识。  我原来也认为： 栈中的内容在跳出{}后成了垃圾值。  只是从输出的结果看，我有点不自信了。 怎么理解这个“垃圾值”？ 准确的说法，是不可预料。如果有别人用了，就会变成一些其他的值；如果没人碰，那就保持不变，怎么都有可能。

user: user-3
content: if(1)的右大括号结束，里面的index就无效了，此时指针p的指向也“无效”了，不应该再使用他了，记住这一点就行了，即使p[0]/p[1]/p[2]的值还是4、5、6，也不能依赖于他。栈上的变量释放，可能只是移动了栈指针esp，但是不是所有的编译器都这么干，谁知道了。

user: user-0
content: 引用确实就从[栈]上被释放了，但只是栈指针esp变动了，栈中的内容还在那里成为了垃圾值，如果又有栈操作的话，就会改变，所以用p引用那个位置的值是不可信的  看到楼上的回复，确定了我之前的认识。  我原来也认为： 栈中的内容在跳出{}后成了垃圾值。  只是从输出的结果看，我有点不自信了。

user: user-4
content: 1. if(1)可以去掉，只要有{}就行 2.第二次p = index;中的index是第二层{}中的局部变量，但p对第二层{}来说相当于全局变量，所以即使index出栈，p仍指向index原来的位置 3.//上面大括号里的 int index[3] = {4,5,6}; 运行到大括号外以后，确实就从[栈]上被释放了，但只是栈指针esp变动了，栈中的内容还在那里成为了垃圾值，如果又有栈操作的话，就会改变，所以用p引用那个位置的值是不可信的     printf("%d,%d,%d\n",p[0],p[1],p[2]); //虽然这里还会显示 3,4,5，但这是垃圾值 你可以插入其他有栈操作，实验一下 int main() {     int index[3] = {1,2,3};     int *p;     p = index;     int a = 3;     {         int index[3] = {4,5,6};         p = index;         int a = 4;     }    {         int index[3] = {40,50,60};         p = index;         int a = 4;     }     printf("%d,%d,%d\n",p[0],p[1],p[2]); //为什么这里还会显示 3,4,5     printf("a:%d\n",a);     return 0; }
user-0 提问: 三维凸包的程序，已有源程序，求大神讲解程序输入是什么

回复:
user: user-0
content: 谢谢你~~问题已经解决了。。

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

user: user-0
content: 还有个问题呀，   while ( scanf ("%d %d %d", &x, &y, &z ) != EOF )  这个函数为什么输入以后不执行呢

user: user-1
content: 引用 3 楼 hj199241 的回复:楼上是几个意思？？？ 3D大牛的博客中搜搜看。

user: user-0
content: 哦哦~~好吧~~我在试试呢

user: user-0
content: 楼上是几个意思？？？

user: user-1
content: http://blog.csdn.net/pizi0475

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

回复:
user: user-1
content: 大小端，4个字节 1234 4321

user: user-2
content: 小端，是  低地址对应整数的低位 高地址对应整形的高位  这个是CPU设计的时候的问题，咋们只需要了解就行了  楼主  把  a=0x12345678  在内存里看下就很清楚了

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

user: user-4
content: 小端模式，是指数据的高位保存在内存的高地址中，而数据的低位保存在内存的低地址； 大端模式，是指数据的高位，保存在内存的低地址中，而数据的低位，保存在内存的高地址； 个人计算机一般是小端，网络传输用的是大端

user: user-5
content: 百度：大小端

user: user-6
content: 这和处理器有关，你的是小端的，所以低位在前
user-0 提问: 如何在一个完整的main.c中调用另一个.c文件？

回复:
user: user-1
content: 不超过1000行的代码就没必要分开成几个.c文件了。

user: user-2
content: 把调试信息弄来看看

user: user-3
content: 是不是编译选项里面没有配置路径哦

user: user-4
content: 你用什么编译工具？ 连代码都copy过去也不行？能够画动画的C函数库不多呀。  #include 可以改成用绝对路径的 #include "c:\xxx.h"这样的方式包括。  把代码贴上来看看呗

user: user-5
content: 在c文件里用extern定义，你需要调用的地方再用extern声明，这应该是可以用的。要是有问题你可以重启一下IDE试试，有时候会抽风，也有可能是代码里有其他问题。
user-0 提问: 关于switch

回复:
user: user-1
content: switch(x<0) { //这里还少个括号

user: user-1
content: 斜杠也写反了 printf("-1/n");  printf("2*x=%d\n", x * 2);

user: user-2
content: switch(x<0)  书上有写啊， switch 只能是 整数，或者自动转成整数类型的

user: user-3
content: 编译都通不过，大括号都没对齐，请问能不能仔细检查再提问。

user: user-1
content: switch(x<0 ? 1 : 0)
user-0 提问: C语言编程

回复:
user: user-1
content: COleDateTime

user: user-2
content: 编程珠玑上有一个计算给定日期是星期几的公式，但我忘了在哪了。。。

user: user-0
content: 非常感谢，太给力了。

user: user-3
content: 消灭零回复： 代码引自：http://blog.163.com/mg_tccx/blog/static/199457130201372624818909?suggestedreading //C.RooKie:2012.1.15(03:51)  #include<stdio.h> #include "conio.h" #include<math.h> int leapyear,sum=0; //星期.. void weekday() {  printf("\t  日  一  二  三  四  五  六\n"); }  //计算每个月的第一天对应星期几.. int firstday(int year) {  double s;  s=floor(year-1+(year-1)/4.0-(year-1)/100.0+(year-1)/400.0+1);  return (int)s%7; }  //计算机离公元01年的距离.. void rizishu(int year) {     for(int i=1;i<year;i++)  {         if((i%4==0&&i%100!=0)||i%400==0)   {       leapyear=29;   }      else   {    leapyear=28;   }   sum+=337+leapyear;  }  if(leapyear==29)  {   printf("\t离公元01年%d天(闺年)\n\n",sum);  }  else  {   printf("\t离公元01年%d天(%d不是闺年)\n\n",sum,year);  }  printf("\n\t\t%d年日历\n\n",year); }  //打印日历.. void PrintRiLi(int year) {  int i,j,yue,ri;  int weekday1;     weekday1=firstday(year);  for(yue=1;yue<=12;yue++)  {   printf("%3d月份",yue);      weekday();   if(yue==4||yue==6||yue==9||yue==11)   {    ri=30;   }   else if(yue==2)   {    if((year%4==0&&year%100!=0)||year%400==0)     ri=29;    else     ri=28;   }   else   {    ri=31;   }         printf("\t");   for(j=0;j<weekday1;j++)   {    printf("    ");   }    for(i=1;i<=ri;i++)   {    printf("%4d",i);    weekday1=(weekday1+1)%7;    if(weekday1==0)    {     printf("\n");     printf("\t");    }   }      printf("\n\n\n");  }  getch(); }  int main() {  int year,weekday;  printf("     *********************************\n");  printf("       C.RooKie:2012.1.15(03:51)\n");  printf("     这是一个随意给出某年份，可以显示\n");  printf("     该年的日历(包括每月的天数和对应)\n");  printf("     的星期几!\n");  printf("     *********************************\n");  printf("\n");  printf("     请输入要查找的年份：");  scanf("%d",&year);  printf("\n\n");     rizishu(year);  PrintRiLi(year);  return 0; }
user-0 提问: 虚拟地址，逻辑地址，线性地址的理解

回复:
user: user-1
content: p的地址是逻辑地址可分为页号和页内偏移，然后每个程序都对应一个页表，根据页号查页表获得对应在内存中物理块的块号，然后物理块号和业内偏移组合形成物理地址，这个物理地址就是在内存中的实际地址了，当然这个时候往内存取的话不是一块一块的取，一般好几块一起搬入cache中。

user: user-2
content: http://www.kerneltravel.net/这个网的某个资料应该有，讲linux 内存管理的。

user: user-2
content: 应该是的， 记得Linux CR3的值是保存在task_struct中， 每一个进程都有自己的task_struct.  可以看看linux内核的资料。 windows的话 ，不一定公开这些。

user: user-3
content: 引用 1 楼 user-6 的回复:好像是那么回事，又好像不是那么回事…… 逻辑地址是程序用的，虚拟地址是操作系统用的，线性地址是 CPU 用的，物理地址是 MMU 用的 实模式～保护模式～实模式～保护模式～～～～～～坑爹的 x86 啊，我要吐～   好像是，但愿别错了

user: user-4
content: 《The Intel 64 and IA-32 Architectures Software Developer's Manual》

user: user-5
content: 引用 楼主 jk10242048 的回复:以下是我的理解，不知道哪里有问题  以windows为例，比如平时用C语言编程,int* p = (int*) malloc(sizeof(int))  这个p的值假设为 0x 0040 0000，这个就是虚拟地址  而  DS段选择子 ：0x0040 0000 叫做逻辑地址  windows CS SS DS ES段基地址都是0，所以虚拟地址的值就是线性地址的值，  之后读取CR3页目录寄存器（应该每个进程都不一样吧）的值，进行分页 形如××××××××：××××××××是逻辑地址 经过段地址换算后为××××××××是线性地址 此时，如果分页，该线性地址就是虚拟地址 如果无分页，该线性地址就是实际地址

user: user-6
content: 好像是那么回事，又好像不是那么回事…… 逻辑地址是程序用的，虚拟地址是操作系统用的，线性地址是 CPU 用的，物理地址是 MMU 用的 实模式～保护模式～实模式～保护模式～～～～～～坑爹的 x86 啊，我要吐～
user-0 提问: 链表结构体中嵌套一个链表结构体，怎么初始化

回复:
user: user-1
content: 计算机组成原理→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

user: user-2
content: 保证new_contract分配即可！

user: user-3
content: 指针本身的内存就在结构体里，指针的内容指向了新分配的空间 new_contract

user: user-0
content: 引用 2 楼 layershow 的回复:对的，不用分配空间，contract 是需要分配的，保证 hq_id->contract_list 初始为 NULL 即可  为什么不用分配啊。contract_list 不是属于哪个HQ_ID结构体里面的一个指针吗，将要作为contract链表的头结点，不分配，那内存从何而来啊

user: user-0
content: 引用 1 楼 Automation_dmu 的回复:*new_contract = contract; 这句new_contract和contract的定义是什么？ 按照你下面的写法，new_contract需要分配内存， contract可以是一个初始化了的局部变量用于给new_contract赋值。 写法上有点冗余，但并不存在错误。  对的。contract是一个局部的结构体变量，用于给new_contract赋值。  接下来就是新的这个节点开始做一个链表，先指向 hq_id->contract_list ，我就是不确定这个结构体里面的contract_list 需不需要malloc空间啊。。。如果不分配，岂不是弄在其他地方了？

user: user-3
content: 对的，不用分配空间，contract 是需要分配的，保证 hq_id->contract_list 初始为 NULL 即可

user: user-4
content: *new_contract = contract; 这句new_contract和contract的定义是什么？ 按照你下面的写法，new_contract需要分配内存， contract可以是一个初始化了的局部变量用于给new_contract赋值。 写法上有点冗余，但并不存在错误。

user: user-5
content: 指针与指针之间赋值不需要再开辟空间

user: user-3

user: user-0
content: 引用 5 楼 layershow 的回复:指针本身的内存就在结构体里，指针的内容指向了新分配的空间 new_contract  你的意思是说 new_contract这个新的节点因为已经分配了空间，结构体里面的那个hq_id->contract_list只要指向了new_contract就行了，对吧。 是这样的话，我就理解了
user-0 提问: C语言排序！

回复:
user: user-1
content: 这个比较一下就得了

user: user-2
content: 引用 4 楼 u013171165 的回复:#include <iostream> #include <vector> #include<algorithm>  int a;     vector<int> st;     while(std::cin>>a)     {     	st.push_back(a);     }     sort(st.begin(),st.end());     for(auto &v :  st) 	{ 		std::cout<<v<<" "; 	}  输入以及输出： 34 25 67 stop 25 34 67   编程嘛！多使用内置数据结构，不要老想自己写。 忘了写int main了，自己加上

user: user-2
content: #include <iostream> #include <vector> #include<algorithm>  int a;     vector<int> st;     while(std::cin>>a)     {     	st.push_back(a);     }     sort(st.begin(),st.end());     for(auto &v :  st) 	{ 		std::cout<<v<<" "; 	}  输入以及输出： 34 25 67 stop 25 34 67   编程嘛！多使用内置数据结构，不要老想自己写。

user: user-3
content: 我直接从大到小打印出来吧 void print(int x, int y, int z) {     int bigger = x > y ? x : y;     int biggest = z > bigger ? z : bigger;     std::cout << biggest << " ";    //打印最大的数      int other1 = (bigger == x ?  y : x);     int other2 = (biggest == z ? bigger : z);     std::cout << (other1 > other2 ? other1 : other2);    // 打印第二大的数字     std::cout << (other1 < other2 ? other1 : other2);   // 打印最小的数字 }

user: user-4
content: 三个数 还要怎么想 ，直接两两比较就出来了

user: user-5
content: 引用 楼主 ruying1389279 的回复:输入三个数，从大到小排序。使用while循环，且不使用数组。如何实现呢？初学者，想了一晚上没想出来。 三个变量，加一个临时变量，比较，交换值就可以了。 比如imax,imiddle,imin，imax和imiddle,imin比较，最大的放到imax中，剩下的imiddle和min比较，剩下的最大的放到imiddle中，imin中的肯定是最小的了。 按要求输出即可。

user: user-6
content: 百度 冒泡法 插入法 快速排序法 选择法排序

user: user-2
content: 引用 6 楼 user-7 的回复:感觉有些没有必要的， 费好大的劲，就为三个数。还是好好思考更有意义的问题吧。 做技术好钻死角，包括我自己。。共勉！！！！！这些基础算法实现，每个语言都有，没有必要老是纠结这些，懂算法原理即可。别人写好的算法你不用，一定要自己写个性能差的没有意义。

user: user-7
content: 感觉有些没有必要的， 费好大的劲，就为三个数。还是好好思考更有意义的问题吧。 做技术好钻死角，包括我自己。。共勉！！！！！
user-0 提问: c语言课件设计绘制饼图 求解

回复:
user: user-1
content: 如楼上推荐，用easyX库，分分钟让你轻松绘图

user: user-2
content: easyx负责将BGI翻译为GDI

user: user-3
content: easyX和gdi什么区别?

user: user-2
content: http://www.easyx.cn
user-0 提问: C语言-碰到个奇怪的问题

回复:
user: user-1
content: gets(name[i]); 应改为 fgets(name[i],100,stdin);

user: user-2
content: scanf("%d ",&k); %d后面加个空格

user: user-3
content: 把换行符干掉就可以了

user: user-4
content: 引用 1 楼 zjq9931 的回复: #include<stdio.h> int main(){ 	//输入n个字符串存入二位数组中     char name[100][100];     int k=0,i=0;     scanf("%d",&k); 	fflush(stdin);     for(i=0;i<k;i++){         gets(name[i]);     }     for(i=0;i<k;i++){         puts(name[i]);     }     return 0; }这个就可以，也可以把fflush(stdin);换成getchar();

user: user-5
content: scanf是以回车键做为输入结束的标志，然后从输入的内容中读取你指定的格式的数据。  也就是说比如你输入一个:  10 回车  10匹配%d，被读到k中，那个回车没有被匹配走，还在那  然后你紧跟着后面是gets，它也是以回车做为输入结束的标志  所以循环第一次的时候gets 把你上面的那个“10 回车”里面剩下的回车判断为输入了一次。只是没有读到内容。  要避免这个问题应该scanf("%d\n",&k); 加一个\n把回车一起读掉。

user: user-6
content: scanf，输入一个数字之后，会有一个回车，把这个清理掉就好了。

user: user-6
content: #include<stdio.h> int main(){ 	//输入n个字符串存入二位数组中     char name[100][100];     int k=0,i=0;     scanf("%d",&k); 	fflush(stdin);     for(i=0;i<k;i++){         gets(name[i]);     }     for(i=0;i<k;i++){         puts(name[i]);     }     return 0; }

user: user-7
content: scanf不会接收回车，所以在scanf语句后要释放掉键盘缓冲区的内容

user: user-8
content: 需要吃回车~~
user-0 提问: 初始化数组中的一个元素，其他元素是不是自动初始化为0

回复:
user: user-1
content: int ar2[100]={ar2[99]=-1}; ar2[99]=-1 这是一个赋值表达式，赋值表达式的值为赋的值 int ar2[100]={ar2[99]=-1}; 相当于 int ar2[100]=[-1]； ar2[99]=-1;

user: user-2
content: int ar2[100]={ar2[99]=-1};//---->将ar2[99]=-1表达式的值作为ar2[0]的值 相当于 int ar2[100]={-1, ....., -1}};

user: user-3
content: 我新定义了一个变量zz，只是想说明一下 (ar2[99] = -1) 是多少

user: user-0
content: zz是哪里来的

user: user-3
content: ar2[99]=-1 是个表达式 int zz = (ar2[99] = -1); 你猜 zz 是多少？ 你在初始化数组时，将第0个元素用表达式(ar2[99]=-1)对其赋值，你说 ar2[0] 现在是多少呢？
user-0 提问: strcpy_s竟然会修改源地址的指针？？？？

回复:
user: user-0
content: 找到问题了 就像上面说的strlen(send_data.token_key) 是不对的，初始化时候没有‘\0’计算结果是错的！！！所以覆盖了栈里的指针

user: user-1
content: 引用 3 楼 u013419621 的回复:send_data.token_key 是一个 char token_key[16]; strcpy_s(send_data.token_key,sizeof(send_data.token_key),pVO->m_ValidateData._AccountData._szGlSid);  另外你要关注一下 _szGlSid 长度问题

user: user-0
content: send_data.token_key 是一个 char token_key[16];

user: user-2
content: 怕是send_data.token_key目标内存不足，影响到了pVO。

user: user-1
content: strlen(send_data.token_key) 是不对的 send_data.token_key 定义是多少？ 看情况是 send_data.token_key 写越界了，覆盖了局部变量 pVO
user-0 提问: C语言实现对XML的解析

回复:
user: user-1
content: 应该有库吧，找一下库咯

user: user-2
content: 参考tinyXML

user: user-3
content: 引用 9 楼 Zidane_2014 的回复:[quote=引用 3 楼 u013823973 的回复:] 用第三方库吧,推荐一个CMARKUP,如果是要用二进制解析的话，那就像2楼那样，一个节点一个节点的读  CMARKUP是针对C++的吗？ 只使用C语言也能够使用这个库吗？[/quote] 如果你是使用VS开发的话，完全没问题，如果你是在LINUX下开发的话，就libxml2吧

user: user-4
content: tinyxml

user: user-5
content: libxml,cmarkup略小用过都还不错

user: user-6
content: http://stackoverflow.com/questions/399704/xml-parser-for-c

user: user-0
content: 引用 3 楼 u013823973 的回复:用第三方库吧,推荐一个CMARKUP,如果是要用二进制解析的话，那就像2楼那样，一个节点一个节点的读  CMARKUP是针对C++的吗？ 只使用C语言也能够使用这个库吗？

user: user-0
content: 引用 1 楼 user-11 的回复:使用第三方开源软件,如libxml  使用libxml简单吗？我需要在短时间内完成解析。对于每日工作时间我能够保证在10小时以上。

user: user-7
content: 引用 1 楼 user-11 的回复:使用第三方开源软件,如libxml 英雄所见略同。

user: user-8
content: Minixml http://www.msweet.org/projects.php?Z3

user: user-9
content: gsoap工具产生的代码就是很好的值得学习的xml的解析过程。不过比较难看懂。可以去网上搜索此工具

user: user-3
content: 用第三方库吧,推荐一个CMARKUP,如果是要用二进制解析的话，那就像2楼那样，一个节点一个节点的读

user: user-10
content: 读文件 fopen 读字符 fgets 判断文件是否结束 feof 查找子串 strstr  之后就是<,  />这些的匹配，解析一个一个的节点

user: user-11
content: 使用第三方开源软件,如libxml
user-0 提问: 关于 char username[] 的含义

回复:
user: user-1
content: 引用 楼主 u013419621 的回复:有这样一个结构 struct RECVPPPSDATA { 	UINT32 len; 	UINT32 command; 	UINT32 status; 	char username[]; }; 我做了如下的测试： 	char l[]="asdsfadfasfafadffsf"; 	RECVPPPSDATA dd; 	strcpy(dd.username,l); 	int sss= sizeof(dd);       sss得到的值是12，这是为什么 char username[] 为什么不占空间呢？？？？？它到底是什么    毕竟我向里面填充了char l[]="asdsfadfasfafadffsf" 这么长的字符呢  struct RECVPPPSDATA { 	... 	char username[]; }; 这个username必须先分配空间才可以strcpy( dd.username,I);

user: user-2
content: 引用 4 楼 u013419621 的回复:这个结构是别人定义的，我需要从别人的tcp buffer接收数据到这个结构中， 实际是这样 char buff[10240] = {0}; RECVPPPSDATA *recvppps = (RECVPPPSDATA*)buff; 我需要将他发过来的username拷贝到我自己定义的结构中，因为不知道他发过来的username到底有多长，所以我就做了上面的测试，那么我用strlen(recvppps->username)是不是就可以得到对方究竟发了多长的字符串呢？？？？？？谢谢啦！  struct RECVPPPSDATA { UINT32 len; //根据这个长度可以计算出username占多少字节 UINT32 command; UINT32 status; char username[]; };   看代码注释，别忘记给分。

user: user-3
content: 引用 4 楼 u013419621 的回复:[quote=引用 3 楼 baichi4141 的回复:] 这是C语言里面的一个技巧，username[]这个结构体成员本身不计算大小，当你使用这个名字时，你得到的指针指向的实际上是这个结构体后面的内存。 这个技巧用于建立链表等数据结构是很方便的，如果这个结构体大小为12，就申请一个长度为100的内存空间，并将结构体指针指向这一段内存起点，那么username这个结构体成员实际上就指向了后面的长度为88的可用内存。 所以像楼主这种写法是不正确的，因为你直接定义了一个大小固定的局部变量，那么这个结构体后面的内存已经被其他有效数据使用，你对username的操作实际上访问和修改了其他有效数据，将会使程序崩溃  这个结构是别人定义的，我需要从别人的tcp buffer接收数据到这个结构中， 实际是这样 char buff[10240] = {0}; RECVPPPSDATA *recvppps = (RECVPPPSDATA*)buff; 我需要将他发过来的username拷贝到我自己定义的结构中，因为不知道他发过来的username到底有多长，所以我就做了上面的测试，那么我用strlen(recvppps->username)是不是就可以得到对方究竟发了多长的字符串呢？？？？？？谢谢啦！[/quote]  不是所有语言的字符串都以/0结尾啊，一般在交互中，需要预定义好用户名的最大长度，同时约定，如果不足最大长度时，用0占位

user: user-0
content: 引用 3 楼 baichi4141 的回复:这是C语言里面的一个技巧，username[]这个结构体成员本身不计算大小，当你使用这个名字时，你得到的指针指向的实际上是这个结构体后面的内存。 这个技巧用于建立链表等数据结构是很方便的，如果这个结构体大小为12，就申请一个长度为100的内存空间，并将结构体指针指向这一段内存起点，那么username这个结构体成员实际上就指向了后面的长度为88的可用内存。 所以像楼主这种写法是不正确的，因为你直接定义了一个大小固定的局部变量，那么这个结构体后面的内存已经被其他有效数据使用，你对username的操作实际上访问和修改了其他有效数据，将会使程序崩溃  这个结构是别人定义的，我需要从别人的tcp buffer接收数据到这个结构中， 实际是这样 char buff[10240] = {0}; RECVPPPSDATA *recvppps = (RECVPPPSDATA*)buff; 我需要将他发过来的username拷贝到我自己定义的结构中，因为不知道他发过来的username到底有多长，所以我就做了上面的测试，那么我用strlen(recvppps->username)是不是就可以得到对方究竟发了多长的字符串呢？？？？？？谢谢啦！

user: user-4
content: 这是C语言里面的一个技巧，username[]这个结构体成员本身不计算大小，当你使用这个名字时，你得到的指针指向的实际上是这个结构体后面的内存。 这个技巧用于建立链表等数据结构是很方便的，如果这个结构体大小为12，就申请一个长度为100的内存空间，并将结构体指针指向这一段内存起点，那么username这个结构体成员实际上就指向了后面的长度为88的可用内存。 所以像楼主这种写法是不正确的，因为你直接定义了一个大小固定的局部变量，那么这个结构体后面的内存已经被其他有效数据使用，你对username的操作实际上访问和修改了其他有效数据，将会使程序崩溃

user: user-5
content: 你要给你的char数组分配空间

user: user-5
content: 你这个dd前面还有 len 等成员呢，你随便初始化一个字符串，就能直接到char数组？那编译器太高级了
user-0 提问: microsoft visual studio\vc98\include\mmsystem.h(40) : error C2143: syntax error 

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

user: user-2
content: 贴完整的错误信息

user: user-0
content: 老是提示这个错误，microsoft visual studio\vc98\include\mmsystem.h(40) : error C2143: syntax error : missing ';' before 'string'
user-0 提问: 系统 string的 拷贝构造函数，构造函数问题

回复:
user: user-1
content: 引用 7 楼 xxxxing 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括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对应的汇编并单步执行观察相应内存和寄存器变化。） 这个回答 模板 至今没改过。 回答小册子 求开源[/quote] 等我用我的回帖小册子灌水捞够分了就开源。

user: user-2
content: 引用 6 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括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对应的汇编并单步执行观察相应内存和寄存器变化。） 这个回答 模板 至今没改过。 回答小册子 求开源

user: user-1
content: 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括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对应的汇编并单步执行观察相应内存和寄存器变化。）

user: user-3
content: 引用系统的string  的构造函数和拷贝构造函数 不是 只是拷贝值而不是地址吗 谁告诉你的， 弄ta

user: user-4
content: 改成这样就好了。  #include <iostream> #include <string> using namespace std;  string Getstr() { 	char szTemp[1024] = "你傻了没"; 	return string(szTemp); }  string GetName(const string& str) { 	printf("szTemp = %s \n",str.c_str()); 	return str; }   int main(int argc, char* argv[]) { 	string s = GetName(Getstr()); 	printf("s = %s\n",s.c_str()); 	return 0; }

user: user-5
content: 引用 3 楼 lovesmiles 的回复:printf是c语方的东西，string是c++ 的东西，你应该用cout打印。可以用printf，但需要加stdio.h头文件

user: user-6
content: printf是c语方的东西，string是c++ 的东西，你应该用cout打印。

user: user-7
content: 晕，第一次看到用%s 匹配 std::string的！  只能匹配std::string.c_str()！
user-0 提问: 一个逻辑运算符的问题

回复:
user: user-1
content: 计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

user: user-2
content: !!0x41的意思是对0x41取反两次，取反运算的后面所跟表达式非0则整个取反运算结果为0，如果表达式结果为0，则取反运算结果为1. 所以第一次取反结果为0x00，第二次取反结果为0x01,注意所有非0数取反两次的结果都为1.

user: user-3
content: !! 两次求非运算

user: user-4
content: ！！就是两次！啊 ！！（0x41）=！（！0x41）=！（0x00）=0x01

user: user-5
content: 没看到过！！运算符
user-0 提问: C语言如何控制有效数字的位数？？？

回复:
user: user-1
content: float：1位符号位，8位阶码，23位有效数字（7位左右十进制有效数字） double：1位符号位，11位阶码，52位有效数字（15-16位十进制有效数字） C++标准规定long double不短于double，而通常见到的编译器都是和double一样

user: user-2
content: 高精度计算吧，开平方有比较简单的移位算法，不过效率是否最优就不好说了

user: user-3
content: %f输出7位有效数字，%.Nf最多也就16位，如果要更多的话，就得研究下有什么其他的方法。

user: user-4
content: 只能用字符串存值了。。。

user: user-5
content: 搜GMP库

user: user-6
content: 你不能控制海王星的运动轨迹——直到人类开发出足以改变行星轨道的科技 默认数值类型的精度本身就是有限的，你不能提供无限精确的浮点数运算，自然也就谈不上任意位有效数字

user: user-7
content: 可以使用setprecision函数或者fixed加setprecision的组合，头文件都是iomanip。 两个的区别在于前者是只更改紧随其后的一个数据的格式，而后者是更改后面全部数据输出的格式  举例 #include<iostream> #include<iomanip> using namespace std; int main() { cout<<12345.0<<endl;//输出12345 //cout<<fixed<<setprecision(2)<<123.456<<endl;/*如果在这个位置就加上fixed的话，后面的输出全部都按照fixed处理*/ cout << setprecision(4)<< 3.1415926 << endl;//输出的结果是3.142 cout<<setprecision(3)<<12345.0<<endl;//输出的结果是 "1.23e+004 " cout<<fixed<<setprecision(2)<<123.456<<endl;//输出的结果是123.46，要进行四舍五入 cout<<showpoint<<12345.0<<endl;//输出12345.0 }
user-0 提问: 对WIN32中ListView插入列数据的疑问

回复:
user: user-0
content: 那就奇怪了，以前我写的时候都没用到ListView_SetItemText这个函数啊  然后我找回以前写的项目打开一看，  lvItem.iSubItem = 0;    // 代表每行的列 			wsprintf(szItemInfo, "%s", mySections->Name); 			lvItem.pszText = szItemInfo;                                   // 名称             ListView_InsertItem(hwndList, lpLvItem);                       // 向相应列插入内容,插第一列需要这个             lvItem.iSubItem = 1;             wsprintf(szItemInfo, "%08x", mySections->VirtualAddress);      // RVA             lvItem.pszText = szItemInfo;                                             ListView_SetItem(hwndList, lpLvItem);                          // 向相应列插入内容,插入同一行其它列用setItem   才发现原来是这样。我用的是ListView_SetItem 估计跟 ListView_SetItemText差不多吧。 先谢谢了，我回去再看看。

user: user-1
content: lvItem.mask = LVIF_TEXT;     for ( i = 0; i < COLUMN_NUM; ++i)     {         lvItem.iItem = i;             // 该成员代表行         lvItem.iSubItem = 0;          // 代表每行的列             lvItem.pszText = szColumnContent[j];             ListView_InsertItem(hListView, &lvItem);         for (int j = 1; j < COLUMN_NUM; ++j)         {            ListView_SetItemText(hListView, i, j,szColumnContent[j]);         }           }

user: user-2
content: 一个函数内，不要做那么多事情

user: user-2
content: 插入或删除列后，再更新，需要重新获得索引
user-0 提问: 问一个变量地址的问题，超出我所知道的C语言的范畴了

回复:
user: user-1
content: 引用 8 楼 waterspace 的回复:我们这边没有运行环境，所以没有办法调试。 只是客户在测的时候出现了这个问题 该程序中没有多进程和多线程  如果是a的值被修改，那肯定是某个变量越界了 现在是a的地址被修改，什么时候能修改到变量的地址呢 就算让我写，我也写不出来修改变量地址的代码  但是有可能 这个地方客户那边打印出来的“//此处结果为878f7592”，打印的不一定是func()里面第二个printf执行的结果，你得在printf的时候，加上__FILE__,__LINE__打印，才能证明执行到什么地方了。  比如下面这个程序： void fun2(DWORD *p) { 	//参数p的地址减4 	//是fun2返回后，要执行的代码的地址 	//本来这地方应该是fun1中的第二个printf 	DWORD b = (DWORD)&p - 4;   	//fun2的地址+0x20 	//是我本机上fun2中printf代码段的地址 	//不同debug，release，是否优化，这个+0x20可能不一样 	p = (DWORD *)((DWORD)&fun2 + 0x20);   	//现在我把fun2返回后要执行的代码，改成fun2自己的printf 	*(DWORD *)b = (DWORD)p;   	printf("fun2:%d\n", __LINE__); 	return; }  void fun1() { 	DWORD a = 0xBBBBBBBB; 	printf("fun1:%d\n", __LINE__); 	fun2(&a); 	printf("fun1:%d\n", __LINE__); 	return; }  int _tmain(int argc, _TCHAR* argv[]) { 	fun1();  	getchar();  	return 0; }  实际结果是  并不是预期的 fun1: fun2: fun1:  所以如果，栈上的数据写越界了，什么情况都有可能发生。

user: user-0
content: 应该还是什么地方越界了，再查查看吧

user: user-2
content: 引用 8 楼 waterspace 的回复:我们这边没有运行环境，所以没有办法调试。 只是客户在测的时候出现了这个问题 该程序中没有多进程和多线程  如果是a的值被修改，那肯定是某个变量越界了 现在是a的地址被修改，什么时候能修改到变量的地址呢 就算让我写，我也写不出来修改变量地址的代码 局部变量是存放在栈中的，但栈要反复压栈出栈，因此有时候会把栈中局部变量的地址再压到栈里 如果越界访问修改了刚刚压入的这个地址，当这个地址出栈后就和该变量的真正地址不一致了 而在编译器的优化下，printf打印的可能就是这个刚刚出栈的错误地址  刻意去写这种功能，在c/c++层面上是写不出来的，因为编译器如何编译优化代码，这不是你该管的事 但编译器保证了合理的代码能够得到合理的结果，如果结果不合理，那就是代码不合理，此时懂一些底层的知识，就有助于你分析代码到底出了什么问题

user: user-0
content: 我们这边没有运行环境，所以没有办法调试。 只是客户在测的时候出现了这个问题 该程序中没有多进程和多线程  如果是a的值被修改，那肯定是某个变量越界了 现在是a的地址被修改，什么时候能修改到变量的地址呢 就算让我写，我也写不出来修改变量地址的代码

user: user-3
content: To set a breakpoint when a variable changes value   From the Edit menu, click Breakpoints.   Click the Data tab of the Breakpoints dialog box.   In the Expression text box, type the name of the variable.   Click OK to set the breakpoint.

user: user-4
content: 很大的可能是栈写越界, 导致a的值被修改.  a的前后有什么什么变量

user: user-1
content: 我觉得这是不是多线程导致的，也就是说printf("%x", &a); //此处结果为878f7592 ， 这是另一个线程打印出来的结果。  lz可以在printf里面多打印一下线程号看看是不是同一个线程

user: user-2
content: func_sub有局部变量越界访问，导致堆栈操作出问题了吧 应该没超出你所知的C语言范畴，只是存在你没发现的错误而已

user: user-5
content: 我要是说不可能LZ信不？ 用debugger跟跟吧。

user: user-6
content: Amazing，也许是堆栈出现了某种未知的错误 c确实会遇到一些吊诡的问题，我也遇到过，很遗憾，对底层认知有限，没办法正面解决 不过这种情况下看汇编是个不错的选择

user: user-7
content: 建议楼主用gdb或VS单步调试一下。
user-0 提问: c语言使用hash表的一些问题，懂hash的大神帮忙看看

回复:
user: user-1
content: 引用 3 楼 Mr_micro 的回复:引用 2 楼 zhao4zhong1 的回复:搜“暴雪哈希”。   我这个代码是最基础的，看那个太浪费时间，如果您能帮忙解决最好，解决不了的话请不要浪费楼层 虽然我想把你的ID拉入我回帖的黑名单，但我懒得拉。

user: user-0
content: 引用 4 楼 user-3 的回复:你这么多注释，运行到哪个注释出错？    可能是我说的不清楚， 感谢您的帮忙， 现在问题已经解决了，是由于我没有为key 和 ord分配内存造成了

user: user-0
content: 引用 6 楼 todo9351 的回复:可以用print 再详细定位的， 检查一下是否有初始化什么的。问题已经解决了，谢谢帮忙

user: user-2
content: 可以用print 再详细定位的， 检查一下是否有初始化什么的。

user: user-3
content: 你这么多注释，运行到哪个注释出错？

user: user-0
content: 引用 2 楼 zhao4zhong1 的回复:搜“暴雪哈希”。   我这个代码是最基础的，看那个太浪费时间，如果您能帮忙解决最好，解决不了的话请不要浪费楼层

user: user-1
content: 搜“暴雪哈希”

user: user-0
content: 补充一下，函数 unsigned Hash(KeyType K)  和 void collision(int *p,int d) 本程序用不到，忽略这个就成