Question: C语言遍历结构体

引用 6 楼 jianyuezhimei 的回复:应该说对于结构体内部进行循环遍历不易做到，使用一些变通的方法或许能够做到，但最主要的是这样做毫无意义。因为结构体很多，而且每个结构体里面的数据也比较多，我列举的只是一个小的例子，所以想通过遍历来取结构体中的值，不知道你有没有什么好的方法能实现一个通用的方法。

引用 5 楼 amoyman 的回复:我猜，楼主是要这样遍历结构体内的每个字节吧  InsertProgramQueryCondition ST char *p = (char*)(&St); for (int i =0; i < sizeof(InsertProgramQueryCondition); i++) { //这里 *p 就是要的内容 p++; } 其实这个结构体里面还有其他类型的变量，如果还有int型变量，能遍历吗？

C,C++ 没有直接的方法 按照 成员变量的类型，通过循环访问他。 你不是要做调试程序吧 那是对每个类型的类型信息，做了记录和封装 所以，才能一一看到。

你是要遍历结构体还是要遍历放了很多结构体变量的一个容器？

引用 2 楼 user-5 的回复:请把题目说清楚，光给个struct怎么遍历就是要遍历结构体啊，没其他的要求

引用 11 楼 user-5 的回复:引用 10 楼 u012947254 的回复:[quote=引用 4 楼 qq423399099 的回复:] 你是要遍历结构体还是要遍历放了很多结构体变量的一个容器？我就是想给结构体中的每一个变量赋值，但是想用循环来遍历结构体，不然依次赋值感觉代码很冗余 你有不止一种类型的变量，如何用循环赋值呢？ 再说了，即使可以做到，一个结构体又能有多少变量。何必把简单的问题复杂化。。。[/quote]分给错了，抱歉

引用 10 楼 u012947254 的回复:引用 4 楼 qq423399099 的回复:你是要遍历结构体还是要遍历放了很多结构体变量的一个容器？我就是想给结构体中的每一个变量赋值，但是想用循环来遍历结构体，不然依次赋值感觉代码很冗余 你有不止一种类型的变量，如何用循环赋值呢？ 再说了，即使可以做到，一个结构体又能有多少变量。何必把简单的问题复杂化。。。

请把题目说清楚，光给个struct怎么遍历

没人吗？？？？求大神解答一下啊


Question: Apache获取页面请求

“深入理解Apache Flink核心技术 - 极客头条”


Question: gcc下release与debug版本的程序大小一样吗？

不一样，否则 release 和 debug 就没区别了。 release 一般 -O2 和 -DNDEBUG，debug 用默认的就行了，我看你刚好搞反了。

一般来说，你的debug版本由于添加了调试信息，一般会大一些。但是也有可能你生成的可执行文件本身就比较小，所以这种差别不明显，看起来二者几乎一样大。还有一种可能就是你的makefile某处可能利用strip将生成的可执行文件中的调试信息去掉了，这样对于debug和release来说都不含调试信息了，所以都一样大（你看看makefile里面有没有什么线索）。

理论上release应该更小一些，但实际你也看到了。。。。 可能是你的软件比较小，所以优化减少的那些东西很少，所以不能体现在文件大小上，具体的原因，你看一下汇编代码应该能搞懂，因为汇编代码和机器码是一一对应的

他怀疑非linux系统都是辣鸡

理论上来讲release要比debug小，release版少了很多调试信息

debug版本肯定要大一些。

一样或不一样都行，和哪个版本无关。


Question: 关于栈和循环的问题，求解

1、L是什么呢？看样子是链表吧，最后一个元素的next是不是0呢 2、p应该是一个指针，是什么原因要定义成BigInter

不要只看着代码在想，单步跟踪程序运行，观察分析原因

目测这几个函数会有问题 InitStack() Push() IsEmpty() Pop() IsEmpty()

很明显你的BigInteger 有问题

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


Question: 前置运算符和后置运算符的区别

看看汇编就知道区别了

（2）int a=4;          ++a+=++a;        最终a的值为12，这是为什呢？ 因为这个属于未定义行为，编译器觉得怎么好怎么玩

第二个问题是因为先算++，也就是把+=前后的++都算完了才算+=，算完了左边是6，右边也是6，所以就等于12了

关于C,C++表达式求值顺序  http://bbs.csdn.net/topics/370153775

问题一：对于类对象来说，后置的++实际是返回该对象，然后调用前置的++运算符，所以效率没前置高，对于基本类型来说一样的  问题二：这是一个未定义行为，与顺序点有关

你是再看C++的书吧，这里说的效率高是针对类对象而言的 不知道你有没有看到运算符重载，在运算符重载时，后置运算符函数是调用前置运算符函数实现的，所以后置的比前置的慢一些，至于为什么，你看到那儿就明白了 对于内置类型来说，他们是没有区别的，最后生成的汇编代码都是一样的（估计是inc）

前置运算符是先运算再赋值，后置运算符是先赋值再运算；

引用 4 楼 qq_24689933 的回复:看看汇编就知道区别了 引用 5 楼 qq423399099 的回复:未定义行为，编译器可能会优化也可以不优化，取决于编译器。 不同编译器会得出不同结果 您说的编译器优化应该如何理解呢？ 我是这么想的：如果编译器存在优化，会将a的值(也就是4)放在寄存器中，先进行一次++，寄存器中的值变成5，然后=后面的++a从寄存器中读取数据，然后加1，变成了6，5+6=11，结果为11 如果不存在优化的话，每次取a的值都是从内存中取值，第一次++后内存中值变成5，第二次++变成6，进行加法运算时再从内存中取值：6+6=12，结果为12 我这么理解对么？我对编译器优化不懂。。


Question: 关于输入方面的问题

现在的码农竟然99%都不会在cmd窗口中输入cd命令设置当前目录为程序所在目录，输入程序名运行程序了！

因为1个getchar()不够用。 做个循环，就可以了。 窗口系统下的控制台程序，就是这个味道。 如果是纯粹的控制台，是不会退出，程序运行结束，控制台依然存在。

程序中没有可以让执行暂停的语句，所以一闪而过了。 printf后的getchar把回车给接收了。

运行到了，只是马上就退出了，你多加几个getchar()就可以了 如不明白欢迎继续追问，如满意请及时结贴，谢谢

main函数中的最后加上getchar();  否则程序执行完就直接退出了

运行到了，只是运行时间太短直接退出了，可以加system("pause");查看结果； 或者设置断点单步调试查看结果；

不是进行不到，而是程序正常结束了，你来不及看到。 可以加system("pause"); 或者F5运行


Question: 运行样例时错误  runtimeerror

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


Question: 二叉树链式存储结构

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

引用 5 楼 gongda2014306 的回复:引用 4 楼 gongda2014306 的回复:[quote=引用 3 楼 zxhuser-2 的回复:] [quote=引用 2 楼 gongda2014306 的回复:] 回车？你的意思是我的ch有可能是‘\0’在代码中添加输出ch数值的语句,看看ch值到底是多少 输入1，ch就是1，；输入#，ch就是#，回车符没有影响[/quote] 不对，好像有影响， [/quote] 就是直接在getchar后面加了一句printf

引用 4 楼 gongda2014306 的回复:引用 3 楼 zxhuser-2 的回复:[quote=引用 2 楼 gongda2014306 的回复:] 回车？你的意思是我的ch有可能是‘\0’在代码中添加输出ch数值的语句,看看ch值到底是多少 输入1，ch就是1，；输入#，ch就是#，回车符没有影响[/quote] 不对，好像有影响，

引用 3 楼 zxhuser-2 的回复:引用 2 楼 gongda2014306 的回复:回车？你的意思是我的ch有可能是‘\0’在代码中添加输出ch数值的语句,看看ch值到底是多少 输入1，ch就是1，；输入#，ch就是#，回车符没有影响

引用 1 楼 zxhuser-2 的回复:回车没处理掉? 回车？你的意思是我的ch有可能是‘\0’

回车没处理掉?


Question: 程序莫名停止运行 找不到问题

引用 1 楼 u010165006 的回复:scanf("%d",&a[i]); 确实是scanf的问题，我把a[]和指针的使用方式搞错了

SUM里面的变量j也可以名为i，因为SUM里的i和main里的i都是局部变量是不同的。

sum的逻辑不对：   for(j=0;j<n;j++)      {         sum += *(p+j);          if(*(p+j)%2!=0)              printf("%d ",*(p+j));      }

scanf("%d",&a[i]);


Question: 请问大家，C语言函数只要加了函数声明，可以在任何地方使用，那么结构体也可以这样吗？

不行的，你调用的函数只是一个入口地址，而定义结构体变量是要分配内存的，只看到声明无法确定所占内存大小，所以编译器必须见到结构体的定义，这也是为什么结构体和类的定义放在头文件，而相关函数的实现放在实现文件中的原因

不完整类型


Question: 大家好，C语言在下面定义了一个结构体，要在定义的上面使用,除了移动到上面定义还有其他方法吗?能不能像函数声明一样，上面就可以用了?

前置声明了也还是不完整类型，只能用指针类型

有大神没呢？


Question: 关于大数求余数问题

引用 1 楼 qq423399099 的回复:输入和报错的截个图看看 我是在nyoj上边测试的

输入和报错的截个图看看


Question: 关于C中fgetc读文件

char ch; 改成 int ch; C 读写字符，返回int 而不是 char, 因为返回值，同时表示读取的字符，和读取文件的状态（成功，失败，文件结束）

引用 1 楼 user-2 的回复:运算符优先级 有点明白了，关系运算符优先级要高于赋值运算。谢谢

运算符优先级


Question: c语言的新人 有个程序看不懂   麻烦帮帮忙  谢谢了

引用 10 楼 user-1 的回复:[quote=引用 9 楼 qq_35555558 的回复:] [quote=引用 7 楼 user-1 的回复:] [quote=引用 6 楼 qq_35555558 的回复:] [quote=引用 5 楼 user-1 的回复:] [quote=引用 3 楼 qq_35555558 的回复:] 那为什么输入一旦大于十位数 output2的name就只输出大于十位数的呢  比如我输进去1234，他就会输出1234.但是我输入123456789012    他就只输出12了  越界了！然后如何处理就说不清楚了  请先处理了越界再说[/quote]  我的问题就是，为什么越界了之后，他只输出后面多的那几位。。。而且output2中的name2即使越界，为什么能输出完整的呢。。。[/quote]  你去研究越界以后的表现有意义么？ 而且我可以告诉你，表现是不一样的，我测试的结果和不一样   Hi! what's your first name? 123456789012 output 1:123456789012, ?@ output 2:123456789012, 123456789012 output 3:10, 4   这个是我这里的表现[/quote]  。。。。 64位和32位不一样对吧。。。我的指针size是8。。。  那用strcpy（）的时候，name的值给了name2的话    name2就不用考虑之前的10个内存了对吧    该多少就多少   12个数就12个数[/quote]  这些不是重点[/quote]   好吧谢谢了！！！！

引用 9 楼 qq_35555558 的回复:[quote=引用 7 楼 user-1 的回复:] [quote=引用 6 楼 qq_35555558 的回复:] [quote=引用 5 楼 user-1 的回复:] [quote=引用 3 楼 qq_35555558 的回复:] 那为什么输入一旦大于十位数 output2的name就只输出大于十位数的呢  比如我输进去1234，他就会输出1234.但是我输入123456789012    他就只输出12了  越界了！然后如何处理就说不清楚了  请先处理了越界再说[/quote]  我的问题就是，为什么越界了之后，他只输出后面多的那几位。。。而且output2中的name2即使越界，为什么能输出完整的呢。。。[/quote]  你去研究越界以后的表现有意义么？ 而且我可以告诉你，表现是不一样的，我测试的结果和不一样   Hi! what's your first name? 123456789012 output 1:123456789012, ?@ output 2:123456789012, 123456789012 output 3:10, 4   这个是我这里的表现[/quote]  。。。。 64位和32位不一样对吧。。。我的指针size是8。。。  那用strcpy（）的时候，name的值给了name2的话    name2就不用考虑之前的10个内存了对吧    该多少就多少   12个数就12个数[/quote]  这些不是重点

引用 7 楼 user-1 的回复:[quote=引用 6 楼 qq_35555558 的回复:] [quote=引用 5 楼 user-1 的回复:] [quote=引用 3 楼 qq_35555558 的回复:] 那为什么输入一旦大于十位数 output2的name就只输出大于十位数的呢  比如我输进去1234，他就会输出1234.但是我输入123456789012    他就只输出12了  越界了！然后如何处理就说不清楚了  请先处理了越界再说[/quote]  我的问题就是，为什么越界了之后，他只输出后面多的那几位。。。而且output2中的name2即使越界，为什么能输出完整的呢。。。[/quote]  你去研究越界以后的表现有意义么？ 而且我可以告诉你，表现是不一样的，我测试的结果和不一样   Hi! what's your first name? 123456789012 output 1:123456789012, ?@ output 2:123456789012, 123456789012 output 3:10, 4   这个是我这里的表现[/quote]  。。。。 64位和32位不一样对吧。。。我的指针size是8。。。  那用strcpy（）的时候，name的值给了name2的话    name2就不用考虑之前的10个内存了对吧    该多少就多少   12个数就12个数

越界以后会如何并没有规定。 一、编程时应该自己防止越界； 二、或者改成这样    scanf("%9s", name);  这个可以自动丢弃多余的输入

引用 6 楼 qq_35555558 的回复:[quote=引用 5 楼 user-1 的回复:] [quote=引用 3 楼 qq_35555558 的回复:] 那为什么输入一旦大于十位数 output2的name就只输出大于十位数的呢  比如我输进去1234，他就会输出1234.但是我输入123456789012    他就只输出12了  越界了！然后如何处理就说不清楚了  请先处理了越界再说[/quote]  我的问题就是，为什么越界了之后，他只输出后面多的那几位。。。而且output2中的name2即使越界，为什么能输出完整的呢。。。[/quote]  你去研究越界以后的表现有意义么？ 而且我可以告诉你，表现是不一样的，我测试的结果和不一样   Hi! what's your first name? 123456789012 output 1:123456789012, ?@ output 2:123456789012, 123456789012 output 3:10, 4   这个是我这里的表现

引用 5 楼 user-1 的回复:[quote=引用 3 楼 qq_35555558 的回复:] 那为什么输入一旦大于十位数 output2的name就只输出大于十位数的呢  比如我输进去1234，他就会输出1234.但是我输入123456789012    他就只输出12了  越界了！然后如何处理就说不清楚了  请先处理了越界再说[/quote]  我的问题就是，为什么越界了之后，他只输出后面多的那几位。。。而且output2中的name2即使越界，为什么能输出完整的呢。。。

引用 3 楼 qq_35555558 的回复:那为什么输入一旦大于十位数 output2的name就只输出大于十位数的呢  比如我输进去1234，他就会输出1234.但是我输入123456789012    他就只输出12了  越界了！然后如何处理就说不清楚了  请先处理了越界再说

引用 1 楼 user-1 的回复:    scanf("%s", name);     printf("output 1:%s, %s\n", name, name2); 程序错误太多 第一句：name数组10个元素，输入那么长，越界了！ 第二句：name2没有初始化   但是为什么输入大于10个元素   就只有后面几位呢    比如输入1234567890123    只输出123

问题二：语法含义不同嘛  sizeof(name)：数组有几个元素   sizeof(name_p)：指针有几个字节


Question: sizeof求数组大小的问题

#include <iostream> using namespace std;}  extern const float model[];  void SizeofAfterDeclare(){        //cout <<sizeof(model)<<endl; //报错 } const float model[]={     1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; void SizeofAfterDefine(){        cout <<sizeof(model)<<endl; //没问题。 }  int main(){      SizeofAfterDeclare();      SizeofAfterDefine();      return 0; }   C,C++ 文法，是上下文相关文法。 不是上下文无关文法。 1） 声明以后，不能知道数组大小，除非直接标明大小 2) 定义以后，可以准确知道数组的大小 ------用常量表达式定义的， 或者用初始化表定义，编译器点数的-------------

不同实现文件中，声明相同名字的数组，大小可以不一致 各个实现文件中，该数组，是同一个，数组， 不过可以得到本文件的声明的数组大小。

楼主其实可以直接把 include a.h 换成 #include "tables.cpp"

incomplete type

The sizeof operator shall not be applied to an expression that has function type or an incomplete type

sizeof 的计算发生在代码编译 的时刻。。  extern 标注的符号 在链接的时刻解析。。。   所以 sizeof 不知道 这个符号到底占用了多少空间。  原因在于没有声明长度的数组是个不完整类型。 匿名长度的数组声明在有初始化值定义时会有编译器根据初始化列表确定其长度。但是对与extern文件外部的数组，只有链接时才能确定其大小（同一文件的extern我等会测试），但sizeof运算符需要在编译时就确定对象的大小，于是错误就出现了。 解决办法就是声明的时候给它个长度。

编译期的话，写上大小就行了，运行期的话，(tables.cpp里)用一个函数返回大小，编译器会优化的


Question: 新手关于c语言知识   求教谢谢

引用 12 楼 qq_35555558 的回复:[quote=引用 11 楼 liups 的回复:] [quote=引用 9 楼 qq_35555558 的回复:] [quote=引用 7 楼 liups 的回复:] printf("output 4:%x, %x\n", name_p,name_p2); 加这句，观察结果    出来是字母加数字的结合。。。说明了什么[/quote]  %x是以16进制输出，也就是分别输出name和name2的地址，你不会不知道吧？！[/quote]    。。。。。 我现在的水平就是个hello world[/quote] 就这个研究越界问题？

name:0011-0020，由于输入12个字符（再加上结束标记） 所以，0011-0023都被占用了，那么首先是0021-0023是分配给谁的，如果刚好是空闲的，这里没有大问题，没有其他变量被覆盖  接下来，  strcpy(name2, name);  这个会出现如下现象： 0001-0013："123456789012"，实际上name的前3个被修改了（巧合的是前2个和原来一样），但是原来第3个由'3'变成了'\0'，相当于name变成了"12"  以上仅限于楼主17楼描述的内存状况，实际上我的测试结果和你是不一样的（大家用的编译器不一样）  小结：不要去越界，因为你不知道会发生什么

引用 14 楼 liups 的回复:[quote=引用 12 楼 qq_35555558 的回复:] [quote=引用 11 楼 liups 的回复:] [quote=引用 9 楼 qq_35555558 的回复:] [quote=引用 7 楼 liups 的回复:] printf("output 4:%x, %x\n", name_p,name_p2); 加这句，观察结果    出来是字母加数字的结合。。。说明了什么[/quote]    %x是以16进制输出，也就是分别输出name和name2的地址，你不会不知道吧？！[/quote]    。。。。。 我现在的水平就是个hello world[/quote] 就这个研究越界问题？[/quote]             char name[10];     char name2[10]; 在内存中申请了两块大小为10字节的内存区，存放于栈区，由于mac中c语言编译运行中内存是向上生长的，所以内存中地址如下所示： 地址：0001-0010，0011-0020 变量名：name2，name1 scanf("%s", name); #输入123456789012是内存中各位置中数据是这样的： 地址：0001-0010，0011-0020, 0021,0023 数据：??????????, 1234567890, 12'\0'???????  又给点提示。。。

引用 13 楼 zxhuser-3 的回复:数组越界...没事别做这么危险的事     跟分配内存有关系，但是具体不知道。。。能帮一下么

引用 13 楼 zxhuser-3 的回复:数组越界...没事别做这么危险的事   越了呢 会怎样？为什么前十位会自动隐藏，只输出十位后面的。

引用 11 楼 liups 的回复:[quote=引用 9 楼 qq_35555558 的回复:] [quote=引用 7 楼 liups 的回复:] printf("output 4:%x, %x\n", name_p,name_p2); 加这句，观察结果    出来是字母加数字的结合。。。说明了什么[/quote]  %x是以16进制输出，也就是分别输出name和name2的地址，你不会不知道吧？！[/quote]    。。。。。 我现在的水平就是个hello world

引用 9 楼 qq_35555558 的回复:[quote=引用 7 楼 liups 的回复:] printf("output 4:%x, %x\n", name_p,name_p2); 加这句，观察结果    出来是字母加数字的结合。。。说明了什么[/quote]  %x是以16进制输出，也就是分别输出name和name2的地址，你不会不知道吧？！

让你观察地址的输出！  如果你运气好，name后面可能有空置没有用到的内存空间，比如6个字节共16个字节，然后才是name2  那么这个越界实际上并没有造成严重的后果，因为你这里只需要13个字节

引用 7 楼 liups 的回复:printf("output 4:%x, %x\n", name_p,name_p2); 加这句，观察结果    出来是字母加数字的结合。。。说明了什么

数组越界...没事别做这么危险的事

http://www.cnblogs.com/hanyulcf/archive/2010/05/24/1742781.html  对齐

引用 3 楼 liups 的回复:[quote=引用 1 楼 liups 的回复:] 又来了。 数组越界啊  重点是name和name2是不是紧挨或连续，这个可没有规定，也可能是name后面是letters，然后才是name2  总之，取决于编译器如何实现  从编译优化的角度看，有较大可能是这样的： name为10个char 后面为了对齐（为了速度）可能会空几个，然后再是name2  而对齐通常是和编译器的位数有关，比如32位的，通常是4的倍数，所以空2个字节，而64位的则空6个字节[/quote]   不太明白对齐是什么意思。。。 当我输出位数小于10的时候，是全部输出，位数大于10，自动忽略掉前十位，只输出十位后面的。按你这个说法，电脑是64位的话，应该空6个字节，为什么是10个呢

引用 2 楼 qq_35555558 的回复:[quote=引用 1 楼 liups 的回复:] 又来了。 数组越界啊  重点是name和name2是不是紧挨或连续，这个可没有规定，也可能是name后面是letters，然后才是name2  总之，取决于编译器如何实现   老师一定让做出来。。。他说跟分配内存有关系。。。我实在不知道咋做。。。 什么叫name后面是letters 然后才是name2.。。[/quote]  如果老师让你观察，我可以理解。做出来？不明白

引用 2 楼 qq_35555558 的回复:[quote=引用 1 楼 liups 的回复:] 又来了。 数组越界啊  重点是name和name2是不是紧挨或连续，这个可没有规定，也可能是name后面是letters，然后才是name2  总之，取决于编译器如何实现   老师一定让做出来。。。他说跟分配内存有关系。。。我实在不知道咋做。。。 什么叫name后面是letters 然后才是name2.。。[/quote]  输出name和name2的地址观察一下吧（通过调试也可以观察）

引用 1 楼 liups 的回复:又来了。 数组越界啊  重点是name和name2是不是紧挨或连续，这个可没有规定，也可能是name后面是letters，然后才是name2  总之，取决于编译器如何实现  从编译优化的角度看，有较大可能是这样的： name为10个char 后面为了对齐（为了速度）可能会空几个，然后再是name2  而对齐通常是和编译器的位数有关，比如32位的，通常是4的倍数，所以空2个字节，而64位的则空6个字节

引用 1 楼 liups 的回复:又来了。 数组越界啊  重点是name和name2是不是紧挨或连续，这个可没有规定，也可能是name后面是letters，然后才是name2  总之，取决于编译器如何实现   老师一定让做出来。。。他说跟分配内存有关系。。。我实在不知道咋做。。。 什么叫name后面是letters 然后才是name2.。。


Question: 关于并查集的问题

考虑这样的情况，所有的城镇都是联通的了，那么bin中存放的并查集中除了root节点bin[i] = i之外其他的节点都有自己的父亲，所以count要从-1开始，多一个没有连通的城镇就是多出一个bin[i] = i的点，显而易见，没有联通就多用一条道连起来，这样就很简单的得到了count


Question: mysql数据库 链接库文件的问题

因为系统和mysql都是64位的  有什么其他办法吗  直接拷贝太暴力了吧  设置ld.so.conf 也没用  一编译就显示  [x@localhost mysql]$ make gcc -o mysql1 mysql1.o -lmysqlclient.so /usr/bin/ld: cannot find -lmysqlclient.so collect2: 错误：ld 返回 1 make: *** [all] 错误 1

把文件复制到 /usr/lib


Return value  Iterator pointing to the first element that is not less than value, or last if no such element is found. http://en.cppreference.com/w/cpp/algorithm/lower_bound

试试不就行了....代码需要多练，看是看不会的 #include <algorithm> #include <iostream> #include <vector> #include <cassert>  int main() {     std::vector<int> v{ 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7, 8, 9, 9, 10 };     auto itr = std::lower_bound(v.begin(), v.end(), 11);     assert(itr == v.end()); }

引用 1 楼 user-2 的回复:...不叫数据库，叫做标准库...和std::find之类的差不多吧...返回end迭代器表示没有找到  就是直接返回没有找到吗？


Question: 并发服务器,接收不到数据

建议楼主先学会使用抓包软件比如wireshark


Question: 工行网上支付接口,订单数据加密

不要做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  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！


Question: 关于C语言指针数组的学习

http://edu.csdn.net/course/detail/2516 理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。


Question: 请教一个传参技巧问题

引用 3 楼 calen_ 的回复:楼主说的不会是 compound literal 的一种黑科技吧..... swap((int[]){/*a=*/2}, (int[]){3}); 还有，楼主你那个括号怎么搞的!!  没错，就是强转成一个复合字面常量数组，好像是C99里面新增的，刚开始忘了加-std=c99，一直遍不过去。。。当时到论坛求助时，没把括号删了。。。后来自己翻了下书，编过去了。

即使能换成数组调用也是int*[2]类型的参数，不可能接受int [2]类型的参数的

请教下楼主，你说的是啥意思？ a b是两个整数，与数组怎么扯上关系呢？ 楼主的swap函数的入参是指针，调用时可传递int型的数组名，指向的就是数组的第一个元素

仅供参考：#include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2


Question: 数据结构程序设计家族关系

能不能用C+++

http://blog.csdn.net/u010590318/article/details/36912439  这里可以参考一下

你这个就是普通的树，非二叉树  一个结点可以多个孩子  因为需要兄弟关系，所以可以考虑在结点中保存层次和双亲信息，如果层次和双亲都相等，则为兄弟，仅层次相等但双亲不一样的为堂兄弟

编不出来，有两个办法： 1、认真学习 2、去网上找别人做好的源码（仔细找肯定能找到的），或者出钱找人做，估计没有会免费给你做的

我也知道是数，可是我编不出来，可不可以帮帮我。

这就是一个树嘛


Question: 前辈们，帮我看看这个程序为什么输出不对吧

引用 4 楼 cyfcsd 的回复:printf("num_1=%d\tnum_2=%d\tnum_2%%num_1=%d\n\n",num_1,num_2,num_2%num_1); 我似乎找到了问题所在,谢谢前辈们

兄弟，细心一点儿啊，这明显就是书写错误啊，就下面这句，你自己查一下吧，这种问题要自己解决的，不能所有错误都找别人啊 printf("num_1=%d\tnum_2=%d\tnum_2%num_1=%d\n\n",num_1,num_2,num_2%num_1);

两种改法：（1）将 Temperatures入参改为float型；                  或（2）输入改为scanf("%lf",&hua);

谢谢回答，在做编程练习又遇到了一个问题，能再帮我看看吗？下面这个程序在我的系统上运行出错 #include<stdio.h> int main(void) { 	int num_1,num_2,a,b;  	printf("please enter the first number(输入非数字停止):"); 	a=scanf("%d",&num_1); 	printf("Please enter the 2th number(输入非数字停止):"); 	b=scanf("%d",&num_2);  	while(a==1&&b==1) 	{printf("num_1=%d\tnum_2=%d\tnum_2%num_1=%d\n\n",num_1,num_2,num_2%num_1); 	printf("please enter the first number(输入非数字停止):"); 	a=scanf("%d",&num_1); 	printf("Please enter the 2th number(输入非数字停止):"); 	b=scanf("%d",&num_2);  	}  	printf("done!\n");  	return 0; }

a=scanf("%f",&hua);改成a=scanf("%lf",&hua);用scanf接收double类型要用lf的


Question: 很短的程序，求指教，内存错误？

楼上抢赵老师饭碗

if (q = NULL)应该是if (q == NULL) 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

引用 2 楼 pkuzhx 的回复:楼上抢赵老师饭碗 但抢不走赵老师的烹调手艺！

int *row1=NULL; int *colu1=NULL; int *num1=NULL; struct B *first=NULL; printf("输入第一个稀疏矩阵A的行数 列数  非零元素的个数:\n");  	scanf("%d%d%d",row1,colu1,num1);  row1,colu1,num1都是指针根本没有存储空间。


Question: 求助帖“there were build errors”。

关闭UAC、防火墙、杀毒软件、…… 以管理员身份运行Setup.exe安装

你建的是什么类型的项目啊


Question: 我用VS2015编写的C程序在别人电脑上不能用，缺少很多***dll，别人说下载VS2015运行库就可以了，请问这个该到什么地方下载呢？

发现安装光盘中如下位置有这个东东 F:\packages\vcRedistD14

引用 5 楼 liups 的回复:[quote=引用 4 楼 yyxgs 的回复:] [quote=引用 3 楼 liups 的回复:] [quote=引用 2 楼 yyxgs 的回复:] [quote=引用 1 楼 liups 的回复:] VC2015运行库有一个安装包的 MS就可以下载 VS2015中应该也有  可以给我网址不?[/quote]  百度“VC2015运行库”[/quote]     都是广告[/quote]  https://www.microsoft.com/zh-CN/download/details.aspx?id=48145[/quote]   非常感谢！

下个依赖库查看软件，比如procexp 然后将需要的DLL打包过去就好（每个系统都有的可以不打包）

引用 4 楼 yyxgs 的回复:[quote=引用 3 楼 liups 的回复:] [quote=引用 2 楼 yyxgs 的回复:] [quote=引用 1 楼 liups 的回复:] VC2015运行库有一个安装包的 MS就可以下载 VS2015中应该也有  可以给我网址不?[/quote]  百度“VC2015运行库”[/quote]     都是广告[/quote]  https://www.microsoft.com/zh-CN/download/details.aspx?id=48145

引用 3 楼 liups 的回复:[quote=引用 2 楼 yyxgs 的回复:] [quote=引用 1 楼 liups 的回复:] VC2015运行库有一个安装包的 MS就可以下载 VS2015中应该也有  可以给我网址不?[/quote]  百度“VC2015运行库”[/quote]  都是广告

引用 2 楼 yyxgs 的回复:[quote=引用 1 楼 liups 的回复:] VC2015运行库有一个安装包的 MS就可以下载 VS2015中应该也有  可以给我网址不?[/quote]  百度“VC2015运行库”

引用 1 楼 liups 的回复:VC2015运行库有一个安装包的 MS就可以下载 VS2015中应该也有  可以给我网址不?

VC2015运行库有一个安装包的 MS就可以下载 VS2015中应该也有


Question: 宏定义

不明白就把宏展开了对着看  可以自己手动展开，也可以让IDE生成展开之后的代码  VS下可以这样；http://blog.csdn.net/qyee16/article/details/9322281

信息没给全，像是类型转化检测。

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898


Question: C语言中的二维元素

int  array [][3] = {{0,1},{0,8,9,7},{4}};   等价于  int  array [3][3] = {{0,1},{0,8,9,7},{4}};   红色这个3表示的是{0,1}, {0,8,9,7}, {4} 这三个  而后蓝色3表示的是上面的每一组里面有三个元素，不足3个的后面用0补，但不能超过3个，所以 {0,8,9,7},是错的  要得到最外这层的个数，可以用sizeof

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

1）能编译通过的，这种缺少一个维度容量的数组， 编译后，容量都是确定的。 2）C99 用变量作为容量，定义数组。 在程序运行到数组定义处以后，如果变量已经初始化， 数组的容量也是确定不变的。 只是，这种是运行时定义数组大小的。 如果，没有初始化，这是程序编写错误，是运行时错误，和逻辑错误。

这是没有声明第二维容量 一维容量为3 ，即每行3列 没有明确确整个数组多少行 这种数组行数，编译后，也是确定的。  如果，初始化表是分行的，------这里每行列数是3----- 但是，初始化的数据，不能多于，每行的列数 所以 {0,8,9,7} 这一行不合法  如果初始化表不分行，编译后 自动按照每行列数，分割初始化表  不论是定义的时候，分行，还是自动分行，不足的补0，多余的，编译会出错  通过初始化表，自动获取数组容量，只能是最高那一维度是自动的。 其他维度必须在定义的时候确定。

这个编译不能通过吧，array[][3]，的意思是定义了一个n行3列的数组，行数n是根据后面的大括号的个数决定的，但每一行必须有三个元素，如果给出的不够三个，那剩下的默认初始化为0，但是不能多于三个，你那个{0,8,9,7}多了‘ 遍历的时候，那个3肯定是一定的，至于行数n，是要自己确定的，也就是你写了多少大括号就是多少行，这跟一维数组一样，你定义 一个a[] = {1 ,3, 5, 7, 9}那遍历a的时候也要给定5的，否则C编译器是无法确定长度的

这个是我写错了


Question: C语言文件路径问题

你的缓冲区（fn）大小是多少，可以设大一点

我的意思是提醒你要创建子目录。

说得太笼统，给出关键代码．

没看太懂老师这是什么意思？造成计算错误的原因是我的路径太长了吗？

_mkdir, _wmkdir Create a new directory.  int _mkdir( const char *dirname );  int _wmkdir( const wchar_t *dirname );  Routine Required Header Compatibility  _mkdir <direct.h> Win 95, Win NT  _wmkdir <direct.h> or <wchar.h> Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns the value 0 if the new directory was created. On an error the function returns –1 and sets errno as follows:  EEXIST  Directory was not created because dirname is the name of an existing file, directory, or device  ENOENT  Path was not found  Parameter  dirname  Path for new directory  Remarks  The _mkdir function creates a new directory with the specified dirname. _mkdir can create only one new directory per call, so only the last component of dirname can name a new directory. _mkdir does not translate path delimiters. In Windows NT, both the backslash ( \) and the forward slash (/ ) are valid path delimiters in character strings in run-time routines.  _wmkdir is a wide-character version of _mkdir; the dirname argument to _wmkdir is a wide-character string. _wmkdir and _mkdir behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tmkdir _mkdir _mkdir _wmkdir    Example  /* MAKEDIR.C */  #include <direct.h> #include <stdlib.h> #include <stdio.h>  void main( void ) {    if( _mkdir( "\\testtmp" ) == 0 )    {       printf( "Directory '\\testtmp' was successfully created\n" );       system( "dir \\testtmp" );       if( _rmdir( "\\testtmp" ) == 0 )         printf( "Directory '\\testtmp' was successfully removed\n"  );       else          printf( "Problem removing directory '\\testtmp'\n" );    }    else       printf( "Problem creating directory '\\testtmp'\n" ); }   Output  Directory '\testtmp' was successfully created     Volume in drive C is CDRIVE  Volume Serial Number is 0E17-1702   Directory of C:\testtmp  05/03/94  12:30p        <DIR>           . 05/03/94  12:30p        <DIR>           ..                2 File(s)          0 bytes                              17,358,848 bytes free Directory '\testtmp' was successfully removed   Directory Control Routines  See Also   _chdir, _rmdir


Question: printf数据丢失。。。。。。。。。。。。。。。

多谢各位！为了防止意外，我给指针申请空间后再用了，发现效果还是大大滴，不过就是有点麻烦，每次都要释放

printf("%s------%s\n",a,b);	参数a,b用错，要求使用字符串指针，程序中的a,b 已经不是字符串了

摒弃strcpy；使用strncpy！

可这样改：   int main() { 	char a[10] = {0}, b[10] = {0};  	strcpy(a,"00"); 	strcpy(b,"00"); 	printf("%s------%s\n",a,b);  	return 0; }

strcpy的时候越界了，而且字符数组需要以\0结尾才算是字符串

字符串需要多一个'\0' 要特别注意需要的空间是字符串长度的大小+1 楼主这个a之所以没有输出，我猜是因为你的a和b分配的空间是连续的，而且b在a分配的前面 所以strcpy(b,"00");	会使得最后的'\0'越界写入到a数组的第一个字符上 所以printf的时候a数组才会输出空（楼主只要%p打印一下a,b的首地址就知道了）

改成指针并不能解决问题，问题  strcpy(a,"00");	,"00"是占用3个字节，a只有两个字节空间，溢出。由此造成printf("%s------%s\n",a,b);	函数调用时发生问题。解决办法，申请足够空间，比如 char a[3],b[3];

‘\0’没有，所以输出的不是字符串

改成指针好了 ！但是数组名不就是指针嘛


Question: 求助排列问题

Talk is cheap,show me the code.


Question: 算法问题

这个算法肯定不对．．． 计算某一天星期几的几个公式 蔡勒公式：W = ([C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1) mod 7． 吉姆拉尔森公式：W =((Y-1)+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+[13*(M+1)/5 ]+d) mod 7． 蔡农公式：W = (C%4*5+Y+Y/4+(13*M+8)/5+D)%7

2000-01-01是周六。  这算法应该不准吧，只考虑四年一闰，没考虑到百年减一闰和400年再恢复一闰。

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

The COleDateTime class handles dates from 1 January 100 – 31 December 9999.

记得以前见过 转盘式的 万年历，年份 是按顺序 排下去的 ，但是每隔 4 年 有一个空，放在闰年之前，闰年的一月和和二月是和其他年份不一样的    http://blog.sina.com.cn/s/blog_4af888810102w4zj.html

例如  2015 年元旦星期四,2015年有365天 除以 7 余 1 2016  年元旦就是星期五,2016年有366  除以 7 余 2 2017 年元旦就是星期日   也就是每年的元旦都比上一年 的 星期数 多1个 ,遇到闰年多2个   也就是数一下 与 设定的标准年份差几年 ,中间隔了几个 2月 29 日      这个程序2000年以前的也不能算

zhao4zhong1公式： COleDateTime::GetDayOfWeek int GetDayOfWeek( ) const;  Return Value  The day of the week represented by the value of this COleDateTime object.  Remarks  Call this member function to get the day of the month represented by this date/time value.  Valid return values range between 1 and 7, where 1=Sunday, 2=Monday, and so on. If the status of this COleDateTime object is not valid, the return value is AFX_OLE_DATETIME_ERROR.  For information on other member functions that query the value of this COleDateTime object, see the following member functions:   GetDay   GetMonth   GetYear   GetHour   GetMinute   GetSecond   GetDayOfYear  COleDateTime Overview |  Class Members |  Hierarchy Chart  See Also   COleDateTime::COleDateTime, COleDateTime::SetDateTime, COleDateTime::operator =, COleDateTime::GetStatus


Question: 关于 %p和%X

源码面前，了无秘密。 1楼得分太少！

%p专门用于输出一个地址（也就是指针的值），而%x用于将一个整型数按照十六进制输出，如果是小写的x则输出小写形式，如果是大写的X则输出大写形式。例如，十进制170如果用%x输出aa，用%X输出AA。%和x之间还可以输入一个整型数表示宽度，输入0表示宽度不足时补零，负号-表示右对齐。还以十进制170为例： %4X    输出：AA[][] %-4X   输出：[][]AA %04X  输出： 00AA %-03X 输出： []0AA 0X%X  输出： 0XAA 等等（[]表示空格）

%X和%x的不同是在a~f上的大小写的不一样；%x是小写a~f,比如(0x)3d; %X是大写A~F,比如(0x)3D;他们都标识以16进制格式； %p是输出指针地址；但是%P不知道是啥鬼,没用过；

32 位程序，%p 等同于 %08x；64 位程序，%p 等同于 %016llx。 也就是说，指针有多少字节他就输出多少字节。

一个是专用，遵纪守法的用法，%p用于输出指针，这是一直以来都这么做的，也是写在标准里面的。 一个是乱用，无视法纪。%x 输出指针，这是没有认真学习，printf 类输出函数，输出数据的方式 想当然的，以为指针和整形数大小相同，胡乱用的。凑巧没错，是不能保证的

%p输出地址，%x 16进制输出值。

顶顶顶顶顶顶

打错了，16进制，不是16位

http://www.cplusplus.com/reference/cstdio/printf/  简单地说就是p->指针, x->16位无符号整型，指针的大小不等于无符号整型的大小，运气好是一样的

顶顶顶顶顶顶顶顶

参考C:\Program Files\Microsoft Visual Studio 1x.0\VC\crt\src\output.c


Question: 给定一个数组，该数组中有相同元素，把数组中相同的元素分组存放。

引用 6 楼 vshuo7013 的回复:[quote=引用 1 楼 u010165006 的回复:] 先排序吧我觉得  排序之后呢？[/quote] 排序之后一轮遍历就解决了。 如果数组元素分布在一个小的范围内，可以以内存换效率，创建统计数组，不用排序，一轮遍历就可以。参考哈希算法

引用 5 楼 vshuo7013 的回复:[quote=引用 2 楼 face_t0_sea 的回复:] 数组元素什么类型，数组长度多少，会有不同算法选择  int 类型， 大小可以确定，有什么好的算法[/quote] 分组具体是什么意思

引用 3 楼 wanren13 的回复:如果如果元素重复的频率非常高可以用counting sort  重复频率是不确定的？

引用 1 楼 u010165006 的回复:先排序吧我觉得  排序之后呢？

引用 2 楼 face_t0_sea 的回复:数组元素什么类型，数组长度多少，会有不同算法选择  int 类型， 大小可以确定，有什么好的算法

题目不很明确，排序有必要

引用 7 楼 vshuo7013 的回复:[quote=引用 3 楼 wanren13 的回复:] 如果如果元素重复的频率非常高可以用counting sort  重复频率是不确定的？[/quote]  并不需要知道元素的频率，counting sort就是去统计元素的频率，只是元素重复率高且在一定范围的话空间复杂度会比较低  比如以下数列:  1777171171713733333311111777113333  就非常适合counting sort  你最好问题给的再具体一点，排序问题是要不同情况不同对待的

如果如果元素重复的频率非常高可以用counting sort

仅供参考：//文件1中的内容排序并去重,结果保存到文件2中 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXCHARS 128      //能处理的最大行宽,包括行尾的\n和字符串尾的\0 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; int c,n,hh,i,L; FILE *f; char ln[MAXCHARS]; int ignore_case=0; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc<3) {         printf("Unique line. Designed by zhao4zhong1@163.com. 2012-08-20\n");         printf("Usage: %s src.txt uniqued.txt [-i]\n",argv[0]);         return 1;     }     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not find file %s!\n",argv[1]);         return 1;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(f);         printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 2;     }     n=0;     hh=0;     i=0;     while (1) {         if (NULL==fgets(ln,MAXCHARS,f)) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             printf("%s Line %d too long(>%d),spilth ignored.\n",argv[1],hh,MAXCHARS);             while (1) {                 c=fgetc(f);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     printf("WARNING: Lines >%d ignored.\n",MAXLINES);                     break;//                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(f);     if (n>1) {         if (ignore_case) qsort(buf,n,MAXCHARS,icompare);         else qsort(buf,n,MAXCHARS,compare);     }     f=fopen(argv[2],"w");     if (NULL==f) {         free(buf);         printf("Can not create file %s!\n",argv[2]);         return 2;     }     fprintf(f,"%s\n",buf);     if (n>1) {         if (ignore_case) {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if (stricmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         } else {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if ( strcmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         }     }     fclose(f);     free(buf);     return 0; }

数组元素什么类型，数组长度多少，会有不同算法选择

先排序吧我觉得


Question: 找错误

我知道了，错在这str[14]={30};只把str【0】赋值为30，其余的默认值为0

1,3,5,7,8,10,12是31天，i<=7的时候奇数是31天，然后奇数加7也是31天；我试了，5月以后是不对了，可是为什么啊

你下面这个写的什么东西？ for (i = 1; i <= 7; i += 2) 	{ 		str[i] = 31; 		str[i + 7] = 31; 	} 你只要随便拿5月以后的日期测，得到的日期都是不对的

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


Question: 关于栈的遍历的问题

1.你的init函数都没有return q; 2.你的init函数里malloc出来的p感觉也没啥意义 3.在你的push函数里加了一步if (S->Bottom == NULL) S->Bottom = p; 4.traverse里修改了下while的条件  # include <stdio.h> # include <stdlib.h> # include <malloc.h>  struct NODE { 	int data; 	struct NODE *pNext; };  struct POINT { 	struct NODE *Top; 	struct NODE *Bottom; };  struct POINT *init(void); void push(struct POINT *S); void traverse(struct POINT *S);  int main() { 	struct POINT *S = NULL; 	int n;  	S = init(); 	if (S != NULL) 		printf("栈 初始化成功\n");  	printf("请输入你需要的结点数： "); 	scanf("%d", &n); 	while (n--) 	{ 		push(S); 	}  	traverse(S);  	return 0; }  struct POINT *init(void) { 	struct POINT *q = (struct POINT *)malloc(sizeof(struct POINT)); 	if (q == NULL) 	{ 		printf("内存分配失败\n"); 		exit(-1); 	}  	q->Top = NULL; 	q->Bottom = NULL; 	return q; }  void push(struct POINT *S) { 	int val; 	printf("请输入你需要压栈的值   "); 	scanf("%d", &val);  	struct NODE *p = (struct NODE *)malloc(sizeof(struct NODE)); 	if (p == NULL) 	{ 		printf("内存分配失败\n"); 		exit(-1); 	} 	if (S->Bottom == NULL) 		S->Bottom = p; 	p->data = val; 	p->pNext = S->Top; 	S->Top = p; }  void traverse(struct POINT *S) { 	struct NODE *p = S->Top;  	while (p) 	{ 		printf("%d   ", p->data); 		p = p->pNext; 	} 	printf("\n"); }

main.c(61): warning C4715: “init”: 不是所有的控件路径都返回值


Question: 条件表达式  ? :

运算符连接的是表达式，而不能是语句  你的前一个分号已经使得这个句子结束了  如果需要根据条件执行不同的语句，可以改写成if else形式  或者写成：printf("%s",a>0?"hello":"world");

引用 3 楼 qq423399099 的回复:多了个分号，去掉试试，我这里VS上是可以运行出正确结果的 a>0 ? printf("hello") : printf("world"); 学习了

int a  = 8;   a>0 ? printf("hello")  : printf("world");

int a  = 8; //我想对这个变量a进行判断，如果a大于0的话，输出一句hello,不大于的话输出  world 但是一下语句提示没有左值,条件表达式语句必须得赋值给一个左值吗  printf("%s",a>0?"hello":"world");  //执行不了

顶顶顶顶顶顶顶顶顶


Question: 求大神帮忙写下这道题的程序~

关键是最终排序要求输出对应平均分排名的运动员哇

这没有什么难度吧．．．

第二个要求看不懂，什么意思啊


Question: 快考试了！求帮忙！大神大牛快快显身来

完全不会还好意思来求助……

自己上网查一查，都会找到一些东西。看懂别人的代码，再根据自己的要求进行添加优化修改。

同意1楼意见

找同学啊

这不是快考试了吧。这是快交大作业了吧

百度“C源代码 学生成绩管理系统”


Question: C中short整型 补码运算

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。

-32768 二进制为 1000 0000 0000 0000  最高位的1是表示是负数  再减1后变成0111 1111 1111 1111  最高位是0，表示正数，这个数值就为32767

short的取值为范围为-32768到32767  你觉得用%hd能输出-32769?

还少了后面 0000

-32768的补码为 1000 0000 0000


Question: 菜鸟求助，linux下的c语言链表实现初始化

楼主你看这样行不行，行的话给我２分吧，我下载个资料 typedef struct Link_node {         int data;         struct Link_node * next; } node_t ;  node_t  *Link_list  = NULL;  node_t *alloc_list_node(int data) {           node_t *p;       p = calloc(sizeof(node_t), 1);            p->data = data;      return p; }  int main(void) {    node_t *node;     node = alloc_list_node(10);    node->next = Link_list;    Link_list = node;     return 0; }

随便回一贴能得积分么？

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

引用 7 楼 icesky1stm 的回复:[quote=引用 6 楼 qq423399099 的回复:] [quote=引用 4 楼 icesky1stm 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 你主函数内的K指针，指向的是未知区域，你在init_Linklist函数里直接解引用*L自然会报错 而且你主函数里Link_list *K;这样用意味着K是二级指针，也不对，写成下面这样就可以了：  typedef struct Link_node { 	int data; 	struct Link_node * next; }node,*Link_list;  void init_Linklist(Link_list *L) {      	*L = (Link_list )malloc(sizeof(node));      	(*L)->data=0; 	(*L)->next=NULL; } void main() { 	Link_list K; 	init_Linklist(&K); }   K已经在栈中分配内存了，在*K无法改变它的地址吧。[/quote] K指针本身确实已经分配了栈内存，但是它此时指向的是位置区域（存的是垃圾值） 不知道你想说啥[/quote]  哎，我说我刚才眼花了，你会鄙视我不[/quote] 必须会

引用 6 楼 qq423399099 的回复:[quote=引用 4 楼 icesky1stm 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 你主函数内的K指针，指向的是未知区域，你在init_Linklist函数里直接解引用*L自然会报错 而且你主函数里Link_list *K;这样用意味着K是二级指针，也不对，写成下面这样就可以了：  typedef struct Link_node { 	int data; 	struct Link_node * next; }node,*Link_list;  void init_Linklist(Link_list *L) {      	*L = (Link_list )malloc(sizeof(node));      	(*L)->data=0; 	(*L)->next=NULL; } void main() { 	Link_list K; 	init_Linklist(&K); }   K已经在栈中分配内存了，在*K无法改变它的地址吧。[/quote] K指针本身确实已经分配了栈内存，但是它此时指向的是位置区域（存的是垃圾值） 不知道你想说啥[/quote]  哎，我说我刚才眼花了，你会鄙视我不

引用 4 楼 icesky1stm 的回复:[quote=引用 1 楼 qq423399099 的回复:] 你主函数内的K指针，指向的是未知区域，你在init_Linklist函数里直接解引用*L自然会报错 而且你主函数里Link_list *K;这样用意味着K是二级指针，也不对，写成下面这样就可以了：  typedef struct Link_node { 	int data; 	struct Link_node * next; }node,*Link_list;  void init_Linklist(Link_list *L) {      	*L = (Link_list )malloc(sizeof(node));      	(*L)->data=0; 	(*L)->next=NULL; } void main() { 	Link_list K; 	init_Linklist(&K); }   K已经在栈中分配内存了，在*K无法改变它的地址吧。[/quote] K指针本身确实已经分配了栈内存，但是它此时指向的是位置区域（存的是垃圾值） 不知道你想说啥

#include <stdio.h>                                                                                #include <stdlib.h> #include <string.h>  typedef struct Link_node {     int data;     struct Link_node * next; }node,*Link_list;  void init_Linklist(Link_list *L) {     Link_list p;     p=(Link_list )malloc(sizeof(node));     *L=p;     p->data=0;     p->next=NULL; }; void main() {     Link_list K;     init_Linklist(&K);     printf("p->data[%d]\n", K->data); }

引用 1 楼 qq423399099 的回复:你主函数内的K指针，指向的是未知区域，你在init_Linklist函数里直接解引用*L自然会报错 而且你主函数里Link_list *K;这样用意味着K是二级指针，也不对，写成下面这样就可以了：  typedef struct Link_node { 	int data; 	struct Link_node * next; }node,*Link_list;  void init_Linklist(Link_list *L) {      	*L = (Link_list )malloc(sizeof(node));      	(*L)->data=0; 	(*L)->next=NULL; } void main() { 	Link_list K; 	init_Linklist(&K); }   K已经在栈中分配内存了，在*K无法改变它的地址吧。

typedef struct Link_node {         int data;         struct Link_node * next; }node,*Link_list;  void init_Linklist(Link_list **L) {            Link_list p;       p=(Link_list )malloc(sizeof(node));             *L=p;       p->data=0;       p->next=NULL; }; void main() {    Link_list *K;    init_Linklist(&K); }

问题解决，十分感谢！ 函数里不能用P=*L代替（*L）也是因为没有明确指针指向吗？


Question: 一直在报错 不知道为什么

你scanf("%d", &n);以后，输入缓冲区会有遗留的回车符，会被gets读走 所以scanf后面加一句fflush(stdin);才行  # include <stdio.h> # include <string.h>  void fun1(char *s1);  int main() { 	int n;                              	scanf("%d", &n); 	fflush(stdin); 	char s1[100000]; 	while (n--)                     //如果去掉这个while就没事  一加上程序就停止工作 不知道为什么 	{ 		gets(s1); 		fun1(s1); 	}   	return 0; }  void fun1(char *s1) { 	char s2[50000]; 	int i, j, len, temp; 	len = strlen(s1);  	if (1 == len) 	{ 		temp = s1[0] - '0'; 		temp %= 9; 		s2[0] = temp + '0'; 		s2[1] = '\0'; 	} 	else 	{ 		for (i=0, j=0; i<len-1; i+=2) 		{ 			temp = (s1[i]-'0')*10 + s1[i+1]-'0'; 			temp %= 9; 			s2[j++] = temp + '0'; 		}  		if (len % 2 != 0) 		{ 			s2[j++] = s1[len-1]; 		}  		s2[j] = '\0'; 	}  	len = strlen(s2);  	if (1 == len) 		printf("%s\n", s2); 	else 		fun1(s2); }


Question: 请教关于没有释放动态分配的内存。

搜“内存延迟分配”

从用户使用程序的角度来看，内存泄漏本身不会产生什么危害，作为一般的用户，根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积，这会最终消耗尽系统所有的内存。从这个角度来说，一次性内存泄漏并没有什么危害，因为它不会堆积，而隐式内存泄漏危害性则非常大，因为较之于常发性和偶发性内存泄漏它更难被检测到。

引用 5 楼 qq_16774199 的回复:[quote=引用 3 楼 paschen 的回复:] [quote=引用 1 楼 qq_16774199 的回复:] 直接malloc(a)而没赋值给指针变量，电脑还是会分配内存空间对吧？  是，只不过你没有记录下这片内存的地址而已 之后就算想free也没办法 当然也算是内存泄露[/quote]  你好，请问内存泄露大意是什么？ 就像我这样无法通过指针找到malloc分配出的空间，然后失去对它的控制？除了占用内存外还有什么危害？[/quote]  什么是内存泄漏（memory leak）？   指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失，而是应用程序分配某段内存后，由于设计错误，失去了对该段内存的控制，因而造成了内存的浪费。   A memory leak is a particular type of unintentional memory consumption by a computer program where the program fails to release memory when no longer needed. This condition is normally the result of a bug in a program that prevents it from freeing up memory that it no longer needs.This term has the potential to be confusing, since memory is not physically lost from the computer. Rather, memory is allocated to a program, and that program subsequently loses the ability to access it due to program logic flaws.

引用 3 楼 paschen 的回复:[quote=引用 1 楼 qq_16774199 的回复:] 直接malloc(a)而没赋值给指针变量，电脑还是会分配内存空间对吧？  是，只不过你没有记录下这片内存的地址而已 之后就算想free也没办法 当然也算是内存泄露[/quote]  你好，请问内存泄露大意是什么？ 就像我这样无法通过指针找到malloc分配出的空间，然后失去对它的控制？除了占用内存外还有什么危害？

引用 2 楼 qq423399099 的回复:对的，还是会分配空间，由于没有记录malloc出来的地址，所以会造成内存泄漏 你可以用直接判断malloc的返回值，由于没有释放，所以经过一定的循环以后，堆空间耗尽，就会malloc失败  你好，经过一定循环后堆空间耗尽，malloc失败。 我还以为malloc会一直申请下去直到电脑没有内存，难怪我盯着任务管理器看很久也没什么变化。是不是malloc只能消耗堆内存地址？ 而且那是个死循环，为什么不会一直循环下去呢？

引用 1 楼 qq_16774199 的回复:直接malloc(a)而没赋值给指针变量，电脑还是会分配内存空间对吧？  是，只不过你没有记录下这片内存的地址而已  之后就算想free也没办法  当然也算是内存泄露

对的，还是会分配空间，由于没有记录malloc出来的地址，所以会造成内存泄漏 你可以用直接判断malloc的返回值，由于没有释放，所以经过一定的循环以后，堆空间耗尽，就会malloc失败  #include<stdio.h> #include<stdlib.h> int main(void) {     int a=20;     while(a>1)     {         ++a;         if(malloc(1024 * 1024 * a) == NULL) 		{ 			printf("%d\n", a); 			break; 		}     }      return 0; }

直接malloc(a)而没赋值给指针变量，电脑还是会分配内存空间对吧？但没有了指针可以引用所以无法被释放吗？


Question: 求大神查一个错误.

代码没问题，至少不是fopen的问题，即使文件打开失败也可以输出hello

这样试试？  printf("hello\n");

我这编译器 今天又能输出了  不知道是怎么回事。

我觉得是这样的，你用fopen打开了一个文件，同时就有文件输出流，如果你 先 fclose(f) ，再 printf("hello") 试一下

用编译器自带的运行器 执行后不显示hello 返回值为0xc0000005，直接运行程序会报错。


Question: 请教malloc分配的内存连续性。

引用 9 楼 zhao4zhong1 的回复:为什么不使用realloc呢？ 我是学到哪里思考到哪里，问到哪里。 recalloc昨天晚还没学习，但是今晚就要学习了。

为什么不使用realloc呢？

malloc 从来不会试图保证两次分配的内存是连续的。

参考Linux源代码中malloc函数的实现。

分配内存时还会有一些记录相关信息的结构  http://blog.csdn.net/a10615/article/details/41063063

楼主觉得地址应该差4才正常？ 那么你想想。如果我此时去free,怎么能知道我应该释放多大的内存空间呢？ malloc的时候，申请的空间一定是大于括号中的字节数的，因为它还需要保存边界信息以及内存管理信息，可能还要对齐 http://blog.csdn.net/misskissc/article/details/17717717

realloc Reallocate memory blocks.  void *realloc( void *memblock, size_t size );  Routine Required Header Compatibility  realloc <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. The return value points to a storage space that is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.  Parameters  memblock  Pointer to previously allocated memory block  size  New size in bytes  Remarks  The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to calloc, malloc, or realloc.  The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument.  realloc calls malloc in order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when realloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call   _set_new_mode(1)  early in your program, or link with NEWMODE.OBJ.  When the application is linked with a debug version of the C run-time libraries, realloc resolves to _realloc_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.  Example  /* REALLOC.C: This program allocates a block of memory for  * buffer and then uses _msize to display the size of that  * block. Next, it uses realloc to expand the amount of  * memory used by buffer and then calls _msize again to  * display the new amount of memory allocated to buffer.  */  #include <stdio.h> #include <malloc.h> #include <stdlib.h>  void main( void ) {    long *buffer;    size_t size;     if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL )       exit( 1 );     size = _msize( buffer );    printf( "Size of block after malloc of 1000 longs: %u\n", size );     /* Reallocate and show new size: */    if( (buffer = realloc( buffer, size + (1000 * sizeof( long )) ))          ==  NULL )       exit( 1 );    size = _msize( buffer );    printf( "Size of block after realloc of 1000 more longs: %u\n",              size );     free( buffer );    exit( 0 ); }   Output  Size of block after malloc of 1000 longs: 4000 Size of block after realloc of 1000 more longs: 8000   Memory Allocation Routines  See Also   calloc, free, malloc

引用 12 楼 jianyuezhimei 的回复:为什么要使用realloc呢？？？？？？？？？？？？？？？？ 难道realloc比malloc高级吗？？？？？？？？？？？？？？？？ realloc同一个指针多次就相当于实现了多次malloc且内存连续。

引用 10 楼 qq_16774199 的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] 为什么不使用realloc呢？ 我是学到哪里思考到哪里，问到哪里。 recalloc昨天晚还没学习，但是今晚就要学习了。 [/quote] 所以建议你今后改掉这个毛病。 学一段时间后再问。

引用 3 楼 qq_16774199 的回复:[quote=引用 1 楼 user-6 的回复:] 00410218   00410228：首先这个是什么进制的？ %p 是以16进制的形式输出内存地址[/quote] 16进制的话就比较正常了，意思是地址差16，符合对齐的原则（为了访问速度更快）

引用 1 楼 user-6 的回复:00410218   00410228：首先这个是什么进制的？ %p 是以16进制的形式输出内存地址

引用 1 楼 user-6 的回复:00410218   00410228：首先这个是什么进制的？ 其次你不能认为它就应该连续！

00410218   00410228：首先这个是什么进制的？


Question: c语言超时求优化

你需要你个哈希表


Question: int类型-1 转换为unsigned类型

-1的原码是 1000 0000 0000 0000 0000 0000 0000 0001 不错 不过，他的补码数表示，是用1的补码来表示 也就是 1111，1111，1111，1111，1111，1111，1111，1111 转换成unsigned  什么也不做 照抄就是了，还是 1111，1111，1111，1111，1111，1111，1111，1111

引用 4 楼 lm_whales 的回复:1）无符号，跟有符号（同一长度的int）之间转换 数据（二进制表示）本身没改变，改变的只是数据类型 2）有符号数是所谓补码数 正数用原码表示(即这个数的序号)。 负数，用他的相反数（绝对值）的补码表示。  用+0 的编码（全0），表示0 用-0 的编码（最高位1，其余全0），表示绝对值，比最大正数大1 的负数。 正数的原码，就是正数的二进制表示 负数的原码，就是绝对值是他的相反数，最高位为1 4） 反码，就是原码按位取反  补码等于 反码+1 补码的本意是，两个数的和（除开溢出的丢失的那一位后）为0。则两个数互为补码。 补码数则是正数用原码，负数用（相反数的）补码表示。0 用全0 表示。 多余的一个-0 的编码，表示绝对值大于最大正数的的负数。  -1作为负数在计算机中存的是它的补码，它的原码是 1000 0000 0000 0000 0000 0000 0000 0001  补码 为 1111 1111 1111 1111 1111 1111 1111 1111   -1转换成unsigned无符号的时候，把最高位的1换成0 即 0111 1111 1111 1111 1111 1111 1111 1111 转换成 十进制 正好是  4294967295    是不是这样

6.3.1.3 Signed and unsigned integers 1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged. 2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. 3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.  这样规定的效果是如果数字用补码表示，同样长度的有符号整数转换为无符号整数，其二进制表示是不变的。（参见7楼）  ====== 写这么复杂的原因是，标准其实是允许用原码或反码表示整数的（虽然实际实现里几乎见不到...）

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。

得到的是unsigned 能表示的最大值  int的最高位表示的是符号，1为负，0为正  而unsigned全为正  把数值转换成二进制计算下就明白了

引用 5 楼 Hamber_Bao 的回复:[quote=引用 4 楼 lm_whales 的回复:] 1）无符号，跟有符号（同一长度的int）之间转换 数据（二进制表示）本身没改变，改变的只是数据类型 2）有符号数是所谓补码数 正数用原码表示(即这个数的序号)。 负数，用他的相反数（绝对值）的补码表示。  用+0 的编码（全0），表示0 用-0 的编码（最高位1，其余全0），表示绝对值，比最大正数大1 的负数。 正数的原码，就是正数的二进制表示 负数的原码，就是绝对值是他的相反数，最高位为1 4） 反码，就是原码按位取反  补码等于 反码+1 补码的本意是，两个数的和（除开溢出的丢失的那一位后）为0。则两个数互为补码。 补码数则是正数用原码，负数用（相反数的）补码表示。0 用全0 表示。 多余的一个-0 的编码，表示绝对值大于最大正数的的负数。  -1作为负数在计算机中存的是它的补码，它的原码是 1000 0000 0000 0000 0000 0000 0000 0001  补码 为 1111 1111 1111 1111 1111 1111 1111 1111   -1转换成unsigned无符号的时候，把最高位的1换成0 即 0111 1111 1111 1111 1111 1111 1111 1111 转换成 十进制 正好是  4294967295    是不是这样 [/quote] ３２位数-1在内存中就是　0xFFFFFFFF,直接赋给unsigned就是0xFFFFFFFF

4294967295 就是全1 4294967295  = 2^32-1

补码数的特征是（全0 ，以及最高位为1，其余为0 ，的两个编码除外），一对相反数，互为补码

值 -1 赋值给unsigned int 类型的时候 存储形式为 1111,1111,1111,1111

引用 1 楼 user-7 的回复:我相信C/C++教程开头就会讲补码..反码...没有讲，你给讲讲吧

我相信C/C++教程开头就会讲补码..反码...


Question: 数值溢出问题

说点别的:  1) maxShortInt + 1 的结果是一个 int （不是 short ），并且超出的 short 的表示范围。（我们假设他没有超出 int 的表示范围） [quote6.5.6/]4 If both operands have arithmetic type, the usual arithmetic conversions are performed on them.[/quote]  2) 关于 %hd :   引用7.21.6.1/7 ... h Specifies that a following d, i, o, u, x, or X conversion specifier applies to a short int or unsigned short int argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to short int or unsigned short int before printing); or that a following n conversion specifier applies to a pointer to a short int argument. 及： 引用7.21.6.1/9 If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined. 所以严格的说这是一个未定义行为（对于 printf 来说）  3) 将 int 转换为 short: 引用6.3.1.3 Signed and unsigned integers 1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged. 2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.60) 3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised. 当结果不在 short 的表示范围内的时候，结果是有实现定义的。

上面写错了 最大值为-  最小值为+

建议查看  《深入理解计算机系统》 此书第一章详细讲解了关于数值运算的上溢出，下溢出的问题。 1 当为最大值时也就是超过计算机位数时 +1 等于    x（设此时值） - 2^32or64（计算机位数） 2 当为最小值时为    x-2^32or64

-32768 二进制为 1000 0000 0000 0000  最高位的1是表示是负数  再减1后变成0111 1111 1111 1111  最高位是0，表示正数，这个数值就为32767   32767 + 1 同理

如果位数为n,则-2的n-1次方的补吗为 1000  0000(假如n为8，理解不了就记一下，这个是特殊的)

引用 9 楼 zycxnanwang 的回复:验证一下min min的补码为  1000 0000 0000 0000 -1 的补码为     1111 1111  1111  1111 两个相加得到结果的补码   0111 1111 1111  1111 （进位溢出） 结果为正数  所以其原码为 0111 1111 1111  数值是+32767 计组课没白上，还记得一点！  MIN的原码是  1111 1111 1111 1111 它的补码应该是  1000 0000 0000 0001 吧  再加上-1的补码 1111 1111 1111 1111  得到的补码是 0000 0000 0000 0000    哎呀我的天啊，我这是怎么算的  哪个大哥再来帮我疏通一下

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

引用 5 楼 Hamber_Bao 的回复:[quote=引用 3 楼 u010165006 的回复:] printf("max=%hX, max+1=%hX\n", maxShortInt,maxShortInt+1); //输出max=7FFF, max+1=8000 //二进制为：max=7FFF=0111 1111 1111 1111 为16位补码表示整数的最大值32767（首位0为正数） //max+1=8000=1000 0000 0000 0000 //首位1为负数，绝对值等于取反加一，取反刚好等于max（32767），+1后等于32768（绝对值），因为负数所以值等于-32768 printf("min=%hX, min-1=%hX\n", minShortInt,minShortInt-1); //输出min=8000, min-1=7FFF   我标记为红的，是什么意思，能给我详细解释解释吗[/quote]  详细的要看《计算机组成原理》（计算机组成与结构）一本书，关于原码、补码、反码及计算。

楼主同类问题提得太多，其实只要去认真学习一下原码、补码、机器数、浮点数什么的就完全明白了

引用 3 楼 u010165006 的回复:printf("max=%hX, max+1=%hX\n", maxShortInt,maxShortInt+1); //输出max=7FFF, max+1=8000 //二进制为：max=7FFF=0111 1111 1111 1111 为16位补码表示整数的最大值32767（首位0为正数） //max+1=8000=1000 0000 0000 0000 //首位1为负数，绝对值等于取反加一，取反刚好等于max（32767），+1后等于32768（绝对值），因为负数所以值等于-32768 printf("min=%hX, min-1=%hX\n", minShortInt,minShortInt-1); //输出min=8000, min-1=7FFF   我标记为红的，是什么意思，能给我详细解释解释吗

short maxShortInt = 32767; //最大 short int。 short minShortInt = -32767;//最小 short int。 short ShortdownLimited = -32767 - 1; //最小可表示数。//这本来是-0 的编码，只是 带符号数，无 -0 这样就用来表示 -32768了; 似乎应该这么写。 现在库里的代码，差不多都改成类似这样了 至于输出， ShortdownLimited 还是输出  -32768;  最大数maxShortInt+1溢出变成最小可表示数 -32768（这个也是 -0的编码）。 最小数minShortInt-1溢出变成最小可表示数 -32768（这个也是 -0的编码）。 最小可表示数 -32768（这个也是 -0的编码） -1  溢出变成最大数maxShortInt。

顶顶顶顶顶顶顶顶顶顶顶顶

求各位大神帮助啊


Question: 【请教】为什么我用多线程反而速度变慢了

这里，如果是界面程序的话，多线程也许不能提高读写效率 但是可以解决界面刷新等待的问题 如果是单线程，界面就会一直在等待读写数据，和哈希表 界面刷新就停掉了，这样用户体验不好。 你这个场景确实不适合多线程。

楼上几位，谢谢了， 我自己测试了一下，时间主要还是消耗在互斥锁上面了，在我的这个场景下，线程越多，速度越慢，即便是只有2个线程，也比单线程慢。至于磁盘读写，倒是没测试。

你这个场景使用多线程是否真的会有提高呢？第一 先说读文件，开24个线程读文件并不能提高 很可能取得反效果，先不说线程切换消耗的时间，单线程切换读不同的文件的时候导致磁盘的磁头需要重新定位消耗的时间就不小，再说你那个写hash表，因为你用的互斥锁，这意味着线程越多，竞争就越大（假设你每个线程参与了写hash表）锁竞争消耗的时间又是一笔不小的开销。所以很多时候效率和线程数并不是有一个正比的关系。

引用 2 楼 lm_whales 的回复:问题是，写文件的速度，跟多线程没关系。因为即便是多硬盘，还是不能多线程写 哈希表更跟多线程，没关系。 有两个线程，基本上就可以了 最多开四个 除非你的程序在服务器上跑  跟多线程无关的话，至少应该是差不多快，而不会慢3倍吧， 不过我也觉得是线程太多的原因，线程抢有限的CPU也会消耗时间。

开多线程，同步处理没做好，效率会明显降低

io是瓶颈，读写硬盘多线程反而会损失效率

用多线程处理肯定比单线程要快，那我该如何优化我的多线程？


Question: C语言 switch-case问题

default 后面要加一个冒号

引用 楼主 fyerd 的回复:1.default:后面可以这样形式吗?也就是说用一个大括号，里面写一些语句，还是只能写一句？ default{ printf("..."); scanf("%d",&n); break; }  你想有几句都可以，想有几个大括号也都可以    引用 楼主 fyerd 的回复:2.我有一个可选择的菜单，default是上面那样写的，但是输入字母，会调用相应功能，而不是重新输入。怎么解决啊，谢谢~  如果想在输入错误后重新输入，可以在default中goto到switch前面

switch里每一个分支（包括default），只要理解为顺序执行的语句系列就可以了（用break可以跳出switch块），不管有多少语句，一般也不需要大括号（除非在分支里面定义局部变量，有些编译器需要在大括号里面）

The C switch Statement The switch and case statements help control complex conditional and branching operations. The switch statement transfers control to a statement within its body.   Syntax  selection-statement :  switch ( expression ) statement  labeled-statement :  case constant-expression : statement default : statement  Control passes to the statement whose case constant-expression matches the value of switch ( expression ). The switch statement can include any number of case instances, but no two case constants within the same switch statement can have the same value. Execution of the statement body begins at the selected statement and proceeds until the end of the body or until a break statement transfers control out of the body.   Use of the switch statement usually looks something like this:   switch ( expression )  { declarations  .  .  .  case constant-expression :   statements executed if the expression equals the  value of this constant-expression  .  .  .  break;  default : statements executed if expression does not equal  any case constant-expression  }  You can use the break statement to end processing of a particular case within the switch statement and to branch to the end of the switch statement. Without break, the program continues to the next case, executing the statements until a break or the end of the statement is reached. In some situations, this continuation may be desirable.  The default statement is executed if no case constant-expression is equal to the value of switch ( expression ). If the default statement is omitted, and no case match is found, none of the statements in the switch body are executed. There can be at most one default statement. The default statement need not come at the end; it can appear anywhere in the body of the switch statement. In fact it is often more efficient if it appears at the beginning of the switch statement. A case or default label can only appear inside a switch statement.   The type of switch expression and case constant-expression must be integral. The value of each case constant-expression must be unique within the statement body.   The case and default labels of the switch statement body are significant only in the initial test that determines where execution starts in the statement body. Switch statements can be nested. Any static variables are initialized before executing into any switch statements.   Note   Declarations can appear at the head of the compound statement forming the switch body, but initializations included in the declarations are not performed. The switch statement transfers control directly to an executable statement within the body, bypassing the lines that contain initializations.  The following examples illustrate switch statements:   switch( c )  {     case 'A':         capa++;     case 'a':         lettera++;     default :         total++; }  All three statements of the switch body in this example are executed if c is equal to 'A' since a break statement does not appear before the following case. Execution control is transferred to the first statement (capa++;) and continues in order through the rest of the body. If c is equal to 'a', lettera and total are incremented. Only total is incremented if c is not equal to 'A' or 'a'.      switch( i )  {     case -1:         n++;         break;     case 0 :         z++;         break;     case 1 :         p++;         break; }  In this example, a break statement follows each statement of the switch body. The break statement forces an exit from the statement body after one statement is executed. If i is equal to –1, only n is incremented. The break following the statement n++; causes execution control to pass out of the statement body, bypassing the remaining statements. Similarly, if i is equal to 0, only z is incremented; if i is equal to 1, only p is incremented. The final break statement is not strictly necessary, since control passes out of the body at the end of the compound statement, but it is included for consistency.  A single statement can carry multiple case labels, as the following example shows:  case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :  hexcvt(c);  In this example, if constant-expression equals any letter between 'a' and 'f', the hexcvt function is called.   Microsoft Specific —>  Microsoft C does not limit the number of case values in a switch statement. The number is limited only by the available memory. ANSI C requires at least 257 case labels be allowed in a switch statement.  The default for Microsoft C is that the Microsoft extensions are enabled. Use the /Za compiler option to disable these extensions.   END Microsoft Specific

贴完整代码吧。 而且你的default后面好像少了一个冒号吧？

default：后面有冒号


Question: 给定一个长度为N的数组，求数组的最大值。

引用 2 楼 baidu_35528643 的回复:新人，不会定义用户规定任意长度的数组，而且需要多组测试数据 求指教 问题描述错误

引用 3 楼 qq423399099 的回复:多组测试直接while(1){}的循环就好 输入多个数，直接用malloc动态申请，如果是GCC编译器什么的直接int arr[N]也可以  int N; int *arr; scanf("%d", &N); arr = (int *)malloc(sizeof(int) * N);    多谢

新人，不会定义用户规定任意长度的数组，而且需要多组测试数据 求指教

这个没有难度吧？！@


Question: 关于unsigned int 和 int

最高位是被看作符号位还是不被看作符号位的区别。

一样大，一个有负数，一个没负数

举个小例子说明就知道了。如 4bit 的数字，则最多只能表示 16 个数字。 你可以用来存储无符号数字： 0、1、2、3、4、5、6、7、8、9、10、11、12、13、14、15 也可以用来存储有符号数字： -7、-6、-5、-4、-3、-2、-1、0、1、2、3、4、5、6、7 反正总数始终是 16 个数字，如何存储，选择在你。

两种类型的范围是一样大  如果只对于正数来说，unsigned int 会比int 大  因为int 最高位是作为符号含义，而unsigned 中代表数值

符号占用了一位，所以范围不一样

能表达的数字数量一致，但是unsigned不用表示负数，所以能表达更大的数。

个数一样，区间不同， int 还表示了负数，unsigned int只表示0 和正数 unsigned 可以表示更多（同时也是更大）的正数（自然数） 个数都是 2^k 个（32Bits k=32）

引用 9 楼 Hamber_Bao 的回复:[quote=引用 8 楼 liups 的回复:] [quote=引用 7 楼 Hamber_Bao 的回复:] [quote=引用 4 楼 qq423399099 的回复:] 在32位机上，int是32位，范围–2,147,483,648 to 2,147,483,647 在32位机上，unsigned int是32位，范围0 to 4,294,967,295那这两个类型的数值范围怎么比较呢？ 哪个大呢   [/quote] 一样大[/quote] 数值范围 和 取值范围 这两个词表示的意思是不一样的吗？[/quote]  一样大是说若干个二进制位排列组合（准确说是排列）后就那么多可能性。至于你的两个词不知道什么意思

引用 8 楼 liups 的回复:[quote=引用 7 楼 Hamber_Bao 的回复:] [quote=引用 4 楼 qq423399099 的回复:] 在32位机上，int是32位，范围–2,147,483,648 to 2,147,483,647 在32位机上，unsigned int是32位，范围0 to 4,294,967,295那这两个类型的数值范围怎么比较呢？ 哪个大呢   [/quote] 一样大[/quote] 数值范围 和 取值范围 这两个词表示的意思是不一样的吗？

引用 7 楼 Hamber_Bao 的回复:[quote=引用 4 楼 qq423399099 的回复:] 在32位机上，int是32位，范围–2,147,483,648 to 2,147,483,647 在32位机上，unsigned int是32位，范围0 to 4,294,967,295那这两个类型的数值范围怎么比较呢？ 哪个大呢   [/quote] 一样大

引用 4 楼 qq423399099 的回复:在32位机上，int是32位，范围–2,147,483,648 to 2,147,483,647 在32位机上，unsigned int是32位，范围0 to 4,294,967,295那这两个类型的数值范围怎么比较呢？ 哪个大呢

要是按 数值的表示范围来说都一样。因为都是占32位。 因为要按取值范围来说。unsign int 取值更大。不解释（4楼已经说清楚了）。 其实，换一个角度来说。如果把unsign int 表示成哺乳动物，int表示成鱼类。比较哺乳动物和鱼类就没有可比性了

两位二机制 对应无符号数 对应有符号数 00 0  0 01 1  1 10 2 -2 11 3 -1

有符号与无符号的区别而已，绝对范围是一样的

明明一样大啊

找资料看一下就明白了


Question: 求大神把这个C++程序改成C的

VS下可以编译通过

估计你用的文件后缀是cpp，修改成c就行了

看不出哪是c++的呀

这个就是C程序  建议楼主认真研究一下C和C++的区别

这个应该可以C编译通过吧。


Question: code blocks  Error creating process  大神来

又的时候就能调试 有的时候就能调试 就是用图表调试哪种  直接编译 就能运行

codeblocks已安装还要加个库的没加的去

关闭了UAC了 杀毒也关闭了 还是不行啊？ 大哥 咋办啊

关闭UAC、防火墙、杀毒软件、…… 以管理员身份运行 以XP兼容模式运行


Question: 菜鸟求助一个很简单的关于C语言的问题

建议多看看书，这个是基本功。

看看这个: http://stackoverflow.com/questions/3173462/int-var-1-void-main-int-i-i

main里的i是局部变量，和全局变量的i不是一个变量，在main里面有效的是局部的那个i。


Question: C语言动态分配问题

代码如下：//这是我的课程设计作业：飞机票系统。汗，好像有点多，不过我已经删减了大部分，第一次发帖，请大家见谅，监听到的错误是lol，当执行到红色代码时，指针值会变为0x1！ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #include<conio.h> #include"list.h" #include"queue.h" #pragma warning(disable:4996) struct route	//航线 { 	int plane;//飞机号 	int num;//航班号 	char finaltion[10];//终点站名 	char date[5];//飞行日期 	int people;//成员定额 	int ticket;//余票额 	struct finisheder* fclient;//已定票的客户名单 	struct unfinisheder* uclient;//预约登记的客户名单 }; void main() { 	int selection; 	int loop=0; 	int aa, bb, cc, dd; 	char ee[10], ff[5]; 	int length = sizeof(aa + bb + cc + dd) + sizeof(ee)+sizeof(ff);//用于读取文件fp的每一行数据 	struct route flight; 	tm t; 	flight.fclient = (struct finisheder*) malloc(sizeof(struct finisheder)); 	flight.uclient = (struct unfinisheder*) malloc(sizeof(struct unfinisheder)); 	struct snode** lol = (struct snode**)malloc(sizeof(struct snode*)); 	struct queue* wow = (struct queue*)malloc(sizeof(struct queue)); 	*lol = (struct snode*)malloc(sizeof(struct snode)); 	wow->front = (struct node*)malloc(sizeof(struct node)); 	wow->rear = (struct node*)malloc(sizeof(struct node)); 	FILE *fp; 	FILE *pf; 	bool Exit = false;//条件控制 	while (!Exit) 	{ 		system("cls"); 		Exit = true; 		printf("*********************\n"); 		printf("**  1.录入班次信息 **\n"); 		printf("**  2.浏览班次信息 **\n"); 		printf("**  3.查询路线     **\n"); 		printf("**  4.退票售票     **\n"); 		printf("**  5.修改航班信息 **\n"); 		printf("*********************\n"); 		printf("Please enter the selection:"); 		scanf("%d", &selection); 		switch (selection) 		{ 		case 1: 			system("cls"); 			fp = fopen("flights.txt", "a");	//a:追加;w:只写（原文件内容清空） 			pf = fopen("member.txt", "a");	//a:追加;w:只写（原文件内容清空） 			fprintf(pf, "航班号:"); 			printf("请输入班次:"); 			scanf("%d", &flight.num); 			while (flight.num != 0) 			{ 				system("cls"); 				printf("飞机号\t\t终点站名\t飞行日期\t成员定额\t余票额\n"); 				scanf("%d%s%s%d%d", &flight.plane, &flight.finaltion, &flight.date, &flight.people, &flight.ticket); 				fprintf(fp, "%d\t\t%d\t\t%-16s%-16s%d\t\t%d\n", flight.plane, flight.num, flight.finaltion, flight.date, flight.people, flight.ticket); 				fprintf(pf, "%d\n", flight.num); 				fprintf(pf, "已定票的客户名单:\n姓名\t\t订票额\n"); 				printf("该航线没人么?y/n\n"); 				getchar(); 				while ((getchar()) != 'y') 				{ 					printf("已定票的客户名单:\n"); 					printf("姓名\t\t订票额\n"); 					scanf("%s%d", flight.fclient->name, &(flight.fclient->ticket)); 					fprintf(pf, "%-16s%d\n", flight.fclient->name, flight.fclient->ticket);	 					printf("座位号:"); 					fprintf(pf, "座位号:"); 					for (int i = 0; i < flight.fclient->ticket; i++) 					{ 						scanf("%d", &flight.fclient->seat[i]); 						fprintf(pf, "%d\t", flight.fclient->seat[i]); 					} 					InsertLastlist(lol, *flight.fclient); 					printf("人员全部录入? y/n\n"); 					getchar(); 				} 				fprintf(pf, "\n预约的客户名单:\n姓名\t\t所需票额\n"); 				printf("该航线没人预约么?y/n\n"); 				getchar(); 				while ((getchar()) != 'y') 				{ 					printf("预约的客户名单:\n"); 					printf("姓名\t\t所需票额\n"); 					scanf("%s%d", &flight.uclient->name, &flight.uclient->need); 					fprintf(pf, "%-16s%d\n", flight.uclient->name, flight.uclient->need); 					Enqueue(wow, *flight.uclient); 					printf("人员全部录入? y/n\n"); 					getchar(); 				} 				system("cls"); 				printf("请输入班次:"); 				scanf("%d", &flight.num); 				fclose(fp); 				system("cls"); 				printf("是否返回上一步?y/n"); 				getchar(); 				if (getchar() == 'y') 					Exit = false; 				break; 			} list.h:          #include <stdio.h> #include<stdlib.h> #include<string.h> #pragma once struct finisheder	//已完成的客户 { 	char name[8];//姓名 	int ticket;//订票额 	int seat[10];//座位号 }; struct snode { 	struct finisheder data;//值域 	struct snode* next;//链接指针域 }; void InsertLastlist(struct snode** lol, struct finisheder x)		//向单链表的表尾插入元素 { 	struct snode* newp; 	newp = (struct snode*)malloc(sizeof(struct snode)); 	if (newp == NULL) 	{ 		printf("内存动态空间用完，退出运行!"); 		exit(1); 	} 	newp->data = x; 	newp->next = NULL; 	struct snode* p = *lol; 	while (p->next != NULL) p = p->next; 	p->next = newp; } queue.h: #pragma once #include <stdio.h> #include <stdlib.h> struct unfinisheder		//预约的客户 { 	char name[8];//姓名 	int need;//所需票额 }; struct node			 { 	struct unfinisheder data;//值域 	struct node* next;//链接指针域 }; struct queue { 	struct node* front;//队首指针 	struct node* rear;//队尾指针 }; void Enqueue(struct queue* q, struct unfinisheder x)		//入队列 { 	struct node* newp; 	newp =(struct node*)malloc(sizeof(struct node)); 	if (newp == NULL) 	{ 		printf("内存动态空间用完，退出运行!"); 		exit(1); 	} 	newp->data = x; 	newp->next = NULL; 	if (q->rear == NULL) 		q->front = q->rear = newp; 	else 	{ 		q->rear->next = newp; 		q->rear = newp; 	} }

仅供参考：#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: 为什么我的快速排序算法这么慢？

#include <stdio.h> #include <stdlib.h> #include <time.h> unsigned long ulrand(void) {     return (      (((unsigned long)rand()<<24)&0xFF000000ul)     |(((unsigned long)rand()<<12)&0x00FFF000ul)     |(((unsigned long)rand()    )&0x00000FFFul)); } unsigned __int64 ullrand(void) {     return (      (((unsigned __int64)ulrand())<<32)     | ((unsigned __int64)ulrand())); } int i; unsigned long ul; unsigned __int64 ull; void main() {     srand(time(NULL));     for (i=0;i<10;i++) {         ul=ulrand();         printf("%010lu 0x%08x\n",ul,ul);     }     for (i=0;i<10;i++) {         ull=ullrand();         printf("%020I64u 0x%016I64x\n",ull,ull);     } } //3971076432 0xecb1d150 //2433428051 0x910b2a53 //1415415336 0x545d8628 //1312330759 0x4e389407 //1845758378 0x6e0409aa //0008069933 0x007b232d //4202720757 0xfa806df5 //2669855255 0x9f22c217 //0312068736 0x1299ca80 //2084555989 0x7c3fccd5 //03502077880857307931 0x3099e1472040ab1b //16884702393146816355 0xea52835e19b43763 //01877364819396611730 0x1a0dbd5b45f34e92 //07839440151924835771 0x6ccb4948756a05bb //09471412086917299176 0x8371371c820bfbe8 //04411255971577469925 0x3d37edef2f321be5 //13735846279546091130 0xbe9f876a65b7367a //04512980766520059820 0x3ea15418aa9927ac //15821377118299441610 0xdb90d2a9f1bb49ca //15512417228822200185 0xd7472d480398bf79   无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

你直接freopen一下，先写好一个全是随机数的文件（PYTHON很方便），再进行测试

这样啊，把随机数写道文件里， 每次读取数据，然后再排序 一次生成永续使用，而且数据生成，和排序测试，可以写成两个独立的程序 是不是简单些 排序程序，其实简单不了多少 大概思路，是不能简单的，能精简的不多。 你可以把测试排序的代码，写成inline 函数，或者宏 然后，直接调用排序测试函数，main 函数，就比较清爽了

引用 31 楼 lm_whales 的回复:随机数生成器，起码要有两个特性 1）不能太均匀，比如奇偶相间排列 2）能够取到，某个范围所有的数值。 嗯嗯，我是说我的程序有点麻烦，能不能简单一点，不是说这个随机数生成函数，你可能理解错了

这么多行，我还真看不出来。

const int A =48271; const int M =21474836647; const int R=M/A; const int Q=M%A; static int s_seed=1; srand31b(int seed){     if(seed<0)seed+=M;     s_seed= seed; }  int rand31b(){ int seed =A *(s_seed %Q)-R*(s_seed/Q); if(seed >=0 ){s_seed=seed; } else s_seed = seed + M; return s_seed; }

const int A =48271; const int M =2147483647; ///修正一下，2^31-1 =2147483647;

引用 28 楼 HowieZhao 的回复:[quote=引用 22 楼 lm_whales 的回复:] 31Bits x[i+1] =A *x[i] %M A=48271； M =21474836647；  注意处理溢出 处理方式如下： R=M/A; Q=M%A;  x[i+1] =A *(x[i] %Q)-R*(x[i]/Q); if(x[i+1]>=0 ){ } else x[i+1] +=M;   这个代码如下：  const int A =48271; const int M =21474836647; const int R=M/A; const int Q=M%A; static int s_seed=1; srand31b(int seed){     if(seed<0)seed+=M;     s_seed= seed; }  int rand31b(){ int seed =A *(s_seed %Q)-R*(s_seed/Q); if(seed >=0 ){s_seed=seed; } else s_seed +=M; return s_seed; }  可以把这个代码封装成类 谢谢啦，还有我觉得我这个程序太麻烦了，能不能改的简单一点？[/quote] 这个是一本书上，经过严格论证的， 我个人感觉已经最简单了 至于伪随机序列生成器（线性同余数生成器），都是有严格数学依据的。 这种生成器，可以生成0～某个范围内的所有数 这里是0～21474836647; 之所以这么麻烦，是为了处理溢出，和负数 这个随机数生成器，不会生成负数，种子也不能有负数。

建议用性能工具分析一下，看主要耗时是在哪些函数，才好具体分析原因

引用 20 楼 qq_35473404 的回复:产生数据范围大一些 关键是如何产生大范围的数据呢？

引用 22 楼 lm_whales 的回复:31Bits x[i+1] =A *x[i] %M A=48271； M =21474836647；  注意处理溢出 处理方式如下： R=M/A; Q=M%A;  x[i+1] =A *(x[i] %Q)-R*(x[i]/Q); if(x[i+1]>=0 ){ } else x[i+1] +=M;   这个代码如下：  const int A =48271; const int M =21474836647; const int R=M/A; const int Q=M%A; static int s_seed=1; srand31b(int seed){     if(seed<0)seed+=M;     s_seed= seed; }  int rand31b(){ int seed =A *(s_seed %Q)-R*(s_seed/Q); if(seed >=0 ){s_seed=seed; } else s_seed +=M; return s_seed; }  可以把这个代码封装成类 谢谢啦，还有我觉得我这个程序太麻烦了，能不能改的简单一点？

引用 23 楼 wangyaninglm 的回复:对，我觉得跟数据也有很大关系，另外就是要用profile分析一下的 嗯嗯，还有我觉得我这个程序太麻烦了，能不能改的简单一点？

引用 24 楼 HowieZhao 的回复:[quote=引用 17 楼 cyfcsd 的回复:] 楼主好早啊，，，佩服，可以用下面简单的方法产生一些大随机数  (rand()*1000)+rand();  但是这个应该很少有可能产生小的数啊，我需要的是范围大的，而不是大的随机数，如果只是大的随机数，那它的范围等于没变多少啊，对吗？还有一个小请求，我看我这个程序太麻烦了，能不能改的简单一点？[/quote] rand()是不会产生很小的数，你可以用(rand()%m*10000)+rand()%n;这种类型的方式，总之是几个随机数相加，应该可以凑出你要的结果的

引用 19 楼 qq_35473404 的回复:可能是你产生的数的范围太小了，你可以看看产生1到2000000的数试试 你说对了，经过检查就是生成数的范围太小了，但是rand()函数最大只能生成3万左右的数啊，有什么办法可以生成1到2000000呢？

引用 17 楼 cyfcsd 的回复:楼主好早啊，，，佩服，可以用下面简单的方法产生一些大随机数  (rand()*1000)+rand();  但是这个应该很少有可能产生小的数啊，我需要的是范围大的，而不是大的随机数，如果只是大的随机数，那它的范围等于没变多少啊，对吗？还有一个小请求，我看我这个程序太麻烦了，能不能改的简单一点？

引用 15 楼 lm_whales 的回复:C++11标准库有新的随机数生成器 并且，你也可以自行定义随机数生成器 ------伪随机序列生成器， 更准确的叫 线性同余数生成器    Unix,Linux 有drand48 函数可用，可以生成32Bits随机数 一些数据结构的书籍里，也有31Bits 随机数生成算法 31Bits x[i+1] =A *x[i] %M A=48271； M =21474836647；  注意处理溢出 处理方式如下： R=M/A; Q=M%A;  x[i+1] =A *(x[i] %Q)-R*(x[i]/Q); if(x[i+1]>=0 ){ } else x[i+1] +=M;  32Bits drand48 公式 x[i+1]=(A * x[i]+C)%(2^B)  A =25214903917 B=48 C=13 返回高32Bits    [quote=引用 14 楼 HowieZhao 的回复:] [quote=引用 13 楼 lm_whales 的回复:] 快排，一般采用三数取中法，比采用左边或者右边的作为划分标志。随机性更好 按理说，采用随机算法。效果最好 不过，随机数生成器本身的效率，比较低，实用性并不好 刚刚那个问题已经基本解决了，现在有遇到了一个新问题，不知该如何生成一个大范围的随机数呢？rand()函数生成的最大随机数也只是3万多啊，不够[/quote][/quote] 不好意思，不是很理解

对，我觉得跟数据也有很大关系，另外就是要用profile分析一下的


Question: 两个问题（1）vs2010 error 找不到标识符  （2）vs 2010   error LNK1120: 1 个无法解析的外部命令

小白·~~刚接触~~~vs2010写c怎么用啊~~·捣鼓了一天还是不清楚~~~

项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项

为什么打开其他人的代码总会出现不一样的数字提示错误error LNK1120: 1 个无法解析的外部命令有时候又是数字2001

clrscr是TC特有的，其它的C语言环境没有这个函数，也就没有头文件包含这个函数。 TC中使用clrscr()必须#include<conio.h>.其他编译环境建议使用system("cls");来替代clrscr();system()函数在#include <stdlib.h>里面.

先包含头文件#include <stdlib.h> 然后把那句红色的变成system("cls");

1>d:\c语言\练习\hah\hah\一.cpp(7): error C3861: “clrscr”: 找不到标识符 错误的提示


Question: 关于typedef的问题

引用 2 楼 zhao4zhong1 的回复:typedef typedef type-declaration synonym;  The typedef keyword defines a synonym for the specified type-declaration. The identifier in the type-declaration becomes another name for the type, instead of naming an instance of the type. You cannot use the typedef specifier inside a function definition.  A typedef declaration introduces a name that, within its scope, becomes a synonym for the type given by the decl-specifiers portion of the declaration. In contrast to the class, struct, union, and enum declarations, typedef declarations do not introduce new types — they introduce new names for existing types.  Example  // Example of the typedef keyword typedef unsigned long ulong;  ulong ul;     // Equivalent to "unsigned long ul;"  typedef struct mystructtag {    int   i;    float f;    char  c; } mystruct;  mystruct ms;   // Equivalent to "struct mystructtag ms;"  typedef int (*funcptr)();  // funcptr is synonym for "pointer                            //    to function returning int"  funcptr table[10];   // Equivalent to "int (*table[10])();" 恩恩

引用 3 楼 qq423399099 的回复:typedef struct Node *PtrToNode; 意思是： 给struct Node *取个别名叫PtrToNode(注意*是跟着前面的) struct Node *a; 等同于PtrToNode a; 恩恩，谢谢讲解

struct Node;  声明一个结构体 typedef struct Node *PtrToNode;  定义一个结构体指针


Question: strdup()作为其他函数的入参会导致内存泄漏么

是  _strdup, _wcsdup, _mbsdup Duplicate strings.  char *_strdup( const char *strSource );  wchar_t *_wcsdup( const wchar_t *strSource );  unsigned char *_mbsdup( const unsigned char *strSource );  Routine Required Header Compatibility  _strdup <string.h> Win 95, Win NT  _wcsdup <string.h> or <wchar.h> Win 95, Win NT  _mbsdup <mbstring.h> Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns a pointer to the storage location for the copied string or NULL if storage cannot be allocated.  Parameter  strSource  Null-terminated source string  Remarks  The _strdup function calls malloc to allocate storage space for a copy of strSource and then copies strSource to the allocated space.  _wcsdup and _mbsdup are wide-character and multibyte-character versions of _strdup. The arguments and return value of _wcsdup are wide-character strings; those of _mbsdup are multibyte-character strings. These three functions behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tcsdup _strdup _mbsdup  _wcsdup    Because _strdup calls malloc to allocate storage space for the copy of strSource, it is good practice always to release this memory by calling the free routine on the pointer returned by the call to _strdup.  Example  /* STRDUP.C */  #include <string.h> #include <stdio.h>  void main( void ) {    char buffer[] = "This is the buffer text";    char *newstring;    printf( "Original: %s\n", buffer );    newstring = _strdup( buffer );    printf( "Copy:     %s\n", newstring );    free( newstring ); }   Output  Original: This is the buffer text Copy:     This is the buffer text   String Manipulation Routines  See Also   memset, strcat, strcmp, strncat, strncmp, strncpy, _strnicmp, strrchr, strspn


Question: 软件错误代码和错误消息如何设计

我一般会记录日志，当然不会打在循环内的，即使在循环内，只要不是太频繁也可以的，如几分钟的一个也可的，或者是针对事件的，就是完成一整件事情有8个步骤，我会记录事件的开始时间日志，和每一步完成的日志，即使程序奔了，也可以查看上一步的日志走到哪里 了，如果，不奔溃，那最好了，把出错的日志也记下来，每天一个txt文件，每次日志都要有开始日期和时间的，

错误码 错误信息字符串（英文） 错误信息字符串（中文） 出现该错误可能的原因 出现该错误后可能的解决办法 出现该错误后可参考的网络连接 出现该错误后可参考的网络连接对应的二维码 出现该错误后可拨打的客服热线电话 ……


Question: #define 可以拼接吗？谢谢

谢谢！问题解决了。。

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

#define cc aa bb

试试# ##  http://www.cnblogs.com/little-ant/p/3463080.html


Question: C语言重定向的问题

引用 13 楼 loveqise 的回复:[quote=引用 11楼talkdream 的回复:]printf("%d\n",a); 去掉\n改成printf("%d",a); 试试可不可以。大神，我把%d变为%c，char a就行了 用%d，int a的时候，即使是纯数字文本，两个文本的内容也不一样[/quote]  谢谢告知结果，看来带数据类型的方法还是更改了原本的数据只不过我们不太了解罢了，从这个角度上看char 也是有风险的，只是我们现在不知道或者没碰到罢了，要是类型无关方法应该更安全。这些做法只当是对语言的理解就好了，如果真的应用时还是寻找些常用的方法更安全。

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

while后需要分号吧

复制文件一般不这么写，也不用freopen，用fopen，最好二进制读写。

引用 10楼小灸舞 的回复:http://bbs.bccn.net/thread-359111-1-1.html 大神，我把%d变为%c，char a就行了 用%d，int a的时候，即使是纯数字文本，两个文本的内容也不一样

引用 11楼talkdream 的回复:printf("%d\n",a); 去掉\n改成printf("%d",a); 试试可不可以。大神，我把%d变为%c，char a就行了 用%d，int a的时候，即使是纯数字文本，两个文本的内容也不一样

大神们，我把%d变为%c，char a就行了 用%d，int a的时候，即使是纯数字文本，两个文本的内容也不一样

引用 6 楼 loveqise 的回复:[quote=引用 5楼user-6 的回复:]我这里代码运行正常，没问题 Ubuntu 14.04.1 LTS  你的运行环境是什么，在当前目录下是否有对应权限 看看freopen返回值：如果成功，则返回该指向该输出流的文件指针，否则返回为NULL调试成功了，不过为什么不能复制word文档内容到另一个word[/quote]  关注。为啥不能呢？（不可以理解成把文件A无任何转换的情况下写到文件B么？）

引用 7楼小灸舞 的回复:谁告诉你freopen能读写word的请问转移word，excel这些用什么？

谁告诉你freopen能读写word的

引用 5楼user-6 的回复:我这里代码运行正常，没问题 Ubuntu 14.04.1 LTS  你的运行环境是什么，在当前目录下是否有对应权限 看看freopen返回值：如果成功，则返回该指向该输出流的文件指针，否则返回为NULL调试成功了，不过为什么不能复制word文档内容到另一个word

引用 2楼yunzhiyoumu 的回复:while后需要分号吧加了也一样

引用 1楼小灸舞 的回复:代码没问题。 自己检查下freopen的返回值以及hello.txt的路径（写上完整路径）请问这个路径应该怎么写？返回值用strlen测吗？


Question: C语言中，const算常量吗？

引用 3 楼 srhouyu 的回复:[quote=引用 2 楼 fefe82 的回复:] 在 C 语言里，不是。  C 语言的 const expression 是如下定义的： 6.6 Constant Expressions 6 An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.  也就是说可以包括： integer constants 在 C 语言里仅包括  1, 23, 123 之类的字面量。 enumeration constants ，枚举值 chracater constants, 字符常量，'a', '1'，同样仅限字面量 sizeof(...) 等  在你的程序里，N 不属于以上任何一类。  那么，我只能define吗？[/quote]  C 语言里，define 应该是一个通常的做法吧 ...

引用 2 楼 fefe82 的回复:在 C 语言里，不是。  C 语言的 const expression 是如下定义的： 6.6 Constant Expressions 6 An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.  也就是说可以包括： integer constants 在 C 语言里仅包括  1, 23, 123 之类的字面量。 enumeration constants ，枚举值 chracater constants, 字符常量，'a', '1'，同样仅限字面量 sizeof(...) 等  在你的程序里，N 不属于以上任何一类。  那么，我只能define吗？

C(C89) 中 const 仅仅表示一个变量是不可修改的，而不具备声明一个常量的功能。


Question: 网页上crtl+h后出来的历史网址在计算机中有保存吗？保存在哪里？

推荐使用软件 http://www.nirsoft.net/utils/opened_files_view.html 和FileMon

注册表里 ？


Question: 数据结构，先序遍历顺序存储二叉树各种结点个数的计算

引用 楼主 fyerd 的回复:用先序遍历计算一个顺序存储二叉树，叶子节点的个数。我用先序遍历的递归做的，最后的结果是对的，如何限定条件，让递归函数输出最后一遍的结果，不出中间的过程呢？谢谢~ void NodeNumber(SqBiTree T, int i,int l){ 	if (T[2 * i + 1] != Nil) 	{ 		NodeNumber(T, 2 * i + 1, l); 	} 	if (T[2 * i + 2] != Nil) 	{ 		NodeNumber(T, 2 * i + 2, l); 	} 	if (T[2 * i + 1] == Nil&&T[2 * i + 2] == Nil){ 		Y++;//全局变量，用于计数叶子结点个数 	}  		printf("叶子结点个数：%d\n", Y);//输出很多遍？  }  在函数中加个静态变量记录一下吧，函数开始++, 结束--, 在--后判定是第几次调用，然后输出。（如果多线程调用时这个方法也不好用，单线程的应该没有问题。）

引用 8 楼 wanren13 的回复:[quote=引用 5 楼 fyerd 的回复:] 同时我还要算度为1的节点，度为2的节点。我为了简便删掉了。这样还可以返回值吗？ 参见我三楼的回复，用传参的方式来计数，因为你用的是post-order，所以根是最后被访问。 最后访问根的时候（i==0）也就是递归结束的时候，输出你的计数就好了。[/quote] 你如果一定要返回的话，同时返回几个数值也是很简单的，返回一个数据结构就可以了，可以是数组，vector，pair或者其他你需要的结构。

引用 5 楼 fyerd 的回复:同时我还要算度为1的节点，度为2的节点。我为了简便删掉了。这样还可以返回值吗？ 参见我三楼的回复，用传参的方式来计数，因为你用的是post-order，所以根是最后被访问。 最后访问根的时候（i==0）也就是递归结束的时候，输出你的计数就好了。

如果要用递归，我觉得只能先返回y个数，然后通过二叉树性质，计算出度为1、2结点个数了。这样应该可以。

参考：  #include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

同时我还要算度为1的节点，度为2的节点。我为了简便删掉了。这样还可以返回值吗？

2楼说的有道理，返回总的叶子数，在函数外输出。

你这是先序？我读书少，别骗我。 程序的最后 if(root) print Y(叶节点个数）

谢谢，我通过指针返回数组，输出结点了。谢谢大家帮助，新手还需努力~

函数返回结点个数就成了 在函数外部输出结点个数,这里假设NULL节点是叶子节点 int mum（tree t）{ if(!t)return 1; return  num(t->left)+num(t->right);  }

Nil指为空，l是总结点个数，我没有用到


Question: 新手，帮忙看看有没有错误？哪里有错误，请指出来，并附上解释。

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

可以先转换为7进制

有几个错误： 1.weeks=days/reday；最后的你是中文的分号 2.scanf("%d,&days");应该是scanf("%d",&days); 3.while应该是if 4.a=days%weeks;;应该是a=days%reday;  #include <stdio.h> int main(void) { 	const int reday=7; 	int days, weeks, a; 	scanf("%d",&days); 	if(days>0) 	{ 		weeks=days/reday; 		a=days%reday; 		printf("%d days are %d weeks,%d days.\n",days,weeks,a); 	} 	return 0; }


Question: 数据结构，先序遍历创建顺序存储二叉树

谢谢您的资料！我定义了一个全局变量j，解决问题了~

#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

T[0]存放根结点，调用该函数为 PreCreateBiTree1（s,l,0,0,T）


Question: 题目:n 维矩阵乘法   A 乘以B 的逆矩阵

以前实现的矩阵类中的代码，仅供参考  //start 求逆阵 Matrix inv(Matrix M) { 	//start 判断矩阵是否可逆 	if(M.row!=M.col) 	{ 		cout<<"只有方阵才能求逆！"<<endl; 		return Matrix(); 	} 	//end 判断矩阵是否可逆 	//start 构造单位阵 	Matrix E(M.row,M.col); 	for(int i=0;i<M.row;++i) 		E[i][i]=1.0; 	//end 构造单位阵 	//start 将矩阵化为阶梯型 	for(int c=0,r=0;c<M.col&&r<M.row;++c,++r) 	{ 		int ind;//记录主元行号 		//start 寻找主元 		for(int i=r;i<M.row;++i) 		{ 			if(M[i][c]!=0) 			{ 				ind=i; 				break; 			} 			if(i==M.row-1) 			{ 				cout<<"矩阵不可逆！"<<endl; 				return Matrix(); 			} 		} 		//end 寻找主元 		//start 交换两行 		for(int j=0;j<M.col;++j) 		{ 			double temp;		 			temp=M[ind][j];		 			M[ind][j]=M[r][j];		 			M[r][j]=temp;  			temp=E[ind][j]; 			E[ind][j]=E[r][j]; 			E[r][j]=temp;			 		} 		//end 交换两行 		//start 主元下元素化0 		for(int i=r+1;i<M.row;++i) 		{ 			double temp; 			temp=M[i][c]/M[r][c]; 			for(int j=0;j<M.col;++j) 			{ 				M[i][j]-=M[r][j]*temp; 				E[i][j]-=E[r][j]*temp; 			} 		} 		//end 主元下元素化0	 	}//end 将矩阵化为阶梯型 	//start 主元化1 	for(int r=0;r<M.row;++r) 	{ 		double temp=M[r][r]; 		for(int c=r;c<M.col;++c) 		{ 			M[r][c]/=temp; 		} 		for(int c=0;c<M.col;++c) 		{ 			E[r][c]/=temp; 		} 	} 	//end 主元化1 	//start 化对角型 	for(int r=M.row-2;r>=0;--r) 	{ 		for(int i=M.row-1;i>r;--i) 		{ 			for(int j=0;j<M.col;++j) 			{ 				E[r][j]-=E[i][j]*M[r][i];							 			} 			for(int j=0;j<M.col;++j) 			{ 				M[r][j]-=M[i][j]*M[r][i];				 			} 		} 	}//end 化对角型 	return E; 	 }//end 求逆阵 //start *重载(矩阵相乘) Matrix operator*(const Matrix& lhs,const Matrix& rhs) { 	if(lhs.row!=lhs.col) 	{ 		cout<<"相乘矩阵不符合条件！"<<endl; 		return Matrix(); 	} 	Matrix temp(lhs.row,rhs.col); 	for(int r=0;r<temp.row;++r) 		for(int c=0;c<temp.col;++c) 		{ 			for(int k=0;k<lhs.col;++k) 				temp[r][c]+=lhs[r][k]*rhs[k][c]; 		} 	return temp; }//end *重载(矩阵相乘)

代数余子式和行列式法 A-1 =A*/det(A) 直接算法可以用 高斯—约当消去法解线性方程组 的方法求出 矩阵成积 A^-1  B  AX=B 则 X=A^-1B  这样只要求出 方程组AX=B的解X 就是 A^-1B了

求逆阵有两种基本方法： 1）初等变换法 2）代数余子式和行列式法


Question: 请教sizeof（指针）问题。

4楼说的很精简。

在Win32下sizeof(指针)都等于4吧，楼主试着输出： sizeof(*p1),sizeof(*p2),sizeof(*p3),sizeof(*p4) 也许就得到想要的了。

我感觉4楼讲解的很透彻，学习了！

谢谢。那就很好理解。 烟盒里的纸条，地址可能是乡下一破小木屋，也可能是北京鸟巢。

引用 3 楼 qq_16774199的回复:[quote=引用 2 楼 paschen 的回复:] 指针长度是固定的，和指针的类型无关  比如： char a[] = "abcd"; char *pa = a; 数组用5字节，因为还有\0。 当pa = pa+1时，我们目的是字符b，若pa为4，那指针不就移动到\0去了？[/quote] Pa的大小为四  但值不为4

引用 3 楼 qq_16774199 的回复:[quote=引用 2 楼 paschen 的回复:] 指针长度是固定的，和指针的类型无关  比如： char a[] = "abcd"; char *pa = a; 数组用5字节，因为还有\0。 当pa = pa+1时，我们目的是字符b，若pa为4，那指针不就移动到\0去了？[/quote]  a是数组类型，pa是指针类型，sizeof(a)得到的是数组的长度，而sizeof(pa)只是指针长度（32位程序总为4） 数组与指针是不同的类型 如果需要获取字符串长度，用strlen

指针的大小和它指向的数据类型无关，主要看操作系统的位数（因为指针保存的是地址），32位的是4字节，64位是8字节。

引用 2 楼 paschen 的回复:指针长度是固定的，和指针的类型无关  比如： char a[] = "abcd"; char *pa = a; 数组用5字节，因为还有\0。 当pa = pa+1时，我们目的是字符b，若pa为4，那指针不就移动到\0去了？

指针长度是固定的，和指针的类型无关

我是这样理解的，甭管你什么类型的数据，它的地址都是一样的。比如，不管男女老少，每个人的身份证号位数都是一样的吧。

分析：既然指针只是要存储另一个变量的地址，。注意，是存放一变量的地址，而不是存放一个变量本身，所以，不管指针指向什么类型的变量，它的大小总是固定的：只要能放得下一个地址就行！（这是一间只有烟盒大小的“房间”，因为它只需要入一张与着地址的纸条）。   存放一个地址需要几个字节？答案是和一个 int 类型的大小相同：4字节。  http://blog.csdn.net/driversmith/article/details/6236893

标准只规定了char, unsigned char, or signed char的结果是1，其他的都是未规定的

指针类型占用空间，跟CPU，操作系统，编译器有关 X86，16Bits dos 和windows有 near（16Bits），far(32Bits) 两种指针 32Bits 本来应该有near(32Bits),far(48Bits)两种指针的 不过windows 和VC 只提供32Bits 一种指针，因此，所有指针长度都是32Bits