Question: c语言指针p等不等于&p

&p相当于**p.p里面存放的是p指向的那个变量的地址,对p取地址找到的是存放指针变量p的这个内存单元的地址

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

不对，你已经定义了指针p，那么&p应该是相当于**p，也就是二级指针，相当于一个新的指针来指向*p的地址。可以自己画一下指向的框架就很清楚了。

推荐参考书： 《深入理解C指针》

指针就是地址 差不多是对的，不完全对，因为指针还有类型，同一个地址，用int *解析它，还是char *解析它，还是struct Student *解析，是各不相同的。  楼主应该了解内存，比如系统有1M的内存（打个比方），就是1024x1024个字节，你可以想象成100万（多）个格子，每个格子都有编号（从0开始），编号就是地址。比如int i，i变量被分配在编号为第100~103个格子（分配的位置是由系统决定的），如果赋值i=10，那么这4个格子里面存储的就是 00000000 00000000 00000000 00001010（等于整数10，这里还有内存字节序的问题，可以先不管），i的地址，就是&i，等于100（编号）。如果有一个int* p，p是一个指针变量，p变量被分配在编号为第104~107个格子，如果赋值p=&i，那么这4个格子里面存储的就是 00000000 00000000 00000000 01100100 （等于整数100），也就是p==100，p变量本身的地址，也就是&p，等于104。  常量，比如const int i=100，是不为i分配空间的，程序编译的时候自动把使用i的地方用100代替。 const char *str="Hello,world", "Hello,world"字符串字面量位于进程内存空间中的文字常量区，比如分配在编号第200~211个格子（每个格子存一个字符，最后有一个'\0'是自动添加的），如果用printf("%p:%s",str,str)输出，结果就是200:Hello,world，200表示str变量指向的地址，str变量可能被分配在108~111个格子（这4个格子里面存的值就等于200），而str变量的地址&str==108。

As you wish

p=&p不对，因为&p是指p本身的地址，而p里面的地址是指指向它的内容的地址并不是它自己本身的地址

#include <stdio.h>   int main(void) {     int a = 5;     int *p = &a;     int **q = &p;       printf("*p = %d, **q = %d\n", *p, **q);      printf("&a = %p, p = %p, &p = %p, q = %p\n", &a, p, &p, q);      return 0; } 以上是用于验证自己想法的一个小程序，可以运行验证一下； p和&p是不相等的。 首先，每个变量在内存中都有自己的存储空间，指针变量也是，只是存储的数据类型不一样，有的存储的是数据值，有的存储的就是地址值； 比如p 指向了变量a，那么指针变量里存储地址，就是a的内存地址；&p是指p变量本身的地址，即指针变量p在内存中的地址。

你可以这么理解，这个里面有两块儿内存，四个值，这四个值分别是两块儿内存的地址和里面放的两个数 第一块儿内存，地址为&p，里面儿放的是p，这是一个指针，即里面儿放的p代表了另一个内存地址 第二块儿内存，地址为p，也就是上面那个指针指向的的地方，而里面面放的是*p，这个不一定是啥类型，是指针指向的那个东西 可见，第一块儿内存里放的东西和第二块儿内存的地址其实是相同的值，即四个值其实是3个，这也就是指针的意思

指针也是变量，也需要内存存储。只不过存储的是一个地址。

p = &(*p)


Question: 自学C语言 遇到段错误  为什么  怎么解决啊！

字符串是使用gets或者fgets得到的。getchar得到的是字符，是字符串的子集。字符没有\0，所以在找\0时会越界访问，导致段错误。 建议先申请字符数组，然后使用scanf, %s或者fgets(gets不安全，不建议使用）从终端得到一个字符串。

getchar()得到的是字符，不是字符串。

谢谢哈 懂了

strlen 接受的参数类型是char* 不是int  还有strlen换个名字，跟标准库的名字冲突了


Question: 冒泡排序法求解

#include<stdio.h>  /* 冒泡排序*/ void bubble_sort(int *arr, int len); /*选择排序*/ void select_sort(int *arr, int len);  int main(void) {     int a[] = {11,33,55,88,99,44,66,77,22,0};     int n = sizeof(a) / sizeof(a[0]);     int i;      //bubble_sort(a, n);     select_sort(a, n);      for (i = 0; i < n; i++)         printf("%4d",a[i]);     printf("\n");      return 0; }  void bubble_sort(int *arr, int len) {     int i, j;     int tmp;      for (i = 0; i < len - 1; i++)         for (j = 0; j < len - 1 - i; j++)             if (arr[j] < arr[j+1]) {                 tmp = arr[j];                 arr[j] = arr[j+1];                 arr[j+1] = tmp;             } }  void select_sort(int *arr, int len) {     int i, j, max_i;     int tmp;      for (i = 0; i < len - 1; i++) {         max_i = i;         for (j = i+1; j < len; j++)             if (arr[j] > arr[max_i])                 max_i = j;         if (max_i != i) {                 tmp = arr[max_i];                 arr[max_i] = arr[i];                 arr[i] = tmp;         }     } } 你的程序像选择排序，是不是搞混了？！ 以上是我的demo，有选择有冒泡，作为一个参考吧；

手动debug一下吧，你就知道哪里错了。

你这整个逻辑都有问题，你排序没有元素的交换，区间的错误等等 这不是单纯的一两处小的错误，是大方面和小方面均有不少问题  你去搜索下冒泡排序的算法和它的c语音实现代码，参考别人的之后再试着自己写一个

我也是初学者，感觉这个算法不论不类，简单选择和冒泡混了貌似…两个for循环不断使数组元素和max比较没有意义…这是我的看法。


Question: codeblocks中文乱码怎么解决

重新敲一遍就可以了，文件格式有点问题吧


Question: 求教帖-一个简单但是我不会的循环问题

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

oo,谢谢各位，看出来了。不仅没写对，题目也看错了.......

题目要求的是用迭代法，你这用的是递归啊，老兄

你的代码里面 当n=1时候 直接就求出平方根了...那还算个什么呢？ 所以 直接 n=1时候 y=a；n>1再按公式算； 然后 题目 里面 都说了 俩值差的绝对值<e ，而你直接让差值<e(我试了几次，应该你现在 这么算的第一个差值 直接是负数，然后x根本就没赋值....所以就出现你现在的这个情况了。  你再想想吧。

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

#include <stdio.h> #include <math.h>  #define MIN_DIFF    (1e-5) #define FZERO       (1e-6)  int main(void) {     float a, prev, cur;     int i;      printf("Please input a number: ");     scanf("%f", &a);      if (fabsf(a) <= FZERO) {         printf("%f sqrt is %.5f\n", a, 0.0);         return 0;     }     prev = 1.0;     cur = (prev + a / prev) / 2;     for (i = 0; fabsf(cur - prev) >= MIN_DIFF; i++) {         prev = cur;         cur = (prev + a / prev) / 2;     }      printf("%.2f sqrt is %.5f\n", a, cur);     return 0; }   循环求平方根。 以上的代码测试通过，作为一个参考吧～

你这是递归吧..


Question: 关于C语言指针用法的问题

引用 13 楼 lin5161678 的回复:[quote=引用 10 楼 xiao969856 的回复:] [quote=引用 9 楼 lin5161678 的回复:] [quote=引用 8 楼 xiao969856 的回复:] [quote=引用 7 楼 lin5161678 的回复:] 贴错误提示   i[str] 的意思是 str[i] == *(str+i) == *(i+str) == i[str] 无聊的边枝末节  除了卖萌 我没见过其他用处 我重点是想知道cout<<str[i]<<'\n';这句代码的原理和用法，重点是“<<”这个运算符的应用原理，不是下面那段程序，弄明白使用方法我自己就能改[/quote] 哦 看书 重点内容  cin 和 类运算符重载[/quote] 哦哦，谢谢，顺便问一下这是C语言里的还是C++的，能用在Linux编程里吗？[/quote] 这是C++ 当然可以在Linux里面用 只要你有一个C++的编译器[/quote] 谢谢

引用 5 楼 cfjtaishan 的回复:第一点，应该是使用str[i]输出； 第二点，建议字符串使用strlen(str);如果字符串是char *str = "helloworld";这个程序就不能正常输出了。 另外，cout输出确定是C语言的语法？我咋看着是C++的输出格式呢？还是现在的编译器强大了，混编都可以？！ 应该不是C的，这是在网上找的一段关于指针用法的代码，在Linux上运行没结果没结果所以过来问问，我主要是想问cout<<str[i]<<'\n';这句代码的原理和用法

引用 10 楼 xiao969856 的回复:[quote=引用 9 楼 lin5161678 的回复:] [quote=引用 8 楼 xiao969856 的回复:] [quote=引用 7 楼 lin5161678 的回复:] 贴错误提示   i[str] 的意思是 str[i] == *(str+i) == *(i+str) == i[str] 无聊的边枝末节  除了卖萌 我没见过其他用处 我重点是想知道cout<<str[i]<<'\n';这句代码的原理和用法，重点是“<<”这个运算符的应用原理，不是下面那段程序，弄明白使用方法我自己就能改[/quote] 哦 看书 重点内容  cin 和 类运算符重载[/quote] 哦哦，谢谢，顺便问一下这是C语言里的还是C++的，能用在Linux编程里吗？[/quote] 这是C++ 当然可以在Linux里面用 只要你有一个C++的编译器

引用 3 楼 a393062456 的回复:楼主需要去看C或C++基础 正在学指针这块的内容

楼主需要去看C或C++基础

引用 1 楼 jianwen0529 的回复:改为 cout<<str[i]<<'\n';  str是数组，i是下标索引 并没有效果，没有输出

引用 11 楼 zhao4zhong1 的回复:http://www.cplusplus.com/reference/ostream/ostream/operator-free/index.html 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 谢谢

引用 9 楼 lin5161678 的回复:[quote=引用 8 楼 xiao969856 的回复:] [quote=引用 7 楼 lin5161678 的回复:] 贴错误提示   i[str] 的意思是 str[i] == *(str+i) == *(i+str) == i[str] 无聊的边枝末节  除了卖萌 我没见过其他用处 我重点是想知道cout<<str[i]<<'\n';这句代码的原理和用法，重点是“<<”这个运算符的应用原理，不是下面那段程序，弄明白使用方法我自己就能改[/quote] 哦 看书 重点内容  cin 和 类运算符重载[/quote] 哦哦，谢谢，顺便问一下这是C语言里的还是C++的，能用在Linux编程里吗？

引用 8 楼 xiao969856 的回复:[quote=引用 7 楼 lin5161678 的回复:] 贴错误提示   i[str] 的意思是 str[i] == *(str+i) == *(i+str) == i[str] 无聊的边枝末节  除了卖萌 我没见过其他用处 我重点是想知道cout<<str[i]<<'\n';这句代码的原理和用法，重点是“<<”这个运算符的应用原理，不是下面那段程序，弄明白使用方法我自己就能改[/quote] 哦 看书 重点内容  cin 和 类运算符重载

引用 7 楼 lin5161678 的回复:贴错误提示   i[str] 的意思是 str[i] == *(str+i) == *(i+str) == i[str] 无聊的边枝末节  除了卖萌 我没见过其他用处 我重点是想知道cout<<str[i]<<'\n';这句代码的原理和用法，重点是“<<”这个运算符的应用原理，不是下面那段程序，弄明白使用方法我自己就能改

改为 cout<<str[i]<<'\n';  str是数组，i是下标索引


Question: 宏定义用##组合标识符

宏替换 是在预处理阶段就要展开的，  也就是说是在编译代码之前，宏替换就已经完成了  而在编译之前，编译器怎么能知道你的 一个变量‘j’ 到底是几呢？

你需要 NNAME(0) NNAME(1) NNAME(2) NNAME(3) ...

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

定义数组不好么？

for(j=0;j<10;j++)     printf("%d ",nj);     //这是预处理后的代码，肯定不能执行啊


Question: C语言选择排序

//n为数组大小，m为从第几个开始排序 void selectsort(char (*a)[23], int n, int m) {     char swap[23]; /* 建议大小为23个字节*/     int min;     int i,j;     for (i = m; i < n - 1; i++) {         min = i;         for (j = i + 1; j < n; j++) {             if (strcmp(a[min], a[j]) > 0)                 min=j;         if (min > i) {             strcpy(swap, a[min]);             strcpy(a[min], a[i]);             strcpy(a[i], swap);         }     } } 从你的选择排序处理上看是字符串排序； 另外，你说从11个开始，是指从第11行（二维数组）开始，还是从每行的11字符开始？ 过从第11行开始，如果数组总共是1行，那肯定是越界了。如果是从11个字符开始，前面的字符会影响排序结果。

引用 2 楼 Butterfly_lily1204 的回复:[quote=引用 1 楼 cyfcsd 的回复:] 代码没问题，是不是你传入的实参有问题  #include <stdio.h> #include <string.h>   void selectsort(char a[][23],int n,int m){//n为数组大小，m为从第几个开始排序     int min;     char swap[10];     int i,j;     for(i=m;i<n-1;i++){         min=i;        	for(j=i+1;j<n;j++){      	    if (strcmp(a[min], a[j]) > 0)                 min=j;         }         if(min>i){      	    strcpy(swap, a[min]);                                                                  strcpy(a[min], a[i]);             strcpy(a[i], swap);        	}     } } int main() {      char arr[5][23] = {"abc", "bac", "cab", "cba", "acb"};     selectsort(arr,5,0);     for(int i=0; i<5; i++){         printf("%s ", arr[i]);     }     return 0; }  如有问题欢迎继续追问，没问题请及时结贴，谢谢  实参是没问题的，我不知是不是数组在进行字母排序前遇到了'\0'，所以不往后操作了，因为我的数组定义为num[10][23]，并且经过了处理，前10个都是空的，从第11 个开始才有数据。[/quote] 字母排序？你说的是字符串排序吧，字母排序这个程序就不对了，这是字符串排序的，也就是排序的单位是字符串，不是字母 前面是空的是每个字符串前面都是'\0'吗，是“\0\0\0\0\0\0\0abc\0”这种格式的吗？这种字符串也可以操作，strcmp的时候跳过前面的空就可以了，strcpy的时候也要对应改一下，但这样太不方便了，所有字符串函数都要改动

引用 1 楼 cyfcsd 的回复:代码没问题，是不是你传入的实参有问题  #include <stdio.h> #include <string.h>   void selectsort(char a[][23],int n,int m){//n为数组大小，m为从第几个开始排序     int min;     char swap[10];     int i,j;     for(i=m;i<n-1;i++){         min=i;        	for(j=i+1;j<n;j++){      	    if (strcmp(a[min], a[j]) > 0)                 min=j;         }         if(min>i){      	    strcpy(swap, a[min]);                                                                  strcpy(a[min], a[i]);             strcpy(a[i], swap);        	}     } } int main() {      char arr[5][23] = {"abc", "bac", "cab", "cba", "acb"};     selectsort(arr,5,0);     for(int i=0; i<5; i++){         printf("%s ", arr[i]);     }     return 0; }  如有问题欢迎继续追问，没问题请及时结贴，谢谢  实参是没问题的，我不知是不是数组在进行字母排序前遇到了'\0'，所以不往后操作了，因为我的数组定义为num[10][23]，并且经过了处理，前10个都是空的，从第11 个开始才有数据。


Question: 求大佬们帮个忙，帮我编写下一个小程序。

引用 4 楼 cyfcsd 的回复:[quote=引用 2 楼 ylkanke 的回复:] [quote=引用 1 楼 cyfcsd 的回复:]  #include <iostream>  using namespace std;   int main() {     int i = 2147483647;     cout<<i<<endl;     i = 2147483647 + 1;     cout<<i<<endl;     double d = 1.79E+308;     cout<<d<<endl;     d = 1.79E+308 + 0.01E+308;     cout<<d<<endl;     d = -1.79E+308;     cout<<d<<endl;     d = -1.79E+308 - 0.01E+308;     cout<<d<<endl;     return 0; }  大佬，在下愚钝，虽然程序可以运行，可是您写的程序可以让我借鉴去理解的地方太少了，主要都太深奥了，我看不懂！！！！！[/quote] 这个原理说来话长啊，可以写一章了，你得了解数字在机器内部的表示方法，原码、补码这些，浮点数还要知道指数和尾数等等 简单可以这么理解，整数上溢就是超过了它的表示范围，比如四位二级制，一位符号位，那么它能表示的数是-8到7，每一个数都对应一个唯一的四位二进制编码，7对应0111，当把数字8装进去的时候，相当于把1000放了进去，但这个数肯定不是8了，对应-7到8的另一个数了。浮点数也差不多，但不会出现“循环”，一般超出范围后编译器会报错[/quote] 要学习的东西还有很多啊，要加把劲了，谢谢大佬。

亲自打开include\float.h一眼。

浮点数格式 http://bbs.csdn.net/topics/390676437

引用 2 楼 ylkanke 的回复:[quote=引用 1 楼 cyfcsd 的回复:]  #include <iostream>  using namespace std;   int main() {     int i = 2147483647;     cout<<i<<endl;     i = 2147483647 + 1;     cout<<i<<endl;     double d = 1.79E+308;     cout<<d<<endl;     d = 1.79E+308 + 0.01E+308;     cout<<d<<endl;     d = -1.79E+308;     cout<<d<<endl;     d = -1.79E+308 - 0.01E+308;     cout<<d<<endl;     return 0; }  大佬，在下愚钝，虽然程序可以运行，可是您写的程序可以让我借鉴去理解的地方太少了，主要都太深奥了，我看不懂！！！！！[/quote] 这个原理说来话长啊，可以写一章了，你得了解数字在机器内部的表示方法，原码、补码这些，浮点数还要知道指数和尾数等等 简单可以这么理解，整数上溢就是超过了它的表示范围，比如四位二级制，一位符号位，那么它能表示的数是-8到7，每一个数都对应一个唯一的四位二进制编码，7对应0111，当把数字8装进去的时候，相当于把1000放了进去，但这个数肯定不是8了，对应-7到8的另一个数了。浮点数也差不多，但不会出现“循环”，一般超出范围后编译器会报错

小弟到处询问之后，有一位和我是看同一本书的大佬给我这个答案参考，希望大佬能解答下我的疑惑。 #include<stdio.h> int main(void) { 	int i = 2147483647;     这些和我的答案都差不多下面我就比较疑惑。 	float a = 3.4e38*100.0f;    为什么要*100.0f  后面的.0f是什么 	float b = -0.1234e-10 / 10.0f;  这里的/10.f我也很费解 	printf("%d %d %d\n", i, i + 1, i + 2);  这里的 i+1 i+2 我也搞不懂，可能我的确比较笨， 希望有个有耐心的大佬解答下。 	printf("%f\n", a); 	printf("%f\n", b); 	return 0; } 小弟到处询问之后，有一位和我是看同一本书的大佬给我这个答案参考，希望

引用 1 楼 cyfcsd 的回复: #include <iostream>  using namespace std;   int main() {     int i = 2147483647;     cout<<i<<endl;     i = 2147483647 + 1;     cout<<i<<endl;     double d = 1.79E+308;     cout<<d<<endl;     d = 1.79E+308 + 0.01E+308;     cout<<d<<endl;     d = -1.79E+308;     cout<<d<<endl;     d = -1.79E+308 - 0.01E+308;     cout<<d<<endl;     return 0; }  大佬，在下愚钝，虽然程序可以运行，可是您写的程序可以让我借鉴去理解的地方太少了，主要都太深奥了，我看不懂！！！！！


Question: 求出二维数组每行的最大数

既然是二维数组就应该是a[i][j];这样来表示吧？  然后：按你现在这么写，user_row  =3没错，但是 user_col 它等于3，那么j就可以取值2，j+1就会等于3，你这个数据中数组没有a[i][3]， 这里会出错，我用vs2013过不了编译器, 需要把两个if 语句块的顺序颠倒下  #define user_row 3 #define user_col 3 	int a[3][3] = { { 8, 6, 4 }, { 5, 9, 3 }, { 2, 10, 7 } };  	int t, max; 	for(int i = 0; i < user_row; i++)    //judge max number,select min number 	{ 		for (int j = 0; j < user_col; j++) 		{  			if (j == (user_col - 1)) 			{ 			max = a[i][j];	 			printf("%d  \n", max);             continue; 			} 			if (a[i][j] > a[i][j + 1]) 			{ 				t = a[i][j]; 				a[i][j] = a[i][j + 1]; 				a[i][j + 1] = t; 				 			}  			 		} 	}

#include <stdio.h> #include <stdlib.h> #include <time.h>  void malloc_arr(int ***arr, int row, int col); void init_arr(int ***arr, int row, int col); void  get_max_list(int *max_list, int **arr, int row, int col); void destroy_arr(int **arr, int row); void print_arr(int **arr, int row, int col);  int main(void) {     int row, col, i;     int **arr = NULL, *max_list;      printf("Please input your row number: ");     scanf("%d", &row);     printf("Please input your col number: ");     scanf("%d", &col);     malloc_arr(&arr, row, col);     max_list = (int *)malloc(row * sizeof(int));     if (!max_list) {         fprintf(stderr, "malloc error!\n");         exit(0);     }      init_arr(&arr, row, col);     print_arr(arr, row, col);     get_max_list(max_list, arr, row, col);      for (i = 0; i < row; i++)         printf("No.%d: max is %d\n", i+1, max_list[i]);      destroy_arr(arr, row);     free(max_list);       return 0; }   void malloc_arr(int ***arr, int row, int col) {     int i;      *arr = (int **)malloc(row * sizeof(int *));     if (!(*arr)) {         fprintf(stderr, "malloc error!\n");         exit(0);     }     for (i = 0; i < row; i++) {         (*arr)[i] = (int *)malloc(col * sizeof(int));         if (!(*arr)[i]) {             fprintf(stderr, "malloc error!\n");             exit(0);         }     } }  void destroy_arr(int **arr, int row) {     int i;      for (i = 0; i < row; i++)         free(arr[i]);     free(arr); }  void init_arr(int ***arr, int row, int col) {     int i, j;      srand(time(NULL));     for (i = 0; i < row; i++)         for (j = 0; j < col; j++)             (*arr)[i][j] = rand() % 200; }  void  get_max_list(int *max_list, int **arr, int row, int col) {     int i, j, max = 0;      for (i = 0; i < row; i++) {         max = arr[i][0];         for (j = 1; j < col; j++) {             if (max < arr[i][j])                 max = arr[i][j];         }         max_list[i] = max;     } }  void print_arr(int **arr, int row, int col) {     int i, j;      for (i = 0; i < row; i++) {         printf("No.%d\n", i+1);         for (j = 0; j < col; j++)             printf("%d ", arr[i][j]);         putchar(10);     } } 作为一个参考吧～


Question: 用二分法求根的问题

The upstairs is niubility.

仅供参考：//用C语言编程，求出2^x=x^10这个方程的解。 #include <math.h> #include <stdio.h> double x,e; void main () {     x=-1.0;     e=0.001;     while (1) {         while (1) {             if (pow(2.0,x)<pow(x,10.0)) {                 x+=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;         while (1) {             if (pow(2.0,x)>pow(x,10.0)) {                 x-=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;     }     printf("%+.14g\n",x);      x=1.0;     e=0.001;     while (1) {         while (1) {             if (pow(2.0,x)>pow(x,10.0)) {                 x+=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;         while (1) {             if (pow(2.0,x)<pow(x,10.0)) {                 x-=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;     }     printf("%+.14g\n",x); }


Question: C语言编程出现这个问题！求大家帮忙看看是怎么回事~谢谢了program stopped at 0x4015c4.It stopped with signal S

引用 8 楼 jjaisgm 的回复:[quote=引用 7 楼 user-2 的回复:] [quote=引用 6 楼 jjaisgm 的回复:] [quote=引用 5 楼 user-2 的回复:] [quote=引用 4 楼 jjaisgm 的回复:] [quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小     空间分配不够[/quote]  引用 5 楼 user-2 的回复:[quote=引用 4 楼 jjaisgm 的回复:] [quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~[/quote]  空间分配不够[/quote]   那 T.mat= (char**)malloc(m*sizeof(char*)*128);  是这样扩大内存空间么？[/quote]  我说是T.mat[i]那句，不是T.mat  你可以自己单步跟踪程序运行分析原因[/quote]  您好,我还是没弄明白`````我内存分配这里学的很不好,请问您能否详细的帮我解释一下呢?谢谢您了!

引用 11 楼 jjaisgm 的回复:[quote=引用 10 楼 cfjtaishan 的回复:] # include <stdio.h> # include <string.h> # include <malloc.h>  typedef struct {     char **mat;     int m, n; }martix;  void initial(martix &T,int m,int n) {     int i;     T.mat= (char**)malloc(m * sizeof(char*));      for(i = 0; i < m; i++)     {         T.mat[i] = (char *)malloc(n*sizeof(char));     }     T.m = m;     T.n = n; }  void initZero(martix &T,int m,int n) {     int i,j;      initial(T, m, n);      for(i = 0; i < m; i++)     {         for(j = 0; j < n; j++)         {             T.mat[i][j]=0;         }     } }  void destroy(martix T) {     int i;      for(i = 0; i < T.m; i++)         free(T.mat[i]);     free(T.mat); }    int main() {     int i, j, k, n;     int clen, klen;      char ciphertext[100];     char key[200];      martix T;        printf("请输入明文：\n");     scanf("%s", ciphertext);     printf("请输入密钥：\n");     scanf("%s", key);      clen = strlen(ciphertext);     klen = strlen(key);      if(clen % klen == 0)         k = clen / klen;     else         k = clen / klen + 1;      printf("clen = %d\t, klen = %d, k = %d\n", clen, klen, k);     //initial(T, k, klen);  /* swap second param with the third*/     initZero(T, k,  klen); /* swap second param with the third*/      strcat(key, ciphertext);     printf("%s\n",key);      for(i = 0; i < k; i++)     {         for(j = 0; j < klen; j++)         {             n = i * klen + j;             T.mat[i][j] = key[n];             printf("%c ", T.mat[i][j]);         }         printf("\n");     }     destroy(T);      return 0; }  用这个吧，上面那个还有点瑕疵[/  您好.这个代码我试了,还是不能正常运行,会出现却结果的现象,而且还会停止运行````其实我想知道怎么能扩大分配的内存,感觉我分配多大的内存空间都不够````

[quote=引用 10 楼 cfjtaishan 的回复:] # include <stdio.h> # include <string.h> # include <malloc.h>  typedef struct {     char **mat;     int m, n; }martix;  void initial(martix &T,int m,int n) {     int i;     T.mat= (char**)malloc(m * sizeof(char*));      for(i = 0; i < m; i++)     {         T.mat[i] = (char *)malloc(n*sizeof(char));     }     T.m = m;     T.n = n; }  void initZero(martix &T,int m,int n) {     int i,j;      initial(T, m, n);      for(i = 0; i < m; i++)     {         for(j = 0; j < n; j++)         {             T.mat[i][j]=0;         }     } }  void destroy(martix T) {     int i;      for(i = 0; i < T.m; i++)         free(T.mat[i]);     free(T.mat); }    int main() {     int i, j, k, n;     int clen, klen;      char ciphertext[100];     char key[200];      martix T;        printf("请输入明文：\n");     scanf("%s", ciphertext);     printf("请输入密钥：\n");     scanf("%s", key);      clen = strlen(ciphertext);     klen = strlen(key);      if(clen % klen == 0)         k = clen / klen;     else         k = clen / klen + 1;      printf("clen = %d\t, klen = %d, k = %d\n", clen, klen, k);     //initial(T, k, klen);  /* swap second param with the third*/     initZero(T, k,  klen); /* swap second param with the third*/      strcat(key, ciphertext);     printf("%s\n",key);      for(i = 0; i < k; i++)     {         for(j = 0; j < klen; j++)         {             n = i * klen + j;             T.mat[i][j] = key[n];             printf("%c ", T.mat[i][j]);         }         printf("\n");     }     destroy(T);      return 0; }  用这个吧，上面那个还有点瑕疵[/   非常感谢您!我学习学习您的代码再来请教!

# include <stdio.h> # include <string.h> # include <malloc.h>  typedef struct {     char **mat;     int m, n; }martix;  void initial(martix &T,int m,int n) {     int i;     T.mat= (char**)malloc(m * sizeof(char*));      for(i = 0; i < m; i++)     {         T.mat[i] = (char *)malloc(n*sizeof(char));     }     T.m = m;     T.n = n; }  void initZero(martix &T,int m,int n) {     int i,j;      initial(T, m, n);      for(i = 0; i < m; i++)     {         for(j = 0; j < n; j++)         {             T.mat[i][j]=0;         }     } }  void destroy(martix *T) {     int i;      for(i = 0; i < T->m; i++)         free(T->mat[i]);     free(T->mat); }    int main() {     int i, j, k, n;     int clen, klen;      char ciphertext[100];     char key[200];      martix T;        printf("请输入明文：\n");     scanf("%s", ciphertext);     printf("请输入密钥：\n");     scanf("%s", key);      clen = strlen(ciphertext);     klen = strlen(key);      if(clen % klen == 0)         k = clen / klen;     else         k = clen / klen + 1;      printf("clen = %d\t, klen = %d, k = %d\n", clen, klen, k);     //initial(T, k, klen);  /* swap second param with the third*/     initZero(T, k,  klen); /* swap second param with the third*/      strcat(key, ciphertext);     printf("%s\n",key);      for(i = 0; i < k; i++)     {         for(j = 0; j < klen; j++)         {             n = i * klen + j;             T.mat[i][j] = key[n];             printf("%c ", T.mat[i][j]);         }         printf("\n");     }     destroy(T);      return 0; }  两个问题： 1.输入明文和密码时，把前面的&去掉，数组名本身就是地址； 2.交换一下initZero函数后两个实参的位置，注意申请空间的时候先申请的是行数，后申请的是列。不交换就会出现越界； 另外，改了一下两个变量名。i,j是用于作为循环变量的。在main函数里初始化操作不用调用，因为在初始化0时会先初始化。

引用 7 楼 user-2 的回复:[quote=引用 6 楼 jjaisgm 的回复:] [quote=引用 5 楼 user-2 的回复:] [quote=引用 4 楼 jjaisgm 的回复:] [quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~[/quote]  空间分配不够[/quote]  引用 5 楼 user-2 的回复:[quote=引用 4 楼 jjaisgm 的回复:] [quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~[/quote]  空间分配不够[/quote]   那 T.mat= (char**)malloc(m*sizeof(char*)*128);  是这样扩大内存空间么？[/quote]  我说是T.mat[i]那句，不是T.mat  你可以自己单步跟踪程序运行分析原因[/quote]  嗯嗯~我再仔细看看~真的很感谢您~

引用 6 楼 jjaisgm 的回复:[quote=引用 5 楼 user-2 的回复:] [quote=引用 4 楼 jjaisgm 的回复:] [quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~[/quote]  空间分配不够[/quote]  引用 5 楼 user-2 的回复:[quote=引用 4 楼 jjaisgm 的回复:] [quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~[/quote]  空间分配不够[/quote]   那 T.mat= (char**)malloc(m*sizeof(char*)*128);  是这样扩大内存空间么？[/quote]  我说是T.mat[i]那句，不是T.mat  你可以自己单步跟踪程序运行分析原因

引用 5 楼 user-2 的回复:[quote=引用 4 楼 jjaisgm 的回复:] [quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~[/quote]  空间分配不够[/quote]  引用 5 楼 user-2 的回复:[quote=引用 4 楼 jjaisgm 的回复:] [quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~[/quote]  空间分配不够[/quote]   那 T.mat= (char**)malloc(m*sizeof(char*)*128);  是这样扩大内存空间么？

引用 4 楼 jjaisgm 的回复:[quote=引用 3 楼 user-2 的回复:] 使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~[/quote]  空间分配不够

引用 3 楼 user-2 的回复:使用堆内存越界了  T.mat[i] = (char *)malloc(n*sizeof(char)); 运行到这里你的n为1，也就是只分配了一个字符的大小  请问应该怎么改呢？这不就是在用malloc分配内存空间么？谢谢您~

通过debug，我发现出错位置在 在第二次大循环结束后，就崩掉了····求大神们指点！！！

这是错误弹出的的对话框


Question: 【请大家帮我看看这个情况是怎么回事？？】

p1是局部变量，，，，

void ClearList(SN **n) {     SN *p1 = *n, *p2;      while (p1) {         p2 = p1->next;         free(p1);         p1 = NULL;         p1 = p2;     }     *n = NULL; } 释放空间并将头节点赋值为NULL；

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=v;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=v;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

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


Question: 帮忙看看是哪个位置问题呢?

引用 3 楼 weixin_37671669 的回复:[quote=引用 1 楼 jianwen0529 的回复:] int main(void)  ; //多了个分号  还有你源.cpp是不是也有一个main函数？ 一个工程只能有一个入口main函数，你把其中一个不要的删除或者注释掉 是不是我源1.cpp里面带了main导致没法运行吗?一个源文件里面只能有一个源.cpp么?[/quote]  不是一个源文件只能有一个main函数，是一个程序只能有一个main  你把main（）后面的分号去掉，然后删除一个cpp就可以了

引用 1 楼 jianwen0529 的回复:int main(void)  ; //多了个分号  还有你源.cpp是不是也有一个main函数？ 一个工程只能有一个入口main函数，你把其中一个不要的删除或者注释掉 是不是我源1.cpp里面带了main导致没法运行吗?一个源文件里面只能有一个源.cpp么?

int main() { } 或者 int main(void) { }


Question: 操作系统怎么检测栈溢出的呢？有什么保护机制吗？

有的时候写出去了也未必会检测到的。

C/C++ COMPILER OPTIONS                                 -OPTIMIZATION-  /O1 minimize space                      /O2 maximize speed /Ob<n> inline expansion (default n=0)   /Od disable optimizations (default) /Og enable global optimization          /Oi[-] enable intrinsic functions /Os favor code space                    /Ot favor code speed /Ox maximum optimizations               /Oy[-] enable frame pointer omission                               -CODE GENERATION-  /GF enable read-only string pooling     /Gm[-] enable minimal rebuild /Gy[-] separate functions for linker    /GS[-] enable security checks /GR[-] enable C++ RTTI                  /GX[-] enable C++ EH (same as /EHsc) /EHs enable C++ EH (no SEH exceptions)  /EHa enable C++ EH (w/ SEH exceptions) /EHc extern "C" defaults to nothrow /fp:<except[-]|fast|precise|strict> choose floating-point model:     except[-] - consider floating-point exceptions when generating code     fast - "fast" floating-point model; results are less predictable     precise - "precise" floating-point model; results are predictable     strict - "strict" floating-point model (implies /fp:except) /GL[-] enable link-time code generation /GA optimize for Windows Application /Ge force stack checking for all funcs  /Gs[num] control stack checking calls /Gh enable _penter function call        /GH enable _pexit function call /GT generate fiber-safe TLS accesses    /RTC1 Enable fast checks (/RTCsu) /RTCc Convert to smaller type checks    /RTCs Stack Frame runtime checking /RTCu Uninitialized local usage checks /clr[:option] compile for common language runtime, where option is:     pure - produce IL-only output file (no native executable code)     safe - produce IL-only verifiable output file     oldSyntax - accept the Managed Extensions syntax from Visual C++ 2002/2003     initialAppDomain - enable initial AppDomain behavior of Visual C++ 2002     noAssembly - do not produce an assembly /Gd __cdecl calling convention          /Gr __fastcall calling convention /Gz __stdcall calling convention        /GZ Enable stack checks (/RTCs) /QIfist[-] use FIST instead of ftol() /hotpatch ensure function padding for hotpatchable images /arch:<SSE|SSE2> minimum CPU architecture requirements, one of:     SSE - enable use of instructions available with SSE enabled CPUs     SSE2 - enable use of instructions available with SSE2 enabled CPUs                                -OUTPUT FILES-  /Fa[file] name assembly listing file    /FA[scu] configure assembly listing /Fd[file] name .PDB file                /Fe<file> name executable file /Fm[file] name map file                 /Fo<file> name object file /Fp<file> name precompiled header file  /Fr[file] name source browser file /FR[file] name extended .SBR file /doc[file] process XML documentation comments and optionally name the .xdc file                                -PREPROCESSOR-  /AI<dir> add to assembly search path    /FU<file> forced using assembly/module /C don't strip comments                 /D<name>{=|#}<text> define macro /E preprocess to stdout                 /EP preprocess to stdout, no #line /P preprocess to file                   /Fx merge injected code to file /FI<file> name forced include file      /U<name> remove predefined macro /u remove all predefined macros         /I<dir> add to include search path /X ignore "standard places"                                  -LANGUAGE-  /Zi enable debugging information        /Z7 enable old-style debug info /Zp[n] pack structs on n-byte boundary  /Za disable extensions /Ze enable extensions (default)         /Zl omit default library name in .OBJ /Zg generate function prototypes        /Zs syntax check only /vd{0|1|2} disable/enable vtordisp      /vm<x> type of pointers to members /Zc:arg1[,arg2] C++ language conformance, where arguments can be:     forScope[-] - enforce Standard C++ for scoping rules     wchar_t[-] - wchar_t is the native type, not a typedef /ZI enable Edit and Continue debug info /openmp enable OpenMP 2.0 language extensions                                -MISCELLANEOUS-  @<file> options response file           /?, /help print this help message /bigobj generate extended object format /c compile only, no link /errorReport:option Report internal compiler errors to Microsoft     none - do not send report     prompt - prompt to immediately send report     queue - at next admin logon, prompt to send report (default)     send - send report automatically /FC use full pathnames in diagnostics   /H<num> max external name length /J default char type is unsigned        /nologo suppress copyright message /showIncludes show include file names   /Tc<source file> compile file as .c /Tp<source file> compile file as .cpp   /TC compile all files as .c /TP compile all files as .cpp           /V<string> set version string /w disable all warnings                 /wd<n> disable warning n /we<n> treat warning n as an error      /wo<n> issue warning n once /w<l><n> set warning level 1-4 for n    /W<n> set warning level (default n=1) /Wall enable all warnings               /WL enable one line diagnostics /WX treat warnings as errors            /Yc[file] create .PCH file /Yd put debug info in every .OBJ        /Yl[sym] inject .PCH ref for debug lib /Yu[file] use .PCH file                 /Y- disable all PCH options /Zm<n> max memory alloc (% of default)  /Wp64 enable 64 bit porting warnings                                  -LINKING-  /LD Create .DLL                         /LDd Create .DLL debug library /LN Create a .netmodule                 /F<num> set stack size /link [linker options and libraries]    /MD link with MSVCRT.LIB /MT link with LIBCMT.LIB                /MDd link with MSVCRTD.LIB debug lib /MTd link with LIBCMTD.LIB debug lib                           -CODE ANALYSIS-  /analyze[:WX-] enable code analysis     WX- - code analysis warnings should not be treated as errors even if /WX is invoked

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

《windows核心编程》专门有就这一问题展开说

由于用到了虚拟存储的技术，所以不会覆盖其他程序的，操作系统是按照页面给进程分配空间的，然后有两个指针指向栈区的开始和结束地址，这两个地址间的距离就是栈的大小，大概就是这个样子，要想彻底明白得去看看操作系统虚拟存储器这部分了

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。


Question: 新人求解答~指针问题

按照scanf的格式来输入。逗号后面不要加空格。

引用 6 楼 jianwen0529 的回复:scanf("%d,%d",&a,&b); 你的问题，你格式用的是 , （英文逗号），你输入的时候用的是中文逗号，不匹配导致b的输入失败 确实是这样！！懂了，谢谢~~~

引用 6 楼 jianwen0529 的回复:scanf("%d,%d",&a,&b); 你的问题，你格式用的是 , （英文逗号），你输入的时候用的是中文逗号，不匹配导致b的输入失败  够仔细........

引用 2 楼 eit520 的回复:没有问题。你再试下啊   void test() { 	int a, b; 	int *p, *q; 	scanf_s("%d,%d", &a, &b); 	p = &a; 	q = &b; 	printf_s("%d,%d\n", *p, *q); } int main() { 	test(); 	system("pause");//此函数是运行了一个系统命令，让命令行窗体暂停，此函数在stdlib.h  	return 0;  }   我是用codeblock，那么是编辑器的问题吗？

引用 1 楼 baidu_36581798 的回复: 我也是新手，看了下你的代码没发现问题...我复制过来 自己用也没发现你说的问题啊? scanf改scanf_s 是vs要求的，难道与这个有关系？还是你输入的时候 不小心没输入逗号啊？ 跟我的第二组数据一样？  我是用codeblock，那么是编辑器的问题吗？

我是用codeblock,那么是编辑器的问题吗？


Question: 两个小问题C语言

引用 4 楼 cfjtaishan 的回复:数组下标是从0开始，所以第0个就是我们平时所说的第一个。 第二个问题，我的方法比较直接： #include <stdio.h>  #define MAX_PEOPLE_NUM   30 #define MAX_MONEY   50  int main(void) {     int m, w, c;      for (m = 0; m <= (int)MAX_PEOPLE_NUM/3; m++) {         for (w = 0; w < MAX_PEOPLE_NUM/2; w++) {             for (c = 0; c <= MAX_PEOPLE_NUM/1; c++) {                 if (m + w + c == MAX_PEOPLE_NUM &&                         3 * m + 2 * w + c == MAX_MONEY)                     printf("Men: %2d, Women: %2d, Children: %2d\n",                             m, w, c);             }         }     }     return 0; }m,w,c应该分别小于等于MONEY/3   /2   /1,同时满足小于30，去最先小的一个。别的是正确的谢谢

[1] X = 0; Y = 20; Z = 10  X + Y + Z = 30 3X + 2Y + Z = 50  [2] X = 1; Y = 18; Z = 11  X + Y + Z = 30 3X + 2Y + Z = 50  [3] X = 2; Y = 16; Z = 12  X + Y + Z = 30 3X + 2Y + Z = 50  [4] X = 3; Y = 14; Z = 13  X + Y + Z = 30 3X + 2Y + Z = 50  [5] X = 4; Y = 12; Z = 14  X + Y + Z = 30 3X + 2Y + Z = 50  [6] X = 5; Y = 10; Z = 15  X + Y + Z = 30 3X + 2Y + Z = 50  [7] X = 6; Y = 8; Z = 16  X + Y + Z = 30 3X + 2Y + Z = 50  [8] X = 7; Y = 6; Z = 17  X + Y + Z = 30 3X + 2Y + Z = 50  [9] X = 8; Y = 4; Z = 18  X + Y + Z = 30 3X + 2Y + Z = 50  [10] X = 9; Y = 2; Z = 19  X + Y + Z = 30 3X + 2Y + Z = 50  [11] X = 10; Y = 0; Z = 20  X + Y + Z = 30 3X + 2Y + Z = 50

1： *(score+i)  等同于 score[i]  2： x + y + z = 30; 3x + 2y + z = 50; 得 2x + y = 20; 那么有多个解 又 x <= 10, y <= 15, z <= 30  int main() {     int x, y, z;     for (x = 0; x <= 10; x++)     {         for (y = 0; y <= 15; y++)         {             if (2 * x + y == 20)             {                 z = 30 - x - y;                 printf("Men = %d, Women = %d, Children: %d\n", x, y, z);             }         }     }      return 0; }

*(score+i) 表示第i个元素，不过是从0开始，第0个、第1个.....  如果要从1数，那就是第i+1个

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

第0个元素，第1个元素……对，我们就是这么数数的。  三重循环。


Question: 结构体指针问题

*s是对结构体指针的引用；因为s->data=0；即结构体第一个元素的值为0，%d输出，s是结构体的地址，那么就是输出*s就是第一个元素的值，所以结果就是0； (*s).data, (*s).data2; s->data, s->data2 都是表示结构体成员的两个元素。

*s 是解引用操作，得出来的是 s 指针指向的内存  printf("%d\n", *s);//你把整个结构体当做int输出了，那么解析出来的只是最前边 int 大小的内存，然后当做int值了  正确写法应该类似下面的：  printf("%d %f\n", s->data, s->data2);


Question: 关于函数的数组形参以及define的参数和函数参数之间的关系

#include <stdio.h>  #define N   12  float average(float *a, int len);  int main(void) {     float a[N], ave;     int i;      for(i = 0; i < N; i++)         scanf("%f",&a[i]);     ave = average(a, N);     printf("$%.2f\n", ave);      return 0; }  float average(float *a, int len) /* equals a[]*/ {     float sum = 0, ave;     int i;      for(i = 0; i < len; i++)         sum += a[i];     ave = sum / len;      return ave; } 建议如上定义和调用函数。

float average(a); 调用的时候不要再 写float 了。。可以定义一个变量来接收返回的avg= average(a);  #include <stdio.h> #define N 12 float average(float a[]);//这个叫申明 int main() {     float a[N];//a[]为输入数组     int i; float avg;     for(i=0;i<N;i++)//浮点数不能作为数组下标     {         scanf("%f",&a[i]);     }     avg=average(a); printf("$%.2f",avg)     return 0;  } float average(float a[])//这个叫定义也叫实现 {     float sum=0,avg;//名称不要重了     int i;      for(i=0;i<N;i++)     {         sum+=a[i];     }     avg=sum/N; return avg; }

主函数里面的float average(a);应该改为average(a); 前者是函数声明，后者才是正确的调用函数。


Question: 关于对一个变量取址后强制转化再解引的意义

1.  你可以通过这种转换,  传递不同类型的数据(只要字节数相同). 比如CListCtrl类中有一个SetItemData函数, 它只接收PTR_DWORD类型,  你想保存float类型, 怎么办.  你就可以用这种方式转换  2.  数据传送.  比如蓝牙, TCP  UDP,  串口  等.     比如TCP吧.  有一个send函数, 接收一个char*缓冲区, 要发送一个double类型的数据. char buf[0x10];  *(double*)buf = 123.0f;  //快速的把double类型数据填充到缓冲区中  send(sock, buf, sizeof(double), 0);

用int类型指针来解释float变量的内容  这与float转成int是不同的

以整数去解读这段内存.

各位，像那样做的意义是什么，如何理解呢？

电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素 http://edu.csdn.net/course/detail/2455 C语言指针与汇编内存地址-二.函数 http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组 http://edu.csdn.net/course/detail/2517 C语言指针与汇编内存地址-四.三维数组

谢谢上面回答的人了，按照你们说的我自己算了测试了一下，现在明白了，谢谢！！

用不同的类型来解读地址对应的内存。

没什么意义。 (signed/unsigned) char*和T*之间还可以转转，其他大多都是未定义行为。 这么喜欢操纵底层，何不去写汇编呢？


Question: 求用C语言写出2048这个游戏的源代码

2048没有，别的游戏有，参考： 《C语言课程设计案例精编》 C语言程序开发范例宝典 C语言经典编程282例   TC（Turbo C）老代码（小游戏）最好看懂了以后，理解了算法和过程，用VC改写成Windows平台的。

神马2048啊？？不懂讲清楚一点，把规则讲讲


Question: 结构体调用，可以访问成员变量但是不能访问成员函数

结构体中定义的是函数指针， 需要struct创建后赋值， 否则不能用

1： int (*FontInit)(char *pcFontFile,unsigned int dwFontSize); int (*GetFontBitMap)(unsigned int dwcode, PT_FontBitMap ptFontBitMap);  以上两个都是一个定义函数指针变量啊 FontInit 的类型是 int (*)(char *pcFontFile,unsigned int dwFontSize) 你使用之前需要赋值吧？  int func(char *pcFontFile,unsigned int dwFontSize){ return 1; }   ptFontOpr->FontInit = func; // 把func赋值给FontInit  ptFontOpr->FontInit(...); // 调用函数  2： 如果你只是声明函数，如下就好了 int FontInit(char *pcFontFile,unsigned int dwFontSize); int GetFontBitMap(unsigned int dwcode, PT_FontBitMap ptFontBitMap);

static int AsciiFontInit(char *pcFontFile,unsigned int dwFontSize) 这个函数的定义应该在结构体static T_FontOpr g_tAsciiOpr = {     .name          = "ascii", /* 前面根据名字可以判断是指向的这个结构体 */     .FontInit      = AsciiFontInit, }; 之后； 或者在初始化结构体时，把AsciiFontInit的声明在结构体初始化之后。


Question: vs2013编写的程序无法启动，小白求救

小白，都要仔细些，楼主都说成这样，举一反三啦！

这个程序编译通不过吧，for语法有问题，应该是两个分号;

先去看下教材，for循环怎么写的吧

你的for表达式里面不需要有逗号， for(j=1;j<=i;j++)这样

引用 6 楼 lz941008 的回复:   那您再看一下我这个呢？  麻烦了 认真看我的回复 for表达式是里面的i后面的逗号是什么鬼?

那您再看一下我这个呢？  麻烦了

引用 4 楼 lz941008 的回复: for循环 要清除for表达式的格式 逗号什么意思 分号什么含义      for (j = 1; j <= i; j++)  // 分号

引用 2 楼 lz941008 的回复:  我的是这种情况。 计算器的启动命令是 start calc

我的是这种情况。

int main() {     int i, j;     printf("请输入你想要的计算器个数");     scanf("%d", &i);     for (j = 1; j <= i; j++){ // 分号          system("start calc"); // calc      }      return 0;  }


Question: 为什么程序显示没错误但是一运行就会无响应啊

#include <iostream>  using namespace std;  void input(int *hour,int *minute); void ouput(int *hour,int *minute);  int main() {     int a = 1;     int *hour,*minute;      hour = new (int);     minute = new (int);     while(a == 1)     {         input(hour, minute);         ouput(hour,minute);         cout<<"是否需要继续，是请输入1，否请输入0"<<endl;         cin>>a;     }     return 0; } void input(int *hour,int *minute) {     cin>>*hour>>*minute; } void ouput(int *hour,int *minute) {     if(*hour>=12)     {         cout<<*hour-12<<":"<<*minute<<"PM"<<endl;     }     if(*hour<12)     {         cout<<*hour<<":"<<*minute<<"AM"<<endl;     } } 这是我改过之后的代码，我在Linux下修改和测试的。 主要问题如下： 1. 野指针，hour和minute都是野指针，没有对其申请空间； 2. a未初始化，并且while判断语句是错误的 a=1改成a == 1，是判断语句不是赋值语句； 3. AM和PM表示的意思颠倒，AM是指上午，PM是指下午吧

int *hour,*minute; 没有分配内存  你可以写成 int hour, minute;  调用的时候用  input(&hour,&minute);  ouput(&hour,&minute);


Question: 指针指向字符串数组

char*ptr1[]={"love","you"};  一级指针本身是一个数组，内存在栈上分配，两个指针均指向常量区的字符串  char**ptr2={"love","you"};  错误用法，char**ptr2 是一个二级指针，但没有对里面的第一级指针分配内存

#include <stdio.h>  #define ROW     3 #define COL     3 int main(void) {     int i, j, num = 0;     char*ptr1[]={"love","you"};    /* 指针数组 */     char**ptr2= NULL;     int arr1[ROW][COL];     int **arr;     int (*p)[COL];     int *array;      size_t len = sizeof(ptr1) / sizeof(ptr1[0]);     for (i = 0; i < len; i++)         printf("ptr1[%d] = %s\n", i, ptr1[i]);     ptr2 = ptr1; /* 二重指针*/     for (i = 0; i < len; i++)         printf("ptr2[%d] = %s\n", i, ptr2[i]);      for (i = 0; i < len; i++)         printf("ptr2[%d] = %s\n", i, *(ptr2+i));      for (i = 0; i < ROW; i++)         for (j = 0; j < COL; j++)             arr1[i][j] = num++;      p = arr1; /* 数组指针*/     for (i = 0; i < ROW; i++) {         for (j = 0; j < COL; j++)             printf("%d ", p[i][j]);     }         putchar(10);      array = &arr1[0][0];     for (i = 0; i < ROW * COL; i++)             printf("%d ", array[i]);     putchar(10);      arr = &array;     for (i = 0; i < ROW * COL; i++)             printf("%d ", arr[0][i]);     putchar(10);      return 0; } 一个demo，验证自己的理解。

第一个是二维数组，也就是数组中的数组，是连续的一块内存，是明确空间大小了的  第二个是指向指针的指针，但是并不能说是二维数组 只是其中一种用法，可以存储数学意义上的二位数组  int **p = new int*[10]; //分配10个int*大小的空间，存储的类型是int*指针 for(int i = 0; i < 10; i++) {     p[i] = new int[5]; //分配5个空间，然后返回给 p[i] }

char*ptr1[]={"love","you"}; 你这里的ptr1是个指针数组，这个数组有两个元素也就是两个指针，分别指向“love”和“you”  char**ptr2={"love","you"}; 这里的char**ptr2的意思是你定义了一个指针，这个指针指向指针ptr2，ptr2指向一个字符串数组，这个数组里有两个元素"love"和"you"


Question: c语言里面写入位置时发生访问冲突是怎么一回事啊？

void CompressRLE_(char* input, char* output1_letter,int* output1_times) {     int i=0, j=0, k = 0;     for (i = 0; i < strlen(input); i++)     {         //直到找到和当前字符不相等的下个字符为止           for (j = i; input[j] == input[i]; j++) 		;         /*存放重复计数*/         output1_times[k] = j - i;         /*存放重复的字符*/         output1_letter[k++] = input[i];         i = j - 1;     } } 要保持重复的字符和计数是同一个位置，即下标相同。

output1_letter刚开始为全０，在函数里面k刚开始为０，记录time后k为１，所以这里output1_letter的第０，１元素全是０，你打印当时没有输出了。  output1_times[k] = j - i;         /*存放重复的字符*/         output1_letter[k++] = input[i];

char* output1_letter,int* output1_times 两个参数都需要预先分配足够的内存空间

output1_letter[k++] = input[i];这是错误的用法； 你的output1_letter只是一个int类型的指针，不是一个指针数组；  你把函数改为void CompressRLE_(char* input, char* output1_letter[512],int* output1_times)实验一下


Question: 共用体使用的时候共用体内存地址特殊情况  求解

引用 1 楼 Jay_Won的回复:给你举个例子： int main() {     int nTag = 10;     int *pTag = &nTag ;      printf("%p\n",&nTag );//输出：002AF744  输出的是nTag 变量的地址     printf("%p\n",pTag );//输出：002AF744  通过指针变量pTag 输出nTag 变量的地址     printf("%p\n",nTag );//输出：0000000A 输出nTag在内存中存储的值     printf("%p\n",&pTag );//输出：002AF738  指针变量pTag 本身自己的地址     printf("%d\n",*pTag );//输出：10      return 0; }  所以你输出的不是地址，而是X.i,X.d,X.c在内存中的值，之所以是0000000A是因为你把它赋值为int型的10了，你要是换成11，输出的肯定是00000000B 嗯嗯  我懂了  谢谢您

%p 需要的是一个指针（32位程序是4字节），如果你传递的参数是一个char（1字节），行为是不确定的

你输出的是值，而不是地址

仅供参考：#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   }; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);     u.bb=0x41;     u.cc=0x21;//dddccccccbbbbbbb     u.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)

#include<stdio.h> #include<stdlib.h>  union A {     int i;     char c;     double d; };  int main() {     union A X;     X.i=10;     printf("%p %p %p\n", &X.i, &X.d, &X.c);     printf("%d %lf %d\n", X.i, X.d, X.c);     return 0; } %p是地址输出，是需要在前面加&符，通过验证可以看出地址是相同的，因为三个联合体使用同一片内存空间，并且大小以最大元素占用的为准。 通过输出他们各自的值，也会发现c和i都是10，但是d是0.00000，这个要看一下double数据在内存中存储方式了。


Question: 各位帮看看

引用 3 楼 cfjtaishan 的回复:[quote=引用 2 楼 weixin_37671669 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:] #include<stdio.h>  const int S_PER_M = 60; const int S_PER_H = 3600; const double M_PER_K = 0.62137;  int main(void) {     double distk,distm;     double rate;     int min, sec;     int time;     double mtime;     int mmin,msec;      printf("This program converts your time for a metric race\n");     printf("to a time for running a mile and to your average\n");     printf("speed in miles per  hour.\n");     printf("Please enter,in kilometers,the disatance run.\n");     scanf("%lf",&distk);     printf("Next enter the time in minutes and seconds.\n");     printf("Begin by entering the  minutes.\n");     scanf("%d", &min);     printf("Now enter the seconds.\n");     scanf("%d", &sec);      time = S_PER_M * min + sec;     distm = M_PER_K * distk;     rate = distm/time*S_PER_H;     mtime = (double)time/distm;     mmin = (int)mtime/S_PER_M;     msec = (int)mtime%S_PER_M;     printf("Your ran %1.2f km (%1.2f miles) in %d min, %d sec.\n",distk,distm,min, sec);  /*少一个%d*/     printf("Thaat  pace corresponds to running a mile in %d min,", mmin);     printf("%d sec.\nYour average speed was %1.2f mph.\n",msec, rate);     return 0; } 少了一个%d其他没发现问题。 建议：全局变量能用宏定义的可以考虑使用宏。全局面量命名建议使用类似gmin_per_m，g标识global 感谢 使用全局变量的名字，有哪些要求么？[/quote] 主要是见名知义就好，局部变量也是。命名方法有多种，比如camel命名法 另外，自己代码风格也建议改改，详尽的coding style.可以参考Linux内核的[/quote]  感谢哦

引用 2 楼 weixin_37671669 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] #include<stdio.h>  const int S_PER_M = 60; const int S_PER_H = 3600; const double M_PER_K = 0.62137;  int main(void) {     double distk,distm;     double rate;     int min, sec;     int time;     double mtime;     int mmin,msec;      printf("This program converts your time for a metric race\n");     printf("to a time for running a mile and to your average\n");     printf("speed in miles per  hour.\n");     printf("Please enter,in kilometers,the disatance run.\n");     scanf("%lf",&distk);     printf("Next enter the time in minutes and seconds.\n");     printf("Begin by entering the  minutes.\n");     scanf("%d", &min);     printf("Now enter the seconds.\n");     scanf("%d", &sec);      time = S_PER_M * min + sec;     distm = M_PER_K * distk;     rate = distm/time*S_PER_H;     mtime = (double)time/distm;     mmin = (int)mtime/S_PER_M;     msec = (int)mtime%S_PER_M;     printf("Your ran %1.2f km (%1.2f miles) in %d min, %d sec.\n",distk,distm,min, sec);  /*少一个%d*/     printf("Thaat  pace corresponds to running a mile in %d min,", mmin);     printf("%d sec.\nYour average speed was %1.2f mph.\n",msec, rate);     return 0; } 少了一个%d其他没发现问题。 建议：全局变量能用宏定义的可以考虑使用宏。全局面量命名建议使用类似gmin_per_m，g标识global 感谢 使用全局变量的名字，有哪些要求么？[/quote] 主要是见名知义就好，局部变量也是。命名方法有多种，比如camel命名法 另外，自己代码风格也建议改改，详尽的coding style.可以参考Linux内核的

引用 1 楼 cfjtaishan 的回复:#include<stdio.h>  const int S_PER_M = 60; const int S_PER_H = 3600; const double M_PER_K = 0.62137;  int main(void) {     double distk,distm;     double rate;     int min, sec;     int time;     double mtime;     int mmin,msec;      printf("This program converts your time for a metric race\n");     printf("to a time for running a mile and to your average\n");     printf("speed in miles per  hour.\n");     printf("Please enter,in kilometers,the disatance run.\n");     scanf("%lf",&distk);     printf("Next enter the time in minutes and seconds.\n");     printf("Begin by entering the  minutes.\n");     scanf("%d", &min);     printf("Now enter the seconds.\n");     scanf("%d", &sec);      time = S_PER_M * min + sec;     distm = M_PER_K * distk;     rate = distm/time*S_PER_H;     mtime = (double)time/distm;     mmin = (int)mtime/S_PER_M;     msec = (int)mtime%S_PER_M;     printf("Your ran %1.2f km (%1.2f miles) in %d min, %d sec.\n",distk,distm,min, sec);  /*少一个%d*/     printf("Thaat  pace corresponds to running a mile in %d min,", mmin);     printf("%d sec.\nYour average speed was %1.2f mph.\n",msec, rate);     return 0; } 少了一个%d其他没发现问题。 建议：全局变量能用宏定义的可以考虑使用宏。全局面量命名建议使用类似gmin_per_m，g标识global 感谢 使用全局变量的名字，有哪些要求么？


Question: c语言 清理输入缓存的疑问？

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];

3楼，是在什么环境下认为不需要呢？我在Centos Linux的gcc下是必须的。如果不清除的话，输出完全不对头。

void main(void) {     int num;     char a,b[10],c;      scanf("%c",&a);     //scanf( "%*[^\n]%*c" );//有效清理输入缓冲，包括回车符\n,其实不需要！！！      scanf("%d",&num);     //scanf( "%*[^\n]%*c" );//有效清理输入缓冲，包括回车符\n，其实不需要！！！      scanf("%s",b);     //scanf( "%*[^\n]" );     //scanf( "%*[^\n]");//必须分开，如果用scanf( "%*[^\n]%*c" )无法清理回车\n     scanf( "%*c");    /*等同于getchar()*/      scanf("%c",&c);     printf("%c %d %s %c\n",a,num,b,c); } 前两个不需要，因为第一个输入”残留“输入缓存里的回车符不会与%d匹配的。第二个也是，第二个的回车符不会与%s匹配的。 最后一个只需scanf("%*c");即可，就能将缓存里的回车符吸收，用getchar也可以实现。第一次输入的残留数据，会在第二次输入整形数据时清除，不会带向下面的输入。第三次的输入需要考虑第二的输入缓存里的”垃圾数据“

等一个解答，马一下

回车键也是字符吧


Question: C语言：这个采药问题的算法有什么问题吗？

昨天ls回复错了  昨天下班路上又想了一下，这是一个背包问题，0-1背包问题  重新给一个算法：  先给推理过程： 我们假设： si：第i株药草的采摘时间 wi：第i株药草的价值 W(i, t) 为：在总时间t内，采摘前i株药草（药草下标从1开始，前0株表示没有药草）所能获得的最大价值 则： 1、W(0, t) = 0 2、W(i, 0) = 0 3、若第i株药草的采摘时间si > t，则W(i, t) = W(i - 1, t) 4、若第i株药草的采摘时间si <= t，则W(i, t) = max( (wi + W(i - 1, t - si )), W(i - 1, t) )  说明： 1、无论总时间多少，无药可采时，所能获得的最大价值为0 2、无论有多少药可采，总时间为0时，所能获得的最大价值为0 3、若第i株草药的采摘时间超过总时间，那么该草药在当前总时间范围以内，无法被采摘： 则前i株草药所能产生的最大价值 = 前（i-1）株草药在总时间内所能产生的最大价值 4、若第i株草药的采摘时间不超过总时间，那么前i株草药所能产生的最大价值为： 要么采摘第i株草药，最大价值 = 第i株草药的价值 + 扣除第i株草药的时间后，用剩余时间去采摘前（i-1）株草药能产生的最大价值 要么不采摘第i株草药，最大价值 = 前（i-1）株草药在总时间内所能产生的最大价值 取以上两者的最大值  修改一下之前的代码  #include <iostream>  // 总时间T unsigned int T = 0; // 总草药数量M unsigned int M = 0; // M株草药的采摘时间和对应价值数组 unsigned int *second; unsigned int *worth; // 用于保存中间计算过程的推导数组（以一维数组的形式表示的二维数组） unsigned int *temp;  // 当总时间为limitSec时，前index株草药所能产生的最大价值 int FindMaxWorth(unsigned int index, unsigned int limitSec) { 	if (0 == index) 	{ 		// FindMaxWorth(0, limitSec) = 0 		// 无论总时间多少，无药可采时，所能获得的最大价值为0 		return 0; 	} 	else if (0 == limitSec) 	{ 		// FindMaxWorth(index, 0) = 0 		// 无论有多少药可采，总时间为0时，所能获得的最大价值为0 		return 0; 	} 	else 	{ 		if (second[index] > limitSec) 		{ 			// 若第index株草药的采摘时间超过总时间，那么该草药在当前总时间范围以内，无法被采摘： 			// 则前index株草药所能产生的最大价值 = 前（index-1）株草药在总时间内所能产生的最大价值 			// 则FindMaxWorth(index, limitSec) = FindMaxWorth(index - 1, limitSec) 			return temp[(index - 1) * T + limitSec]; 		} 		else 		{ 			// 若第index株草药的采摘时间不超过总时间，那么前index株草药所能产生的最大价值为： 			// 要么采摘第index株草药，最大价值 = 第index株草药的价值 + 扣除第index株草药的时间后，用剩余时间去采摘前（index-1）株草药能产生的最大价值 			// 要么不采摘第index株草药，最大价值 = 前（index-1）株草药在总时间内所能产生的最大价值 			// FindMaxWorth(index, limitSec) = worth[index] + FindMaxWorth(index - 1, limitSec - second[index]) 			// FindMaxWorth(index, limitSec) = FindMaxWorth(index - 1, limitSec) 			// 取以上两者的最大值 			unsigned int w1 = worth[index] + temp[(index - 1) * T + (limitSec - second[index])]; 			unsigned int w2 = temp[(index - 1) * T + limitSec]; 			return w1 > w2 ? w1 : w2; 		} 	} }  int main(int argc, char* argv[]) { 	T = 0; 	M = 0; 	std::cout << "enter T M:" << std::endl; 	std::cin >> T >> M; 	T = T + 1; // 时间下标从0开始，+1 	M = M + 1; // 草药下标从0开始，+1 	second = new unsigned int[M]; 	worth = new unsigned int[M]; 	temp = new unsigned int[M * T]; 	if (NULL != second && NULL != worth && NULL != temp) 	{ 		second[0] = 0; 		worth[0] = 0; 		for (unsigned int i = 1; i <= M; i++) 		{ 			std::cout << "enter second[" << i << "] worth[" << i << "]:" << std::endl; 			std::cin >> second[i] >> worth[i]; 		}  		// 推导 总时间为i，草药数量为j 时，能产生的最大价值 		for (unsigned int i = 0; i <= T; i++) 		{ 			for (unsigned int j = 0; j <= M; j++) 			{ 				temp[j * T + i] = FindMaxWorth(j, i); 			} 		}  		// 最后一个元素即为 总时间为T，草药数量为M 时的最终解 		std::cout << temp[M * T - 1] << std::endl; 	}  	if (NULL != second) 	{ 		delete[] second; 	} 	if (NULL != worth) 	{ 		delete[] worth; 	} 	if (NULL != temp) 	{ 		delete[] temp; 	}  	system("pause");  	return 0; }

这题的算法：  步骤1、 找出M株药草中，在有限时间内，可以采摘的单位价值（价值/时间）最高的那一株药草  步骤2、 总时间T，扣除该株药草所需时间，该株药草的价值清零（按题意应该是1株药草只能采摘1次，不可重复采摘）  然后继续步骤1，直到找不到药草（即所有药草全部采摘完毕，或剩余时间不足以再次采摘）为止。   #include <iostream>  // 总时间T unsigned int T = 0; // 总药草数量M unsigned int M = 0; // M株药草的采摘时间和对应价值数组 unsigned int *second; unsigned int *worth;  // 找出M株药草中，在有限时间内，可以采摘的单位价值（价值/时间）最高的那一株药草 int FindMaxWorth(unsigned int limitSec) { 	float maxWorth = 0.0f; 	int maxIndex = -1; 	for (unsigned int i = 0; i < M; i++) 	{ 		if (0 < second[i] && second[i] <= limitSec) 		{ 			if ((1.0f * worth[i] / second[i]) > maxWorth) 			{ 				maxWorth = 1.0f * worth[i] / second[i]; 				maxIndex = i; 			} 		} 	}  	return maxIndex; }  int main(int argc, char* argv[]) { 	T = 0; 	M = 0; 	std::cout << "enter T M:" << std::endl; 	std::cin >> T >> M; 	second = new unsigned int[M]; 	worth = new unsigned int[M]; 	if (NULL != second && NULL != worth) 	{ 		for (unsigned int i = 0; i < M; i++) 		{ 			std::cout << "enter second[" << i << "] worth[" << i << "]:" << std::endl; 			std::cin >> second[i] >> worth[i]; 		}  		unsigned int currWorth = 0;	// 已采摘的总价值 		unsigned int lastSecond = T;// 剩余时间 		int maxIndex = -1;			// 找到的单位价值（价值/时间）最高的药草下标 		while (true) 		{ 			maxIndex = FindMaxWorth(lastSecond); 			if (0 <= maxIndex) 			{ 				currWorth = currWorth + worth[maxIndex];		// 累积价值 				lastSecond = lastSecond - second[maxIndex];		// 扣除剩余时间 				worth[maxIndex] = 0;							// 被采摘的药草价值清零 			} 			else 			{ 				break; 			} 		}  		std::cout << currWorth << std::endl; 	}  	if (NULL != second) 	{ 		delete[] second; 	} 	if (NULL != worth) 	{ 		delete[] worth; 	}  	system("pause");  	return 0; }   代码是C++的，输入是控制台输入的，lz自行修改为输入读文件即可

#include <stdio.h>  int total_time, medics; int value[100]; int time[100]; int max[1001];  int main() {     int i, t;      printf("Please input total time and medics: ");     scanf("%d%d", &total_time, &medics);      for (i = 0; i < medics; i++) {         scanf("%d%d", &time[i], &value[i]);     }      for (i = 0; i < medics; i++)         for ( t = total_time; t > 0; t--)             if (time[i] <= t)                 if (value[i] + max[t-time[i]] > max[t])//第i个的价值+不选第i个且用时为t-time[i-1]时最大价值                     max[t] = value[i] + max[t-time[i]];      printf("%d\n", max[total_time]);      return 0; } 作为一个参考～

那里确实有问题，但改完还有问题。 Result: Wrong Answer     Memory Used: 824 KB     Time Used: 0 ms  Language: GNU C     Username:      Problem ID:   Copy #include <stdio.h> int main(void) {     int T, M;     while(scanf("%d %d", &T, &M) == 2){         int t[M],val[M];         int output = 0;         for(int i = 0;i < M;i++)             scanf("%d %d",t+i, val+i);         int max[M][T+1];         for(int j = 0;j <= T;j++){             for(int i = 0;i < M;i++){                 if(!i)                 {                     max[i][j] = (j < t[i])?0 : val[i];                 }                 else{                     max[i][j] = (j < t[i])?max[i-1][j] : max[i-1][j-t[i]]+val[i];                 }          //       printf("i:%d j:%d ----->%d\n", i, j, max[i][j]);         }         }         for(int i = 0;i < M;i++)             output = (output > max[i][T]) ? output : max[i][T];         printf("%d\n", output);     }     return 0; }

不应该赋值为0啊，赋值 max[i-1][j-1]

中间那个printf();是我自己用来测试的


Question: 求大神帮忙改错

missing ';',你可以在附近找找是不是丢失了分号

语法错误，应该是在提示行号的上一语句缺少分号“;"

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

提示错误那里的代码贴出来


Question: 一个简单的合并排序小程序，奇怪的是我在断点调试的时候没有点击下一步，位置变量i，j之类的变量仍然一直在变，求大神帮我看看是怎么回事

一些下标的临界情况要考虑清楚  #include<iostream> using namespace std; template <class T> void MergeSort(T a[],int left,int right); template <class T> void Merge(T a[],T b[],int left,int middle,int right); template<class T> void Copy(T a[],T b[],int left,int right);   template<class T> void MergeSort(T a[],int left,int right) {     if(right>left+1){         int middle=(left+right)/2;         MergeSort(a,left,middle);         MergeSort(a,middle,right);         T b[right-left];         Merge(a,b,left,middle,right);         Copy(a,b,left,right);     } }   template <class T> void Merge(T a[],T b[],int left,int middle,int right) {     int k=0,i=left,j=middle;     while(i<middle&&j<right){         if(a[i]<a[j]){             b[k++]=a[i++];         }         else{             b[k++]=a[j++];         }     }     if(i<middle){         while(i<middle)         b[k++]=a[i++];     }     if(j<right){         while(j<right)         b[k++]=a[j++];     } }   template<class T> void Copy(T a[],T b[],int left,int right){     int tmp=left, i = 0;     while(tmp<right){         a[tmp]=b[i];         tmp++;         i++;     } }   int main() {     int a[]={8,7,6,5,4,3,2,1};     MergeSort(a,0,8) ;     for(int i=0;i<8;i++){         cout<<a[i]<<"  "<<endl;     } }  如有问题欢迎继续追问，没问题请及时结贴，谢谢

引用 2 楼 zgl7903 的回复:C/C++ 数组访问 最需要注意越界的问题能麻烦您详细说说到底是哪里越界了吗，我分开用这几个函数都没问题，调试了很长时间也没有找到问题在哪里。。。

C/C++ 数组访问 最需要注意越界的问题

木有人吗？？？大神在哪里？！

仅供参考：#include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }


Question: C语言经典问题之快速排序

最后一个for多了一个;


Question: 字符串的小问题

引用 10 楼 MikeDDT009 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] 数组长度不是位，字符数组每个元素都是一个字节。 第二个问题，str1能够正常输出但不等于就是对的，可以这样做的。把str2拷贝至str1中是越界的。所以strcpy没有strncpy安全。 建议不要这么做，在strcpy函数介绍里，就已经有提示了，目的缓存要大于源字符串的长度；至少要是strlen(src)+1个长度。误些单位，是我不够严谨了，就是因为这里示例，源数组里存储的字符是按照字符串常量进行的初始化，那么就应该有个‘\0’字符，而目标数组明显只有9字节大小，既只能存9个字符，那么源数组复制过去，按理来说是不对的，但是却没报错，我还以为是我理解错了，而产生的疑惑[/quote] 这是随机性的，小程序不出问题，不等于在大程序里这样做不出问题。对于越界就是一个bug,很容易出问题。

引用 6 楼 xiaohuh421 的回复:char str1[9],str2[]={"Microsoft"};    strcpy(str1,str2)  因为没有\0的存放位置了  char str[6]=“CHINA”;   //这叫初始化,   (定义的时候同时赋值, 这是正确的)  str[6] = “CHINA”;    // 这是赋值了, 是错误的.    字符串变量的赋值,   只能一次赋值一个字符. 并且索引从0开始, 只能赋值0-5.   比如  str[0]= 'C'; str[1]='H'; str[2] = 'I'; ....  要一次性赋值, 就只能使用函数   strcpy(str, "CHINA"); 原来如此，也就是说翻看的老教材太不够严谨了，直接赋值那个的确是我自己写的不够严谨，原来是char str[5]="CHINA"这样的

引用 4 楼 cfjtaishan 的回复:数组长度不是位，字符数组每个元素都是一个字节。 第二个问题，str1能够正常输出但不等于就是对的，可以这样做的。把str2拷贝至str1中是越界的。所以strcpy没有strncpy安全。 建议不要这么做，在strcpy函数介绍里，就已经有提示了，目的缓存要大于源字符串的长度；至少要是strlen(src)+1个长度。误些单位，是我不够严谨了，就是因为这里示例，源数组里存储的字符是按照字符串常量进行的初始化，那么就应该有个‘\0’字符，而目标数组明显只有9字节大小，既只能存9个字符，那么源数组复制过去，按理来说是不对的，但是却没报错，我还以为是我理解错了，而产生的疑惑

引用 1 楼 gametheory1010 的回复:char str[6];//定义是正确的 str[6] = "CHINA"； //这样赋值不正确。下标是从 0 开始的， 从str[0]到str[5]，每一位代表一个字符。 //只有初始化的时候才可以直接赋值字符串。  是我表述不够清楚，我意思就是在初始化的时候进行赋值，就是针对str[5]="CHINA"这个来说的，字符串有个‘\0’，而字符串数组只有5个，也既5字节大小，存储了CHINA这几个字符后  引用 4 楼 cfjtaishan 的回复:数组长度不是位，字符数组每个元素都是一个字节。 第二个问题，str1能够正常输出但不等于就是对的，可以这样做的。把str2拷贝至str1中是越界的。所以strcpy没有strncpy安全。 建议不要这么做，在strcpy函数介绍里，就已经有提示了，目的缓存要大于源字符串的长度；至少要是strlen(src)+1个长度。 引用 4 楼 cfjtaishan 的回复:数组长度不是位，字符数组每个元素都是一个字节。 第二个问题，str1能够正常输出但不等于就是对的，可以这样做的。把str2拷贝至str1中是越界的。所以strcpy没有strncpy安全。 建议不要这么做，在strcpy函数介绍里，就已经有提示了，目的缓存要大于源字符串的长度；至少要是strlen(src)+1个长度。函数说明是那样，但是下面那个代码示例的情况让人纠结，纠结的地方在于前者9个字节，存了后者的字符以后，不会有一个字符串的结尾'\0'吗，主要在于前面看字符串常量的时候字符‘a’和字符串“a”是不一样的，前者一个字节，而后者存储所占位置是2个字节，自带‘\0’字符

有时候越界运行的时候不出错并不代表你这样做没错，只能说明你运气好

越界不是编译错误，运行是没崩只能算运气好，仅此

引用 6 楼 xiaohuh421 的回复:char str1[9],str2[]={"Microsoft"};    strcpy(str1,str2)  因为没有\0的存放位置了  char str[6]=“CHINA”;   //这叫初始化,   (定义的时候同时赋值, 这是正确的)  str[6] = “CHINA”;    // 这是赋值了, 是错误的.    字符串变量的赋值,   只能一次赋值一个字符. 并且索引从0开始, 只能赋值0-5.   比如  str[0]= 'C'; str[1]='H'; str[2] = 'I'; ....  要一次性赋值, 就只能使用函数   strcpy(str, "CHINA");正解

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

前者是初始化  str[5]="CHINA"这是赋值语句，字符串数组不能这样子赋值的，str[5] 表示的是取str的第六个字符 就是是 str[100]="CHINA"那也不正确  strcpy不考虑你目标字符串缓存是否足够，编译的时候也不会报错 如果目标缓存不足以存储下源字符串  运行的时候可能完全无误，也可能对其他堆栈数据造成破坏，更严重的会导致程序直接崩溃 是一个不可预知的bug，慎重对待

缓存不足，不代表一定报错，可能会错误地占用其它堆栈，比较危险，但不是一定会导致进程挂掉。


Question: 问个问题 涉及javascript  和一些底层知识.因为我知道C 版块有赵老师

找个开源的javascript实现研究之。 据说Chrome就是开源的。

引用 6 楼 ForestDB 的回复:如果只是想学好JS，那么“底层”只是充分条件，非必要条件。  但是在计算机的世界中，但凡要更上一层楼，或多或少都会接触到些“底层”的知识。  哦

引用 7 楼 zhao4zhong1 的回复:为什么不使用Chrome或FireFox自带的js调试器调试js呢？ 赵老师好啊 火狐的那个插件嘛 在用啊

为什么不使用Chrome或FireFox自带的js调试器调试js呢？

本人对语言的一些底层逻辑和实现，虽有挺多接触但还不是很深刻，有什么说得不对的地方还请大家见谅

真要研究底层的东西确实是需要很大毅力和比较多方面的知识的  再来感觉不大适合用JS入手，因为JS根本没有涉及具体内存的操作，内存分配，销毁，怎么读写完全是由引擎来管理

引用 2 楼 baidu_37533913 的回复:那大哥你的意思就是说：我如果想要学好JS  那必须倒回去。把 计算机组成原理   编译原理 操作系统  数据结构 这些东西搞透彻了 才能学JS ?  你题意是说研究底层的实现吧？那当然是需要了解很多基础的知识了 如果你只是说学怎么用JS，或者熟练掌握JS，那你完全可以没有任何计算机基础就入手  就本版块来说研究熟悉c/c++底层实现的人数比例也不会很高 而且科班出身的哪个没学过计算机组成原理，数据结构，算法，编译原理甚至汇编？

引用 1 楼 jianwen0529 的回复:不了解js引擎是怎么实现的，又是如何在管理对象的  只能给出几点建议或者失误的地方： 1：目前两大主流型的编译方式：编译型程序，解释型程序，你可以网上找些资料了解  2： 继续,js代码就是告诉浏览器，他该干什么。什么时候 改变一个DIV的背景颜色，什么时候让一个DIV  display:'none';  这些更倾向于CSS和HTML DOM吧？  3： function Box(){}        浏览器执行这一句:   请问在 堆内存中就会被谁 划分一块区域用来存储 这个 构造函数?他是存放在堆内存中的吗？如果不是 他应该在内存中的什么地方？  function Box();这是一个函数啊，只是代码而已 var box=new Box();才是创建对象  4： 我以前自学过C , int  a;     这在C中是申明一个 整形变量a,但是没有赋值,所以此时 变量a的值应该 NULL.  看位置，内置类型的全局变量才会初始化为0 局部变量的值是随机的 再者，在c中 #define NULL (void*)0 NULL其实是这个void*指针，并不等同于0（虽然0可以转换为任何指针）  5： 由于int 型 占4个字节大小内存.所以 系统会在内存中分配4字节大小的空间给变量a.  int的占用大小是编译器相关的，它只规定了int不能小于多少bit，不能说一定是4字节，只是大多编译器选择4字节罢了 32位和64位程序下也不一定相同  6： 那么在这张内存表中就会存放 变量a 和与之对应的内存地址  为什么会记录它们的地址呢    那大哥你的意思就是说：我如果想要学好JS  那必须倒回去。把 计算机组成原理   编译原理 操作系统  数据结构 这些东西搞透彻了 才能学JS ?


Question: 红色的地方有什么错，好像没有运行到

谢谢各位大佬

为什么结不了帖，怎么结帖，第一次用，这个网站很好啊

for(i=0;i<=j;i++)     {         if(L->data[i].no==item)         {             return (i+1);         }     }  这个no是char *， item是int不能直接比较吧，没有仔细看逻辑，这个地方是肯定有问题的，也许是：  if( atoi(L->data[i].no) == item）

LocItem是不是有执行，如果没有执行，往前查，如果有执行，L->len是不是为0

if (L->data[i].no == item) // no是char*类型，item是int类型，他们不能直接比较  修改为  // atoi 是把一个字符串包含的字符数字转换为int类型 // 需要#include <stdlib.h> if (atoi(L->data[i].no) == item)  或者  char tmp[10]; sprintf(tmp, "%d", item); // 把item存储在字符串中 if (strcmp(L->data[i].no, item) == 0) // 比较两个字符串的内容是否相同

gdb 加个断点调试一下看看是不是执行到？


Question: 此简易计算加减法小代码哪里有问题？

引用 1 楼 jianwen0529 的回复:scanf("%ld%ld",&num1,&num2); 改为 scanf("%lf%lf", &num1, &num2); // double的格式是 %lf  感谢，检查了10+分钟就没看到格式控制符的错误


Question: C语言中位运算右移和左移

就是看是不是要当作乘除2了

Try it and you will get an answer.

c语言的移位操作 　　左移时总是移位和补零。 　　右移时无符号数是移位和补零，此时称为逻辑右移; 　　而有符号数大多数情况下是移位和补最左边的位（也就是补最高有效位），移几位就补几位,此时称为算术右移。

这个问题在C语言的前几章节里有介绍，至于补0或者补1，要看被移位的是有符号数还是无符号数。 对于无符号数，右移高位补0，对于有符号数高位补1（可能对特定的系统或者编译器）；

仅供参考：#include <stdio.h> unsigned short int ui;   signed short int si; int main() { 	ui=(unsigned short int)0x8000u; 	si=(  signed short int)0x8000; 	printf("ui=%u\n",ui); 	printf("si=%d\n",si); 	ui=ui>>1; 	si=si>>1; 	printf("ui=%u\n",ui); 	printf("si=%d\n",si);  	printf("--------------\n"); 	ui=(unsigned short int)0x8000u; 	si=(  signed short int)0x8000; 	printf("ui=%u\n",ui); 	printf("si=%d\n",si); 	ui=((  signed short	int)ui)>>1; 	si=((unsigned short	int)si)>>1; 	printf("ui=%u\n",ui); 	printf("si=%d\n",si);  	return 0; } //ui=32768 //si=-32768 //ui=16384 //si=-16384 //-------------- //ui=32768 //si=-32768 //ui=49152 //si=16384

对于无符号整数，右移后左边补0；对于有符号整数，可能补1或0，对于VC2010，补1。

对于unsigned类型，右移空出来的左端用0补充 ，对于有符号的类型，结果依赖于机器。空出的位可能用0补充，或使用符号位的副本补充。

无符号数肯定是补0 有符号数依据编译器的实现

补0。你试一下不就知道了


Question: HDOJ-1002 A+Bproblem一直WA 小白求大神帮助

引用 3 楼 qq423399099 的回复:网上找下AC的代码吧。 1.看看你们的输入输出格式是不是一致 2.多测试一些样例    请问一下 做题的时候有时候好久都不能做出来  是应该全靠自己想出来还是看一下别人的代码提供一下思路呀

引用 2 楼 HHUPUP 的回复:还是WA啊   请问一下 做题是应该自己独立想出来 还是看一下别人的代码呀

好的好的 谢谢啦

还是WA啊

case改成Case，注意大小写


Question: 在C中给从VBA中传过来的自定义对象赋值疑问

不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？ 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话，文本文件的格式问题可参考json或xml  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！

没这么用过，一般是用com做中转，所以不知道为何出错 你可以看看这一片文章


附加包含目录：头文件 附加库目录：你lib所在目录 附加依赖项：lib库的名字（你好像上面没提到） 你把这附加库目录和附加依赖项都截个图

1：目录不正确  2： 静态库： 只需要提供头文件和lib文件  动态库： 静态调用：需要提供头文件，lib文件（主要记录函数入口信息等），dll（主要是包含实现，需要放置在工程可见的目录下） 动态调用：只需要dll，通过winapi直接查找dll内的接口，然后才能使用  第三方的提供的是不是动态库？  3：静态库，但是头文件的版本和lib的版本不一致

学会使用dumpbin.exe查看lib或dll中的导出函数。  dll 导出函数名的那些事 关键字：　VC++ 　DLL  导出函数　 经常使用VC6的Dependency查看DLL导出函数的名字，会发现有DLL导出函数的名字有时大不相同，导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系。 VC++支持两种语言：即C/C++，这也是造成DLL导出函数差异的根源 我们用VS2008新建个DLL工程，工程名为"TestDLL" 把默认的源文件后缀 .CPP改为.C（C文件） 输入测试代码如下： 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数，我们有以下几个方法： 1. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def)，文件内容为： LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件：/DEF:"TestDll.Def" 2. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法，我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数： 第一种方法导出的函数为： MyFunction 第二种方法导出的函数为： _MyFunction@4 __stdcall会使导出函数名字前面加一个下划线，后面加一个@再加上参数的字节数，比如_MyFunction@4的参数（int iVariant）就是4个字节 __fastcall与 __stdcall类似，不过前面没有下划线，而是一个@，比如@MyFunction@4 __cdecl则是始函数名。 小结：如果要导出C文件中的函数，并且不让编译器改动函数名，用def文件导出函数。 下面我们来看一下C++文件 我们用VS2008新建个DLL工程，工程名为"TestDLL" 默认的源文件后缀为 .CPP （即C++文件）。 输入测试代码如下： 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数，我们有以下几个方法： 3. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def)，文件内容为： LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件：/DEF:"TestDll.Def" 4. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法，我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数： 第一种方法导出的函数为： MyFunction 第二种方法导出的函数为： ?MyFunction@@YGHH@Z 可以看到 第二种方法得到的 导出函数名 并不是我们想要的，如果在exe中用显示方法（LoadLibrary、GetProcAddress）调用 MyFunction 肯定会失败。 但是用引入库(*.LIB)的方式调用，则编译器自动处理转换函数名，所以总是没有问题。 解决这个问题的方法是： 用VC 提供的预处理指示符 "#pragma" 来指定链接选项。 如下： #pragma comment(linker, "/EXPORT:MyFunction=?MyFunction@@YGHH@Z") 这时，就会发现导出的函数名字表中已经有了我们想要的MyFunction。但我们发现原来的那个 ?MyFunction@@YGHH@Z 函数还在，这时就可以把 __declspec() 修饰去掉，只需要 pragma 指令即可。 而且还可以使如下形式： #pragma comment(linker, "/EXPORT:MyFunction=_MyFunction@4,PRIVATE") PRIVATE 的作用与其在 def 文件中的作用一样。更多的#pragram请查看MSDN。 小结：如果要导出C++文件中的函数，并且不让编译器改动函数名，用def文件导出函数。 同时可以用#pragma指令（C 中也可以用）。 总结： C++编译器在生成DLL时，会对导出的函数进行名字改编，并且不同的编译器使用的改编规则不一样，因此改编后的名字也是不同的（一般涉及到C++ 中的重载等）。 如果利用不同编译器分别生成DLL和访问DLL的exe程序，后者在访问该DLL的导出函数时就会出现问题。如上例中函数MyFunction在C++编译器改编后的名字是?MyFunction@@YGHH@Z。我们希望编译后的名字不发生改变，这里有几种方法。 第一种方法是通过一个称为模块定义文件DEF来解决。 LIBRARY TestDll EXPORTS MyFunction LIBRARY 用来指定动态链接库内部名称。该名称与生成的动态链接库名一定要匹配，这句代码不是必须的。 EXPORTS说明了DLL将要导出的函数，以及为这些导出函数指定的符号名。 第二种是定义导出函数时加上限定符：extern "C" 如：#define DLLEXPORT_API extern "C" _declspec(dllexport) 但extern "C"只解决了C和C++语方之间调用的问题(extern "C" 是告诉编译器，让它按C的方式编译)，它只能用于导出全局函数这种情况 而不能导出一个类的成员函数。 同时如果导出函数的调用约定发生改变，即使使用extern "C"，编译后的函数名还是会发生改变。例如上面我们加入_stdcall关键字说明调用约定（标准调用约定，也就是WINAPI调用约定）。 #define DLLEXPORT_API extern "C" _declspec(dllexport) 01 DLLEXPORT_API int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 编译后函数名MyFunction改编成了_MyFunction@4 通过第一种方法模块定义文件的方式DLL编译后导出函数名不会发生改变。 DLL(动态库)导出函数名乱码含义 C++编译时函数名修饰约定规则：   __stdcall调用约定：   1、以"?"标识函数名的开始，后跟函数名；    2、函数名后面以"@@YG"标识参数表的开始，后跟参数表；    3、参数表以代号表示：   X--void   D--char   E--unsigned char   F--short   H--int   I--unsigned int   J--long   K--unsigned long   M--float   N--double   _N--bool   ....   PA--表示指针，后面的代号表明指针类型，如果相同类型的指针连续出现，以"0"代替，一个"0"代表一次重复；   4、参数表的第一项为该函数的返回值类型，其后依次为参数的数据类型,指针标识在其所指数据类型前；    5、参数表后以"@Z"标识整个名字的结束，如果该函数无参数，则以"Z"标识结束。   其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ"，例如                       int Test1(char *var1, unsigned long)-----"?Test1@@YGHPADK@Z"                      void Test2()-----"?Test2@@YGXXZ"    __cdecl调用约定：   规则同上面的_stdcall调用约定，只是参数表的开始标识由上面的"@@YG"变为"@@YA"。   __fastcall调用约定：   规则同上面的_stdcall调用约定，只是参数表的开始标识由上面的"@@YG"变为"@@YI"。   如果要用DEF文件输出一个"C++"类，则把要输出的数据和成员的修饰名都写入.def模块定义文件   所以...   通过def文件来导出C++类是很麻烦的,并且这个修饰名是不可避免的


Question: c语言问题

main函数是整个程序的切入点，即运行的时候是从main函数里第一条语句开始执行的。main函数与系统交互的参数就是main函数里的两个参数（参数个数和参数内容）； 我们都能理解自定义函数里，我们通过传递实参来调用自定义函数。同样，main作为与系统接口的函数，那么main可以理解为一个子函数，调用它的是系统。系统可以传递参数进来，也可以定义main的参数为void.

不知道这个是不是你需要的http://blog.csdn.net/tong_xin2010/article/details/41008863

引用 2 楼 qq_24282081 的回复:这我知道，可是他没有让用户输入的语句啊，直接就存储吗  这是C++编译的执行程序的入口点，由系统调用，参数也由系统处理之后传进来的  很类似exe调用dll，dll函数作为入口点，由exe中调用，参数由它传递过来

这我知道，可是他没有让用户输入的语句啊，直接就存储吗

int main(int argc, char *argv[]) //argc指明输入参数个数，argv存储参数的字符串形式


Question: 字符串的修改（串）

代码可读性很差，局部变量太多，随意定义。循环变量i,j,k，这是大家通用的。计数变量cnt(count)也是大家通用的，定义这些变量大家基本上都能理解是什么意思，做什么的。还有如果有些变量特殊，建议使用单词或者对应单词的缩写。 gets不建议使用，不安全。使用scanf或者fgets代替gets

什么问题？感觉你这个程序有点危险，主要还是0的问题，也就是字符串结尾的问题。保险期间，建议声明数组时初始化为0.  char a[80]={0}, b[80]={0}, c[80]={0};


Question: fread以二进制读取变量和实际看到的不一样

引用 3 楼 zgl7903 的回复:用无符号BYTE  UINT 数据 谢谢高手，我加个unsigned解决了

A程序 int main() { 	int f = 5152628; 	printf("%d", f); 	getchar(); 	return 0; } B程序 int main() { 	FILE *WinIn; 	ULONGLONG i; 	int sum; 	char buffer; 	if (WinIn = fopen("A.exe", "rb+")) 	{ 		printf("OPEN TEST1.EXE SUCCESS"); 		printf("\n"); 		getchar(); 	} 	else 	{ 		printf("OPEN A.EXE FAIL"); 		getchar(); 		exit(0); 	}        fseek(WinIn, 0xbe7, SEEK_SET); 	sum = ftell(WinIn); 	printf("LOCATION IS %x",sum); 	printf("\n");         for(i = 0;i <06 ;i++)        { 	fread(&buffer,1,1,WinIn); 	printf("%x",buffer);         }         getchar();         fclose(WinIn);         return 0; }

对了，用的是VSC2015，程序是.cpp  引用 2 楼 jianwen0529 的回复:怎么个格式写出去，就怎么个格式读进来  把读写代码贴出来才好分析 用一个char保存，用%X打印的

用无符号BYTE  UINT 数据

怎么个格式写出去，就怎么个格式读进来  把读写代码贴出来才好分析


Question: 能自由排版的C语言就是好，就是好呀就是好呀就是好！

百度搜的代码啊? 好个粑粑啊

棒棒哒，初学者正在学使用csdn

受 SQLite 多年青睐，C 语言到底好在哪儿？ https://www.oschina.net/news/99485/why-is-sqlite-coded-in-c

http://bbs.csdn.net/topics/380157851?page=1 哈哈，看了赵老师这几篇，真的觉得很有意思。 在不考虑代码内容、代码可读性又保证代码正确的情况下，探索代码的编码风格和手法，确实是一件很有趣的事情。

C 语言编程可以写成这个样子，厉害厉害

C代码的优雅，哈奥！

挽尊。。。。。。 谁还敢说我们程序员没有艺术细胞！！！

接分，赵老师威武

接点分，支持赵老师，

我悄悄的来接分，把以前发给赵老师的分接回来

一度与怪异发生关联之后，会更容易被怪异所吸引。

能(wu)自(chan)由(jie)排(ji)版(wen)的(hua)C(da)语(ge)言(ming)，嗨！就是好，就是好呀就是好呀就是好！

这个好看是好看，读懂干啥就不容易了。不过C语言是永远的爱！爱C语言的自由自在，无所不能。这是距离汇编语言最近的高级语言，感觉整个电脑都尽在手中。 用java之类的面向对象语言总是缚手缚脚的。虽然java也是好语言.......

赵老师比较有时间，尽情研究

这个我点赞 了。。反正我觉得很牛。只是我看不懂。。。写成这样还可以跑起来也是好代码了

赵4老师威武

C语言怪异代码大赛历届作品大全 1984～1996，1998，2000，2001，2004～2006，2011，2012http://download.csdn.net/detail/zhao4zhong1/5538847

挽。。挽。。挽


Question: 关于回调函数LRESULT CALLBACK  的分号？？

手动敲一遍。  如果还有那么就不是这一段的问题。

看起来这应该是一个windows程序 是不是你没有包含必须的头文件导致那些并没有定义就使用了？

建议你重新敲一下代码。有时候是因为字符格式问题，复制的有时候是不可以用的。特别是采用不同格式保存 。单看这个看不出来

标点符号必须用英文的

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


Question: 新手代码改错请多多指教

if和else后面最好是{}要不然就是后面的第一个语句。你加了;也就是空语句。

感谢指明，很受启发！

lf和else的括号后应该不加分号吧

#include <stdio.h> #include <math.h>  int main(void) {     int x, a, b, sum, sub, multi, mod;     float dev;      printf ("Please input n:\n");     scanf ("%d", &x);      if (x > 0) {         a = x /100;         b = x % 100;         printf ("%d, %d\n", a, b);     } else {         a = -abs(x) / 100;         b = -abs(x) % 100;          printf ("%d, %d\n", a, b);     }      printf ("a = %d, b = %d\n", a, b);     sum = a + b;     printf ("sum = %d\n", sum);     sub = a - b;     printf ("sub=%d\n", sub);     multi = a * b;     printf ("multi=%d\n",multi);     if (b ==0) {         printf ("The second operator is zero!\n");     } else {         dev = a *1.0 / b;         printf ("dev=%.2f\n", dev);         mod = a % b;         printf ("mod=%d\n", mod);     }       return 0; } 基本语法错误，建议自己一个一个的解决；LZ是初学C语言吗？问题比较多了，另外，求余数的运算，除数也是不能为0的。

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


Question: 做题时交上代码出现runtime error，辅助解释是ot allowed system call: runid:275149 :使用了系统禁止的操作系统调用

在Linux下编译和运行没有问题

引用 3 楼 Jack_zhuiyi 的回复:不是。。。这个define是因为我在VS上运行，不加的话，scanf会报错。。。  报错的话， 请把它加在 项目属性的 预处理器定义中：

n的大小是0—10

自己编译器编译链接答案均是对的…交到oj上就报那个错了…

运行时错误，单步调试下，看具体是哪行代码出错

#define _CRT_SECURE_NO_WARNINGS 这行的锅

题目大致描述是给定一个n，和一个2^n长的位串，如3，10001011，将位串不断二分，左边作为左子树，右边作为右子树。当位串包含1和0时节点存'F'，位串全为0时，节点存'B'，位串全为1时，存'I'。输出时，后序遍历树，输出一个字符串。


Question: 求助，关于素数的判断与输出，

好猥琐的代码

f(n%i==0) { flag=1; i=i+1;  红色那句，在找到素数之后，终止了while循环，当然只能找到一个素数

#include<stdio.h> #include<math.h>  int judgeprime(int n) {     int k,i,flag;     k=sqrt((double)n);     i=2;flag=0;     while(i<=k&&flag==0)     {         if(n%i==0)         {             flag=1;             i=i+1;         }         else {             i++;         }     }     return(!flag); } int main() {     int k;     for(k=3;k<100;k=k+2)     {         //printf("%d",k);         if(judgeprime(k)==1)         {             printf("%d\n",k);         }     }      return 0; } 注意判断条件，i的值也是需要变化的

Finding prime numbers - Kenneth Haugland  Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers

循环判断条件在if语句里，在条件不成立时成为死循环，把判断条件移出来就行了

#include<stdio.h> #include<math.h> int judgeprime(int n) { 	int k, i, flag; 	k = sqrt((double)n); 	i = 2; flag = 0; 	while (i <= k&&flag == 0) 	{ 		if (n%i == 0 || n%(i+2) == 0) 		{ 			flag = 1; 			 		} 	i = i + 1;//把这个提出来啊，不能只在里边转啊。成死循环了 	} 	return(!flag); } void main() { 	int k; 	for (k = 3; k<100; k = k + 2) 	{ 		printf("%d\t", k); 		if (judgeprime(k) == 1) 		{ 			printf("%d\n", k); 		} 	} 	 }


Question: 利用二叉搜索树的中序遍历进行排序时遇到问题，求助

引用 1 楼 jianwen0529 的回复:把p的指针值赋给q，只会改变q的指针值，并不会影响root中即后续左右子树的指针值（注意是指针值，不是指向的内存）   void TreeBuild(int num) {     if (root == NULL)     {         root = (struct BiSearchTree *)malloc(sizeof(struct BiSearchTree));         root -> data = num;         root -> lchild = root -> rchild = NULL;     }     else     {         p = (struct BiSearchTree *)malloc(sizeof(struct BiSearchTree));         p->data = num;         p->lchild = p->rchild = NULL;                  //增加一个parent指针，来记录数据插入点的父节点，然后把数据插入到此节点的左右子树当中         parent = q = root;         while(q != NULL)         {             parent = q;             if (num > q -> data && q->rchild)             {                 q = q -> rchild;             }             else if (num < q->data && q->lchild)             {                 q = q -> lchild;             }             else             {                 break;             }         }                  if (num > q->data)         {             parent->rchild = p;         }         else         {             parent->lchild = p;         }     } }  谢谢，我明白了。

parent这个指针有些多余了，修改如下          q = root;         while(q != NULL)         {             if (num > q -> data && q->rchild)             {                 q = q -> rchild;             }             else if (num < q->data && q->lchild)             {                 q = q -> lchild;             }             else             {                 break;             }         }                   if (num > q->data)         {             q->rchild = p;         }         else         {             q->lchild = p;         }


Question: 很想使用vs学习c，但是怎么弄都是用不了，各位看看有方法吗?

Linux下编程，可以考虑找我。

这个SDK可以单独安装的。不会加我Q。510323535

提示已经说得很清楚了，确实sdk  你安装vs的时候是不是缺少选择某些项？ 打开安装包文件，选择增加或者删除功能看看是不是sdk没有勾选安装  实在不行就下个2013 或者 2015的正式版本

辛苦各位再帮我看看

引用 1 楼 jianwen0529 的回复:.c 怎么在头文件那栏？  把它移除，在源文件项右键——增加——然后找到这个文件添加进去   不是很懂， 具体点


Question: 这道ACM河南省赛的题目有人会吗？求教

没有大神教教我吗？


Question: 将十进制转换为十六进制后的数组，如何返回，在主函数中得到应用

按照一楼做了简单改动，以解决

int* aa1(int num) { int *result = (int*)malloc(sizeof(int)*100);  return result; }  void aa2(int num, int result[]) { //result代替你a }  int main() { int x; int *ret = aa1(x); free ret;  int arr[100[; aa2(x, arr); }


Question: 如何有效清空udp socket的缓存

recvfrom读到的数据是内核给的，如果要清也是清内核里收到的数据。 不建议清除缓存的方式处理，建议你收到数据之后判断一下数据内容，不是自己想要的直接丢掉即可呢； 如果去清缓存会增加难度。


Question: mingw gcc 编译helloworld 不生成可执行文件

引用 4 楼 w1641 的回复:@DelphiGuy，执行as --32 hello.s -o hello.o也没有文件生成  我用tdm-gcc-64 5.1测试是正常的，你看看目录的访问权限。

注意有无错误信息。  关了杀毒软件。

cmd输入 gcc -help 测试配置是否正确  编译的时候先进入到你文件所在目录

@cfjtaishan， 啥问题，怎么解决 @DelphiGuy，执行as --32 hello.s -o hello.o也没有文件生成

gcc -c hello.s -o hello.o 应该用 as --32 hello.s -o hello.o

不是程序的问题，应该是编译环境的问题；

同时尝试了单步调试， 首先执行gcc -E hello.c -o hello.i，生成了19KB大小的hello.i，个人认为这部执行时没有问题的 再次执行gcc -S hello.i -o hello.s，生成了1KB大小的文件hello.s， 然后想通过gcc -c hello.s -o hello.o，就没有结果文件生成了，也不报错。  第二步生成的hello.s用文本方式打开如下， 	.file	"hello.c" 	.def	___main;	.scl	2;	.type	32;	.endef 	.section .rdata,"dr" LC0: 	.ascii "hello world!\0" 	.text 	.globl	_main 	.def	_main;	.scl	2;	.type	32;	.endef _main: LFB6: 	.cfi_startproc 	pushl	%ebp 	.cfi_def_cfa_offset 8 	.cfi_offset 5, -8 	movl	%esp, %ebp 	.cfi_def_cfa_register 5 	andl	$-16, %esp 	subl	$16, %esp 	call	___main 	movl	$LC0, (%esp) 	call	_puts 	movl	$0, %eax 	leave 	.cfi_restore 5 	.cfi_def_cfa 4, 4 	ret 	.cfi_endproc LFE6: 	.ident	"GCC: (GNU) 4.8.1" 	.def	_puts;	.scl	2;	.type	32;	.endef  哪位大侠帮忙看下，是什么原因导致的，谢谢


Question: 求教 Visual Studio Code 开发C语言 如何 格式化代码 ？

我也是用vscode来编辑c语言项目的，但是按ctrl+alt+F或者如下图一样，选中所有的代码之后然后点击右键，选择格式化代码，也是没有任何变化

LZ解决了吗？我也遇到了

已经选了， 用鼠标 全部都选中了。。。。 有哪个项目 但是 点了后 也没反应。。。 感觉是不是需要配置 格式文件啊？ 还是怎么样？

你试试是不是需要选择文本才能进行格式化  —————————————————————————————— 代码格式化： Shift+Alt+F，或 Ctrl+Shift+P 后输入 format code 引用自http://www.cnblogs.com/bindong/p/6045957.html


Question: poj1029 输入总是有问题，求解答

scanf("%c",&com); /*接收了缓存里的'\n'回车了。*/  建议在这句上面加上一句：  getchar(); scanf("%c",&com);

网上找下AC的代码吧。 1.看看你们的输入输出格式是不是一致 2.多测试一些样例


Question: 在线等！

好多问题： 1.没有#endif 2.第22行student[];应该是student[MAXSIZE]; 3.第39行，return 0;应该是return; 4.第30,36行，你的Student结构体根本没有成员变量叫name,num,age的

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

另外，scanf格式 %s后面的name,no都不需要再加&，因为本身就是数组，数组名就是地址。

你的代码编译有比较多的语法问题，首先运用的结构体成员未定义，很明显和结构体定义的不符。 C语言不支持可变数组，所以长度需要是固定的。

一般是少 { }之类的  你struct少了一个 }


Question: 帮我看下这个程序有没有问题，这个c prime里面的

#include<stdio.h> int main(void) { 	float megabits; 	float megabytes;  	float seconds; 	printf("请输入你家的网速："); 	scanf("%f",&megabits) ; 	printf("请输入你要下载的程序大小："); 	scanf("%f",&megabytes); 	seconds=megabytes/megabits*8; 	printf("At %.2f megabits per seconds," 	"a file of %.2f megabytes.\n",megabits,megabytes); 	printf("downloads in %.2f seconds",seconds); 	return 0; 	  }    错误的位置我改了，主要是对于seconds的算法错了 真是一个宝地

除十次都可以  seconds=megabytes/(megabits/8); 或者 seconds=megabytes*8/megabits;  2.20 ÷ 18.12 ÷ 8 跟  2.20 ÷ (18.12 ÷ 8)  可不一样

请输入你家的网速：18.12 请输入你所下载的文件大小：2.20 At 18.12 megabits per seconds,a file of 2.20 mmegabytes downloads in 0.02 seconds. 请按任意键继续. . .   但是为什么最后会出现这个结果呢，正常结果应该是0.97

程序里面允许   seconds = megabytes/(megabits*8);，这么写么？感谢了

#include<stdio.h> int main(void) {     float megabits;     float megabytes;     float seconds;      printf("请输入你家的网速：");     scanf("%f",&megabits);     printf("请输入你所下载的文件大小：");     scanf("%f,",&megabytes);     seconds = megabytes/(megabits*8);     printf("At %.2f megabits per seconds,a file of %.2f mmegabytes\n",megabits, megabytes);     printf("downloads in %.2f seconds.\n", seconds);     return 0;  } 最后一个输出缺少东西。

#include<stdio.h> int main(void) {     char name [20];     float megabits;     float megabytes;     float seconds;      printf("请输入你家的网速：");     scanf("%f",&megabits);     printf("请输入你所下载的文件大小：");     scanf("%f,",&megabytes);      seconds = megabytes/(megabits*8);     printf("At %.2f megabits per seconds,a file of %.2f mmegabytes\n",megabits,megabytes);     printf("downloads in %.2f seconds.\n");     return 0;  } 除两次，为啥不除于后两个数的乘积呢？ 灵活一些


Question: 用char *指针从源到目的复制一个int或者double数组

毫无区别，memcpy不管类型的，都是按字节内容拷贝

比如源和目的都用char *指针，就是把指针指向那一个字节作为char复制到目的数组，目的字节对源字节的位模式没有改变（因为用相同类型的指针），对吗？

完全没问题，只要不是转换类型进行解析

能，和类型没关，你复制的长度大小正确就没问题

我的理解，不论什么数据在内存里存放的方式都是一样的，0和1，而我们读出来的数据不一样，是因为我们用不同的格式读取的，不如整型，float类型等等； 只要注意大小端，传输是没问题的； 以下是我的demo: #include <stdio.h> #include <string.h>  int main(void) {     int i;     double dnum = 125.887;     int num = 345;      char buf[32];      memcpy(buf, &dnum, sizeof(dnum));     for (i = 0; i < sizeof(dnum); i++) {         printf("%u ", *((unsigned char *)buf+i));     }     printf("\n");     dnum = *(double *)buf;     printf("num = %lf\n", dnum);      memcpy(buf, &num, sizeof(num));     for (i = 0; i < sizeof(num); i++) {         printf("%u ", *((unsigned char *)buf+i));     }     printf("\n");      num = *(int *)buf;     printf("num = %d\n", num);      return 0; }


Question: c语言问题求纠错

你的代码验证了一下，测试了你的用例，没有什么问题。

多写多练多读。

程序没有问题啊，你的问题是什么？

引用 1 楼 cfjtaishan 的回复:把错误贴出来，最好把你的代码粘贴出来（不是图片形式）可以协助给你调一下  #include <stdio.h>  int main(){     int a[100]={0};     //各幂次对应的系数     int x=0,y=0;        //幂次x，系数y     int flag=0,cnt=0;   //非零项最低幂次flag   输出次数cnt      for(int i=0;i<2;i++){       //输入次幂和系数         do{             scanf("%d %d",&x,&y);             a[x]+=y;         }while(x!=0);     }       for(int i=0;i<100;i++){     //寻找非零项最低的幂次记为flag         if(a[i]!=0){             flag=i;             break;         }     }      for(int i=99;i>=0;i--){         if(a[i]!=0){             cnt++;             printf("%d",a[i]);     //输出系数             if(i>0){                 printf("x");                 if(i>1){            //高于一次幂时，输出幂次                     printf("%d",i);                 }             }             if(i>flag){             //非最后一项时输出“+”                 printf("+");             }         }     }      if(cnt==0){                     //全0时输出0         printf("0");     }      printf("\n");     return 0; }

仅供参考：//链表实现一元多项式的加法减法乘法 #include <stdio.h> #include <stdlib.h> typedef struct node {     float coef;   //系数     int expn;     //指数     struct node *next; } PolyNode;      //多项式节点 polynomial node typedef PolyNode* Polynomial; Polynomial createPolynomial() {  //创建多项式     PolyNode *p, *q, *head = (PolyNode *)malloc(sizeof(PolyNode));   //头节点     head->next = NULL;     float coef;     int expn;     printf("输入该多项式每一项的系数和指数，每项一行，输入0 0结束！\n");     while (scanf("%f %d", &coef, &expn) && coef) {   // 默认，按指数递减排列         if (head->next) {             p = head;             while (p->next && expn < p->next->expn)                 p = p->next;             if (p->next) {                 if (expn == p->next->expn) { //有相同指数的直接把系数加到原多项式                     p->next->coef += coef;                     if (p->next->coef > -0.000001 && p->next->coef < 0.000001) { //若是相加后系数为0，则舍弃该节点                         q = p->next;                         p->next = q->next;                         free(q);                     }                 } else {                     q = (PolyNode*)malloc(sizeof(PolyNode));                     q->coef = coef;                     q->expn = expn;                     q->next = p->next;                     p->next = q;                 }             } else {                 p->next = (PolyNode*)malloc(sizeof(PolyNode));                 p = p->next;                 p->coef = coef;                 p->expn = expn;                 p->next = NULL;             }         } else {             head->next = (PolyNode*)malloc(sizeof(PolyNode));             head->next->coef = coef;             head->next->expn = expn;             head->next->next = NULL;         }     }     return head; } Polynomial multiply(Polynomial poly, float coef, int expn) {  //多项式与指定单项式相乘，该单项式为 coefx^expn     PolyNode *p, *q, *Poly = (PolyNode*)malloc(sizeof(PolyNode));     p = Poly;     q = poly->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = (q->coef*coef);         p->expn = (q->expn + expn);         q = q->next;     }     p->next = NULL;     return Poly; } void add(Polynomial poly1, Polynomial poly2) {  //把 poly2 加到 poly1 上     PolyNode *p, *q, *r;     r = poly1;     p = poly1->next;  //指向第一个节点     q = poly2->next;     poly2->next = NULL;     while (p && q) {         if (p->expn > q->expn) {             r->next = p;             p = p->next;             r = r->next;         } else if (p->expn < q->expn) {             r->next = q;             q = q->next;             r = r->next;         } else {             PolyNode *t;             p->coef += q->coef;             if (!(p->coef > -0.000001 && p->coef < 0.000001)) //系数不为0             {                 r->next = p;                 r = r->next;                 p = p->next;             } else {                 t = p;                 p = p->next;                 free(t);             }             t = q;             q = q->next;             free(t);         }     }     if (p)         r->next = p;     if (q)         r->next = q; } Polynomial polySubtract(Polynomial poly1, Polynomial poly2) {  //多项式减法 poly1-poly2形成一个新的多项式     //把poly2的系数取相反数，形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode)); //构造头节点     PolyNode *p, *q;     p = poly;     q = poly2->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = -(q->coef);  //系数取反         p->expn = q->expn;         q = q->next;     }     p->next = NULL;     add(poly, poly1);  //利用加法     return poly; } Polynomial polyAdd(Polynomial poly1, Polynomial poly2) { //多项式相加 poly1+poly2形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //和多项式的头节点     poly->next = NULL;     PolyNode *p, *q, *r;     r = poly;     p = poly1->next;     q = poly2->next;     while (p&&q) {         if (p->expn > q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = p->coef;             r->expn = p->expn;             p = p->next;         } else if (p->expn < q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = q->coef;             r->expn = q->expn;             q = q->next;         } else {             float m = p->coef + q->coef;             if (!(m > -0.000001 && m < 0.000001)) {                 r->next = (PolyNode*)malloc(sizeof(PolyNode));                 r = r->next;                 r->coef = m;                 r->expn = p->expn;             }             q = q->next;             p = p->next;         }     }     while (p) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = p->coef;         r->expn = p->expn;         p = p->next;     }     while (q) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = q->coef;         r->expn = q->expn;         q = q->next;     }     r->next = NULL;     return poly; } Polynomial polyMultiply(Polynomial poly1, Polynomial poly2) {  //多项式相乘     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //创建多项式和的头节点     poly->next = NULL;     PolyNode *p;     p = poly2->next;     while (p) {         add(poly, multiply(poly1, p->coef, p->expn));         p = p->next;     }     return poly; } void printPoly(Polynomial poly) {  //打印多项式     if (poly && poly->next) {         PolyNode *p = poly->next;  //p指向第一个节点         while (p->next) {             printf("%gx^%d", p->coef, p->expn);             p = p->next;             if (p && (p->coef > 0))                 printf("+");         }         if (p->expn == 0)             printf("%g", p->coef);   //打印常数项         else             printf("%gx^%d", p->coef, p->expn);         printf("\n");     } } void freePoly(Polynomial poly) {  //释放内存     if (poly && poly->next) {         PolyNode *p, *q;         p = poly;         while (p) {             q = p->next;             free(p);             p = q;         }     }     poly = NULL; } int main() {     printf("用链表实现多项式的加减法\n");     Polynomial poly1, poly2, poly3;     printf("创建多项式一\n");     poly1 = createPolynomial();     printf("多项式一：\n");     printPoly(poly1);     printf("创建多项式二\n");     poly2 = createPolynomial();     printf("多项式二：\n");     printPoly(poly2);     printf("两多项式相加，和为：\n");     poly3 = polyAdd(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两个多项式相乘，积为：\n");     poly3 = polyMultiply(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两多项式相减，差为：\n");     poly3 = polySubtract(poly1, poly2);     printPoly(poly3);     freePoly(poly1);     freePoly(poly2);     freePoly(poly3);     system("pause");     return 0; }

#include <stdio.h> int main(){     int a[100]={0};     int x=0,y=0;     int flag=0,cnt=0;     for(int i=0;i<2;i++){         do{             scanf("%d %d",&x,&y);             a[x]+=y;         }while(x!=0);     }     for(int i=0;i<100;i++){         if(a[i]!=0){             flag=i;             break;         }     }     for(int i=99;i>=0;i--){             if(a[i]!=0){                 cnt++;                 printf("%d",a[i]);                 if(i>0){                     printf("x");                     if(i>1){                         printf("%d",i);                     }                 }                 if(i>flag){                     printf("+");                 }             }                  }     if(cnt==0){         printf("0");     }     printf("\n");     return 0; }

把错误贴出来，最好把你的代码粘贴出来（不是图片形式）可以协助给你调一下