Mxode/CSDN-C_Language-2013_2023 huggingface dataset:
user-0 提问: 求解释这一段代码，说明需要测试的功能点

回复:
user: user-1
content: static void TSP_Proc_Main_Step_2(void) { GM_BOOL rt = GM_FALSE; /*CR:TSP00002604 应用运行时间*/ GM_UINT32 startTime = 0U; GM_UINT32 endTime = 0U;  /*CR:TSP00002604 应用运行时间*/ startTime = GM_CurrentTimestamp((GM_UINT8)(1U)); /*add by joseph 20120917,备系要进行数据同步，所以要learn*/  if((GM_FALSE == TSP_State_Interface_Is_Active(GM_FALSE)) && (TSP_STATE_DATA_SYN_OK == TSP_State_Interface_Get(TSP_STATE_TYPE_SELF_CUR_DATA_SYN))) {  /* Initialize();*/ /*CR:TSP00001802 删除 20121204 ironMan*/ /*CR:TSP00001720 20121119 ironMan*/ #ifndef TSP_MPS_MPU_TST_YWB_256K  TSP_Interface_Learn();  /*CR:2286 20130513 OO,若TSP_App_Syn_RxData.trxFlag为false，则置自身不同步*/  if(GM_FALSE == GetTrxFlagStatus())  {  	/*设置自身数据不同步*/  TSP_State_Interface_Set(TSP_STATE_TYPE_SELF_CUR_DATA_SYN, TSP_STATE_DATA_SYN_NOT);   } #endif  TSP_Interface_Reset_Syn_RxProc(); }       TSP_Interface_Main_Proc();      /*add by joseph 20120917,主系要向备系发送同步数据，所以要teach*/     if(GM_TRUE == TSP_State_Interface_Is_Active(GM_FALSE))     {     	TSP_Interface_Reset_Syn_TxProc();/*cr:2241*/     	TSP_Interface_Teach();     }  rt = TSP_Interface_RXMQ_Clear();/*错误处理已在函数中*/ if (GM_FALSE == rt) { TSP_ErrProc_Safefault_Proc(); }  /*CR:TSP00002604 应用运行时间*/ endTime = GM_CurrentTimestamp((GM_UINT8)(1U));        g_globalinfo_struct.g_app_run_time = GM_TimestampInterval(endTime,startTime);  rt = TSP_TASK_CHECK(g_globalinfo_struct.g_VSN1, 2U); if(GM_FALSE == rt) { TSP_ErrProc_Interface_Add(MAINPROC_ERROR_TASK_SLOT2); TSP_ErrProc_Safefault_Proc(); }  bFlag = GM_TRUE;  return; }

user: user-2
content: 爱莫能助，帮顶！！！！！！！！
user-0 提问: 字符串常量给字符指针赋值问题

回复:
user: user-1
content: 再啰嗦一句，c++里面的标准写法是 const char *p = “abcd”;  // const表示不会修改p指向的内容，也就是*p 如果写 char *p = “abcd"; 编译器可能会给警告。

user: user-1
content: 首先，编译器在常量区保存一个字符串abcd，其内容不许修改。 char *p = "abcd"; // p是一个指针，直接指向常量区，修改p[0]就是修改常量区的内容，这是不允许的。 char p[] = "abcd"; // 编译器在栈上创建一个字符串p，把abcd从常量区复制到p，修改p[0]就是修改一个局部变量，这是允许的。 更多详细解释请楼主搜索“常量区”

user: user-1
content: 改成 char p[] = "abcd";

user: user-2
content: 因为指针值指的是"abcd"的内存地址，它是常量，不允许修改。

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

user: user-4
content: 应该编译通不过吧 常量区域的数据不能被修改的，只读的
user-0 提问: 菜鸟一枚，麻烦大家帮忙看下哪错了。

回复:
user: user-1
content: 1，scanf()在读取时不检查边界，所以可能会造成内存泄露。所以vc++2005/2008中提供了scanf_s(),在最新的VS2013中也提供了scanf_s()。在调用时，必须提供一个数字以表明最多读取多少位字符。 2，for (m = 0; m < 10; m++);//for循环后多了一个分号

user: user-2
content: 引用 2 楼 w673339759 的回复:注意细节+1+2

user: user-3
content: 为什么会多个分号。。

user: user-4
content: 引用 7 楼 sagittarius_520 的回复: 	printf("输入这次百米跑的秒数：（10个人）\n"); 	for (m = 0; m < 10; m++)			//多输入了一个分号 	{ 		scanf("%f", &n[m]);				//这个不是系统C库函数，最好别用这个输入。 		 		if (n[m] >= 13.00)     //不合格 			a++;  		if (n[m]<13.00 && n[m]>12.00) 			b++;         //合格 		if (n[m] <= 12.00) 			c++;        //优秀 	}   心细很重要。。。。

user: user-5
content: 引用 7 楼 sagittarius_520 的回复: 	printf("输入这次百米跑的秒数：（10个人）\n"); 	for (m = 0; m < 10; m++)			//多输入了一个分号 	{ 		scanf("%f", &n[m]);				//这个不是系统C库函数，最好别用这个输入。 		 		if (n[m] >= 13.00)     //不合格 			a++;  		if (n[m]<13.00 && n[m]>12.00) 			b++;         //合格 		if (n[m] <= 12.00) 			c++;        //优秀 	}  scanf_s这个不是系统C库函数，最好别用这个输入。

user: user-5
content: printf("输入这次百米跑的秒数：（10个人）\n"); 	for (m = 0; m < 10; m++)			//多输入了一个分号 	{ 		scanf("%f", &n[m]);				//这个不是系统C库函数，最好别用这个输入。 		 		if (n[m] >= 13.00)     //不合格 			a++;  		if (n[m]<13.00 && n[m]>12.00) 			b++;         //合格 		if (n[m] <= 12.00) 			c++;        //优秀 	}

user: user-6
content: for (m = 0; m < 10; m++);//去掉分号，for循环这里不需要分号

user: user-7
content: 用IDE编译的时候，不通过一定会有提示信息的……照着报错位置推敲就好了啊……

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

user: user-9
content: scanf_s("%f", &n[m]);//输入是scanf 直接写成scanf("%f", &n[m]);即可

user: user-10
content: 注意细节+1

user: user-11
content: for (m = 0; m < 10; m++); //多了个分号 {     scanf_s("%f", &n[m]);
user-0 提问: 内核模块加载

回复:
user: user-0
content: root@ubuntu:~# uname -a Linux ubuntu 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:39:31 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux   感谢指点。。。
user-0 提问: 二叉搜索树删除结点操作，算法找不出问题，调试也没看明白

回复:
user: user-1
content: t = set_up(t);//不写这样的代码会怎么样？ 你除了将变量命名为t之外，你还会想到用其它的名字吗？把t全部改掉，不同的地方用不用的变量名。然后 再测试。

user: user-2
content: 目测代码太乱，而且本人不会改。。。

user: user-3
content: 代码太乱，没有全部看完  struct node *set_up(struct node *t) { int a; scanf("%d", &a); if (a == 0) { t = NULL;                // t是一个临时变量，在这里设置t = NULL没有任何意义，楼主的本意应该是将t设置为NULL，那么参数应该传递struct node **t ，这里应该改为*t = NULL } else { t = (struct node *) malloc(sizeof(struct node));      // 这个t申请后应该设置t->left和t->right 为NULL，否则后面操作这两个节点会出现异常，因为malloc不会对内存初始化 if (t == NULL) { exit(1); } t->key = a; printf("insert the left of %d: ", t->key); t->left = set_up(t->left); printf("insert the right of %d: ", t->key); t->right = set_up(t->right); } return t; }
user-0 提问: C语言、关于二分查找的问题。

回复:
user: user-0
content: 引用 2 楼 lovesmiles 的回复:函数内部已经将参数变成int * 计算sizeof（int*）和sizeof（int[]）是不一样的，前者是指针类型的大小，无论它指向什么都是不变的。 后者是数组的长度。  所以不能够用这个计算函数参数的长度。因为类型已经被函数转换了。这样啊，那我先在main函数中计算好，再传过去吧。

user: user-1
content: 函数内部已经将参数变成int * 计算sizeof（int*）和sizeof（int[]）是不一样的，前者是指针类型的大小，无论它指向什么都是不变的。 后者是数组的长度。  所以不能够用这个计算函数参数的长度。因为类型已经被函数转换了。

user: user-2
content: void* bsearch (const void* key, const void* base,                size_t num, size_t size,                int (*compar)(const void*,const void*));
user-0 提问: AD按键扫描程序

回复:
user: user-1
content: 继续继续，，，期待哪位大神贡献好代码。

user: user-2
content: 啥叫AD按键扫描？

user: user-3
content: 对于这种刚发的帖子，我总是毫不犹豫的顶了。如果火了就是个前排，可以混个脸熟，说不定谁好心就给粉了…稳赚不赔；如果沉了就感觉是我弄沉的，很有成就感，还能捞经验。
user-0 提问: 关于后自加的问题

回复:
user: user-0
content: 有点明白了，谢谢。

user: user-1
content: 前面使用过有关系吗？使用后自增只限定在当前语句

user: user-0
content: 谢谢两位的讲解。 第45句之前，while和if调用low，这是不是相当于已经使用过low了？

user: user-2
content: a[low++] = a[high]; 等价于  a[low] = a[high];low++;

user: user-1
content: 第45行，low的值不变 第47行，low的值已经加1了
user-0 提问: 有没有什么函数能播放resource.rc里的mp3文件？

回复:
user: user-1
content: 请通读MSDN中Resources相关章节。

user: user-1
content: Finding and Loading Resources Before using a resource, an application must load it into memory. The FindResource and FindResourceEx functions find a resource in a module and return a handle to the binary resource data. FindResource locates a resource by type and name. FindResourceEx locates the resource by type, name, and language. Information about FindResource in this topic also applies to FindResourceEx.   The LoadResource function uses the resource handle returned by FindResource to load the resource into memory. After an application loads a resource by using LoadResource, the system automatically unloads and reloads the resource as memory conditions and application execution require. Thus, an application need not explicitly unload a resource it no longer needs.   An application can use FindResource and LoadResource to find and load any type of resource, but these functions should be used only if the application must access the binary resource data for subsequent function calls. To use a resource immediately, an application should use one of the following resource-specific functions to find and load resources in one call.   Function Action  FormatMessage Loads and formats a message-table entry.  LoadAccelerators Loads an accelerator table.  LoadBitmap Loads a bitmap resource.  LoadCursor Loads a cursor resource.  LoadIcon Loads an icon resource.  LoadImage Loads an icon, cursor, bitmap, or enhanced metafile resource.  LoadMenu Loads a menu resource.  LoadString Loads a string-table entry.    Before terminating, an application should release the memory occupied by accelerator tables, bitmaps, cursors, icons, and menus by using one of the functions in the following table.   Resource Release function  Accelerator table DestroyAcceleratorTable  Bitmap DeleteObject  Cursor DestroyCursor  Icon DestroyIcon  Menu DestroyMenu    When the application terminates, the system automatically releases the memory occupied by the other types of resources.

user: user-0
content: 引用 3 楼 zhao4zhong1 的回复:先将这个mp3资源写到磁盘文件tmp.mp3中，然后ShellExecute这个tmp.mp3播放。 哦 今天刚接触这个 请问如何找到资源文件的指针呢？ 这样就可以用fwrite写入了。。。

user: user-2
content: 你要用第三方库。系统没有API可以放MP3.

user: user-1
content: 先将这个mp3资源写到磁盘文件tmp.mp3中，然后ShellExecute这个tmp.mp3播放。

user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:保存为临时文件tmp.mp3 然后ShellExecute这个tmp.mp3 ? 我只想做成一个exe文件 然后在里面播放一首歌  wav的文件太大了 MP3还行 但是不知道怎么弄。。

user: user-1
content: 保存为临时文件tmp.mp3 然后ShellExecute这个tmp.mp3 ?
user-0 提问: 线索二叉树在遍历上的优势到底在哪？

回复:
user: user-1
content: 一个是均摊O(1)，一个是最坏O(1)。在对latency有要求的情况下当然要后者。

user: user-2
content: MSDN98 mk:@MSITStore:C:\MSDN98\98VS\2052\vccore.chm::/html/_core_types_of_profiling.htm   Types of Profiling Home |  How Do I |  Details  Feature Only in Professional and Enterprise Editions   Profiling is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.  The profiler can analyze the execution of your code with two levels of detail:   Function Profiling is good for detecting inefficient code. Function profiling is faster than line profiling because there is less information to collect.  Line Profiling can be useful for checking the validity of an algorithm because it shows how many times each line is executed in response to certain input data. Line profiling also lets you see which lines aren’t executed at all.

user: user-3
content: 引用 2 楼 zhao4zhong1 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！ profiler 英 ['prəʊfaɪlə(r)] 美 ['proʊfaɪlə(r)]  n. 靠模工具机；仿形铣床；仿形工   网 络  效能评测器； 软件； 仿形铣床； 靠模铣床 赵老师，这个单词此处做何解释？

user: user-4
content: 评价一个算法的好坏除了可行性，就是时间复杂度和空间复杂度，尽管时间复杂度一样，那线索二叉树在遍历上的优势就是节省了空间 我的智能创意，请您支持一下，谢谢！

user: user-5
content: 我觉得可能是因为递归对程序而言是份很大的开销，所以才选择线索二叉树。

user: user-6
content: 看wiki吧 http://en.wikipedia.org/wiki/Threaded_binary_tree 实际上 O() 是一个很粗糙的复杂度定义，因为它表示的是最差情况下的开销，并且忽略了常数因子。它适用于理论讨论中还好些，对于实践应用有时候就会有很大的偏差。在实践应用场合，一个O(n^2)的算法快过O(n)都很正常。

user: user-0
content: 哎~   还是新手~   对自己的想法和观点还是不那么肯定，但是觉得书上不对也不想盲目相信，只好到处问了，谢谢各位了

user: user-2
content: 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

user: user-7
content: 二叉树的线索化
user-0 提问: 为什么结构体中有指针类型就不能用“=”赋值了

回复:
user: user-1
content: 当结构体中有指针时,  它只复制了指针, 但那个指针指向的地址中的数据还是没有变.  struct myStruct {      char * buf; };  myStruct st1, st2; char *pBuf = new char[10]; st1.buf = pBuf;  memcpy(&st2,&st1, sizeof(myStruct));   //这时st1.buf和st2.buf都指向pBuf.  //在某个地方 delete st1.buf;  //删除掉pBuf st1.buf = NULL;  //在另一个地方 st2.buf[0]  = 'a';  //crash.  因为指针相同, 这里就是野指针了. 所以这样的直接memcpy是内存不安全的.

user: user-2
content: 百度搜 “深拷贝，浅拷贝”

user: user-3
content: 引用 楼主 xhw88398569 的回复:不理解为什么，使用memcpy呢?  直接指针可以的，相当于复制了一个地址，前提要确保指针所指的内存块还安全

user: user-3
content: #include<stdio.h>  struct test { 	int a; 	int b; 	int c; };  int main() { 	struct test t1,t2; 	struct test* p2; 	p2=&t2;  	t1.a=1; 	t1.b=2; 	t1.c=3;  	*p2 = t1;  	printf("%d,%d,%d",t2.a,t2.b,t2.c);  	return 0; }      没问题啊 指针也可以有 = 而不用memcpy啊

user: user-4
content: 能不能用这个要看你的实际意图了。POD类型的结构体，“=”表现出来的都是按位copy。。直接结果就是浅拷贝，如果你能接受那就没问题。

user: user-5
content: 指针理解为能打开某个抽屉（内存）的钥匙，指针“=”意味着复制（重新配）了一把某个抽屉的钥匙，如果以抽屉中的东西改变作为内存销毁（理解为回收或不归你使用更好一些），如果有人用一把钥匙拿走了里边的东西（你是不知情的），你用“=”来的钥匙再想拿是不行的。

user: user-6
content: 能赋值，只不过指针分量的值不是你所期望的值而已。

user: user-7
content: 指针变量和其他的变量一样，都是可以使用=赋值的。

user: user-7
content: 因为在指针=赋值的时候，你期望的不是这个指针变量被赋值，而是她指向的内容被复制。

user: user-0
content: 引用 1 楼 user-8 的回复:每个数据都是一个箱子，每个指针都是一个号码，这个号码对应另一个箱子 其他类型的数据用=复制时，从一个箱子变成两个相同的箱子 指针用=复制时，从一个号码变成两个相同的号码——不管变成多少个，相同的号码永远对应同一个箱子，当一个人去砸这个号码对应的箱子的时候，另一个持有相同号码的人不可能当作没看见明白了，可以赋值，但是他们的指针成员指向的内存空间都是同一个。谢了。。

user: user-8
content: 每个数据都是一个箱子，每个指针都是一个号码，这个号码对应另一个箱子 其他类型的数据用=复制时，从一个箱子变成两个相同的箱子 指针用=复制时，从一个号码变成两个相同的号码——不管变成多少个，相同的号码永远对应同一个箱子，当一个人去砸这个号码对应的箱子的时候，另一个持有相同号码的人不可能当作没看见
user-0 提问: 关于希尔排序的分段问题

回复:
user: user-0
content: 引用 1 楼 bubu8633 的回复:源码贴出来看看  在楼上

user: user-0
content: 源码贴出来，不过是用JAVA写的 原文在：https://d396qusza40orc.cloudfront.net/algs4partI/slides%2F21ElementarySorts.pdf    第42页  public static void shellSort(int[] arr) { 		int len = arr.length; 		int h = 1; 		while (h < len / 3) { 			h = 3 * h + 1; 		} 		while (h >= 1) { 			for (int i = h; i < len; i++) { 				for (int j = i; j >= h && arr[j] < arr[j - h]; j -= h) { 					int temp = arr[j]; 					arr[j] = arr[j - h]; 					arr[j - h] = temp; 				} 			} 			h /= 3; 		} 	}

user: user-1
content: 3n+1 这个序列的数据，排一下看： 3*1+1 =3 是质数 3*2+1 =7 是质数 3*3+1 =10 是和数，但是跟7互质 3*5+1 =16 是和数 3*6+1 =19  是质数，跟16 互质 3*7+1 =22 是和数，跟19 互质 3*8+1 =25 是和数 ，跟22互质 3*9+1 =31 是质数  这个序列，有大量的质数，并且，大部分相邻的两个数，是互质的 2^n 几乎都是和数，并且相邻的两个数都不是互质的。  所以关于希尔排序， 这个增量序列比2^n 要快 如果，这个增量序列，每个数都是质数，还要更快。  具体原因，请看算法导论，或者其他算法类书籍。

user: user-2
content: 源码贴出来看看
user-0 提问: 新手，求大神解惑

回复:
user: user-0
content: 我的QQ407854730 哪位老师加我给讲解下 跪谢了

user: user-0
content: 你看 if (year>2000)    d=(year-1-2000)/4-(year-1-2000)/100+(year-1-2000)/400+1;    else     d=(year-2000)/4-(year-2000)/100+(year-2000)/400;    dy=(year-2000)+d;     /*** 该年 1月1号 到2000年1月1号的 " 星期差 " ***/  它是先/4，然后/100，然后/400 最后d不是整数了吧而且d是闰年和平年综 合的一个差吧 ，怎么这样算的呢

user: user-1
content: 一年≈365.2425天

user: user-2
content: 万年历主要理解这两点: 1、判断是不是闰年 (year%4!=0||year%100==0&&year%400!=0)满足条件就是平年，把一年中的所有月份分为四类（28，29，30，31）。  2 、 求出 一年 中的 第一 天是 周 几  (year  +(year-1)/4-(year-1)/100+(year-1)/400)%7。  其他都简单了.
user-0 提问: C程序变量如何赋值。。

回复:
user: user-1
content: memset函数的作用只是用来清空数组的值，将数组中所有元素全部写为0.所以你想要写死一个值就可以直接用赋值语句就好了，或者调用字符串拷贝函数也可以。但是为了不出现一些错误的数据，所以在对一些重复使用到的同一个数组需要进行清零操作，防止下次输出的时候输出了一部分上一次残留在数组中的元素。

user: user-2
content: “变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。

user: user-3
content: GetWorkDate(prtdate);    /* 打印日期 */ 替换成 strcpy(prtdate, "YYYYMMDD");

user: user-4
content: char prtdate[8+1] = "20140805";  好吧我是来接分的

user: user-5
content: 引用 1 楼 lisong694767315 的回复: char prtdate[8+1] = "20140805"; +1

user: user-6
content: 将GetWorkDate(prtdate); 替换成下面的一句： sprintf(prtdate,"%s","20140805");

user: user-0
content: 引用 1 楼 lisong694767315 的回复: char prtdate[8+1] = "20140805";  额，不用做memset这累操作么？

user: user-7
content: char prtdate[8+1] = "20140805";
user-0 提问: 冒泡排序法

回复:
user: user-1
content: 引用 3 楼 chlth007 的回复:[quote=引用 1 楼 zjq9931 的回复:] 改了，理清思路是关键。 一遍不行，就再练一遍。  #include<stdio.h> main() { 	int t,i,j,a[5]; 	printf("input number of data:\n"); 	for(i=1;i<=5;i++) 		scanf("%d",&a[i]); 	for(i=1;i<5;i++) 	{ 		for(j=i; j<5; j++) 			if(a[j]>a[j+1]) 			{ 				t=a[j]; 				a[j]=a[j+1]; 				a[j+1]=t; 			} 	} 	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	printf("\n"); } 我把你的运行了也不行啊 [/quote] 确实我的也错了。唉，我也粗心了。。。 有我的原因，还有另外一个原因：越界了。 下面是改好的代码：   #include<stdio.h> main() { 	int t,i,j,a[7]; 	printf("input number of data:\n"); 	for(i=1;i<=5;i++) 		scanf("%d",&a[i]);  	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	puts(""); 	for(i=1;i<5;i++) 	{ 		for(j=i+1; j<=5; j++) 		if(a[i]>a[j]) 		{ 			t=a[i]; 			a[i]=a[j]; 			a[j]=t; 		} 	} 	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	printf("\n"); }

user: user-0
content: 引用 1 楼 zjq9931 的回复:改了，理清思路是关键。 一遍不行，就再练一遍。  #include<stdio.h> main() { 	int t,i,j,a[5]; 	printf("input number of data:\n"); 	for(i=1;i<=5;i++) 		scanf("%d",&a[i]); 	for(i=1;i<5;i++) 	{ 		for(j=i; j<5; j++) 			if(a[j]>a[j+1]) 			{ 				t=a[j]; 				a[j]=a[j+1]; 				a[j+1]=t; 			} 	} 	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	printf("\n"); } 我把你的运行了也不行啊

user: user-2
content: 引用 1 楼 zjq9931 的回复:改了，理清思路是关键。 一遍不行，就再练一遍。  #include<stdio.h> main() { 	int t,i,j,a[5]; 	printf("input number of data:\n"); 	for(i=1;i<=5;i++) 		scanf("%d",&a[i]); 	for(i=1;i<5;i++) 	{ 		for(j=i; j<5; j++) 			if(a[j]>a[j+1]) 			{ 				t=a[j]; 				a[j]=a[j+1]; 				a[j+1]=t; 			} 	} 	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	printf("\n"); }   +1！理清思路是关键！

user: user-1
content: 改了，理清思路是关键。 一遍不行，就再练一遍。  #include<stdio.h> main() { 	int t,i,j,a[5]; 	printf("input number of data:\n"); 	for(i=1;i<=5;i++) 		scanf("%d",&a[i]); 	for(i=1;i<5;i++) 	{ 		for(j=i; j<5; j++) 			if(a[j]>a[j+1]) 			{ 				t=a[j]; 				a[j]=a[j+1]; 				a[j+1]=t; 			} 	} 	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	printf("\n"); }

user: user-0
content: 引用 4 楼 zjq9931 的回复:[quote=引用 3 楼 chlth007 的回复:] [quote=引用 1 楼 zjq9931 的回复:] 改了，理清思路是关键。 一遍不行，就再练一遍。  #include<stdio.h> main() { 	int t,i,j,a[5]; 	printf("input number of data:\n"); 	for(i=1;i<=5;i++) 		scanf("%d",&a[i]); 	for(i=1;i<5;i++) 	{ 		for(j=i; j<5; j++) 			if(a[j]>a[j+1]) 			{ 				t=a[j]; 				a[j]=a[j+1]; 				a[j+1]=t; 			} 	} 	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	printf("\n"); } 我把你的运行了也不行啊 [/quote] 确实我的也错了。唉，我也粗心了。。。 有我的原因，还有另外一个原因：越界了。 下面是改好的代码：   #include<stdio.h> main() { 	int t,i,j,a[7]; 	printf("input number of data:\n"); 	for(i=1;i<=5;i++) 		scanf("%d",&a[i]);  	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	puts(""); 	for(i=1;i<5;i++) 	{ 		for(j=i+1; j<=5; j++) 		if(a[i]>a[j]) 		{ 			t=a[i]; 			a[i]=a[j]; 			a[j]=t; 		} 	} 	for(i=1;i<=5;i++) 		printf("a[%d]=%d\n",i,a[i]); 	printf("\n"); } [/quote]谢谢，我刚学编程两个星期，有好多地方还不太清楚。
user-0 提问: 这段代码的实际内存使用量为什么与预计的

回复:
user: user-0
content: 终于知道问题所在了。  正如6楼提到的第二点，malloc分配出来的实际空间会比参数指定的size还要多出一点点。如果malloc的次数少还发现不到这问题，可一旦malloc的次数十分巨大时，那些多出来的“碎片”加起来就变得十分可观了。  最后我采用的方法是预先malloc出一大片空间池，以后每次需要申请内存保存数据的话，就把指针指向那片空间池对应的位置把数据保存到里面。这样程序运行时实际使用的内存量就和之前估算的差不多了。

user: user-0
content: 引用 6 楼 FancyMouse 的回复:一般会有两种浪费。 1. 这种大规模小size的内存分配正常都不会给你正好分配这个size的内存的。你得去看你的C运行库代码，看看比如是不是会对9字节的malloc请求给你实际分配了16字节。我印象里的glibc把小size内存的malloc给向上取整到2幂次，那么9字节就实际分配16字节，20字节就实际分配32字节，直接就多出来(7+12)*300w=57MB了。当然具体数字因情况而异，但是正常情况下这类浪费肯定有。大块malloc这类浪费忽略不计，但是小的肯定不行。 2. 每一块malloc的内存，在那个指针的前面，allocator会存储一些关于这块内存是如何分配的这种信息，以便它free的时候使用。具体也是要看allocator怎么写，不过正常都在8~16字节左右。每块malloc的空间都会有。这也是为什么越界经常会导致崩溃……因为这块数据被破坏了allocator就不知道该怎么free这块内存了。如果算它8字节，这里就有8*300w*3=72MB了。  所以即使通用allocator再厉害，自己做内存池的理由还是有很多的，这就是其中一个。 刚刚试用VS2010和DevCPP编译同一份代码，发现编译出来的程序在运行时使用的内存量貌似真的有很大的差异呢。  请问有没有什么编译器推介一下，可以让生成的程序占用较小的内存？ 谢谢！

user: user-1
content: 几个建议： 1、编译器换最新的VS 2013 或者 gcc 4.9.x 2、把malloc内存的操作全部替换掉，改成C++ 0x11的 vector 和 tuple 组合 3、算法似乎可以优化，但不知道你的具体需求。

user: user-0
content: 引用 3 楼 user-6 的回复:1. 没算name的20个字节 2. 没算栈 name的20个字节已经包含了（见估算过程的第3点），共占用20Byte * 100万 * 3 = 57.22MB。 至于栈的空间，这应该怎么算呢？会造成2-3倍的内存空间差异吗？

user: user-2
content: 我的意思是，程序需要占用264.19MB的内存是不是都由这个无向图占用的。比如，如果10万条记录要用30M，那就是；如果10万条记录占用150M，那就不是。

user: user-3
content: VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533

user: user-4
content: 一般会有两种浪费。 1. 这种大规模小size的内存分配正常都不会给你正好分配这个size的内存的。你得去看你的C运行库代码，看看比如是不是会对9字节的malloc请求给你实际分配了16字节。我印象里的glibc把小size内存的malloc给向上取整到2幂次，那么9字节就实际分配16字节，20字节就实际分配32字节，直接就多出来(7+12)*300w=57MB了。当然具体数字因情况而异，但是正常情况下这类浪费肯定有。大块malloc这类浪费忽略不计，但是小的肯定不行。 2. 每一块malloc的内存，在那个指针的前面，allocator会存储一些关于这块内存是如何分配的这种信息，以便它free的时候使用。具体也是要看allocator怎么写，不过正常都在8~16字节左右。每块malloc的空间都会有。这也是为什么越界经常会导致崩溃……因为这块数据被破坏了allocator就不知道该怎么free这块内存了。如果算它8字节，这里就有8*300w*3=72MB了。  所以即使通用allocator再厉害，自己做内存池的理由还是有很多的，这就是其中一个。

user: user-5
content: 那么多malloc却只有一个free.  内存占用高也很正常, 最后也会有一大堆的内存泄漏

user: user-6
content: 1. 没算name的20个字节 2. 没算栈

user: user-0
content: 引用 1 楼 brookmill 的回复:建议LZ分别试一下10万、1万、1000、100、10、1条记录的情况，然后对比找规律 这个算黑盒吧，白盒的由楼下补充  我也曾经打算用1条、10条记录来调试，只是这样的内存量太少了，我在Win7的任务管理器->进程->内存一栏看不出内存的变化(那里的单位都是KB级别的......)。 或者您有什么好的工具推荐一下吗？

user: user-2
content: 建议LZ分别试一下10万、1万、1000、100、10、1条记录的情况，然后对比找规律 这个算黑盒吧，白盒的由楼下补充
user-0 提问: 自己在写一个小程序的时候遇到了问题，望前辈们指教！万分感谢

回复:
user: user-1
content: 这个是不是应该用java写比较好呢？我不懂诶

user: user-0
content: 引用 1 楼 zjq9931 的回复:[quote=引用 楼主 bryantno1 的回复:] 本人是大学生，开学后该选课了，介于学校的网非常烂，选课那天学校的选课入口往往特别拥堵，所以我想用C语言写一个刷选课入口的程序，学校的入口如果抢不上就是显示 选课人数已满，我想做一个无限刷这个网址的程序直到不出现选课入口已满出现入口为止，无限刷的代码已经敲好，就是不知道怎么判断网页是选课人数已满还是进去入口，所以不知道什么时候break，，哪位大神能帮我看一下，万分感激！！！！ 这是我核心代码，网址就先用百度代替了，怕弄错了把机子搞死机了就先弄了5个循环  CInternetFile 这个类。 用这个类来读取文件的内容。 找到特定的位置根据字符来判断。[/quote]具体是怎样获取网页中的字符呢？刚百度了半天没找到

user: user-0
content: 引用 2 楼 zhao4zhong1 的回复:使用curl库？唔。。。不懂。。我就是想获取网页中的内容。。如果显示选课人数已满 就停止这个循环。。

user: user-2
content: 选个课都要这么下功夫，LZ的学校不一般啊

user: user-3
content: 使用curl库？

user: user-4
content: 引用 楼主 bryantno1 的回复:本人是大学生，开学后该选课了，介于学校的网非常烂，选课那天学校的选课入口往往特别拥堵，所以我想用C语言写一个刷选课入口的程序，学校的入口如果抢不上就是显示 选课人数已满，我想做一个无限刷这个网址的程序直到不出现选课入口已满出现入口为止，无限刷的代码已经敲好，就是不知道怎么判断网页是选课人数已满还是进去入口，所以不知道什么时候break，，哪位大神能帮我看一下，万分感激！！！！ 这是我核心代码，网址就先用百度代替了，怕弄错了把机子搞死机了就先弄了5个循环  CInternetFile 这个类。 用这个类来读取文件的内容。 找到特定的位置根据字符来判断。

user: user-5
content: 百度

user: user-4
content: 引用 5 楼 bryantno1 的回复:[quote=引用 1 楼 zjq9931 的回复:] [quote=引用 楼主 bryantno1 的回复:] 本人是大学生，开学后该选课了，介于学校的网非常烂，选课那天学校的选课入口往往特别拥堵，所以我想用C语言写一个刷选课入口的程序，学校的入口如果抢不上就是显示 选课人数已满，我想做一个无限刷这个网址的程序直到不出现选课入口已满出现入口为止，无限刷的代码已经敲好，就是不知道怎么判断网页是选课人数已满还是进去入口，所以不知道什么时候break，，哪位大神能帮我看一下，万分感激！！！！ 这是我核心代码，网址就先用百度代替了，怕弄错了把机子搞死机了就先弄了5个循环  CInternetFile 这个类。 用这个类来读取文件的内容。 找到特定的位置根据字符来判断。[/quote]具体是怎样获取网页中的字符呢？刚百度了半天没找到[/quote] 和本地文件操作差不多啊。
user-0 提问: unsigned char*与unsigned char问题

回复:
user: user-0
content: 引用 8 楼 user-7 的回复:u8_t sendbuf[5];在栈上有问题吧，函数返回就被收了... 已解决，就是这样。

user: user-0
content: 引用 2 楼 shenchenman 的回复:什么编译器？ qmdk。我正在试

user: user-1
content: i编译器的问题吧

user: user-1
content: i编译器的问题吧

user: user-2
content: VS2013下运行：

user: user-3
content: 这个不可能吧  /home/mymtom/src/demo$ cat demo1.c  #include <stdio.h>  int main(int argc, char *argv[]) {         unsigned char bfBuf[4] = {0x01,0x01,0x01,0x01};         unsigned char * dataptr;          dataptr = bfBuf;         printf("%02X\n",bfBuf [0]);         printf("%02X\n",dataptr[0]);          return 0; }  /home/mymtom/src/demo$ make demo1 cc     demo1.c   -o demo1 /home/mymtom/src/demo$ ./demo1 01 01

user: user-4
content: 什么编译器？

user: user-5
content: -----------------

user: user-6
content: 什么时候打印的打印的呢？ 理论应该是一样的！不必纠结这里！

user: user-7
content: u8_t sendbuf[5];在栈上有问题吧，函数返回就被收了...

user: user-0
content: 就好像指针s->textptr 指的不是原来的地址

user: user-0
content: .h文件  struct tcp_demo_appstate { 	u8_t state; 	u8_t *textptr; 	int textlen; }; typedef struct tcp_demo_appstate uip_udp_appstate_t;  uip的udp接受命令，tcp发数据。接受命令时解析命令一点问题没有，然后把返回的状态通过tcp发送给上位机。每次发送时都不是原来的数据。不知道怎么回事 .c  //解析 void DealCmd(struct tcp_demo_appstate *s) { 	u8_t sendbuf[5]; 	u8_t cmd,len,chid,paracode,para;  	/* 得到指定参数 	*/  	cmd = ((u8_t *)uip_appdata)[0]; 	len = ((u8_t *)uip_appdata)[1];  	chid = ((u8_t *)uip_appdata)[2];  	paracode = ((u8_t *)uip_appdata)[3];  	sendbuf[0] = cmd; sendbuf[1] = len;  	sendbuf[2] = chid;  	sendbuf[3] = paracode; s->textptr = sendbuf; s->textlen = sizeof(sendbuf); } //发送 static void senddata(void) { 	struct tcp_demo_appstate *s = (struct tcp_demo_appstate *)&uip_udp_conn->appstate; 	if (s->textlen > 0) 	{ 	uip_send(s->textptr, s->textlen); 	} }
user-0 提问: rsa加解密软件，大家都来试试你的C语言学好了吗？

回复:
user: user-1
content: 没有32位的怎么修改呀？

user: user-2
content: 引用 2 楼 zxhuser-3 的回复:怎么感觉你这是变相来求代码的呢有同感。

user: user-3
content: 怎么感觉你这是变相来求代码的呢

user: user-3
content: 给个代码呀,我可是伸手党
user-0 提问: Win-Tc编译时遇到问题：未定义的符号     '__STKLEN' 在模块    C0M

回复:
user: user-0
content: 嗯 把中文全部换成英文就OK了

user: user-1
content: 编译正常通过的说，就是中文是乱码而已

user: user-2
content: 将#include后面的"..."改为<...>再试试。
user-0 提问: 排列组合的一个算法问题

回复:
user: user-1
content: //qplw.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> int v=0; int w=0; int m;//记录字符串长度 int n;//记录字符串中的字符种类数 char map[256];//记录是哪几种字符 int count[256];//记录每种字符有多少个 int stack[1000];//递归用的栈，并记录当前生成的排列 void Make_Map(char *str) {//统计字符串的相关信息     int s[256];     int i;     memset(s,0,sizeof(s));     memset(count,0,sizeof(count));     m=strlen(str);     if (w<1 || m<w) w=m;     while(*str) {         s[*str]++;         str++;     }     n=0;     for (i=0;i<256;i++)         if (s[i]) {             map[n]=i;             count[n]=s[i];             n++;         } } void Find(int depth) {//递归式回溯法生成全排列     if (depth==w) {         int i;         for (i=0;i<depth;i++) putchar(map[stack[i]]);         putchar('\n');     } else {         int i;         if (v && depth>0) {             for (i=0;i<depth;i++) putchar(map[stack[i]]);             putchar('\n');         }         for (i=0;i<n;i++)             if (count[i]) {                 stack[depth]=i;                 count[i]--;                 Find(depth+1);                 count[i]++;             }     } } void main(int argc,char**argv) {     if (argc<2) {         printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);         return;     }     if (argc>=3) w=atoi(argv[2]);     if (-1==w) v=1;     Make_Map(argv[1]);     Find(0); } //C:\test>qplw //qplw 要产生全排列的字符串 [限定长度|-1] // //C:\test>qplw 123 //123 //132 //213 //231 //312 //321 // //C:\test>qplw 123 2 //12 //13 //21 //23 //31 //32 // //C:\test>qplw 122333 3 //122 //123 //132 //133 //212 //213 //221 //223 //231 //232 //233 //312 //313 //321 //322 //323 //331 //332 //333 // //C:\test>qplw 123 -1 //1 //12 //123 //13 //132 //2 //21 //213 //23 //231 //3 //31 //312 //32 //321 //

user: user-2
content: 引用 1 楼 zjq9931 的回复:大体就是这样：  char pcList[]="abcdefg"; int ix,iy,iz; for(ix =0; ix<strlen(pcList); ix++) {     for(iy=0; iy<strlen(pcList); iy++)     {             for(iz=0; iz<strlen(pcList); iz++)             {                   printf("%c%c%c\r\n", pcList[ix], pcList[iy], pcList[iz]);             }     } }  +1,按数学的方法去实现就行了，一位位填充，这个最好理解了

user: user-3
content: 大体就是这样：  char pcList[]="abcdefg"; int ix,iy,iz; for(ix =0; ix<strlen(pcList); ix++) {     for(iy=0; iy<strlen(pcList); iy++)     {             for(iz=0; iz<strlen(pcList); iz++)             {                   printf("%c%c%c\r\n", pcList[ix], pcList[iy], pcList[iz]);             }     } }
user-0 提问: 编译器实现操作变量的方法

回复:
user: user-1
content: 引用 楼主 garbageam 的回复:举个简单的例子 char a=1,b; b=a;   //这里编译器处理的时候是不是视作b=*&a??? 汇编代码如下：  4:        int a=1, b; 00401028   mov         dword ptr [ebp-4],1 5:        b=a; 0040102F   mov         eax,dword ptr [ebp-4] 00401032   mov         dword ptr [ebp-8],eax  a=1;//把1放到a变量的内存里。 b=a;//把内存里的值取放到eax寄存器里面。然后把eax寄存器的值放到b变量对应的内存里面。
user-0 提问: undefined reference to 函数名

回复:
user: user-1
content: 使用线程要引入线程库-lpthread

user: user-0
content: 用尽各种办法 这个问题 还是没能完美解决。 最后 只好 用其他效率不高的方法。

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

user: user-2
content: 就是没有函数声明，可能是少编译了什么文件。

user: user-3
content: 估计还是makefile写漏东西了

user: user-4
content: 都在链接阶段了，可能a.o最后没加进去...

user: user-0
content: 按正常来说 以上两种方法 都是可行的  其实在其他.c里也有同样的用法  可是 偏偏我这个b.c里的却编译通过不了。  修改它makefike  gcc .... -c -o `test -f 'b.c' || echo $(srcdir)/`b.c   添加  gcc .... -c -o `test -f 'b.c' || echo $(srcdir)/`b.c  mmr/a.c 或 gcc .... -c -o `test -f 'b.c' || echo $(srcdir)/`b.c  mmr/a.o  均会显示：undefined reference to video  纠结。。

user: user-5
content: 只需要在b.c 里 include   一个头文件,比如 extern_a.h  extern_a.h里有 extern  void* a()就可以了   a.c -> a.o  b.c 去找a.o里关于 void* a()的定义,找到了就没错误

user: user-6
content: 需要在A.c文件里定义函数时声明extern吧:  extern void * video(){ ..... }   然后在B.c文件中：  void *video(); .... pthread_create(&pid,NULL,video,(void *)GTK_WINDOW(win->toplevel)); ....

user: user-0
content: 或者  在B.c文件里  #include "mmr/B.h" .... pthread_create(&pid,NULL,video,(void *)GTK_WINDOW(win->toplevel)); ....   在mmr文件夹下创建A.h A.h ... void *video();  A.c里 void *video(){   ..... }  同样报 undefined reference to video
user-0 提问: 帮忙分析一下！关于FindWindow函数

回复:
user: user-1
content: 引用 7 楼 my3439955 的回复:这种情况下就不能单单使用FindWindow了，要使用FindWindowEx，它除了能用类名和窗口名查找窗口外，还可以指定父窗口和兄弟窗口。  你的情况就是先查找到一个，然后将其作为兄弟窗口查找下一个 ++

user: user-2
content: 首先，你自己知道需要那个窗口吗？ 如题目所说，一个窗口有三个参数，进程，类，标题。 那么在获取 窗口后，使用 GetWindowThreadProcessId 进一步获取 进程，线程。

user: user-3
content: GetWindowThreadProcessId The GetWindowThreadProcessId function retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window.   DWORD GetWindowThreadProcessId(   HWND hWnd,             // handle to window   LPDWORD lpdwProcessId  // address of variable for process identifier );   Parameters hWnd  Handle to the window.  lpdwProcessId  Pointer to a 32-bit value that receives the process identifier. If this parameter is not NULL, GetWindowThreadProcessId copies the identifier of the process to the 32-bit value; otherwise, it does not.  Return Values The return value is the identifier of the thread that created the window.   QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winuser.h.   Import Library: Use user32.lib.  See Also Windows Overview, Window Functions

user: user-4
content: 这种情况下就不能单单使用FindWindow了，要使用FindWindowEx，它除了能用类名和窗口名查找窗口外，还可以指定父窗口和兄弟窗口。  你的情况就是先查找到一个，然后将其作为兄弟窗口查找下一个

user: user-5
content: 引用 5 楼 chenxu1223537114 的回复:回复所有： 其实我担心的就是当我用FindWindow找窗口句柄的时候，如果出现相同的窗口名和类名，那么如何得到我想要的句柄？ 那么只根据窗口名和类名，判断不了了，你还要根据窗口中的内容来判断，或者窗口的大小，总之要指定独有特征。

user: user-0
content: 引用 9 楼 Saleayas 的回复:首先，你自己知道需要那个窗口吗？ 如题目所说，一个窗口有三个参数，进程，类，标题。 那么在获取 窗口后，使用 GetWindowThreadProcessId 进一步获取 进程，线程。 获取进程、线程ID有什么用吗？在我只知道窗口名和类型的情况下。

user: user-0
content: 回复所有： 其实我担心的就是当我用FindWindow找窗口句柄的时候，如果出现相同的窗口名和类名，那么如何得到我想要的句柄？

user: user-0
content: 引用 1 楼 user-7 的回复:“他们所创建的窗口的名称和类名都是一样的“你的意思应该是说这两个进程运行的是用一个程序吧。进程是程序的实例化。可以类比一下，比如我定义了一个类class A。A a；A b；a，b就是A的实例化。我是想说明，A的实例化可以是多个，但是a和b是完全不同的，a.findwindow和b.findwindow是不一样的。进程和进程也是不同的，即使他们运行的是一个程序，但他们在不同的内存里，互不影响，所以FindWindow只会在自己的进程空间里找，而不会找到别的进程去。不知道这能否解决你的问题？ 假如是不同的两个人写的程序，a.exe、b.exe，但窗口名和类名刚好相同，如果我调用FIndWindow得到的是哪个窗口的句柄？如果我想要得到b.exe窗口的句柄，函数却返回a.exe的句柄怎么办？

user: user-6
content: 当前激活的是哪个就是哪个

user: user-5
content: The FindWindow function retrieves a handle to the top-level window whose class name and window name match the specified strings. This function does not search child windows. This function does not perform a case-sensitive search.   找到的是最上层的那个。 相当于，按ALT+TAB切换窗口，先切换到哪个就是哪个。

user: user-7
content: “他们所创建的窗口的名称和类名都是一样的“你的意思应该是说这两个进程运行的是用一个程序吧。进程是程序的实例化。可以类比一下，比如我定义了一个类class A。A a；A b；a，b就是A的实例化。我是想说明，A的实例化可以是多个，但是a和b是完全不同的，a.findwindow和b.findwindow是不一样的。进程和进程也是不同的，即使他们运行的是一个程序，但他们在不同的内存里，互不影响，所以FindWindow只会在自己的进程空间里找，而不会找到别的进程去。不知道这能否解决你的问题？
user-0 提问: 怎么会是死循环呢

回复:
user: user-1
content: 创建链表时for(int i=0;i<N;i++) 把N改成n。另外，合并两个链表的函数中while循环没有写对。   //创建一个虚拟的新链表，原链表升序有序 #include <stdio.h> #include <stdlib.h> #define M 5 #define N 7  //定义一个含有两个域的结点 typedef struct node{ 	int data; 	struct node *next; }ElemSN;  ElemSN * CombineLink(ElemSN *h1,ElemSN *h2) { 	ElemSN *h=NULL,*s;  	if(h1 && h2 && h1->data < h2->data){ 		h = h1; 		s = h1; 		h1 = h1->next; 	} 	else{ 		h = h2; 		s = h2; 		h2 = h2->next; 	}  	while(h1&&h2) 	{ 		if(h1->data <h2->data )   		{ 			s->next = h1; 			h1 = h1->next; 			s = s->next; 		} 		else { 			s->next = h2; 			h2 = h2->next; 			s = s->next; 		} // 每次将较小的节点加入新链表中 	} 	if(h1)  s->next =h1; 	else  s->next =h2; // 判断哪个比较长，把剩余部分接到尾结点 	return h; }  //创建正向链表（尾插） ElemSN * CreatLink1(int a[],int n) { 	ElemSN *h,*p,*t; 	for(int i=0;i<n;i++) 	{ 		p=(ElemSN *)malloc(sizeof(ElemSN)); 		p->data=a[i]; 		p->next=NULL; 		if(!i) h=t=p;//是第一个结点 		else t=t->next=p; 	} 	return h; }  //输出单向链表 void PrintLink(ElemSN *h) { 	ElemSN *p; 	printf("\n输出的链表为：\n"); 	for(p=h;p;p=p->next) 		printf("%5d",p->data); 	printf("\n\n"); }  //主函数调用 int main(void) { 	ElemSN *head1,*head2,*head; 	int a[M]={0},b[N]={0}; 	int i; 	printf("\n请依次输入第一个链表每个结点的值：\n"); 	for(i=0;i<M;i++) 		scanf_s ("%d",a+i); 	head1=CreatLink1(a,M); 	printf("\n请依次输入第二个链表每个结点的值：\n"); 	for(i=0;i<N;i++) 		scanf_s ("%d",b+i); 	head2=CreatLink1(b,N); 	head=CombineLink(head1,head2); 	PrintLink(head1);  	system("pause"); 	return 0; }
user-0 提问: typedef相关

回复:
user: user-1
content: 引用 7 楼 Nsplayerol 的回复:[quote=引用 2 楼 lisong694767315 的回复:] 第二个是一种函数类型   #include<stdio.h>  typedef int (point)();  int func() { 	printf("this is func().\n"); 	return 0; }  int main() { 	point* f = func; 	(*f)(); 	return 0; }   point代表着什么意思？请问下[/quote]  代表返回值为int，参数列表为空的函数类型，而point*则是相应的函数指针类型。

user: user-2
content: 和 type int MYTYPE 以及 type int *MYTYPEP 一致。  MYTYPE *p1; MYTYPEP p2;

user: user-3
content: 引用 8 楼 lisong694767315 的回复:[quote=引用 7 楼 Nsplayerol 的回复:] [quote=引用 2 楼 lisong694767315 的回复:] 第二个是一种函数类型   #include<stdio.h>  typedef int (point)();  int func() { 	printf("this is func().\n"); 	return 0; }  int main() { 	point* f = func; 	(*f)(); 	return 0; }   point代表着什么意思？请问下[/quote]  代表返回值为int，参数列表为空的函数类型，而point*则是相应的函数指针类型。   [/quote]  也就是typedef int (point)()的意思等同于可以自定义一个不带参数返回值的函数，而这个函数可以叫任何名字？

user: user-3
content: 引用 2 楼 lisong694767315 的回复:第二个是一种函数类型   #include<stdio.h>  typedef int (point)();  int func() { 	printf("this is func().\n"); 	return 0; }  int main() { 	point* f = func; 	(*f)(); 	return 0; }   point代表着什么意思？请问下

user: user-4
content: 引用 5 楼 lovesmiles 的回复:#include <iostream> #include<stdio.h> typedef int (point)();  int main() { 	 point f;//声明了一个函数 int f();楼主试试把这一句去掉，没有它，下面的f(）就是未声明的。 	f(); 	return 0; }  int f()//定义一个函数，因为前面有point f了，所以不用将这个定义移到main 的前面。 { printf("this is point().\n");  	return 0; }+1

user: user-5
content: #include <iostream> #include<stdio.h> typedef int (point)();  int main() { 	 point f;//声明了一个函数 int f();楼主试试把这一句去掉，没有它，下面的f(）就是未声明的。 	f(); 	return 0; }  int f()//定义一个函数，因为前面有point f了，所以不用将这个定义移到main 的前面。 { printf("this is point().\n");  	return 0; }

user: user-1
content: 引用 3 楼 user-6 的回复:[quote=引用 2 楼 lisong694767315 的回复:] 第二个是一种函数类型   #include<stdio.h>  typedef int (point)();  int func() { 	printf("this is func().\n"); 	return 0; }  int main() { 	point* f = func; 	(*f)(); 	return 0; }  学到！！还真没这么用过，楼主思考问题还是很别致的[/quote]  表示从来没这么用过。。。我只是回答楼主的问题而已。。。

user: user-6
content: 引用 2 楼 lisong694767315 的回复:第二个是一种函数类型   #include<stdio.h>  typedef int (point)();  int func() { 	printf("this is func().\n"); 	return 0; }  int main() { 	point* f = func; 	(*f)(); 	return 0; }  学到！！还真没这么用过，楼主思考问题还是很别致的

user: user-1
content: 第二个是一种函数类型   #include<stdio.h>  typedef int (point)();  int func() { 	printf("this is func().\n"); 	return 0; }  int main() { 	point* f = func; 	(*f)(); 	return 0; }

user: user-6
content: 看楼下！！！
user-0 提问: 串口数据发送如何包装

回复:
user: user-1
content: 自己写个处理数据的函数，把数据分门别类的填充到结构体了，然后发送结构体，不就行了。

user: user-2
content: 这2个方法不是一回事吗 send_command(FrameData * data) { send_command(（uint8_t *）data, data-> length) }
user-0 提问: C语言的关于文件读取的问题

回复:
user: user-0
content: 太感谢你们啦，棒棒哒

user: user-1
content: fscanf(fin,"d",&n); 少了个百分号  fscanf(fin,"%d",&n);

user: user-2
content: 仅供参考 #include <stdio.h> #include <stdlib.h> #include <malloc.h>  int main()  { 	 FILE* fp_in; 	 FILE* fp_out; 	 int* start; 	 int* p; 	 int n; 	 int count=0; 	 fp_in = fopen("data.in","rb"); 	 if(fp_in==NULL) 	 { 		 printf("FILES data.in can not open!\n"); 		 exit(1); 	 } 	 fp_out = fopen("data.out","wb"); 	 fscanf(fp_in,"%d",&n); 	 p=start=(int*)malloc(sizeof(int)*n); 	 for(;n>0;n--) 	 { 		 fscanf(fp_in,"%d",p); 		 p++; 	 } 	 fscanf(fp_in,"%d",&n); 	 for(p--;p>=start;p--) 	 { 		 if(*p<n)count++; 	 } 	 printf("%d\n",count); 	 fclose(fp_in); 	 fclose(fp_out); 	 return 0;  }

user: user-3
content: 不知道是否符合，仅供参考：  #include <stdio.h> #include <stdlib.h> int main() { 	FILE *fin,*fout; 	 	fin = fopen("data.in","rb"); 	if(fin == NULL) 	{ 		printf("fin null\n"); 		exit(1); 	} 	fout = fopen("data.out","wb"); 	  	int n,m,x,count = 0;  	fscanf(fin,"%d",&n); 	printf("n = %d\n",n);  	fseek(fin,-2,SEEK_END);  //按你的题意，m是在文件最后，所以重新定位一下 	fscanf(fin,"%d",&m); 	printf("m = %d\n",m);  	fseek(fin,2,SEEK_SET);//跳过已经输入的n 	while(fscanf(fin,"%d",&x) == 1) 	{ 		if (x < m) 		{ 			 count++; 		} 	} 	printf("count = %d\n",count); 	fclose(fin); 	fclose(fout); 	return 0; }
user-0 提问: 为什么main不用const char **？

回复:
user: user-1
content: 不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

user: user-2
content: 路过。。。

user: user-3
content: 这只是一个标准吧，没啥好奇怪的

user: user-4
content: 我刚才细看了一下标准，确实，规定，必须要可被程序修改。。。。。 原文如下： — The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.  引用 6 楼 cyd54454 的回复:对于一些这样也可以那样也行的东西，标准是不会规定死的，要知道制定C标准时的原则，有一条就是：相信程序员,不阻止程序员需要做的事。以下内容来自《C Primer Plus》 The committee had several guiding principles. Perhaps the most interesting was this: Keep the spirit of C. The committee listed the following ideas as expressing part of that spirit:  Trust the programmer.  Don't prevent the programmer from doing what needs to be done.  Keep the language small and simple.  Provide only one way to do an operation.  Make it fast, even if it is not guaranteed to be portable.

user: user-4
content: 引用 楼主 NTparasite 的回复:C99说main函数只有两种符合标准 int main() 和int main(int argc, char *argv[]) 但是argv不是变成const更好吗？ 比如这样int main(int argc, const char *argv[])  到底什么时候需要用const啊？有时候不用也好像没关系，只要你记得不要随便修改内容？ 原文如下： — The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.  确实规定说必须要可被程序修改。but我确实不知道深层次的原因。我上面的只是猜想。

user: user-5
content: 对于一些这样也可以那样也行的东西，标准是不会规定死的，要知道制定C标准时的原则，有一条就是：相信程序员,不阻止程序员需要做的事。以下内容来自《C Primer Plus》 The committee had several guiding principles. Perhaps the most interesting was this: Keep the spirit of C. The committee listed the following ideas as expressing part of that spirit:  Trust the programmer.  Don't prevent the programmer from doing what needs to be done.  Keep the language small and simple.  Provide only one way to do an operation.  Make it fast, even if it is not guaranteed to be portable.

user: user-4
content: 深层原因不了解。 不过我想可能是因为，会有不少人习惯用argv++;这样的方式，来读取参数，所以，没用const修饰。

user: user-6
content: 引用 11 楼 zhao4zhong1 的回复:不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！赵老师NB！学习了

user: user-7
content: const char *argv[]是说**argv不能修改，但是事实上可能需要修改，所以标准不必要规定必须使用const。 另外const char **p和char * const *p，char ** const p是不一样的

user: user-8
content: 因为C99要向C89兼容。

user: user-9
content: 既然看标准  就看仔细点  main参数都是可读写的 #include <stdio.h> int main(int n, char *str[]) { 	char* pstr = "123"; 	**str = 'a'; 	puts(*str); 	str = &pstr; 	puts(*str); 	return 0; }  可读写 当然不可以用const  什么时候用const  当你想告诉别人 这个函数不会修改参数指向的对象 你函数内部不修改 但是别人不知道啊  别人想调用这个函数 而且不想参数指向的对象被修改 你用char* 别人心里没底 你用const char* 别人就能放心大胆的随便传

user: user-10
content: const char *是为了保护字符串不被函数修改，如果无意间修改了编译器会提示错误，是一种编程技巧。 命令行参数可能需要修改内容，所以就没有设置。
user-0 提问: 请教宏高手,宏如何展开#include,

回复:
user: user-1
content: 引用 18 楼 hanger1212 的回复:[quote=引用 15 楼 Saleayas 的回复:] #if _DEBUG #define INCLUDE_FILE() "Debug.h" #else #define INCLUDE_FILE() "Release.h" #endif  #include INCLUDE_FILE()+1[/quote] 呵呵，直接把include放进里面不就好了吗？还多此一举

user: user-2
content: 引用 15 楼 Saleayas 的回复:#if _DEBUG #define INCLUDE_FILE() "Debug.h" #else #define INCLUDE_FILE() "Release.h" #endif  #include INCLUDE_FILE()+1

user: user-3
content: 引用 15 楼 Saleayas 的回复:#if _DEBUG #define INCLUDE_FILE() "Debug.h" #else #define INCLUDE_FILE() "Release.h" #endif  #include INCLUDE_FILE() 这个方法似乎可以

user: user-4
content: 参考gcc源代码中#define和#include的实现逻辑。

user: user-5
content: #if _DEBUG #define INCLUDE_FILE() "Debug.h" #else #define INCLUDE_FILE() "Release.h" #endif  #include INCLUDE_FILE()

user: user-0
content: 好吧,没有就没有了,只是多维护了两份重复的类名列表

user: user-3
content: 其实  //#define A   #if  defiened (A) #include "A.h" #elif defined(B) #include "B.h" #else  #include "C.h" #endif  应该足以满足大部分这种需求了。  如果还不能满足，可以直接生成头文件  //------------------ //inc.h #ifndef __INC_H__ //这里所有#include 指令全部使用程序生成 #include "a.h" #include "b.h" //...... .#endif  在你的程序里，写上 #include “inc.h” 就可以了  需要更新#include指令只要手动修改一下inc.h  或者调用你的程序，重新生成这个inc.h 就可以了

user: user-3
content: 预编译语句不能，放在宏定义中使用。 C，C++没有办法扩展，带预编译语句的宏定义。  如果需要，自己写个预编译器，在编译前执行。 然后用编译器，编译经过你预编译后的文件。

user: user-6
content: 楼主还是把最原始的需求讲出来吧

user: user-3
content: 更正一下： #if defined(A)

user: user-7
content: 通常是这样  #ifdef AAAAA #include "a.h" #else #ifdef BBBBB #include "b.h" #else #include "c.h" #endif #endif  或者是类似这样 #ifndef AAAAA #define BBBBB #endif #ifdef AAAAA #include "a.h" #endif #ifdef BBBBB #include "b.h" #endif

user: user-8
content: 宏不是万能的，别瞎折腾。 说你的原始需求。

user: user-9
content: 宏里面 不能在用#include了 只能 #if xxx #include "a" #endif

user: user-10
content: 引用 楼主 u013573183 的回复:比如 #define includeExtern(a) #include a   编译结果因为 # 符号而错误 宏展开是在预处理期进行的，你的#define在预处理期处理后，又出现的预处理指令#include 但此时预处理期已经结束，无法再处理预处理指令#include了

user: user-1
content: 据我所知， 是不能这样子实现的，#号在宏里面有特殊的意义。你不能将它当变量来用的。

user: user-11
content: 引用 6 楼 u013573183 的回复:有没有什么 \# 之类的东西 把#的特殊含义转掉 从而可以正常的展开你想多了。。。

user: user-12
content: 设计 不合理，基本楼主要改一下想法了，这样也没有意义。说说你为啥想要这样做

user: user-9
content: 引用 6 楼 u013573183 的回复:有没有什么 \# 之类的东西 把#的特殊含义转掉 从而可以正常的展开没有

user: user-0
content: 有没有什么 \# 之类的东西 把#的特殊含义转掉 从而可以正常的展开
user-0 提问: 求助  在c++ mfc中 报错：“类型转换”: 从“char *”到“int”的指针截断

回复:
user: user-1
content: 同样的语句编译却提示   ：“类型转换”: 从“char *”到“int”的指针截断  这是个错误还是警告？应该只是个精度丢失的警告吧？可以不用理会的

user: user-2
content: *(int *)0x0043FCFC = *(int *)"ABC"; 等号左边是一个int型的左值，那么右值也得是一个int型的，而“ABC”其实是个改字符串的首地址（"ABC"[1] == B,和 str[] = "ABC",str[1] == B是一样的），你把地址转换成int *,再解除引用就是int型了。

user: user-3
content: 引用 3 楼 elf_share 的回复:[quote=引用 1 楼 zjq9931 的回复:] 好吧，等号左边的方式我汗真没用过，不过，等号右边的，(int)换成(int*)应当就可以编译通过了。 楼上大哥，我按照你说的改好了，但是报错说：“=”: 无法从“int *”转换为“int”[/quote] 你是想把“ABC”转换成数字型的ABC？ 如果是，就不要这样用。推荐使用atoi，或者sscanf

user: user-3
content: 引用 3 楼 elf_share 的回复:[quote=引用 1 楼 zjq9931 的回复:] 好吧，等号左边的方式我汗真没用过，不过，等号右边的，(int)换成(int*)应当就可以编译通过了。 楼上大哥，我按照你说的改好了，但是报错说：“=”: 无法从“int *”转换为“int”[/quote] 等号左边，最开始的那个*去掉就可以了。

user: user-0
content: 引用 1 楼 zjq9931 的回复:好吧，等号左边的方式我汗真没用过，不过，等号右边的，(int)换成(int*)应当就可以编译通过了。 楼上大哥，我按照你说的改好了，但是报错说：“=”: 无法从“int *”转换为“int”

user: user-4
content: 把左边那个(int *)删掉？

user: user-3
content: 好吧，等号左边的方式我汗真没用过，不过，等号右边的，(int)换成(int*)应当就可以编译通过了。
user-0 提问: 关于C语言通讯录的代码，大家来看看 

回复:
user: user-1
content: 引用 7 楼 u012632288 的回复:当n=1的时候，，输出的是p1，，当n大于1的时候，输出的是什么。。   if(n==1)  //                 head=p1;               else                   p2->next=p1;               p2=p1;   这一段是怎么起作用的。。可以讲讲吗，我链表这一块学得不好，基础有点差 如果n等于1（这里判断n==1，是因为上面，n = n + 1的缘故），head指向p1所指向的内存，即让head指向链表的头，只执行那么一次。否则，因为p2实则是指向链表最后一个节点的，那么让p2->next = p1,就是让最后一个节点的next指针指向p1（p1是新malloc出来的内存）。然后让p2再指向p1，保证了p2永远是链表最后一个节点，方便你一直尾插。你可以把p2名字改成tail，可能会清晰一点。

user: user-0
content: 引用 5 楼 cyd54454 的回复:malloc出来的内存都是无名内存，也就是说你不能通过变量名知道它的地址，所以你必须手动用指针指向该地址，一旦没有指针指向该内存，你就找不到它了，所以才有p2=p1，不然p1指向别的地方，前面的那块内存就没那么方便的被找到（你要是不用p2，你可以从head开始遍历..脑洞大开的人才这么做）。有名内存：比如int a ;你就能通过a这变量名，访问该内存地址。     当n=1的时候，，输出的是p1，，当n大于1的时候，输出的是什么。。   if(n==1)  //                 head=p1;               else                   p2->next=p1;               p2=p1;   这一段是怎么起作用的。。可以讲讲吗，我链表这一块学得不好，基础有点差

user: user-2
content: p2保存了一个节点内存块的首地址啊

user: user-1
content: malloc出来的内存都是无名内存，也就是说你不能通过变量名知道它的地址，所以你必须手动用指针指向该地址，一旦没有指针指向该内存，你就找不到它了，所以才有p2=p1，不然p1指向别的地方，前面的那块内存就没那么方便的被找到（你要是不用p2，你可以从head开始遍历..脑洞大开的人才这么做）。有名内存：比如int a ;你就能通过a这变量名，访问该内存地址。

user: user-1
content: 引用 2 楼 zxh707wk 的回复:引用 1 楼 lisong694767315 的回复:p2用来记录p1的上一个节点。。。+1 +2，蹭一个

user: user-3
content: 记录上一个节点。 不然后边无法继续向后读取。

user: user-4
content: 引用 1 楼 lisong694767315 的回复:p2用来记录p1的上一个节点。。。+1

user: user-5
content: p2用来记录p1的上一个节点。。。
user-0 提问: 软件测试的相关问题

回复:
user: user-1
content: 当然有帮助了，比如：测试要求各种逻辑，功能上的覆盖，如果这些问题你能够在写代码之前就想好了所有覆盖面，那么你在开发的过程中就已经进行了处理，这样能减少返工，节约开发时间！

user: user-2
content: 引用读一些关于软件测试的书籍，对自身的软件开发能力有没有什么特别的帮助  -------------------  测试，源于实践； 好的开发人员，一定也是个好的测试人员；

user: user-3
content: 想做开发，就专心学开发吧，旁的需要了再说。

user: user-4
content: 没有特别帮助。 实际上，测试和软件开发要的技能交集不大。

user: user-5
content: 会有一些帮助，但特别的帮助我觉得谈不上吧。像开发模式之类的，只有基本功到了一定的地步，这些东西才能慢慢显示出它的作用。

user: user-6
content: 实践是检验真理的唯一标准

user: user-7
content: 毕竟要读的那么多，不可能都读。要有针对性 这句话不错  引用 1 楼 user-8 的回复:不知道你所特别指的是什么。但是感觉实践才能知道自己要读什么书。毕竟要读的那么多，不可能都读。要有针对性

user: user-8
content: 不知道你所特别指的是什么。但是感觉实践才能知道自己要读什么书。毕竟要读的那么多，不可能都读。要有针对性
user-0 提问: 我这个冒泡和标准的比如何？

回复:
user: user-1
content: #include <stdio.h> #include <time.h> #include <stdlib.h> void better_bubble_sort(int *D, int n) {     int b,i,m,t;      b=n-1;     while (b) {         m=0;         for (i=0;i<b;i++) {             if (D[i]>D[i+1]) {t=D[i];D[i]=D[i+1];D[i+1]=t;m=i;}         }         b=m;     } } int main() {     int d[10],n,i;      srand(time(NULL));     for (n=0;n<10;n++) {         printf("------%d------\n",n);         for (i=0;i<n;i++) {d[i]=rand()%100;printf(" %02d",d[i]);}         printf("\n");         better_bubble_sort(d,n);         printf("sorted:\n",n);         for (i=0;i<n;i++) {               ;printf(" %02d",d[i]);}         printf("\n");     } } //------0------ // //sorted: // //------1------ // 87 //sorted: // 87 //------2------ // 41 40 //sorted: // 40 41 //------3------ // 21 03 02 //sorted: // 02 03 21 //------4------ // 27 03 70 21 //sorted: // 03 21 27 70 //------5------ // 02 50 57 77 34 //sorted: // 02 34 50 57 77 //------6------ // 74 94 80 05 58 10 //sorted: // 05 10 58 74 80 94 //------7------ // 50 43 98 36 90 83 73 //sorted: // 36 43 50 73 83 90 98 //------8------ // 07 20 21 13 56 90 06 51 //sorted: // 06 07 13 20 21 51 56 90 //------9------ // 14 94 94 32 14 24 81 32 00 //sorted: // 00 14 14 24 32 32 81 94 94 //

user: user-2
content: 数据交换需要 3个赋值操作。  冒泡最重要的特点是比较相邻元素，可交换则交换。  选择则是选出来当前的最大或者 最小值，交换到合适的位置。 选择排序，交换的次数比冒泡要少.  插入排序，是在前若干已经排好序的数据中，找到新数据的插入位置位置。 如果需要，移动那些需要移动的数据，给新数据腾出位置，然后插入新数据。 插入排序 移动N个数据只需要一次交换。  你这个排序，不是冒泡，也不是选择，当然也不是插入。 倒像是冒泡和选择的混合排序。  但是和冒泡比，每次比较的不是相邻元素，所以不算冒泡。时间复杂度也许和冒泡一样。 和选择比，每次比较都交换，交换的次数有点多，显然不是选择排序。  虽然选择排序和冒泡排序时间复杂度一致。 但是由于交换次数明显减少，所以选择通常比冒泡要快。

user: user-3
content: 引用 6 楼 u012033027 的回复:你这不是冒泡，你这叫插入排序。 这应该不叫插入吧。

user: user-4
content: 你这不是冒泡，你这叫插入排序。

user: user-5
content: 我也喜欢写这种，看起来清晰一点 不过这应该不算是冒泡了，效率上基本还是O(n^2)和普通冒泡没区别

user: user-6
content: 写一些测试代码测试一下不就知道了吗

user: user-7
content: 呵呵，你这应该不叫冒泡，你这叫沉底算法。别人冒泡是一个极值一个极值不停地浮上去的，你找到极值后就沉在那个地方雷打不动了。应该叫沉底法。

user: user-3
content: 其实从理论上来说，应该是一个样的。都是O(n^2)的复杂度 不同的是冒泡每次都是把先从头开始把最大的冒到后面去，你的是每次从头开始选择一个最小的弄到头上去。 你这种有点选择排序的味道，而且还写麻烦了。  你可以去看看选择排序。

user: user-8
content: 你没有考虑序列初始有序的情况。。。   void BubbleSort(ElementType A[], int n)   {       for(int i=0; i<n-1; ++i)       {           bool flag = false;   // 表示本次冒泡是否发生交换的标志           for(int j=n-1; j>i; --j) // 从后往前           {               if(A[j-1] > A[j])                {                   flag = true;                   // 交换                   A[j-1] = A[j-1]^A[j];                   A[j] = A[j-1]^A[j];                   A[j-1] = A[j-1]^A[j];               }           }              if(flag == false)               return;       }   }
user-0 提问: 初学者，求大神帮忙看一下这段代码

回复:
user: user-1
content: 数组里的元素是getchar(),一个个来的，最后需要手动加上'\0'，StringA[i] = '\0',再去计算n = strlen(StringA)才会是正确的结果，基本字符串操作的函数都是要判断'\0'做结束的，像strcpy什么的。最后输出的时候格式选的不对，StringB[j]明显是一个字符，要选择%c作为格式转化符，%s的输出是以'\0'做结束的。以下为修改后的程序： #include <stdio.h> #include <string.h>  #define NUM 100  void chString();  int main() { 	chString();  	return 0; }  void chString() { 	char StringA[NUM]; 	char StringB[NUM]; 	int i = 0; 	int j = 0; 	int n;  	printf("please input char:");  	while((StringA[i] = getchar()) != '\n') 	{ 		i++; 	} 	StringA[i] = '\0'; //here is new 	i = 0; 	n = strlen(StringA);  	while(i < n) 	{ 		StringB[j] = StringA[i]; 		j++; 		i = i + 2; 	} 	while(j >= 0) 	{ 		printf("%c",StringB[j]); //here is new 		j--; 	} }

user: user-2
content: 仅供参考 #include <stdio.h>  void minus(char* str,char* temp) { 	while(*str) 	{ 		*temp=*str; 		temp++; 		if(*(str+1)=='\0')break; 		str=str+2; 	} 	*temp='\0'; }  int main() { 	char str[100]; 	char temp[100]; 	scanf("%s",str); 	minus(str,temp); 	puts(temp); 	return 0; }

user: user-3
content: 天气太热了，好烫……

user: user-2
content: 怎么又贴图片，直接发代码不行吗

user: user-4
content: printf输出字符要用%c而不是%s。

user: user-5
content: 引用 3 楼 bluesnail1986 的回复:为什么要%s输出呢？如果是%s，后面对应的参数应该是字符串的地址，可是StringB[j]显然是个字符 换成%c吧  另外，目测代码中有不少不规则的地方。用strlen判断数组长度，但StringA又没有memset(0)，这个不靠谱吧？栈里的值可都是随机的...  +1

user: user-6
content: 为什么要%s输出呢？如果是%s，后面对应的参数应该是字符串的地址，可是StringB[j]显然是个字符 换成%c吧  另外，目测代码中有不少不规则的地方。用strlen判断数组长度，但StringA又没有memset(0)，这个不靠谱吧？栈里的值可都是随机的...

user: user-0
content: 引用 1 楼 caozhy 的回复:第二个while循环你判断的是i，可是i在循环体能总是初始值，你累加的是j。不是啊，我后面有一个i=i+2这样的话，再判断的时候，i的值是改变的，所以说这个循环应该没有错啊。

user: user-7
content: 第二个while循环你判断的是i，可是i在循环体能总是初始值，你累加的是j。