Question: 字符串删除子串问题，研究了好几天还是搞不定，只好求助了

cstring str; str.replace("substr", "");

#include <stdio.h> #include <string.h>  /*              s1[] = "0123456789ABCDEF";  s2[] = "45678";   n1 = strlen(s1);  n2 = strlen(s2);  p1 = strstr(s1, s2);  p2 = p1 + n2;           n1          |  |---------------|  "0123456789ABCDEF"       |___||_____|       | |  |  |      p1 |  p2 |         |     |         n2    |              (n1-n2-(p1-s1))  */  int main(int argc, char *argv[]) {     char s1[] = "0123456789ABCDEF";     char s2[] = "45678";     char *p1;     char *p2;     int n1;     int n2;      n1 = strlen(s1);     n2 = strlen(s2);     p1 = strstr(s1, s2);     p2 = p1 + n2;          if (p1 != NULL)         memmove(p1, p2, n1 - n2 - (p1 - s1) + 1);      printf("%d\n",  n1 - n2 - (p1 - s1) + 1);     printf("s1=%s\n", s1);      return 0; } /* 输出: 8 s1=01239ABCDEF */

用strstr找到子串，然后用memove删除即可  #include <stdio.h> #include <string.h>  /*              s1[] = "0123456789ABCDEF";  s2[] = "45678";   n1 = strlen(s1);  n2 = strlen(s2);  p1 = strstr(s1, s2);  p2 = p1 + n2;           n1          |  |---------------|  "0123456789ABCDEF"       |___||_____|       | |  |  |      p1 |  p2 |         |     |         n2    |              (n1-n2-(p-s1))  */  int main(int argc, char *argv[]) {     char s1[] = "0123456789ABCDEF";     char s2[] = "4567";     char *p1;     char *p2;     int n1;     int n2;      n1 = strlen(s1);     n2 = strlen(s2);     p1 = strstr(s1, s2);     p2 = p1 + n2;          if (p1 != NULL)         memmove(p1, p2, n1 - n2 - (p1 - s1) + 1);      printf("%d\n",  n1 - n2 - (p1 - s1) + 1);     printf("s1=%s\n", s1);      return 0; }

拼音联想惹的祸。

引用 4 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <string.h> char s[256]; char *p; int r,n,i; int main() {     while (1) {         printf("请输入一行文字(空行结束),\"%%20\"将替换为\" \",\"你懂得\"将替换为\"XXXXXX\":\n");         fgets(s,256,stdin);         if ('\n'==s[0]) break;         p=s;         while (1) {             p=strstr(p,"%20");             if (p) {                 memmove(p+1,p+3,strlen(p)-3+1);                 p[0]=' ';             } else break;         }         p=s;         while (1) {             p=strstr(p,"你懂得");             if (p) {                 memmove(p+6,p+6,strlen(p)-6+1);                 for (i=0;i<6;i++) p[i]='X';             } else break;         }         printf("%s",s);     }     return 0; } //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //abcdefg%20helloworld%20something.pdf //abcdefg helloworld something.pdf //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //这是测试文字你懂得，在这个你懂的地方，就得做你懂得的事 //这是测试文字XXXXX，在这个你懂的地方，就得做XXXXX的事 //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //     赵老湿，是“你懂的”，不是“你懂得”。特此更正。

咋研究的？？有没有单步调试？一边调试一边分析自己写的，肯定可以弄出来

//********************************************************************************* //【功能】在给定字符串中查找所有特定子串并删除，如果没有找到相应子串，则不作任何操作。 //【输入】 str：输入的被操作字符串 //              sub_str：需要查找并删除的特定子字符串 //【输出】 result_str：在str字符串中删除所有sub_str子字符串后的结果 //【返回】 删除的子字符串的个数 //【示例】输入：str = "abcde123abcd123"        sub_str = "123" //               输出：result_str = "abcdeabcd"  //              返回：2 //******************************************************************************** #include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h>  int delete_sub_str(const char *str, const char *sub_str, char *result_str) { 	int i=0,num=0; 	int sub_str_len=strlen(sub_str); 	const char *temp; 	const char *p,*p1; 	char *q; 	p=str; p1=sub_str; 	q=result_str; 	while(*str) 	{ 		if(*str==*sub_str)	 		{ 			temp=str;             //刚开始写成了while((*str++)==(*sub_str++)&&(*sub_str))，这样就出了问题，二者的不通过在于++之后判断*sub_str为空还是++之前 			while((*sub_str)&&(*str++)==(*sub_str++))  				i++; 			if(i==sub_str_len)  				num++; 			else 				for(int j=0;j<i;j++) 				{ 					*q++=*(temp+j); 				} 			sub_str=p1; 			i=0; 		} 		else 			*q++=*str++; 	} 	printf("%s\n",result_str); 	return num; } int main() { 	char *a="a123bc123de123abc123d123"; 	char *b="123"; 	char c[100]={0}; 	int i=delete_sub_str(a, b,c); 	printf("Total %d stings was deleted!\n",i); 	system("pause"); 	return 0; }

int del_substr (char * str, char const * substr) {     int cnt = 0;     char * p, * q, * r;     while (q = (char *)substr, * (p = r = str ++) != '\0')         while (* q != '\0' && * p ++ == * q)             if (* ++ q == '\0' && ++ cnt)                 while ((* r ++ = * p ++) != '\0') ;     return cnt; }  http://bbs.csdn.net/topics/390946225


Question: 新人求解 这段代码为什么运行得不到我想要的结果 复图 附代码 真心看了很久没看出来什么

scanf("%d\n",&a); //改为 scanf("%d",&a);


Question: fgets函数只读取EOF是什么结果？

都没有读到东西，你希望line是啥呢？

这个函数遇到EOF自动返回NULL，不会把它读进去

试一试不就知道了吗。

引用 1 楼 zhao4zhong1 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？+1，实践是检验真理的唯一标准

额，受教了。


Question: 新入手c/c++.求解a,b,c的值，并解释一下为什么？

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

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

这里a打印出的是字符串的内容，其实a的真实值是字符串的首地址，之所以打印出字符串的内容，是因为istream和ostream类对<<做了运算符重载，对char和char*有特殊处理。至于b和c的值，1楼的朋友解释的很清楚，需要说明的是使用间接引用运算符，系统会根据指针指向的类型确定读取字节的数量，比如例子中的*(char*)读一个字节，*(short*)读取两个字节。 至于三楼的朋友说的，稍微有一点问题，“0123456789”确实是在文字常量区，这块区域的内存是只读的，不能修改，但是不代表不能用栈区的指针指向该区域指向该指针。从严谨的角度而言，应该定义为“const char* a = “0123456789””(注意const的位置)。

#include <iostream>  using namespace std;  int main()   {        char *a = "0123456789";   //这里声明了字符串类型        short b = *(a + 3);    //把字符串首地址加3个字节，指向字符3，对应ascii为33h，符号扩展为short，于是b=0033h，转化为十进制打印所以b = 51        short c = *((short *)(a + 4)); 把字符串首地址加4个字节，指向字符4，但此处指针强转为short*，所以指向4和5两个字符，             对应ascii为34h和35h，注意转化是在寄存器中进行的，所以高字节在前为3534h，再转化为十进制打印所以c=13620        cout << "a=" << a << endl << "b=" << b << endl;       cout << "c=" << c << endl;       return 0;   }

哪里有问题啊。。。

引用 4 楼 woai_tudou 的回复:回复一楼：注意转化是在寄存器中进行的，所以高字节在前为3534h。可以解释的更加详细一点吗？是指的大小端问题？ 1，这里确实是跟大端小端相关的，intel处理器是小端，所以高地址字节为高8位，低地址字节在低8位；如果是小端处理器，那么转化结果为3435h。 2，跟转化是否在寄存器中进行无关，即使因为寄存器不够（寄存器溢出），转化在内存中进行，对于小端处理器来说，也是高字节在高位，低字节在低位，即3534h。

引用 3 楼 baidu_26722537 的回复:不能让字符指针指向常量。 http://bbs.csdn.net/topics/391002016  为什么？？ 证据呢？？


Question: 数据类型所占大小

引用 7 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //  +1

typedef struct A {   char a;      int b;      float c;      double d;     int *e;    char *f;     short g; }A; 该struct中，double类型所占空间最大，故此该struct为8字节对齐方式，a和b占据8个字节，c占据8个字节，d占据8个字节，两个指针占据8个字节，最后一个short占据8个字节，一共是40个字节。 内存对齐技术是一种以空间换取读取效率的做法，比如b，应该是从第5个字节存储到第8个字节，字节偏移为4，实际上就是要struct实例对象的基地址+字节偏移4能够整除b的类型大小(int为4)。具体你可以打印出所有struct成员的地址来看看内存排布，PS:打印a地址的时候，请注意将其强制转换为(void*)，否则打印出来的不是地址值。

在 结构定义前加上 #pragma pack(1) 再试试

引用 4 楼 woai_tudou 的回复:结构体的对齐和补齐，在32位机上是按照4个字节进行对齐和补齐的。即小于4个字节的数据类型会自动转换为4个字节。大于或者是等于4个字节的。会保存4个字节的倍数。你还可以去看一下大小端的问题。也是用的这个原理。  你的意思是 sizeof (struct {char c;}) 的结果是4？？

引用 1 楼 user-9 的回复:搜“c语言结构体字节对齐”+1

项目属性可以设置 字节对齐方式 32位操作系统默认应该是 32bit 也就是每个成员变量的起始地址是4字节的倍数 是一个char  a[1] 和 a[4]占有的空间一样

搜“c语言结构体字节对齐”


Question: 如何用C抓取某个网站的部份内容？

用Python吧

C的话用libcurl库，但更推荐python的request，这方面python更有天赋


Question: 求个校验值计算器...

的确是奇偶校验,,有人做出来了...

引用 4 楼 daols 的回复:[quote=引用 1 楼 worldy 的回复:] 不会是奇偶校验，那是用于校验字节的； 11c9这样的值不是4位，是32位，应该是某个模式的CRC32！ 我试了crc32,,算出来是8位的...crc16算出来倒是4位...但是也对不上...= =b[/quote] CRC32有好多计算模式，还有初始值也可以不同

引用 1 楼 worldy 的回复:不会是奇偶校验，那是用于校验字节的； 11c9这样的值不是4位，是32位，应该是某个模式的CRC32！ 我试了crc32,,算出来是8位的...crc16算出来倒是4位...但是也对不上...= =b

引用 2 楼 zxhuser-3 的回复:C#?目测lz来错板块了 好的...C/C++/C#...只要是gcc能编译的就好= =b

C#?目测lz来错板块了


Question: 请教个问题！关于运算中的数据类型

测了一下，VC10,，转换类型没有转换其二进制值，也就是说类型转换其二进制值不变

4.5 Integral promotions [conv.prom] 1 A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int. 2 A prvalue of type char16_t, char32_t, or wchar_t (3.9.1) can be converted to a prvalue of the first of the following types that can represent all the values of its underlying type: int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int. If none of the types in that list can represent all the values of its underlying type, a prvalue of type char16_t, char32_t, or wchar_t can be converted to a prvalue of its underlying type. § 4.5 ISO/IEC 14882:2011(E) 83 © ISO/IEC 2011 – All rights reserved 3 A prvalue of an unscoped enumeration type whose underlying type is not fixed (7.2) can be converted to a prvalue of the first of the following types that can represent all the values of the enumeration (i.e., the values in the range b min to b max as described in 7.2): int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int. If none of the types in that list can represent all the values of the enumeration, a prvalue of an unscoped enumeration type can be converted to a prvalue of the extended integer type with lowest integer conversion rank (4.13) greater than the rank of long long in which all the values of the enumeration can be represented. If there are two such extended types, the signed one is chosen. 4 A prvalue of an unscoped enumeration type whose underlying type is fixed (7.2) can be converted to a prvalue of its underlying type. Moreover, if integral promotion can be applied to its underlying type, a prvalue of an unscoped enumeration type whose underlying type is fixed can also be converted to a prvalue of the promoted underlying type. 5 A prvalue for an integral bit-field (9.6) can be converted to a prvalue of type int if int can represent all the values of the bit-field; otherwise, it can be converted to unsigned int if unsigned int can represent all the values of the bit-field. If the bit-field is larger yet, no integral promotion applies to it. If the bit-field has an enumerated type, it is treated as any other value of that type for promotion purposes. 6 A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one. 7 These conversions are called integral promotions .

引用 15 楼 Czui1990 的回复:你好，两个变量相乘，提升数据长度C语言有明确的定义吗？或者说C语言如何定义类似的情况的？ http://download.csdn.net/detail/user-2/8513111  这里是c++11的ISO文档, 4.5章 因为我给你都说过了, 显然没说明白.所以自己看吧.不过是英文的.

引用 14 楼 user-2 的回复:[quote=引用 13 楼 Czui1990 的回复:] [quote=引用 10 楼 user-2 的回复:] [quote=引用 5 楼 Czui1990 的回复:] user-2你好，你的意思是，因为Sa1_Inport,Sa1_Sign是定义成int16的，所以运算前会转成int16，然后把变量都强制转换成Uint16之后，得出的结果还是会转换为Int类型的进行计算。 但这应该不存在装不下的问题吧，因为计算的结果我没有赋给任何一个变量。 char-a* int-b, 结果是int, 假如a*b超过int范围了, 不会自动变成unsigned int char-a* unsigned int-b, 结果是unsigned int[/quote]  你好，这个我清楚，但问题是int16类型变量强制转换成uint16类型相乘后，我并没有把这个值赋给任何一个变量，所以不存在溢出或超范围的情况，而是直接把这个值去参与比大小的运算，那么这个值是int类型的呢？还是uint类型？是否变成32bit？[/quote] 因为(UInt16)Sa1_InPort)和 ((UInt16) Sa1_Sign)都先提升到int32,所以结果也是int32 [/quote]  你好，两个变量相乘，提升数据长度C语言有明确的定义吗？或者说C语言如何定义类似的情况的？

引用 13 楼 Czui1990 的回复:[quote=引用 10 楼 user-2 的回复:] [quote=引用 5 楼 Czui1990 的回复:] user-2你好，你的意思是，因为Sa1_Inport,Sa1_Sign是定义成int16的，所以运算前会转成int16，然后把变量都强制转换成Uint16之后，得出的结果还是会转换为Int类型的进行计算。 但这应该不存在装不下的问题吧，因为计算的结果我没有赋给任何一个变量。 char-a* int-b, 结果是int, 假如a*b超过int范围了, 不会自动变成unsigned int char-a* unsigned int-b, 结果是unsigned int[/quote]  你好，这个我清楚，但问题是int16类型变量强制转换成uint16类型相乘后，我并没有把这个值赋给任何一个变量，所以不存在溢出或超范围的情况，而是直接把这个值去参与比大小的运算，那么这个值是int类型的呢？还是uint类型？是否变成32bit？[/quote] 因为(UInt16)Sa1_InPort)和 ((UInt16) Sa1_Sign)都先提升到int32,所以结果也是int32

引用 10 楼 user-2 的回复:[quote=引用 5 楼 Czui1990 的回复:] user-2你好，你的意思是，因为Sa1_Inport,Sa1_Sign是定义成int16的，所以运算前会转成int16，然后把变量都强制转换成Uint16之后，得出的结果还是会转换为Int类型的进行计算。 但这应该不存在装不下的问题吧，因为计算的结果我没有赋给任何一个变量。 char-a* int-b, 结果是int, 假如a*b超过int范围了, 不会自动变成unsigned int char-a* unsigned int-b, 结果是unsigned int[/quote]  你好，这个我清楚，但问题是int16类型变量强制转换成uint16类型相乘后，我并没有把这个值赋给任何一个变量，所以不存在溢出或超范围的情况，而是直接把这个值去参与比大小的运算，那么这个值是int类型的呢？还是uint类型？是否变成32bit？

去这个网站. 可以在线编译运行代码的. http://ideone.com/

引用 9 楼 Czui1990 的回复:[quote=引用 7 楼 worldy 的回复:] 上机试一下，看看编译器是怎么处理的  你好，我这没有VC之类的工具，公司电脑安装软件还需要向IT部门申请，很麻烦。[/quote]  去这个网站. 可以在线编译运行代码的.

引用 5 楼 Czui1990 的回复:user-2你好，你的意思是，因为Sa1_Inport,Sa1_Sign是定义成int16的，所以运算前会转成int16，然后把变量都强制转换成Uint16之后，得出的结果还是会转换为Int类型的进行计算。 但这应该不存在装不下的问题吧，因为计算的结果我没有赋给任何一个变量。 char-a* int-b, 结果是int, 假如a*b超过int范围了, 不会自动变成unsigned int char-a* unsigned int-b, 结果是unsigned int

引用 7 楼 worldy 的回复:上机试一下，看看编译器是怎么处理的  你好，我这没有VC之类的工具，公司电脑安装软件还需要向IT部门申请，很麻烦。

之前的回复写错了，应该是若是32bit的，此时如何看待这32bit的值，是int类型还是uint类型？

上机试一下，看看编译器是怎么处理的

引用 4 楼 user-2 的回复:你可以理解成, 运算中的每一个步骤都是以int(unsigned int)来运算的 是这样的.Sa1_InPort Sa1_Sign 在运算之前会转成int(unsigned int) (UInt16)Sa1_InPort你强转了之后, 还是会先转成int((unsigned int)在运算  是运算之前转, 运算过程中还是会越界的  引用 2 楼 Czui1990 的回复:[quote=引用 1 楼 user-2 的回复:] 转int, int装不下转unsigned int  user-2你好，也就是说得出的值是32位的对吧？如果int32装不下，我的理解就是溢出了，得到一个不确定的值，难道会自动转成Uint32吗？  另外如果我需要两个int32相乘，得出的结果按uint16和C1比较大小，但我没有加上强制说明转换符，是不是会得出unexpected result。[/quote]  1是不会自动转Uint32. 2. a*b>c, abc都先提升到int(或unsigned int), 之后才运行.a32*b32>c32[/quote]  你好，抱歉，我还是没有明白你的意思，运算前到底先转成int还是uint呢？两个16bit的变量强制转换uint类型相乘后，得出的结果是32bit的吗？若是32bit 的，此时是如何看待这32bit的变量，int类型还是uint类型？

引用 3 楼 user-2 的回复:[quote=引用 2 楼 Czui1990 的回复:] [quote=引用 1 楼 user-2 的回复:] 转int, int装不下转unsigned int  user-2你好，也就是说得出的值是32位的对吧？如果int32装不下，我的理解就是溢出了，得到一个不确定的值，难道会自动转成Uint32吗？  另外如果我需要两个int32相乘，得出的结果按uint16和C1比较大小，但我没有加上强制说明转换符，是不是会得出unexpected result。[/quote]  是这样的.Sa1_InPort Sa1_Sign 在运算之前会转成int(unsigned int) (UInt16)Sa1_InPort你强转了之后, 还是会先转成int((unsigned int)在运算[/quote]  user-2你好，你的意思是，因为Sa1_Inport,Sa1_Sign是定义成int16的，所以运算前会转成int16，然后把变量都强制转换成Uint16之后，得出的结果还是会转换为Int类型的进行计算。 但这应该不存在装不下的问题吧，因为计算的结果我没有赋给任何一个变量。

你可以理解成, 运算中的每一个步骤都是以int(unsigned int)来运算的 是这样的.Sa1_InPort Sa1_Sign 在运算之前会转成int(unsigned int) (UInt16)Sa1_InPort你强转了之后, 还是会先转成int((unsigned int)在运算[/quote]  是运算之前转, 运算过程中还是会越界的  引用 2 楼 Czui1990 的回复:[quote=引用 1 楼 user-2 的回复:] 转int, int装不下转unsigned int  user-2你好，也就是说得出的值是32位的对吧？如果int32装不下，我的理解就是溢出了，得到一个不确定的值，难道会自动转成Uint32吗？  另外如果我需要两个int32相乘，得出的结果按uint16和C1比较大小，但我没有加上强制说明转换符，是不是会得出unexpected result。[/quote]  1是不会自动转Uint32. 2. a*b>c, abc都先提升到int(或unsigned int), 之后才运行.a32*b32>c32

引用 2 楼 Czui1990 的回复:[quote=引用 1 楼 user-2 的回复:] 转int, int装不下转unsigned int  user-2你好，也就是说得出的值是32位的对吧？如果int32装不下，我的理解就是溢出了，得到一个不确定的值，难道会自动转成Uint32吗？  另外如果我需要两个int32相乘，得出的结果按uint16和C1比较大小，但我没有加上强制说明转换符，是不是会得出unexpected result。[/quote]  是这样的.Sa1_InPort Sa1_Sign 在运算之前会转成int(unsigned int) (UInt16)Sa1_InPort你强转了之后, 还是会先转成int((unsigned int)在运算

引用 1 楼 user-2 的回复:转int, int装不下转unsigned int  user-2你好，也就是说得出的值是32位的对吧？如果int32装不下，我的理解就是溢出了，得到一个不确定的值，难道会自动转成Uint32吗？  另外如果我需要两个int32相乘，得出的结果按uint16和C1比较大小，但我没有加上强制说明转换符，是不是会得出unexpected result。

转int, int装不下转unsigned int


Question: c语言中定义变量

域的问题，你定义对象和指针的时候，stu这个自定义类型以及存在了。

你确定不是这样？ struct stu { 	int num; 	int age; }s = {1, 2}, *a = &s;

你在定义指针的时候，没有指明类型吧？

具体警告什么？


Question: 大学生为进BAT当软件开发工程师，数据结构进阶学习要看什么书？？？谢谢啦。

“为了进BAT”而学..而不是为兴趣而学..不是很好。  想进bat，有作品成果出来的话，发链接我，合适的话给你内推

非常感谢您的指点

虽然我进不了bat，还是想说，把学校教的都学好，打好基础

引用 13 楼 Raffin 的回复:[quote=引用 5 楼 Falleyes 的回复:] 算法导论，我也准备这个秋天去BAT，正在研究学习。 还有包括基础的计算机核心课程，操作系统、数据库、编译原理、计算机网络（计网非必须）都要好好学的。  我觉得BAT对技术要求应该没那么高的，做个QQ什么的还需要深入研究操作系统，数据结构吗？ 国内的软件应用不到很复杂的理论基础和算法架构，如果说国内有什么优势的话，那也就是人多，对服务器的并发处理这块要求很高。[/quote]数据结构算法肯定是需要的，操作系统是C\C++开发需要的，因为C\C++偏向于底层嘛

引用 5 楼 Falleyes 的回复:算法导论，我也准备这个秋天去BAT，正在研究学习。 还有包括基础的计算机核心课程，操作系统、数据库、编译原理、计算机网络（计网非必须）都要好好学的。  我觉得BAT对技术要求应该没那么高的，做个QQ什么的还需要深入研究操作系统，数据结构吗？ 国内的软件应用不到很复杂的理论基础和算法架构，如果说国内有什么优势的话，那也就是人多，对服务器的并发处理这块要求很高。

比如数据结构里那些排序算法，在高级开发语言里都有内置的排序方法，调用一下就行了（我的开发语言用的是快速排序实现的），没人会去深究排序的算法。 像涉及到空间复杂度的，现在计算机内存超大，除了嵌入式开发可能还需要计算着省内存，一般应用开发程序员基本不用关注内存是否够用。

至少研究生？不然你得acm得个奖吧。。。

看英语版的图灵系列教材。 其实实际工作中大部分开发都不需要用到算法和数据结构的知识的，只要会写代码逻辑会调用类库就行了。 要到比较高阶地方的开发才会需要很专业的知识。

数据结构关键在运用，多看看开源项目中如何用数据结构

数据结构的话，看完严就差不多了。 关键是熟练掌握，可以去oj上面做些题，比如从leetcode oj开始。 说句题外话，LZ看样子像本科生，其实本科生想进BAT比较难的，要比其他人付出更多努力。

非常感谢您的指教。

写个操作系统

非常感谢您的指教。

同意楼上，算法导论不错，你也可以看看MIT公开课推荐的书籍，不过建议看英文版的。此外，数据结构和算法这个东西，如果你现在无法体会数据结构在程序中的作用以及程序=数据结构+算法这两个理念，其实光看书的作用是不大的，我建议你看看云风的《游戏之旅--我的编程感悟这本书》，里面对于数据结构的描述讲的不错，关键是立足于实践。若想真的提高自己，书是一定要看的，看书之余，建议去开源社区下一些开源项目看看，提升会很大。

算法导论吧。。。


Question: 递归反向输出字符串

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

一般是建议通过名字来理解这个函数的，不过显然这个名字过于简朴，那就直接用递归树来理解了，假设输入“123#” '1' ->print()        '2'      -> print()                       '3'       -> print()                                      '#'         从此返回 每个返回都要执行 if(a != '#') printf("%c",a);  从而完成逆序输出

递归调用与一般调用的区别就在于此。 函数在调用另一个函数时，会开辟空间生成调用函数栈帧和被调用函数栈帧，调用函数会push保存寄存器如eax，edx，ecx，被调用函数也会push保存寄存器到栈中，比如edi，ebx，esi，ebp，esp，所有的中间值都保存在每一个调用所对应的栈帧中。在调用结束时pop恢复这些寄存器，同时返回到之前保存的调用函数地址，这样一步步逆着原来的顺序返回。 如果是一般的函数调用，就只需恢复寄存器然后执行ret指令返回；但是在递归调用时，除了要恢复寄存器，还要执行一些含有递归意义的指令，否则只是把中间的值保存，而没有利用， 这里 if(a != '#') printf("%c",a); 的作用就是把每个值打印出来。这一句就是你利用递归需要达成的目的。 举个栗子，如果是阶乘，比如5！，5，4，3，2，1这些值都保存在每次调用对应的栈帧中，在调用结束时每次返回除了恢复寄存器，还要计算i*(i-1)!，i =  2,3,4,5。

比如输入“abcd#”， 输入‘a’后先if(a != '#') print();继续递归接收下一个字符； 输入‘b’后继续if(a != '#') print();递归接收下一个； 输入‘c’继续递归 输入‘d’继续递归 输入‘#’后if(a != '#') print();if(a != '#') printf("%c",a); 均不被执行，函数结束，返回上一层递归 返回到输入‘d’的那一层，执行if(a != '#') printf("%c",a);输出‘d’，函数结束，返回上一层 返回到输入‘c’的那一层，执行if(a != '#') printf("%c",a);输出‘c’，返回上一层 ...

这个递归输入懂，到那时在输出的时候就不懂了，


Question: C语言面试题

引用 5 楼 dooX8086 的回复:[quote=引用 4 楼 u010024618 的回复:] [quote=引用 2 楼 luckyaslan 的回复:] 这道题目的问题是什么？ 不可能什么都没写吧。就是这段代码有什么错误？可以理解这段代码在什么特殊情况下会产生无法确定的结果？[/quote] 不是什么特殊情况下. 不同编译器就会产生不同结果.(只要压栈方式不一样) vc  不管是  _cdecl  stdcall  fastcall ...等等都是从右到左. 而 c++ builder   clang gcc 等....有些是从左到右有些是从右到左... 为以程序结果跟编译器有关...即行为不确定[/quote]多谢，我测试下您说的。另外编译器默认的入栈方式不是可以改变吗

引用 4 楼 u010024618 的回复:[quote=引用 2 楼 luckyaslan 的回复:] 这道题目的问题是什么？ 不可能什么都没写吧。就是这段代码有什么错误？可以理解这段代码在什么特殊情况下会产生无法确定的结果？[/quote] 不是什么特殊情况下. 不同编译器就会产生不同结果.(只要压栈方式不一样) vc  不管是  _cdecl  stdcall  fastcall ...等等都是从右到左. 而 c++ builder   clang gcc 等....有些是从左到右有些是从右到左... 为以程序结果跟编译器有关...即行为不确定

引用 2 楼 luckyaslan 的回复:这道题目的问题是什么？ 不可能什么都没写吧。就是这段代码有什么错误？可以理解这段代码在什么特殊情况下会产生无法确定的结果？

引用 1 楼 user-3 的回复:是不是read(&val),read(&ch)的执行顺序问题我写Demo测试暂时没啥问题。 你说的执行顺序也能是考虑的一个点。如果按照你的建议面试官期待的应该是代码吗： int read(int* p) {     scanf("%d",p);     return *p; } ...  i = read(&val);  j = read(&ch); insert(&graph[vert],i,j);  这个代码和上面的代码在什么情况下会产生区别呢？

这道题目的问题是什么？ 不可能什么都没写吧。

是不是read(&val),read(&ch)的执行顺序问题


Question: 如何从混杂着数字、字母或者汉字的txt文本文件中读取数字

问题已经解决了。多谢楼上两位回帖。

使用正则表达式

最好是能给出简单的C语言代码，多谢。


Question: 关于isdigit函数和数组初始化

引用 6 楼 u014178386 的回复:[quote=引用 3 楼 Revivedsun 的回复:] Checks whether c is a decimal digit character. Decimal digits are any of: 0 1 2 3 4 5 6 7 8 9   [quote=引用 2 楼 u014178386 的回复:] [quote=引用 1 楼 luckyaslan 的回复:] int isdigit(char c); 传入参数是char，你传入的是int ，传参出错了。 你把 int a[10];改成char a[10]就可以了。  isdigit还是返回0。。[/quote]  char[10] = {"0"}; [/quote]  其实我想问的是在不初始化数组的情况下，数组元素默认为0，那么isdigit应该返回1才对呀![/quote]  int的48对应的才是char的0, 去看ascii码表

引用 3 楼 Revivedsun 的回复:Checks whether c is a decimal digit character. Decimal digits are any of: 0 1 2 3 4 5 6 7 8 9   [quote=引用 2 楼 u014178386 的回复:] [quote=引用 1 楼 luckyaslan 的回复:] int isdigit(char c); 传入参数是char，你传入的是int ，传参出错了。 你把 int a[10];改成char a[10]就可以了。  isdigit还是返回0。。[/quote]  char[10] = {"0"}; [/quote]  其实我想问的是在不初始化数组的情况下，数组元素默认为0，那么isdigit应该返回1才对呀!

引用 2 楼 u014178386 的回复:[quote=引用 1 楼 luckyaslan 的回复:] int isdigit(char c); 传入参数是char，你传入的是int ，传参出错了。 你把 int a[10];改成char a[10]就可以了。  isdigit还是返回0。。[/quote]  嗯，，，， 我刚看了下，默认的情况，数组a被初始化为0x00,而字符'0'的16进制是0x30。 0x00代表的是NULL空值，不是字符‘0’。所以在判断的时候，isdigit返回的是0。

去看一下ascii码表 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 56 8 57 9

Checks whether c is a decimal digit character. Decimal digits are any of: 0 1 2 3 4 5 6 7 8 9   引用 2 楼 u014178386 的回复:[quote=引用 1 楼 luckyaslan 的回复:] int isdigit(char c); 传入参数是char，你传入的是int ，传参出错了。 你把 int a[10];改成char a[10]就可以了。  isdigit还是返回0。。[/quote]  char[10] = {"0"};

引用 1 楼 luckyaslan 的回复:int isdigit(char c); 传入参数是char，你传入的是int ，传参出错了。 你把 int a[10];改成char a[10]就可以了。  isdigit还是返回0。。


Question: 线程互斥锁和条件变量实现特殊的生产者和消费者，要求消费者节省cpu

引用 6 楼 zhao4zhong1 的回复:《Windows核心编程》 有人向庖丁求解牛技巧，庖丁建议他去把动物世界看一遍 他回来之后发现自己成了赵忠祥

《Windows核心编程》

手快打错了 ，是unordered_map<int, vector<policy>>

引用 2 楼 user-6 的回复:加入策略的时候先做分类？每个消费者只关注其兴趣的类别 你的意思是分类将策略存进不同的策略池，然后每个消费者去访问其中一个策略池吗？ 你的办法相当nice啊 我试试

这个池的应该是一个unordered_multimap<int, vector<policy>>而不应该是vector,这样方便插入和查询。当然里面的vector<policy>也可以考虑用queue，看你的需求

引用 14 楼 u010424605 的回复:[quote=引用 10 楼 lincolnandlinda 的回复:]  楼主的实现思路有一个问题, 每个消费者都会在适当的时刻去遍历那个生产者-消费者对列. 其实没这个必要, 我的想法是做四个对列, 第一个对列实现对所有策略依据ModuleID进行分发, 分别向另外三个对列中放入对应ID的策略.每个对应的消费者实现各自的处理流程. 这样每个生产者-消费者的对列的实现就简单很多(只需要用条件数进行等待即可), 而且方便进行类的封装. 如果楼主是在Windows平台, 可以使用MS的提供的Concurrency runtime , 库里面提供了Aynchronous message blocks, 可以很方便实现消息的过滤, 我以前做过一个项目就是用这个整的, 很容易. 这个想法之前有位仁兄也说了，不过描述没有您这么具体，这个思路确实很好，正考虑替换现有方案。 ps. 我是在linux下做的，windows的没怎么接触过。[/quote]  思想是一致的。只是接口不同。用自己熟悉的环境即可，这样得心应手

引用 9 楼 u010424605 的回复:[quote=引用 8 楼 my_live_123 的回复:] 把消费者代码的倒数2，3注释掉！这两句wait和signal我觉得是多余的。 这样如果策略池不为空，并且里面的策略不是这个线程所需要的，那么这个线程就会一直循环来查询。 添加这两句在单个线程是可以把这个线程阻塞住的，但如果有多个线程的话，会互相signal那么wait的效果就没有了。[/quote]  不同的消费着消费不同的资源，如果不多，那么查询自己的策略，只是循环一次O(n)的开销，有就拿，没有就继续阻塞！ 如果策略非常多，遍历开销很明显，那么就把策略队列拆分，不同策略不同的队列。然后每个资源队列单独的同步控制。这样锁的范围变小,控制也更精确

引用 11 楼 zhao4zhong1 的回复:[quote=引用 7 楼 u010424605 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 《Windows核心编程》 有人向庖丁求解牛技巧，庖丁建议他去把动物世界看一遍 他回来之后发现自己成了赵忠祥[/quote] 有人向冯诺依曼求解编程技巧，冯诺依曼建议他去研究图灵机 他回来之后发现自己成了比尔盖茨。 [/quote] 您还挺喜欢跟人争论的嘛

引用 13 楼 xihu1364 的回复:弄多少个线程，并且哪些线程做哪些策略，就传参nStrategy 之前的moduleId就是传进来的参数，跟前面的仁兄想法差不多，thank you！

引用 10 楼 lincolnandlinda 的回复:楼主的实现思路有一个问题, 每个消费者都会在适当的时刻去遍历那个生产者-消费者对列. 其实没这个必要, 我的想法是做四个对列, 第一个对列实现对所有策略依据ModuleID进行分发, 分别向另外三个对列中放入对应ID的策略.每个对应的消费者实现各自的处理流程. 这样每个生产者-消费者的对列的实现就简单很多(只需要用条件数进行等待即可), 而且方便进行类的封装. 如果楼主是在Windows平台, 可以使用MS的提供的Concurrency runtime , 库里面提供了Aynchronous message blocks, 可以很方便实现消息的过滤, 我以前做过一个项目就是用这个整的, 很容易. 这个想法之前有位仁兄也说了，不过描述没有您这么具体，这个思路确实很好，正考虑替换现有方案。 ps. 我是在linux下做的，windows的没怎么接触过。

弄多少个线程，并且哪些线程做哪些策略，就传参nStrategy

//将这些不同的策略分开，用不同的队列，否则就是用链表了，不是先进先出的方式 queue<char*> queue1;  queue<char*> queue2;  queue<char*> queue3;   void work_thread(int nStrategy) { 	while (1) 	{ 		switch (nStrategy) 		{ 		case 1: 			{ 				char* pstr;  				//queue1是一个同步队列，pop节点是 等待信号的方式，参数0为超时时间  （这样的队列可以自己去实现） 				if (queue1.wait_queue(pstr,0)) 				{ 					//deal pstr; 				} 				break; 			} 		case 2: 			{ 				char* pstr;  				//queue1是一个同步队列，pop节点是 等待信号的方式，参数0为超时时间  （这样的队列可以自己去实现） 				if (queue2.wait_queue(pstr,0)) 				{ 					//deal pstr; 				} 				break; 			} 		case 3: 			{ 				char* pstr;  				//queue1是一个同步队列，pop节点是 等待信号的方式，参数0为超时时间  （这样的队列可以自己去实现） 				if (queue3.wait_queue(pstr,0)) 				{ 					//deal pstr; 				} 				break; 			} 		default: 			{ 				break; 			} 		} 	} }

引用 7 楼 u010424605 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 《Windows核心编程》 有人向庖丁求解牛技巧，庖丁建议他去把动物世界看一遍 他回来之后发现自己成了赵忠祥[/quote] 有人向冯诺依曼求解编程技巧，冯诺依曼建议他去研究图灵机 他回来之后发现自己成了比尔盖茨。

引用 8 楼 my_live_123 的回复:把消费者代码的倒数2，3注释掉！这两句wait和signal我觉得是多余的。 这样如果策略池不为空，并且里面的策略不是这个线程所需要的，那么这个线程就会一直循环来查询。 添加这两句在单个线程是可以把这个线程阻塞住的，但如果有多个线程的话，会互相signal那么wait的效果就没有了。

把消费者代码的倒数2，3注释掉！这两句wait和signal我觉得是多余的。

加入策略的时候先做分类？每个消费者只关注其兴趣的类别

这个是我实现生产者的代码 这个是我实现消费者的代码 问题是当生产者生产出例外的moduleId的策略时，消费者多线程相互发送条件信号，导致cpu利用率超标到100%之上 我想 每生产一个策略 消费线程依次来检查一下有没有自己需要的 如果没有则阻塞在那里 不知道如何实现


Question: 关于C语言printf的计算顺序问题？

看见这个要晕了

引用 11 楼 u013449715 的回复:好吧 ，= =其实是你第一个printf的\n前面多了一个逗号 不信你看？ 好吧 我傻逼了。用你的代码 在我机器上是正确的

好吧 ，= =其实是你第一个printf的\n前面多了一个逗号 不信你看？

这个真的没有意义，不同的编译器，不同的做法

引用 8 楼 sholber 的回复:什么叫有意义，什么叫没有意义？ 能直接看出来不对叫没意义？不能直接看出来不对就有意义？ # include <stdio.h>  int main (void) {      int i = 2, * p = & i, * q = p, * r = p;      printf ("%d,%d,%d,%d,\n", p ++, ++ q, i, r ++);      printf ("%d\n", i);      return 0; } 这程序不对吧！声明好像有问题！

引用 6 楼 svgbdbdbd 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] http://bbs.csdn.net/topics/370153775 看完之后一时半会儿，还无法领悟，只是感到讨论这个好像没必要。[/quote] 只要看这个帖子中所有我的回复即可。

引用 2 楼 zhao4zhong1 的回复:http://bbs.csdn.net/topics/370153775 看完之后一时半会儿，还无法领悟，只是感到讨论这个好像没必要。

引用 1 楼 lin5161678 的回复:代码是错的  怎么错 请阅读置顶帖  ps 不要以为能运行就是对的 C语言没这么肤浅 看完后觉得，不能说错，只能说没意义，

引用 3 楼 user-7 的回复:实际应该说的是：这种东西根本不该写，讨论其效果没有意义。 你说的很有道理，只是一时好奇。

实际应该说的是：这种东西根本不该写，讨论其效果没有意义。


Question: 朕的目标是在积分上超过赵4老湿。

既然君无戏言，那好，赵老湿，速速给朕汇10万美元真金白银来！不然，扒翎夺顶，发配南海，无诏不得回京！钦此！

引用 56 楼 sholber 的回复:朕真是不理解，为什么竟然有人把这个帖子当真……**捉急呀。 那是因为“朕”说话通常都是一言九鼎，即君无戏言。

朕真是不理解，为什么竟然有人把这个帖子当真……**捉急呀。

希望楼主成熟起来，把分全给哥

楼主把csdn数据库攻掉，给我也加几朵花 赶上赵四老师10年积累的分数还是挺难的哈

不得不鄙视下楼主 居然以这个为目标

有点意思，赵四老师这么有名啊

引用 49 楼 zhao4zhong1 的回复:栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……  赵老湿旁征博引，果然高妙得紧。一番话既涵盖了硬件的术语，也涉及汇编和C、C++，真是包罗万象，虽千古之人不能及也！不过，这个栈是哪里来的，C标准中从未提及，如果我是大师，能否制造一款不用栈的处理器，届时，赵老湿又当何论？唵？

引用 47 楼 sholber 的回复:[quote=引用 45 楼 zhao4zhong1 的回复:] 法无定法。 赵老湿言辞高妙，但不知何意，尚祈明示。[/quote] 其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

引用 45 楼 zhao4zhong1 的回复:法无定法。 赵老湿言辞高妙，但不知何意，尚祈明示。

法无定法。

int x; struct t {int i;} t;  int f (void) {     int y;     int a [22];      static int * p0 = & x;      //合法。     static int * p1 = & t.i;    //合法。     static int * p2 = & y;      //非法。     static int * p3 = & a [0];  //非法。 }

找(zhao)死(4)中(zhong)医(1)老师的分辨率一直比较低,有一种这大神其实不存在于这个世界的感觉

围观

超四老师是CSDN C++版块的镇版之宝啊

李和赵老师 都好拼啊

zhao4,的徽标：进士->探花->榜样->XX  状元--以名列第一为“元”，乡试第一为“解元”。举人进京参加礼部考试者，皆须投状。考试成绩居首者为状头，故有“状元”之称。考中状元者，号称“大魁天下”，为考试科名中最高荣誉。唐代起，如殿试一甲第一名，亦称“殿元”。 榜眼-殿试一甲第二名称为“榜眼”。宋代将第二、三名均称为榜眼，意指榜中之双眼。后专指第二名。 探花-科举考试中，殿试一甲第三名称为“探花”。唐代进士在杏化花园举行“探花宴”，以年少英俊的二、三人为“探花使”（又称“探花郎”）。南宋以后专指第三名为探花。 进士-意即贡举的人才。唐代科目考试中以进士科为最重要，参加礼部考试者均可称为进士。试毕合格者赐予“进士及第”，后又有赐“进士出身”、“同进士出身”之名义。明清时代均以举人经会试合格者为“贡士”。初始专指经殿试后合格的贡士为进士，后来泛指参加殿试者，赐出身者为进士。


Question: 北大OJ1001高精度乘幂，求诸位大神看看我写的到底哪里错了

楼主你的 if((temp[i]=getchar())=='.') digit=0; 也接收了回车了吧

求不沉啊T^T


Question: vc6.0++ 调试

如果是在debug下：  1.检查工程配置是否设置正确。   •C++>General->Debug Information Format->Program Database (/Zi) •C++>Optimization->Optimization->Disabled (/Od) •Linker->Debugging->Generate Debug Info->Yes (/DEBUG) •Linker->Debugging->Generate Program Database File->$(TargetDir)$(TargetName).pdb  1.如果工程配置没问题，请打开：  　　Tools->Option->debugging->General  找到 Require source files to exactly match the original version 不要打勾  　　即：工具->选项->调试里->常规 找到  要求原文件与原始版本完全匹配 不要打勾

Debug模式 Release 选不优化 生成调试信息


Question: （SWU）对于一个什么都不懂的新手来学习C语言怎么搞

引用 12 楼 my_live_123 的回复:把《K&R》读5遍，代码写至少一遍。然后回来你就会把这个帖子删了！believe me！ 10遍

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

因为在C语言中i, j呀这些东西可以代表一个地址哇 你也可以直接使用地址不使用i,j呀这些东西，看看谁更方便撒

别嚓，好好学习才是关键

变量名称是可以随便起的。不用变量如何存储数据呢？程序过程中需要存储结果的。 i来自于index的首字母，j则是从字母表接着i的，然后是k。大家约定俗成就用这些字母来表示存储序数的变量了。

抄书上一个程序到运行成功，再回去理解程序（）。

为什么要用 i j这些量啊

C语言一直都是大一新生的入门编程语言，各个高校都是如此安排。历代高手都是这样走过来的。 我们选用的教材是《C Programming Language》，非常适合看书编程学习。跟着坚持下去，肯定学得会。

就是基础差罢了。 这也难怪， 一个大学新生， 一边学计算机原理， 一边已经开始学C语言， 好像没有这么干的， 但大学就是如此。 填鸭教育 嘎嘎。

一开始 学习编程我也是这样，慢慢来 就好了，但一定要去尝试着写代码

Good good study, day day up!嘎嘎

好好学习，认真听课


Question: poj 1002

还是WA呢?

在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。  static char ph[100000][9];

老是WA，运行原来的数据也没错，我用二维数组去存电话号码，将输入的字串转化为标准形式，然后放入ph数组里面，最后qsort排序，在用以上算法，运行结果没问题，但就是WA，这道题是我返回来做的，现在都还在WA，请问出了什么毛病，是最后那段算法出了问题吗？


Question: 为什么原文说total+=*start++和total+=*(start++)是等价的？

引用 6 楼 my_live_123 的回复:C99   想知道这张图的出处，顺便primary-expression应该是前++，postfix-expression应该是后++吧

start++这句还没结束时，start指针地址不变，所以取*不变

把start++这个表达式看成一个函数，看看它的返回值 ， 它是这样的 tmp=start, ++start, return tmp; 而(start++) 是这样的 ( tmp=start, ++start,return tmp) 比较一下，显然是一样的

引用 11 楼 cfvmario 的回复:就算编译角度有差别，现代计算机需要在乎这点？ 我强烈建议一律加括号，可读性才是第一位的 鱼和熊掌不可兼得，看个人选择！  爱速度的人，还是喜欢压榨时间的，无论编译还是运行！

引用 8 楼 luckyaslan 的回复:根据运算符优先级来看： total+=*start++ 的执行顺序是这样的：total += (*start)++ 所以等同于下面两个表达式： total+=(*start)++ total+=*(start++)  在这里把++的作用理解了，这个问题就看明白了。 例如:i++ i++的实现如下：  { int temp; temp = i; i = i+1; return temp; }   可以看出来i++；执行后，得到的值，是一个临时变量，这个值和i之前的值是相同的。  写错了。  二楼说的对。

解释一下： total+=*start++和total+=*(start++)从结果上讲是一样的，从编译角度讲不太一样  *属于unary-operator ++放在表达式之后，构成：postfix-expression ++  total+=*start++ 从语法分析上要先分析postfix-expression ++，然后转到unary-expression，过度到cast-expression，整合 * 的unary-operator组合成unary-operator cast-expression，最后转一圈回到赋值表达式 因此先执行++，再执行*  total+=*(start++) 要比上面不加括号的情况下，多一圈语法分析；即start++自身走一圈回到exp，然后再转一圈把*整合进去。  因此从编译角度讲，如果想让代码编译更快点，在知道优先级的情况下，优先选择total+=*start++，因为每加一个括号，就要从上面12点钟方向重新开始一遍语法分析。  不过，编译出来的指令都是一样的，因此运算结果也都是一样的。

//只要了解后缀 ++ 就很清楚了 // 后缀 ++ 其实就是豆号表达式组 // 如: 把 start++ 展开就是 int *tmp;   //编译器创建的临时变量 (tmp = start, start = start + 1, tmp);  //那么: total+=*(start++);  就是  int *tmp;    total += *( (tmp = start, start = start + 1, tmp) );   // 所以外面这对 () 添加以否都是一样的  // 一目了然了..... //

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

total+=*start++和total+=*(start++) 因为不管是那种情况都是先执行*start，再赋值运算，最后start+1， 除非是*(++start)才先执行start+1，再*start，再赋值运算， 我理解形如i++的操作，是等赋值运算完后再执行的操作

这里是优先级表： http://www.slyar.com/blog/c-operator-priority.html  虽然*和++优先级一样，但是结合性是从右到左，也就是说它们在一起时右边的优先级高。

因为自增++ 在这里面的优先级最高 加不加括号 都一样！


Question: 帮忙看下这段汇编代码

引用 4 楼 user-2 的回复:看cmpw指令应该是PowerPc的指令集，对这个不太了解。 Warning: using `%dx' instead of `%edx' due to `w' suffix 这个貌似应该是30行开始的。 cmpw 指令 比较的应该是32bit的数据，看这个警告，应该是两个操作数有问题。   :"=m" (plock->pid)  :"q" (pid)  第一个冒号是输出操作数，第二个冒号是输入操作数。在这段内联汇编里应该都是做输入才对。 30行和40行两段 中间又没C代码，合并一起会比较好。  参考链接： 内联汇编：http://blog.csdn.net/liuqiaoyu080512/article/details/8457528 GCC：https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Machine-Constraints.html#Machine-Constraints PPC汇编入门：http://blog.csdn.net/skywind/article/details/6347684  仅供参考。 谢谢,看了一下参考的链接,虽然更多的还是不懂.但是至少现在语法上面没有太多的误区了.

引用 5 楼 a198997 的回复:spinlock.c:43: Error: operand size mismatch for `xadd'  spinlock.c:72: Error: operand size mismatch for `add'  spinlock.c:87: Error: operand size mismatch for `xadd' 这几个是使用xadd，add指令与后面的操作符的运算位数不对应。 很久没用了，忘了具体指令。xaddw 是16位计算，其他的忘了，你对应一下。   spinlock.c:90: Error: no such instruction: `mv %eax,$-1'  spinlock.c:91: Error: no such instruction: `mv -24(%ebp),%eax'  spinlock.c:125: Error: no such instruction: `mvw %eax,%eax'  spinlock.c:126: Error: no such instruction: `mvw (%edx),%eax' 这几个应该是指令使用错误，看看指令有没有写错的。  PS： __asm__ __volatile__(             "cmpw %1, %0\n"             "jne 1f\n"             "call abort\n"             "1:"             :"=m" (plock->pid)             :"q" (pid)              :"memory", "cc"             );       __asm__ __volatile__(             "1:\n"             "cmpw %1, %0\n"             "jne 1b\n"             "lock xaddw %1, %2\n"             :"=q" (unlock), "=m" (plock->lock)             :"q" (lock)             :"memory", "cc"             );   这两个完全可以放一起写。。。 谢谢,你说的的确.今天又看了一下,操作符后面可以接b,w,l分别表示bit(8), word(16), long(32).至于add报的错误,是因为add必须有一个参数是m类型的才可以.所以     __asm__ __volatile__(             "1:\n"             "cmpw %1, %0\n"             "jne 1b\n"             "lock xaddw %2, %1\n"             :"=q" (unlock), "=m" (plock->lock)             :"q" (lock), "m" (plock->lock)             :"memory", "cc"             ); 这样写就是可以的.

第一次发帖啊.没有人回答吗?

就是按着自己的思路实现的一个简单的自旋锁.因为对于汇编实在是一窍不通.坑爹队友还一直催,所以就想走个捷径,希望能够得到大牛们的指点.


Question: 关于伸展树内部路径长证明的疑问

你看得是<<数据结构与算法分析 c语言描述>>吗? b.如果进行find操作（就是根据伸展树的伸展原理把目标节点提升到树根的那个操作),find(1),find(2),find(3),find(4),find(5),find(6) 操作后，分别计算内部路径长 你可以看看书中32个节点的例子, 跟这个类似,就可以求出内部路径长了.

好像很多都是关于怎么操作的论述。。。。和证明这俩没什么联系。。。

引用 1 楼 zhao4zhong1 的回复:其实我真的真的在这个问题上知道的比楼主还少，只能帮顶。  赵老师谦虚了。。。。  我觉得我现在学的数据结构这本书。。。这类的证明题都好难

其实我真的真的在这个问题上知道的比楼主还少，只能帮顶。

先别急着去看书，还是先用http://www.baigoogledu.com/搜搜看吧。

看完了变成可别赖我啊！

引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 Philipyexushen 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 其实我真的真的在这个问题上知道的比楼主还少，只能帮顶。  赵老师谦虚了。。。。  我觉得我现在学的数据结构这本书。。。这类的证明题都好难[/quote] 《线性代数》 《概率论与数理统计》 《数论》 [/quote]  额，好的我去看一下

引用 2 楼 Philipyexushen 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 其实我真的真的在这个问题上知道的比楼主还少，只能帮顶。  赵老师谦虚了。。。。  我觉得我现在学的数据结构这本书。。。这类的证明题都好难[/quote] 《线性代数》 《概率论与数理统计》 《数论》


Question: poj 1007

引用 8 楼 cdddfq 的回复:程序能够运行了，可是一直wa，又是什么原因？ 可能不让用qsort，改为冒泡排序试试。

先把问题描述出来

WA,实在看不出什么问题了

哦，对了，谢谢赵老师，我会练的

程序能够运行了，可是一直wa，又是什么原因？

恩，谢谢老师，我的指法确实存在问题，这也是我所清楚的，我会细心练习的！

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

int cmp(const void *a,const void *b)     {         if(((struct order *)a)->reverse!=((struct order *)b)->reverse)             return(((struct order *)a)->reverse>-((struct order *)b)->flagreverse);         else             return(((struct order *)a)->flag-((struct order *)b)->flag);     }

int cmp(const void *a,const void *b)     {         if(((struct order *)a)->reverse!=((struct order *)b)->reverse)             return(((struct order *)a)->reverse>((struct order *)b)->flagreverse);         else             return(((struct order *)a)->flag-((struct order *)b)->flag);     }

这是一个求逆序数的问题，我用flag作为稳定qsort的标记，调试过后发现逆序数算法没问题，不过一断点到qsort就发现结构体数组没有排序，下面是我的代码，经过单步跟踪调试 发现qsort没有起到将reverse作为一级排序，flag作为二级排序的作用


Question: 求问个算法问题

10000000天/365天/年≈27397年！ 出题者。

读不倒→读不到（暴露了我之前常输入不倒这个词！）

读不倒10MB的文件会超时？

题目的限时多少？

引用 2 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <string.h> #define MAXLEN 1000 char ln[MAXLEN]; FILE *f; int i,z; int b,n,L; int main(int argc,char **argv) {     if (argc<2) {         printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);         return 1;     }     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     z=0;     b=0;     n=0;     L=0;     while (1) {         if (NULL==fgets(ln,MAXLEN,f)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) {             if (0==z) {                 for (i=0;i<L-1;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L-1) z=1;//当前行不是空行             }             if (0==z) b++; else n++;             z=0;         } else {             if (0==z) {                 for (i=0;i<L;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L) z=1;//当前行不是空行             }         }     }     fclose(f);     if (L>0 && '\n'!=ln[L-1]) {         if (0==z) b++; else n++;//最后一行末尾无'\n'也计算     }     printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);     return 0; }  我还是没理解这个的算法，1000w位每个都要读一遍的话很容易就会超时的！

引用 5 楼 zhangxiangDavaid 的回复:[quote=引用 4 楼 my_bkb 的回复:] [quote=引用 3 楼 zhangxiangDavaid 的回复:] 仅供参考：  #include <stdio.h> #include <string.h> int day_credit(int day_sum) { 	if (day_sum <= 3) 		return 1; 	else if (day_sum <= 7) 		return 2; 	else if (day_sum <= 15) 		return 3; 	else 		return 4; } int credits(char *signs, int days) { 	//积分 	int credit = 0; 	//连续签到天数 	int day_sum = 0; 	int i; 	for (i = 0; i < days; i++) 	{ 		if (signs[i] == '1')  //第i天签到 		{ 			day_sum++;    //累计签到天数加一 			credit += day_credit(day_sum); 		} 		else  //第i天未签到 		{ 			day_sum = 0;    //累计签到天数置0 		} 	} 	return credit; } int main(void) { 	char *signs = malloc(10000001); 	memset(signs, 0, 10000001); 	scanf("%s", signs); 	//总天数 	int days = strlen(signs);  	int credit = credits(signs, days); 	printf("credits=%d\n", credit);  	//如果全部签到 	memset(signs, '1', days); 	credit = credits(signs, days); 	printf("全部签到credits=%d\n", credit); 	free(signs);  	return 0; }  //10001110001 //credits=5 //11111111111 //全部签到credits=23 请问下 这句是什么意思char *signs = malloc(10000001);[/quote]  字符串的最大位数是1000W位，再加上最后的结束符'\0'，共10000001位，故分配这么多字节数[/quote] 我还是没理解这个的算法，1000w位每个都要读一遍的话很容易就会超时的！

为啥非要分配这么多数据？一个char足以使用。  //积分     int credit = 0;     //连续签到天数     int day_sum = 0; char c; int count = 0; while(scanf("%c", &c) != EOF) {     if (c == '1') { //处理逻辑          day_sum++;    //累计签到天数加一             credit += day_credit(day_sum);     } else if (c == '0') {       day_sum = 0;    //累计签到天数置0     } else {         break;     }     count++; } printf("credits=%d\n", credit);  if (count > 15) { credit=3*1 +4*2+8*3+(count-15)*4; } else if (count>7) { credit=3*1 +4*2+(count-7)*3; } else if (count > 3){ credit=3*1 +(count-3)*2; } else { credit=count; }  printf("全部签到credits=%d\n", credit);    代码抄点楼上的。

答得好，记得给分哦

引用 4 楼 my_bkb 的回复:[quote=引用 3 楼 zhangxiangDavaid 的回复:] 仅供参考：  #include <stdio.h> #include <string.h> int day_credit(int day_sum) { 	if (day_sum <= 3) 		return 1; 	else if (day_sum <= 7) 		return 2; 	else if (day_sum <= 15) 		return 3; 	else 		return 4; } int credits(char *signs, int days) { 	//积分 	int credit = 0; 	//连续签到天数 	int day_sum = 0; 	int i; 	for (i = 0; i < days; i++) 	{ 		if (signs[i] == '1')  //第i天签到 		{ 			day_sum++;    //累计签到天数加一 			credit += day_credit(day_sum); 		} 		else  //第i天未签到 		{ 			day_sum = 0;    //累计签到天数置0 		} 	} 	return credit; } int main(void) { 	char *signs = malloc(10000001); 	memset(signs, 0, 10000001); 	scanf("%s", signs); 	//总天数 	int days = strlen(signs);  	int credit = credits(signs, days); 	printf("credits=%d\n", credit);  	//如果全部签到 	memset(signs, '1', days); 	credit = credits(signs, days); 	printf("全部签到credits=%d\n", credit); 	free(signs);  	return 0; }  //10001110001 //credits=5 //11111111111 //全部签到credits=23 请问下 这句是什么意思char *signs = malloc(10000001);[/quote]  字符串的最大位数是1000W位，再加上最后的结束符'\0'，共10000001位，故分配这么多字节数

引用 3 楼 zhangxiangDavaid 的回复:仅供参考：  #include <stdio.h> #include <string.h> int day_credit(int day_sum) { 	if (day_sum <= 3) 		return 1; 	else if (day_sum <= 7) 		return 2; 	else if (day_sum <= 15) 		return 3; 	else 		return 4; } int credits(char *signs, int days) { 	//积分 	int credit = 0; 	//连续签到天数 	int day_sum = 0; 	int i; 	for (i = 0; i < days; i++) 	{ 		if (signs[i] == '1')  //第i天签到 		{ 			day_sum++;    //累计签到天数加一 			credit += day_credit(day_sum); 		} 		else  //第i天未签到 		{ 			day_sum = 0;    //累计签到天数置0 		} 	} 	return credit; } int main(void) { 	char *signs = malloc(10000001); 	memset(signs, 0, 10000001); 	scanf("%s", signs); 	//总天数 	int days = strlen(signs);  	int credit = credits(signs, days); 	printf("credits=%d\n", credit);  	//如果全部签到 	memset(signs, '1', days); 	credit = credits(signs, days); 	printf("全部签到credits=%d\n", credit); 	free(signs);  	return 0; }  //10001110001 //credits=5 //11111111111 //全部签到credits=23 请问下 这句是什么意思char *signs = malloc(10000001);


Question: 一串文字里面包含单字节和双字节，请转换为双字节输出

这，编码之间的转换...

String Manipulation These routines operate on null-terminated single-byte character, wide-character, and multibyte-character strings. Use the buffer-manipulation routines, described in Buffer Manipulation, to work with character arrays that do not end with a null character.  String-Manipulation Routines  Routine Use  _mbscoll, _mbsicoll, _mbsncoll, _mbsnicoll Compare two multibyte-character strings using multibyte code page information (_mbsicoll and _mbsnicoll are case-insensitive)  _mbsdec, _strdec, _wcsdec Move string pointer back one character  _mbsinc, _strinc, _wcsinc Advance string pointer by one character  _mbslen Get number of multibyte characters in multibyte-character string; dependent upon OEM code page  _mbsnbcat Append, at most, first n bytes of one multibyte-character string to another  _mbsnbcmp Compare first n bytes of two multibyte-character strings  _mbsnbcnt Return number of multibyte-character bytes within supplied character count  _mbsnbcpy Copy n bytes of string  _mbsnbicmp Compare n bytes of two multibyte-character strings, ignoring case  _mbsnbset Set first n bytes of multibyte-character string to specified character  _mbsnccnt Return number of multibyte characters within supplied byte count  _mbsnextc, _strnextc, _wcsnextc Find next character in string  _mbsninc. _strninc, _wcsninc  Advance string pointer by n characters  _mbsspnp, _strspnp, _wcsspnp Return pointer to first character in given string that is not in another given string  _mbstrlen Get number of multibyte characters in multibyte-character string; locale-dependent  sprintf, _stprintf Write formatted data to a string  strcat, wcscat, _mbscat Append one string to another  strchr, wcschr, _mbschr Find first occurrence of specified character in string  strcmp, wcscmp, _mbscmp Compare two strings  strcoll, wcscoll, _stricoll, _wcsicoll, _strncoll, _wcsncoll, _strnicoll, _wcsnicoll Compare two strings using current locale code page information (_stricoll, _wcsicoll, _strnicoll, and _wcsnicoll are case-insensitive)  strcpy, wcscpy, _mbscpy Copy one string to another  strcspn, wcscspn, _mbscspn,  Find first occurrence of character from specified character set in string  _strdup, _wcsdup, _mbsdup Duplicate string  strerror Map error number to message string  _strerror Map user-defined error message to string  strftime, wcsftime Format date-and-time string  _stricmp, _wcsicmp, _mbsicmp Compare two strings without regard to case  strlen, wcslen, _mbslen, _mbstrlen Find length of string  _strlwr, _wcslwr, _mbslwr Convert string to lowercase  strncat, wcsncat, _mbsncat Append characters of string  strncmp, wcsncmp, _mbsncmp Compare characters of two strings  strncpy, wcsncpy, _mbsncpy Copy characters of one string to another  _strnicmp, _wcsnicmp, _mbsnicmp Compare characters of two strings without regard to case  _strnset, _wcsnset, _mbsnset Set first n characters of string to specified character  strpbrk, wcspbrk, _mbspbrk Find first occurrence of character from one string in another string  strrchr, wcsrchr,_mbsrchr Find last occurrence of given character in string  _strrev, _wcsrev,_mbsrev Reverse string  _strset, _wcsset, _mbsset Set all characters of string to specified character  strspn, wcsspn, _mbsspn Find first substring from one string in another string  strstr, wcsstr, _mbsstr Find first occurrence of specified string in another string  strtok, wcstok, _mbstok Find next token in string  _strupr, _wcsupr, _mbsupr Convert string to uppercase  strxfrm, wcsxfrm Transform string into collated form based on locale-specific information  vsprintf, _vstprint Write formatted output using a pointer to a list of arguments

char buf[] = "小同志你好！请问一下,你知道人民北路29号怎么走呀?..........。"   //多字节   即有单字节, 也有双字节  wchar_t  wbuf[0x100] = {0};  //双字节  然后使用这个函数, 就可以把  buf转换到wbuf中. MultiByteToWideChar

LZ的意思应该类似全角，半角

这个勉强算“双性恋”吧： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

引用 14 楼 sholber 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] 一件编码问题引发的血案！  给俺一个案例，证明赵4老师离开Windows也能活得很好。 嘎嘎~~[/quote] 说“跨平台一定比不跨平台好”就和说“双性恋一定比异性恋好”一样！

引用 12 楼 zhao4zhong1 的回复:一件编码问题引发的血案！  给俺一个案例，证明赵4老师离开Windows也能活得很好。 嘎嘎~~

引用 12 楼 zhao4zhong1 的回复:一件编码问题引发的血案！ # include <stdio.h>  int main (void) {     printf (u8"赵4老湿好诗！\n"); }

一件编码问题引发的血案！

再捅9楼一刀  在被虐中成长的sholber！ #pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> extern "C" HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     wchar_t wc[2];      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48,0,0,0,0,0,0,0,GB2312_CHARSET ,0,0,0,0,"宋体-方正超大字符集");     SelectObject(hdc,hfont);     wc[0]=0xD854u;     wc[1]=0xDC00u;     TextOutW(hdc,10,10,wc,2);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; } #if 0 代理项或代理项对是一对共同表示单个字符的 16 位 Unicode 编码值。需要记住的关键一点是： 代理项对实际上是 32 位单个字符，不能再假定一个 16 位 Unicode 编码值正好映射到一个字符。  使用代理项对 代理项对的第一个值是高代理项，包含介于 U+D800 到 U+DBFF 范围内的 16 位代码值。 该对的第二个值是低代理项，包含介于 U+DC00 到 U+DFFF 范围内的值。通过使用代理项对， 16 位 Unicode 编码系统可以对已由 Unicode 标准定义的一百多万个其他字符 (220) 进行寻址。  在传递给 XmlTextWriter 方法的任何字符串中都可以使用代理项字符。不过，代理项字符在编写的 XML 中应该有效。例如，万维网联合会 (W3C) 建议不允许在元素或属性的名称中使用代理项字符。 如果字符串包含无效的代理项对，则引发异常。  另外，可以使用 WriteSurrogateCharEntity 写出与代理项对相对应的字符实体。字符实体以十六 进制格式写出，并用以下公式生成：  (highChar -0xD800) * 0x400 + (lowChar -0xDC00) + 0x10000  如果字符串包含无效的代理项对，则引发异常。下面的示例显示将代理项对作为输入的 WriteSurrogateCharEntity 方法。  C#复制  // The following line writes 𐀀. WriteSurrogateCharEntity ('\uDC00', '\uD800'); 下面的示例生成一个代理项对文件，将其加载到 XmlReader 中，并用新的文件名保存文件。 然后，原始文件和新文件被加载回应用程序的 XML 文档对象模型 (DOM) 结构中以进行比较。  C#复制  char lowChar, highChar; char [] charArray = new char[10]; FileStream targetFile = new FileStream("SurrogatePair.xml",       FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  lowChar = Convert.ToChar(0xDC00); highChar = Convert.ToChar(0xD800); XmlTextWriter tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDC01); highChar = Convert.ToChar(0xD801); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDFFF); highChar = Convert.ToChar(0xDBFF); tw.WriteSurrogateCharEntity(lowChar, highChar);  // Add 10 random surrogate pairs. // As Unicode, the high bytes are in lower // memory; for example, word 6A21 as 21 6A. // The high or low is in the logical sense. Random random = new Random(); for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       charArray[i] = highChar;       charArray[++i] = lowChar; } tw.WriteChars(charArray, 0, charArray.Length);  for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       tw.WriteSurrogateCharEntity(lowChar, highChar); }  tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  XmlTextReader r = new XmlTextReader("SurrogatePair.xml");  r.Read(); r.MoveToFirstAttribute(); targetFile = new FileStream("SurrogatePairFromReader.xml",        FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteString(r.Value); tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  // Load both result files into the DOM and compare. XmlDocument doc1 = new XmlDocument(); XmlDocument doc2 = new XmlDocument(); doc1.Load("SurrogatePair.xml"); doc2.Load("SurrogatePairFromReader.xml"); if (doc1.InnerXml != doc2.InnerXml) {       Console.WriteLine("Surrogate Pair test case failed"); } 在使用 WriteChars 方法（一次写出一个缓冲区的数据）写出时，输入中的代理项对可能 会在一个缓冲区内被意外拆分。由于代理项值是定义完善的，如果 WriteChars 遇到来自 较低范围或者较高范围的 Unicode 值，它将该值标识为代理项对的一半。当遇到  WriteChars 将导致从拆分代理项对的缓冲区写入的情况时，将引发异常。使用   IsHighSurrogate 方法检查缓冲区是否以高代理项字符结束。如果缓冲区中的最后一个   字符不是高代理项，可以将该缓冲区传递给 WriteChars 方法。  请参见 概念 使用 XmlTextWriter 创建格式正确的 XML XmlTextWriter 的 XML 输出格式设置 XmlTextWriter 的命名空间功能  #endif

9楼在我面前谈编码，好似关公面前耍大刀： 搜“ConvertZ”  先http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考： C:\>dir /w "C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\cvt"  驱动器 C 中的卷是 C_HD5_1  卷的序列号是 1817-D526   C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\cvt 的目录  [..]         [.]          8859_1       8859_10      8859_13      8859_14      8859_15      8859_16      8859_2 8859_3       8859_4       8859_5       8859_6       8859_7       8859_8       8859_9       baltic       big5 cp037        cp1006       cp1026       cp1250       cp1251       cp1252       cp1253       cp1254       cp1255 cp1256       cp1257       cp1258       cp424        cp437        cp500        cp737        cp775        cp850 cp852        cp855        cp856        cp857        cp860        cp861        cp862        cp863        cp864 cp865        cp866        cp869        cp874        cp875        cp932        cp936        cp949        cp950 cyrillic     ebcdic       euc          euc_0208     gb12345      gb2312       greek        iceland      jis jis0201      jis_0208     ksc5601      latin2       one_one      roman        sjis         sjis_0208    turkish utf16        utf8         utf8_utf16   wbuffer      wstring      xjis         xone_byte    xtest        xtwo_byte               79 个文件      4,638,592 字节                2 个目录 12,588,097,536 可用字节

引用 8 楼 zhao4zhong1 的回复:#include <stdio.h> #include <locale.h> #include <windows.h> char s[]="小同志你好！请问一下,你知道人民北路29号怎么走呀?..........。"; wchar_t *ws; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main() {     setlocale(LC_ALL,"chs");     printf("%s\n",s);     HexDump(s,strlen(s)+1,(int)s);     int nLen = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, NULL);     ws = new wchar_t[nLen];     MultiByteToWideChar(CP_ACP, 0, s, -1, ws, nLen);     wprintf(L"%s\n",ws);     HexDump((char *)ws,wcslen(ws)*2+2,(int)ws);     delete[] ws;     return 0; } //小同志你好！请问一下,你知道人民北路29号怎么走呀?..........。 //00414410 - d0 a1 cd ac d6 be c4 e3 ba c3 a3 a1 c7 eb ce ca  ................ //00414420 - d2 bb cf c2 2c c4 e3 d6 aa b5 c0 c8 cb c3 f1 b1  ....,........... //00414430 - b1 c2 b7 32 39 ba c5 d4 f5 c3 b4 d7 df d1 bd 3f  ...29..........? //00414440 - 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e a1 a3 00           ............. //小同志你好！请问一下,你知道人民北路29号怎么走呀?..........。 //00422420 - 0f 5c 0c 54 d7 5f 60 4f 7d 59 01 ff f7 8b ee 95  .\.T._`O}Y...... //00422430 - 00 4e 0b 4e 2c 00 60 4f e5 77 53 90 ba 4e 11 6c  .N.N,.`O.wS..N.l //00422440 - 17 53 ef 8d 32 00 39 00 f7 53 0e 60 48 4e 70 8d  .S..2.9..S.`HNp. //00422450 - 40 54 3f 00 2e 00 2e 00 2e 00 2e 00 2e 00 2e 00  @T?............. //00422460 - 2e 00 2e 00 2e 00 2e 00 02 30 00 00              .........0.. //   事情没这么简单的。 在符合楼主要求的前提下，考虑一下，从GB2312转换到UTF-16。 16位编码方案很多。 现在的C不仅仅支持char和wide char。 你积攒的东西需要更新了。

汉字是双 数字是单 吧

整串文字整体来的，不会是一部分多字节，一部分宽字节的，看你怎么存了，如果是char数组，那么汉字就是占2个字节存，数字占1个，如果是wchar_t数组，那么汉字和数字都是2个字节存的

哪个是单字节？哪个又是双字节？鄙人浅陋


Question: 我是小白 ，有大神可以解释下吗 为什么是 1,2 不是1,3

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

是，a&&b当a为假的时候，后面的就不执行了，a||b为假的时候，再判断b，最后再输出结果！同为菜鸟！

楼上的解答是对的！ 第一次循环条件是(a=-2)&&(b=1)，执行循环体（楼主的程序中没有）后，a=-1，b=1； 第二次循环条件是(a=-1)&&(b=2)，循环后a=0，b=2； 第三次循环条件a=0，&&运算为假，后面的b++不再执行，循环结束，所以b是第二次循环后的结果   #include<stdio.h> int main() { 	int a=-2; 	int b=0; 	while(a++&&++b) 		printf("%d %d\n",a,b); 	printf("%d %d\n",a,b); 	return 0; }

int a=-2; int b=0; while(a++&&++b);   第一次循环：a=-1;b=1; 第二次循环：a=0;b=2; 第三次循环：a++这个表达式的值是0，就表条件不成立，++b就不在运算了，而a加了一，变成1，故最后输出1,2。 这是运算符&&的”短路“现象。


Question: 求助贴，呜呜~~~~~~

记得以前好像做过类似的东西， 没记错的的话汉字两个字节的ascii值的最高位都是1，楼主可以根据判断字符的asii码值对获取的字符串所有字符进行判断，应该可以

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h>  typedef struct lnode{//节点定义 读取数据是链表中的节点 		char key; 		int count; 		lnode *next; 	}*link;  link createnode(void){//创建节点 	link newnode=(lnode*)malloc(sizeof(lnode)); 	if(newnode!=NULL){ 		newnode->count=0; 		newnode->next=NULL; 	} 	return newnode; }  int main(){  	FILE*fp; 	char ch;   	if((fp=fopen("test.txt","rt"))==NULL){//打开文件 		printf("cannot open file!\n"); 		getch(); 		exit(1); 	} 	         bool flag; 	link head=NULL; 	link current=head;               while((ch=fgetc(fp))!=EOF){//统计概率 		flag=true; 		for(current=head;current!=NULL;current=current->next){ 			if(current->key==ch){ 				current->count++; 				flag=false; 				break; 			} 		} 			if(flag){ 				link newcode=createnode(); 				newcode->key=ch; 				newcode->count++; 				newcode->next=head; 				head=newcode; 			} 	putchar(ch); 	}   	    printf("\n"); 		printf("字符\t");         printf("次数\n"); 		 		int total=0;  	for(current=head;current!=NULL;current=current->next){//读出统计的字符和相应的次数； 		printf("字符%c\t",current->key); 		printf("频率%d\n",current->count); 		total++; 		}  这里只实现了英文文本的读取和存储，中英文混合的时候要怎么分辨出来，并且要存放在和英文字符统一的结构体里面呢？最好能给个代码，这问题纠结好久了。。。。呜呜~~~~

做一下 汉字 和英文字符  的判断！

String Manipulation These routines operate on null-terminated single-byte character, wide-character, and multibyte-character strings. Use the buffer-manipulation routines, described in Buffer Manipulation, to work with character arrays that do not end with a null character.  String-Manipulation Routines  Routine Use  _mbscoll, _mbsicoll, _mbsncoll, _mbsnicoll Compare two multibyte-character strings using multibyte code page information (_mbsicoll and _mbsnicoll are case-insensitive)  _mbsdec, _strdec, _wcsdec Move string pointer back one character  _mbsinc, _strinc, _wcsinc Advance string pointer by one character  _mbslen Get number of multibyte characters in multibyte-character string; dependent upon OEM code page  _mbsnbcat Append, at most, first n bytes of one multibyte-character string to another  _mbsnbcmp Compare first n bytes of two multibyte-character strings  _mbsnbcnt Return number of multibyte-character bytes within supplied character count  _mbsnbcpy Copy n bytes of string  _mbsnbicmp Compare n bytes of two multibyte-character strings, ignoring case  _mbsnbset Set first n bytes of multibyte-character string to specified character  _mbsnccnt Return number of multibyte characters within supplied byte count  _mbsnextc, _strnextc, _wcsnextc Find next character in string  _mbsninc. _strninc, _wcsninc  Advance string pointer by n characters  _mbsspnp, _strspnp, _wcsspnp Return pointer to first character in given string that is not in another given string  _mbstrlen Get number of multibyte characters in multibyte-character string; locale-dependent  sprintf, _stprintf Write formatted data to a string  strcat, wcscat, _mbscat Append one string to another  strchr, wcschr, _mbschr Find first occurrence of specified character in string  strcmp, wcscmp, _mbscmp Compare two strings  strcoll, wcscoll, _stricoll, _wcsicoll, _strncoll, _wcsncoll, _strnicoll, _wcsnicoll Compare two strings using current locale code page information (_stricoll, _wcsicoll, _strnicoll, and _wcsnicoll are case-insensitive)  strcpy, wcscpy, _mbscpy Copy one string to another  strcspn, wcscspn, _mbscspn,  Find first occurrence of character from specified character set in string  _strdup, _wcsdup, _mbsdup Duplicate string  strerror Map error number to message string  _strerror Map user-defined error message to string  strftime, wcsftime Format date-and-time string  _stricmp, _wcsicmp, _mbsicmp Compare two strings without regard to case  strlen, wcslen, _mbslen, _mbstrlen Find length of string  _strlwr, _wcslwr, _mbslwr Convert string to lowercase  strncat, wcsncat, _mbsncat Append characters of string  strncmp, wcsncmp, _mbsncmp Compare characters of two strings  strncpy, wcsncpy, _mbsncpy Copy characters of one string to another  _strnicmp, _wcsnicmp, _mbsnicmp Compare characters of two strings without regard to case  _strnset, _wcsnset, _mbsnset Set first n characters of string to specified character  strpbrk, wcspbrk, _mbspbrk Find first occurrence of character from one string in another string  strrchr, wcsrchr,_mbsrchr Find last occurrence of given character in string  _strrev, _wcsrev,_mbsrev Reverse string  _strset, _wcsset, _mbsset Set all characters of string to specified character  strspn, wcsspn, _mbsspn Find first substring from one string in another string  strstr, wcsstr, _mbsstr Find first occurrence of specified string in another string  strtok, wcstok, _mbstok Find next token in string  _strupr, _wcsupr, _mbsupr Convert string to uppercase  strxfrm, wcsxfrm Transform string into collated form based on locale-specific information  vsprintf, _vstprint Write formatted output using a pointer to a list of arguments

Stream I/O These functions process data in different sizes and formats, from single characters to large data structures. They also provide buffering, which can improve performance. The default size of a stream buffer is 4K. These routines affect only buffers created by the run-time library routines, and have no effect on buffers created by the operating system.  Stream I/O Routines  Routine Use  clearerr Clear error indicator for stream  fclose Close stream  _fcloseall Close all open streams except stdin, stdout, and stderr  _fdopen, wfdopen Associate stream with handle to open file  feof Test for end of file on stream  ferror Test for error on stream  fflush Flush stream to buffer or storage device   fgetc, fgetwc Read character from stream (function versions of getc and getwc)  _fgetchar, _fgetwchar Read character from stdin (function versions of getchar and getwchar)  fgetpos Get position indicator of stream  fgets, fgetws Read string from stream  _fileno Get file handle associated with stream  _flushall Flush all streams to buffer or storage device  fopen, _wfopen Open stream  fprintf, fwprintf Write formatted data to stream  fputc, fputwc Write a character to a stream (function versions of putc and putwc)  _fputchar, _fputwchar Write character to stdout (function versions of putchar and putwchar)  fputs, fputws Write string to stream  fread Read unformatted data from stream  freopen, _wfreopen Reassign FILE stream pointer to new file or device  fscanf, fwscanf Read formatted data from stream  fseek Move file position to given location  fsetpos Set position indicator of stream  _fsopen, _wfsopen Open stream with file sharing  ftell Get current file position  fwrite Write unformatted data items to stream  getc, getwc Read character from stream (macro versions of fgetc and fgetwc)  getchar, getwchar Read character from stdin (macro versions of fgetchar and fgetwchar)  gets, getws Read line from stdin  _getw Read binary int from stream  printf, wprintf Write formatted data to stdout  putc, putwc Write character to a stream (macro versions of fputc and fputwc)  putchar, putwchar Write character to stdout (macro versions of fputchar and fputwchar)  puts, _putws Write line to stream  _putw Write binary int to stream  rewind Move file position to beginning of stream  _rmtmp Remove temporary files created by tmpfile  scanf, wscanf Read formatted data from stdin  setbuf Control stream buffering  _setmaxstdio Set a maximum for the number of simultaneously open files at the stream I/O level.   setvbuf Control stream buffering and buffer size  _snprintf, _snwprintf Write formatted data of specified length to string  sprintf, swprintf Write formatted data to string  sscanf, swscanf Read formatted data from string  _tempnam, _wtempnam Generate temporary filename in given directory  tmpfile Create temporary file  tmpnam, _wtmpnam Generate temporary filename  ungetc, ungetwc Push character back onto stream  vfprintf, vfwprintf  Write formatted data to stream  vprintf, vwprintf Write formatted data to stdout  _vsnprintf, _vsnwprintf Write formatted data of specified length to buffer  vsprintf, vswprintf Write formatted data to buffer    When a program begins execution, the startup code automatically opens several streams: standard input (pointed to by stdin), standard output (pointed to by stdout), and standard error (pointed to by stderr). These streams are directed to the console (keyboard and screen) by default. Use freopen to redirect stdin, stdout, or stderr to a disk file or a device.  Files opened using the stream routines are buffered by default. The stdout and stderr functions are flushed whenever they are full or, if you are writing to a character device, after each library call. If a program terminates abnormally, output buffers may not be flushed, resulting in loss of data. Use fflush or _flushall to ensure that the buffer associated with a specified file or all open buffers are flushed to the operating system, which can cache data before writing it to disk. The commit-to-disk feature ensures that the flushed buffer contents are not lost in the event of a system failure.   There are two ways to commit buffer contents to disk:   Link with the file COMMODE.OBJ to set a global commit flag. The default setting of the global flag is n, for “no-commit.”   Set the mode flag to c with fopen or _fdopen.  Any file specifically opened with either the c or the n flag behaves according to the flag, regardless of the state of the global commit/no-commit flag.  If your program does not explicitly close a stream, the stream is automatically closed when the program terminates. However, you should close a stream when your program finishes with it, as the number of streams that can be open at one time is limited. See _setmaxstdio for information on this limit.   Input can follow output directly only with an intervening call to fflush or to a file-positioning function (fseek, fsetpos, or rewind). Output can follow input without an intervening call to a file-positioning function if the input operation encounters the end of the file.


Question: 下面这个程序时快速排序的实现，不知道哪儿出问题，求指教？

引用 2 楼 fly_dragon_fly 的回复:while (low < high) low和high如果都不变，这个语句没法退出，既然是递归实现，这个while就没必要，你要while就不要递归。正解，多谢了！

int QSort(int *a, int low, int high) {     int pivot;     while (low < high)     {         pivot = Partition(a,low,high); //        QSort(a,low,pivot); //        low = pivot+1; /****如果按照上面两句就是对的，但如果换成下面两行代码就不对，这有什么区别呢？****/ /*答：上面两句每执行一次while循环，QSort函数只执行一次，low位置改变一次，下面两行要执行QSort函数两次，low位置改变一次*/          QSort(a,low,pivot);          QSort(a,pivot+1,high);     }     return 0; }

具体的实现方法没看   while (low < high)     {         pivot = Partition(a,low,high); //        QSort(a,low,pivot); //        low = pivot+1; /****如果按照上面两句就是对的，但如果换成下面两行代码就不对，这有什么区别呢？****/          QSort(a,low,pivot);         QSort(a,pivot+1,high);   //使用下面这个不是在while(1) 中么？     }


Question: printf函数的参数压栈顺序问题

引用 2 楼 lin5161678 的回复:你被骗了  题目是错的  参数的压栈顺序是压栈顺序 和副作用没什么关系  你应该去看看本版的置顶帖 麻烦给个链接呗

引用 1 楼 akirya 的回复:你被坑了。。 求解释啊

你被坑了。。


Question: 基于ASP.NET的电子政务系统

ASP.NET的技术去.NET技术板块，这里是是C\C++语言版啊！


Question: 用puts输出数组中的字符串

w中存放小写字母 c中存放大写字母

我猜你是想把大写字母和小写字母区分开来，对吗？ 如果是这样，有几处要改动：  int main() { 	char a[100], w[100], c[100]; 	int i = 0, k = 0, l = 0; 	gets(a); 	while (a[i] != '\0') 	{ 		if (a[i] >= 'a' && a[i] <= 'z') 		{ 			w[k] = a[i]; 			k++; 		} 		else 		{ 			c[l] = a[i]; 			l++; 		} 		i++; 	} 	//scanf("\0", &w[k]); 	//scanf("\0", &c[l]); 	w[k] = '\0'; 	c[l] = '\0';         printf("w="); 	puts(w);         printf("c="); 	puts(c); 	return 0; }  //alskdDSAasdWEFasd //w=alskdasdasd //c=DSAWEF

scanf("\0",&w[k]); scanf("\0",&c[l]);  改为： w[k] = '\0'; c[l] = '\0';   puts是对字符串进行处理，需要‘\0’来结束


Question: 滚动条位置设定后又马上重新获取的疑惑

nPos如果超过范围, 就会被改到合适范围内.


Question: C语言调试时出现了unhandled exception...查资料说是用了非法内存，但是检查不出来啊，求大神指导，代码如下

char * ptr[LIM];。。。。 你这个。。。。 要么char *ptr 要么char ptr [ ]。。。。

你这错得好凌乱呀~~ 基本上代码都是"废"代码  - -!!! 主要是指针搞错了 如输入函数  int input(char * str[], int num); char *str[]  跟  char (*str)[SIZE] 是两码事 .....  代码中处理二维表  char str[LIM][SIZE] 的指针可以是  int input( char str[LIM][SIZE], int num); 或者  int input( char (*str)[SIZE], int num); 等...... ...... 因为指针搞错了所以你代码中所有关于指针的操作都有问题,..为以才非法使用内存  把指针理一理重新写写就OK了  // ps :你用的是什么编译器呀..没给 错误/警告 ?? //// 你的 结帖率：0%     ....唉~~

没人搭理么……

不怎么会用论坛，也不知道发的对不对。。。见谅


Question: 如何将两个8位数拼接成一个16位的数

get it

引用 21 楼 zhao4zhong1 的回复:[quote=引用 14 楼 sholber 的回复:] 据我所知，没有任何一个国际标准正式地定义一个字节的比特数，我想，这已经足够说明问题了。 据我所知，没有任何一个国际标准正式地定义一个人的手脚甚至脑袋数，我想，这已经足够说明问题了。  [/quote]  正因为如此，在用C解决和手有关的问题时，需要考虑有的人是6指。如果不考虑，就会出现问题。做为一个程序爱好者，你认为你在做这个项目时，不考虑有的人是6指或者7指？我不信。

引用 14 楼 sholber 的回复:据我所知，没有任何一个国际标准正式地定义一个字节的比特数，我想，这已经足够说明问题了。 据我所知，没有任何一个国际标准正式地定义一个人的手脚甚至脑袋数，我想，这已经足够说明问题了。

引用 30 楼 zhao4zhong1 的回复:[quote=引用 29 楼 sholber 的回复:] [quote=引用 27 楼 zhao4zhong1 的回复:] [quote=引用 22 楼 sholber 的回复:] [quote=引用 21 楼 zhao4zhong1 的回复:] [quote=引用 14 楼 sholber 的回复:] 据我所知，没有任何一个国际标准正式地定义一个字节的比特数，我想，这已经足够说明问题了。 据我所知，没有任何一个国际标准正式地定义一个人的手脚甚至脑袋数，我想，这已经足够说明问题了。  [/quote]  正因为如此，在用C解决和手有关的问题时，需要考虑有的人是6指。如果不考虑，就会出现问题。做为一个程序爱好者，你认为你在做这个项目时，不考虑有的人是6指或者7指？我不信。[/quote] 我真的从来没考虑过。[/quote]  眼看已经将赵老师逼到墙角，赵老师就地一滚，撒起泼来。 嘎嘎~~[/quote] 跟我比谁脸皮厚？！你找错对象了。 过去叫“厚颜无耻”；现在叫“心理素质过硬”！ [/quote]  赵老湿是哪里人？我回家要是路过的话，一定找你把酒言欢，共论天下大事！ PS： 自打我来CSDN之后，字里行间，就知道赵老湿是个宽厚的人，心想日后必能成为朋友。只是没想到把酒言欢的事是我先提出来，谁脸皮厚？

引用 29 楼 sholber 的回复:[quote=引用 27 楼 zhao4zhong1 的回复:] [quote=引用 22 楼 sholber 的回复:] [quote=引用 21 楼 zhao4zhong1 的回复:] [quote=引用 14 楼 sholber 的回复:] 据我所知，没有任何一个国际标准正式地定义一个字节的比特数，我想，这已经足够说明问题了。 据我所知，没有任何一个国际标准正式地定义一个人的手脚甚至脑袋数，我想，这已经足够说明问题了。  [/quote]  正因为如此，在用C解决和手有关的问题时，需要考虑有的人是6指。如果不考虑，就会出现问题。做为一个程序爱好者，你认为你在做这个项目时，不考虑有的人是6指或者7指？我不信。[/quote] 我真的从来没考虑过。[/quote]  眼看已经将赵老师逼到墙角，赵老师就地一滚，撒起泼来。 嘎嘎~~[/quote] 跟我比谁脸皮厚？！你找错对象了。 过去叫“厚颜无耻”；现在叫“心理素质过硬”！

引用 27 楼 zhao4zhong1 的回复:[quote=引用 22 楼 sholber 的回复:] [quote=引用 21 楼 zhao4zhong1 的回复:] [quote=引用 14 楼 sholber 的回复:] 据我所知，没有任何一个国际标准正式地定义一个字节的比特数，我想，这已经足够说明问题了。 据我所知，没有任何一个国际标准正式地定义一个人的手脚甚至脑袋数，我想，这已经足够说明问题了。  [/quote]  正因为如此，在用C解决和手有关的问题时，需要考虑有的人是6指。如果不考虑，就会出现问题。做为一个程序爱好者，你认为你在做这个项目时，不考虑有的人是6指或者7指？我不信。[/quote] 我真的从来没考虑过。[/quote]  眼看已经将赵老师逼到墙角，赵老师就地一滚，撒起泼来。 嘎嘎~~

如果只是将两个8bit的数合并成一个16bit的数，前面的达人们给出的方法都能够实现，只是需要要注意位序的问题，我个人觉得移位然后再按位或比较好，可以避免位序出错。

引用 22 楼 sholber 的回复:[quote=引用 21 楼 zhao4zhong1 的回复:] [quote=引用 14 楼 sholber 的回复:] 据我所知，没有任何一个国际标准正式地定义一个字节的比特数，我想，这已经足够说明问题了。 据我所知，没有任何一个国际标准正式地定义一个人的手脚甚至脑袋数，我想，这已经足够说明问题了。  [/quote]  正因为如此，在用C解决和手有关的问题时，需要考虑有的人是6指。如果不考虑，就会出现问题。做为一个程序爱好者，你认为你在做这个项目时，不考虑有的人是6指或者7指？我不信。[/quote] 我真的从来没考虑过。

而且有些ARM 的 cpu是可以调整字节序方式的 不知道下面的对不对。。。  //just  for intel_ia32 uint16_t Compose(uint8_t hi,uint8_t lo) {         register uint16_t reval = hi;         return (reval<<8) | lo;  }

没有说明字节序，这个要依赖于CPU  最好写个ARCH相关的函数  在不同框架中对该函数进行改写

一般的电脑表示都是八位，九位甚至更多一般都是在硬件的吧

我只能说我现在暂时还不知道还有九位这中说法。

楼主太笼统。 1，怎么拼接？9和9拼接，结果是18呢，还是99，没说； 2，原来的两个8位数是有符号呢，还是没有符号？没说； 3，放不下怎么办？没说。

引用 18 楼 worldy 的回复:[quote=引用 13 楼 sholber 的回复:]  我会说某ID见识短，孤陋寡闻吗？ 即使全世界只有一台这样的计算机，而且拥有C的实现，你就说一字节是八位，也是极不负责任的胡说。这些家伙幸亏不是WG14的成员。这种认识比无知更恶劣。因为少，就可以视而不见吗？我只能说，x86和Windows蒙蔽了你的双眼。 C标准相比于其它语言标准，可以说，是唯一一个没有被实现绑架的。 字符编码里有个术语叫“八位元”，如果按你们的想法，干脆叫字节好了－－－还真有人这么干。  或许这位老兄能举例说出一个不是8位一字节的芯片？[/quote]  尽管绝大多数计算机CHAR_BIT == 8，但仍然有些架构是例外的： http://computer-programming-forum.com/47-c-language/d1a610bbac942565.htm  PS: C99 says that CHAR_BIT must be at least 8; POSIX says it must be exactly 8; on Windows it's 8. That's about all the platforms it's worth caring about.  There was a port of gcc for PDP-10 where CHAR_BIT=9: http://pdp10.nocrew.org/gcc/download/gcc-pdp10-20020611.tar.bz2

引用 13 楼 sholber 的回复:我会说某ID见识短，孤陋寡闻吗？ 即使全世界只有一台这样的计算机，而且拥有C的实现，你就说一字节是八位，也是极不负责任的胡说。这些家伙幸亏不是WG14的成员。这种认识比无知更恶劣。因为少，就可以视而不见吗？我只能说，x86和Windows蒙蔽了你的双眼。 C标准相比于其它语言标准，可以说，是唯一一个没有被实现绑架的。 字符编码里有个术语叫“八位元”，如果按你们的想法，干脆叫字节好了－－－还真有人这么干。  或许这位老兄能举例说出一个不是8位一字节的芯片？

union aType{ unsigned char a[2]; short int b; }  aType a;  a.a[0]=v1;//一个值 a.a[1]=v2;  short int x=a.b; 这个应该是最有效的拼接了

这是个极具挑战性的问题。

引用 10 楼 sholber 的回复:[quote=引用 8 楼 my_live_123 的回复:] [quote=引用 5 楼 sholber 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] unsigned char uc[2]={0x10,0xA0}; unsigned short us1,us2; unsigned char *p; p=(unsigned char *)&us1; p[0]=uc[0];p[1]=uc[1]; p=(unsigned char *)&us2; p[0]=uc[1];p[1]=uc[0]; printf("%hu(%04hx),%hu(%04hx)\n",us1,us1,us2,us2);  引用 2 楼 a30037338 的回复: unsigned char hi = 0x15; unsigned char lo = 0x51; unsigned short  i = 0; i |= hi << 8; i |= lo;   引用 3 楼 henuyx 的回复:char buf[24] snprintf(buf, 24, "%d%08d", num1, num2); 引用 4 楼 my_live_123 的回复:(a << 8) | b  楼主并没有说明他所采用的编译环境和执行环境。 所以， 我想知道， 如果他所采用的C的实现 一个字节是9位，或者更多位（有的机器可以达到18位） 该怎么办？ 不要说我钻牛角尖，也不要说没有这样的CPU架构。 我只想说， 你们错了， 这样的机器是有的。[/quote]  还有没有提供移位计算的机器呢？怎么办呢？暂时我想偷懒 留给你解决的了[/quote] 你说得不对， 不对，不对，不对啊， 不对。 字节长度不同，对于在该架构上实现C，没有任何影响，没有，没有的。没有的么。 有些计算机架构， 对于实现C语言困难重重，这是高难度计算机。也没办法， 再说， 赵4老湿曾说，没有 没有移位的计算机， 赵4老湿，你来反驳他！你来！ 来！ 嘎嘎~~[/quote]  安全起见，一般会选择与上一个位掩码  现代计算机架构应该是没有没有移位计算的机器，但是“古代”计算机就不一定喽！

引用 5 楼 sholber 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] unsigned char uc[2]={0x10,0xA0}; unsigned short us1,us2; unsigned char *p; p=(unsigned char *)&us1; p[0]=uc[0];p[1]=uc[1]; p=(unsigned char *)&us2; p[0]=uc[1];p[1]=uc[0]; printf("%hu(%04hx),%hu(%04hx)\n",us1,us1,us2,us2);  引用 2 楼 a30037338 的回复: unsigned char hi = 0x15; unsigned char lo = 0x51; unsigned short  i = 0; i |= hi << 8; i |= lo;   引用 3 楼 henuyx 的回复:char buf[24] snprintf(buf, 24, "%d%08d", num1, num2); 引用 4 楼 my_live_123 的回复:(a << 8) | b  楼主并没有说明他所采用的编译环境和执行环境。 所以， 我想知道， 如果他所采用的C的实现 一个字节是9位，或者更多位（有的机器可以达到18位） 该怎么办？ 不要说我钻牛角尖，也不要说没有这样的CPU架构。 我只想说， 你们错了， 这样的机器是有的。[/quote]  还有没有提供移位计算的机器呢？怎么办呢？暂时我想偷懒 留给你解决的了


Question: 求问个算法问题（正常的数我还可以试着写一写，可这这样大这样多应该怎么办）

引用 9 楼 zhao4zhong1 的回复:[quote=引用 6 楼 henuyx 的回复:] 要我出题，n个数应该是无序的！！ 要我出题,整数位数不限长度,只要硬盘能存下.[/quote] 这样的话要怎么定义啊 就算是动态分配的话 不也的是有个范围吗？

引用 13 楼 mymtom 的回复:[quote=引用 12 楼 my_bkb 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 6 楼 henuyx 的回复:] 要我出题，n个数应该是无序的！！ 要我出题,整数位数不限长度,只要硬盘能存下.[/quote] 那个还是想问下 这里的n的数量是没有限制的 ，那要怎么定义啊[/quote] 根据n动态分配内存就可以啊[/quote] 怎么个分配法？

引用 12 楼 my_bkb 的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 6 楼 henuyx 的回复:] 要我出题，n个数应该是无序的！！ 要我出题,整数位数不限长度,只要硬盘能存下.[/quote] 那个还是想问下 这里的n的数量是没有限制的 ，那要怎么定义啊[/quote] 根据n动态分配内存就可以啊

引用 9 楼 zhao4zhong1 的回复:[quote=引用 6 楼 henuyx 的回复:] 要我出题，n个数应该是无序的！！ 要我出题,整数位数不限长度,只要硬盘能存下.[/quote] 那个还是想问下 这里的n的数量是没有限制的 ，那要怎么定义啊

bsearch函数就能解决的问题呀  #include <stdio.h> #include <string.h> #include <stdlib.h>  #define SIZE    12  char * format(char buf[SIZE + 1]) {     int len;      len = strlen(buf);     memmove(buf + (SIZE - len), buf, len + 1);     memset(buf, '0', SIZE - len);      return buf; }  int compare(const void *v1, const void *v2) {     return memcmp(v1, v2, SIZE); }  int main(int argc, char *argv[]) {     int ret;     int m, n;     int i, j;     char *mp;     char *np;      if (scanf("%d %d", &n, &m) != 2)         exit(1);      mp = malloc((SIZE + 1) * m);     np = malloc((SIZE + 1) * n);      for (i = 0; i < n; i++) {         scanf("%12s", &np[(SIZE + 1) * i]);         format(&np[(SIZE + 1) * i]);     }      for (j = 0; j < m; j++) {         scanf("%12s", &mp[(SIZE + 1) * j]);         format(&mp[(SIZE + 1) * j]);     }      for (j = 0; j < m; j++) {         if (bsearch(&mp[(SIZE + 1) * j], np, n, SIZE + 1, compare)) {             printf("%s: yes\n", &mp[(SIZE + 1) * j]);         } else {             printf("%s: no\n", &mp[(SIZE + 1) * j]);         }     }      free(mp);     free(np);      return 0; }

static char[1000000][13];

引用 6 楼 henuyx 的回复:要我出题，n个数应该是无序的！！ 要我出题,整数位数不限长度,只要硬盘能存下.

引用 4 楼 zhao4zhong1 的回复:用字符串比较的话，注意比较前将宽度不够12个数字的数左边补0 还有这个我用数字数组行吗 ，可我怕数字数组太大编译不通过

引用 5 楼 zhao4zhong1 的回复:[quote=引用 3 楼 gqjjqg 的回复:] 别怕，数值范围是1 - 10^12，可以int64(long)保存。 查询用二分搜索，或者做个hash表查询。 int64通常是long long而非long，此题如果改为10的21次方，int64就不够了。[/quote] 这里面这个n怎么办啊，你n>=1,没有最大范围啊  还有这个数组 由于数组里面的数太大了 我这样定义数组可以吗 unsigned long long a[1000000000000000];

要我出题，n个数应该是无序的！！

引用 3 楼 gqjjqg 的回复:别怕，数值范围是1 - 10^12，可以int64(long)保存。 查询用二分搜索，或者做个hash表查询。 int64通常是long long而非long，此题如果改为10的21次方，int64就不够了。

用字符串比较的话，注意比较前将宽度不够12个数字的数左边补0

字符串比较＋二分查找。

转成字符对比查找的方式……


Question: CString 对象Format遇到的内存读取问题

四楼说的是对的！或者你把vs编译环境换成debug也行

引用 8 楼 henanwansui 的回复:7楼的方法都试了，str.Format(L"%.2f",a);这种会出现无法参数转化的错误，加T的话，没有用，还是指向atlsimpstr.h文件， 唉，这个问题折磨好几天了  你把代码垃圾文件删掉, 传到网盘. 如果不需要保密的话

vc6.0里面，CString 默认情况下代表的是ascii字符集，而VC2010里，默认情况下，CString代表的是unicode字符集，所以，赵4老师说的是对的  str.Format(_T("%.2f"),a);  要加一个_T()，或者  str.Format(L"%.2f",a);  因为在VC2010下CString的Format函数的原型是:  Format(const wchar_t* ,...)  所以你的第一个参数，必须使用wchar的字符串常量

不是a是否初始化的问题，问题出在Format函数处，断点停在这，然后转到 CStringData *GetData() const throw() { return (reinterpret cast<CStringData *>(m_pszData)-1); ｝这个位置，会显示Unhandled exception at 0x5a20fe3c(mfc100d.dll ) in 76p.exe :0xC0000005:Access violation reading location 0x00006644, 而且程序中的CString 类的对象在vc6.0中是可以编译的，但在VS2010环境下就出现问题，

a需要初始化

str.Format("%.2f",a); 和 str.Format(_T("%.2f"),a); 不是一回事！

引用 2 楼 henanwansui 的回复:其实，我已经试过这种可能了，还是错误。我看了程序，出现错误的都是CString类，而且最后的断点都指向 CStringData *GetData() const throw() { return (reinterpret cast<CStringData *>(m_pszData)-1); ｝这个位置  我就vs2010, 为什么我能跑过呢  #include <StdAfx.h> #include<iostream> #include <afxwin.h> using namespace std;  int main(int argc, char* argv[]) { 	CString str; 	float a = 0; 	str.Format(_T("%.2f"),a); 	cout << a << endl; 	system("pause"); }

float a = 0;  永远记住要初始化变量. 所有有时候不是必须的, 但是省的麻烦.


Question: 求大神指教。帮忙运行一下看看错误在哪，怎么改正

引用 4 楼 qq_18888869 的回复:谢谢 ，你的程序确实正确！能告诉一下我 我的那个程序错误在哪吗。。。十分感谢 嘿嘿，根据你贴的代码，首先有一些编译错误，比方说main函数声明错误、变量重复定义等等 但这些都是很简单的，编译期间的错误你根据编译器的提示来解决的话很方便的 至于如何解决运行期间的错误无非就是各种调式啦

谢谢 ，你的程序确实正确！能告诉一下我 我的那个程序错误在哪吗。。。十分感谢

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

简单测试结果

//仅供参考 //简单的按照楼主的思路修改了下，希望有所帮助(楼主想用的是单向链表吧) #include<stdio.h> #include<string.h> #include<malloc.h>  struct node { 	char name[20]; 	int num; 	char sex[10];//考虑到中文字符男女性，所以改为数组 	int age; 	float score[10]; 	struct node *pNext; };  struct node *g_pHead,*g_pTail;//全局指针类型变量，加了个g_p前缀，个人习惯，嘿嘿  void init_ht() { 	g_pHead=NULL; 	g_pTail=NULL; }  void destory_ht()//添加与init_ht()对应的销毁函数，释放资源,避免内存泄露 { 	struct node* pTemp1=g_pHead; 	while(pTemp1) 	{ 		struct node* pTemp2=pTemp1->pNext; 		free(pTemp1); 		pTemp1=pTemp2; 	} 	g_pHead=NULL; 	g_pTail=NULL; }  void put(struct node *p) { 	if(p!=NULL) 	{ 		if(g_pHead==NULL) 		{ 			g_pHead=p; 		} 		if(g_pTail!=NULL) 		{ 			g_pTail->pNext=p;//将上个尾节点的next指针指向当前节点 		} 		g_pTail=p;//更新尾节点 	} }  void print_node(struct node* p)//打印节点的函数 { 	printf("\n%s\n","=========begin==========");//加个分割线 	printf("name=%s\n",p->name); 	printf("num=%d\n",p->num); 	printf("sex=%s\n",p->sex); 	printf("age=%d\n",p->age); 	printf("scores="); 	for(int i=0;i<10;i++) 	{ 		printf("%f\t",p->score[i]); 	} 	printf("\n%s\n","=========end==========");//加个分割线 }  void input_data() { 	int i; 	char ch; 	struct node *p=NULL; 	while(1) 	{ 		fflush(stdin); 		printf("input data(Y/N):"); 		scanf("%c",&ch);//这里将getch()改为scanf();不然会出问题 		if(ch=='y'||ch=='Y') 		{ 			p=(struct node *)(malloc(sizeof(struct node))); 			memset(p,0,sizeof(struct node));//初始化p中属性，避免未知值 			printf("input name:"); 			scanf("%s",&p->name); 			printf("input num:"); 			scanf("%d",&p->num); 			printf("input sex:"); 			scanf("%s",&p->sex); 			printf("input age:"); 			scanf("%d",&p->age); 			printf("input 10 score:"); 			for(i=0;i<10;i++) 			{ 				scanf("%f",&p->score[i]); 			} 			put(p); 		} 		else 			break; 	} }  void FDname() { 	char name[20]; 	struct node *p; 	printf("input name:"); 	scanf("%s",name); 	p=g_pHead; 	int iCount=0;//统计计数 	while(p!=NULL) 	{ 		if(strcmp(name,p->name)==0) 		{ 			++iCount; 			print_node(p); 		} 		p=p->pNext; 	} 	if(iCount==0) 	{ 		printf("没有该记录！\n"); 	} }  void FDnum() { 	int i,num; 	struct node *p; 	printf("input num:"); 	scanf("%d",&num); 	p=g_pHead; 	int iCount=0;//统计计数 	while(p!=NULL) 	{ 		if(num==p->num) 		{ 			++iCount; 			print_node(p); 		} 		p=p->pNext; 	} 	if(iCount==0) 	{ 		printf("没有该记录！\n"); 	} }  void find_data() { 	char ch; 	while(1) 	{ 		fflush(stdin);//刷新输入缓冲，避免后续输入错误 		printf("1:Find by name\n"); 		printf("2:Find by num\n"); 		printf("3:Exit\n"); 		scanf("%c",&ch); 		switch(ch) 		{ 		case '1': 			FDname(); 			break; 		case '2': 			FDnum(); 			break; 		case '3': 			return; 		} 	} }  void main() { 	init_ht(); 	input_data(); 	find_data(); 	destory_ht(); }


Question: 一道递归函数，把我搞糊涂了

仔细的画图理解就可以了

递归调用与一般调用是不一样的。 函数在调用另一个函数时，会开辟空间生成调用函数栈帧和被调用函数栈帧，调用函数会push保存寄存器如eax，edx，ecx，被调用函数也会push保存寄存器到栈中，比如edi，ebx，esi，ebp，esp，所有的中间值都保存在每一个调用所对应的栈帧中。在调用结束时pop恢复这些寄存器，同时返回到之前保存的调用函数地址，这样一步步逆着原来的顺序返回。 如果是一般的函数调用，就只需恢复寄存器然后执行ret指令返回；但是在递归调用时，除了要恢复寄存器，还要执行一些含有递归意义的指令，否则只是把中间的值保存，而没有利用， 这里  printf("%d", n);         e(--n); 的作用就是把每个保存在栈帧中的值打印出来，然后把这个值减1（n--），再次利用递归把比它小的值按同样的递归方法打印出来此处e(--n)是纯粹的重复递归，似乎意义不大。这两句其实就是你利用递归需要达成的目的。

用笔画画图就能看懂了

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

问题是什么了？

void e(int , int, char*);    int main() { 	int a; 	int count = 0; 	a=3; 	e(a, count, "fist time"); 	system("pause"); } void printFormat(int count) { 	for (int i = 0; i < count; i++) 	{ 		printf("\t"); 	} } void e(int n, int count, char * p) { 	printFormat(count); 	printf("%s第%d层入口\n", p, count); 	if(n>0) 	{ 		count++; 		e(--n, count, "before print"); 		printFormat(count - 1); 		printf("printing第%d层值%d\n", count-1, n); 		e(--n, count, "after print"); 		count--; 	} 	printFormat(count); 	printf("%s第%d层出口\n", p, count); 	count--; }


Question: c语言for语句与if语句的嵌套使用

这种问题太低端了，大神都不愿意解决

这跟一下不就知道了?

单步调试就知道了。

单步调试吧...

这种问题不是走一下编译器 调试一下就OK的么....

我大概看懂了，不是只循环了一遍，而是每次循环都是在给a[i][j]，i=n-1,j=n-1,赋值，但是n 的值没变，所以你的数组就只有一个值其他的都是0

楼主代码的目的是什么

你猜~~~~~~~~~~~~

循环的次数由你输入的n的大小决定的啊~~~向赵四老师致敬，多单步试试。。。

VC6不象后来的VS，总是无端地臃肿、无端地保留或封装功能、无端地升级、……

输入的n是多少？

VS编译器，何其强大，会用工具，是一个程序员的基本功

引用 2 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  赵老湿， C发展到今天， VS已经无法应对。 不， 不是无法应对， 是Microsoft公司不愿应对， MOFT公司自己都说从VC6之后， 不再支持新的C语言标准， 为什么您老 向学生们推荐VS 这里是C语言版块 你个老家伙居心何在？ 唵？ 嘎嘎~~~~~~


Question: 关于2维数组的

从内存的角度 a[0][0]  a[0][1] a[0][2] a[1][0].....a[2][2]的顺序排布。 所以a[0],a[0][0]的地址只是一样。

a[3][3]  我是这么理解的：a[0]内，装着数组{ a[0][0]、a[0][1]、a[0][2] }的地址 而a代表的是a[0]的地址。

引用 8 楼 Beinggeeks 的回复:[quote=引用 4 楼 sholber 的回复:] 你为啥要关注a的地址？ C用类型来理解足够， 不需要地址。 你是垃圾书的受害者。 珍惜生命，远离坏书，抛弃地址。我一直觉得C语言的本质就是地址[/quote]  如果你是认真的， 那么， 你保留你的认识和感觉。 如果你的眼神里有疑惑， 那么， 我们可以继续讨论。

引用 4 楼 sholber 的回复:你为啥要关注a的地址？ C用类型来理解足够， 不需要地址。 你是垃圾书的受害者。 珍惜生命，远离坏书，抛弃地址。我一直觉得C语言的本质就是地址

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

引用 1 楼 user-6 的回复:相当于是{ { 1,2,3} 的地址 (不知道这么说对不对) b -> { { 1,2,3} , { 4,5,6},{7,8,9}}; b++之后 b->{  { 4,5,6},{7,8,9}}; 所以b[0][0]是4, b[1][1]是7 b[1][1] = 9之后变成{ { 1,2,3} , { 4,5,6},{9,8,9}}; b[0][0][0]是4，但是b[1][1]是8哦。  b[1][1] = 9之后变成{ { 1,2,3} , { 4,5,6},{7,9,9}}

你为啥要关注a的地址？ C用类型来理解足够， 不需要地址。

引用 1 楼 user-6 的回复:相当于是{ { 1,2,3} 的地址 (不知道这么说对不对) b -> { { 1,2,3} , { 4,5,6},{7,8,9}}; b++之后 b->{  { 4,5,6},{7,8,9}}; 所以b[0][0]是4, b[1][1]是7 b[1][1] = 9之后变成{ { 1,2,3} , { 4,5,6},{9,8,9}}; b[1][1]是8的位置, { { 1,2,3} , { 4,5,6},{7,9,9}};


Question: 函数 传指方式，得不到相应的值，咋回事？

看代码没看出问题来，会不会别的地方内存溢出了。检测下没贴出来的代码。

recv_data[i]=*(volatile unsigned int *)FPGA_READ;   把volatile 去掉试试看。

引用 1 楼 user-4 的回复:recv_data[i]=*(volatile unsigned int *)FPGA_READ;     函数中指针类型改变，操作的内存空间也变了  不是这个原因

单步调试一下吧


Question: 为什么用pow函数计算结果有误？少了一个水仙花数，费解

运行时库的pow()的精度有问题？基本上该换掉了…… 不换的话，本题中可将所有pow()的返回值或者它们的总和手动四舍五入到整数后再与n比较。

pow()函数的第一个参数好像不能是int型的，你把它强制转换成double型再把返回值强制转换成int型试试。

引用 6 楼 zhao4zhong1 的回复:if(n==pow(n/100,3)+pow(n%100/10,3)+pow(n%10,3)) 改为 if(1E-6<fabs(n-(pow(n/100,3)+pow(n%100/10,3)+pow(n%10,3))) 纠正楼上 if(1E-6>fabs(n-(pow(n/100,3)+pow(n%100/10,3)+pow(n%10,3)))

double pow( double x, double y );  http://bbs.csdn.net/topics/390676437

he pow(int, int) overload is no longer available. If you use this overload, the compiler may emit C2668. To avoid this problem, cast the first parameter to double, float, or long double.

这个算法还是不要用浮点运算吧  int main(int argc, char *argv[]) {     int i, n;     int d1, d2, d3;      i = 0;     for (n = 100; n < 1000; n++) {         d1 = n % 10;         d2 = n % 100 / 10;         d3 = n / 100;         if (n == d1*d1*d1 + d2*d2*d2 + d3*d3*d3) {             i++;             printf("%d\n", n);         }     }     printf("%d\n", i);      return 0; }


Question: #define的一点问题

楼主的问题，归根结底是不懂得预处理。学一下预处理即可。 楼上还有人说用const限定的类型，其对象位于.rdata 实际上位于哪里并不重要。这样的理解已经本末倒置。 引入const，只是一种优化提示， 是你用const告诉编译器，你并不准备修改一个对象的值。这是你对编译器的保证，编译器接受你的保证，优化代码。 现在的情况是， 有些人并不了解const的语义，在他们那里const变成了一种攻防关系。于是，他自己声明了一个const限定类型的对象，然后又想着能不能修改它，这不是很荒谬吗？？

你打印的是C啊，写错了！

const 是在编译时确定的内存大小，定义一个const ，编译时内存中是要为这个变量分配存储位置的，一般的exe文件多半是在 .rdata节，并将初始值赋给这块区域。 define是一个字符串替换，打个比方 ：   # define x  class x y {  int m;  int n; };  则编译时x 会被替换成class字符串，源代码就变成了：  class y {  int m;  int n; };  define 只是个编译器命令，不分配内存的，你宏定义出来的2 是直接硬编码进二进制文件，不进行内存操作。 看看这篇博客就知道了： http://blog.csdn.net/u012842205/article/details/40452799

const     effective C++不是说了吗，跟编译时提示有关，define在预处理时已经换成具体值了，如果有问题没有任何提示。

哥哥，c的值一直是0……你看你打印那里，define定义的还是可以加减啊！

打印错误，你打印的一直都是c的值，所以一直都是0！

VC编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

printf_s("二维数组的平均值为%f\n",c);这里打印的是c的值，c的值没有变过当然为0啊。你是想打印b的值吧：printf_s("二维数组的平均值为%f\n",b); #define是宏定义，在预处理阶段就进行宏替换了，比如你这个程序在预处理阶段时就把这个源文件中所有NUM1都替换成了2.0，NUM2都替换成3.0，之后才进行编译。而const是声明常量，被const声明的变量占用内存空间，而#define没有，const有类型检查，而#define仅仅做了替换没有类型检查

你的c的值不是一直是0么    没赋其他值啊


Question: 求助（新手）

仅供参考：#include <algorithm> #include <iostream> #include <functional> #include <cstring> using namespace std; int main() {     char *Alphabet = "abcdefghijklmnopqrstuvwxyz" ;     char *Vowels   = "aeiou" ;     char *AlphaNum = "0123456789abcdef" ;     char result[45] ;     char *last ;      int lenA  = strlen(Alphabet) ;     int lenV  = strlen(Vowels  ) ;     int lenAN = strlen(AlphaNum) ;      cout << "Alphabet = " << Alphabet << endl ;     cout << "Vowels   = " << Vowels   << endl ;     cout << "AlphaNum = " << AlphaNum << endl ;      cout << "\nusing non-predicate versions" << endl ;      //non-predicate set_difference     last = set_difference(Alphabet, Alphabet+lenA,                           AlphaNum, AlphaNum+lenAN,                           result) ;     *last = 0 ;     cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;      //non-predicate set_intersection     last = set_intersection(Alphabet, Alphabet+lenA,                             AlphaNum, AlphaNum+lenAN,                             result) ;     *last = 0 ;     cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;      //non-predicate set_symmetric_difference     last = set_symmetric_difference(Alphabet, Alphabet+lenA,                                     Vowels  , Vowels  +lenV,                                     result) ;     *last = 0 ;     cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;      //non-predicate set_union     last = set_union(Alphabet, Alphabet+lenA,                      AlphaNum, AlphaNum+lenAN,                      result) ;     *last = 0 ;     cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;      cout << "\nusing predicate versions" << endl ;      //predicate set_difference     last = set_difference(Alphabet, Alphabet+lenA,                           AlphaNum, AlphaNum+lenAN,                           result  , less<char>()) ;     *last = 0 ;     cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;      //predicate set_intersection     last = set_intersection(Alphabet, Alphabet+lenA,                             AlphaNum, AlphaNum+lenAN,                             result  , less<char>()) ;     *last = 0 ;     cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;      //predicate set_symmetric_difference     last = set_symmetric_difference(Alphabet, Alphabet+lenA,                                     Vowels  , Vowels  +lenV,                                     result  , less<char>()) ;     *last = 0 ;     cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;      //predicate set_union     last = set_union(Alphabet, Alphabet+lenA,                      AlphaNum, AlphaNum+lenAN,                      result  , less<char>()) ;     *last = 0 ;     cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;      return 0 ; }

那怎么得到数组a和数组b中你初始化的个数？

m=strlen(x); n=strlen(y); 是得不到数组a和数组b中你初始化的个数的。

（1）creat里面int * c，只定义了一个指针，没有分配空间，所以不能使用c[u]。 （2）返回的指针如果是指向函数内部分配的变量，在函数返回后内存被释放，指针指向的内存被释放了。 （3）如果要想返回数组，可以在函数外面定义数组，并且通过参数返回，例如： int a[100],b[100],c[100]. void creat(int *x,int *y, int *z);