Question: c语言多文件编程  大家帮看看错在哪？？程序很短。。谢谢！

引用 15 楼 ds_guteng 的回复:[quote=引用 13 楼 lipoor1234 的回复:] 用我上面的方法没有解决么 那你先确定你所有的文件都有保存 然后重新rebuild看看  什么是打几个空格？[/quote] 就是随便修改一下cpp然后保存,改一下时间戳,不然只改点h,cpp文件不会重新编译的,和重新编译是同一个意思

引用 11 楼 fang098 的回复:哦，知道了，你把你的myfile1.cpp中的#include "myfile1.h"去掉试下。  重启可以了，谢谢！！！！

引用 14 楼 cyz7758520 的回复:你试试全部重新编译 引用 14 楼 cyz7758520 的回复:你试试全部重新编译 重启可以了，谢谢！！！！

引用 13 楼 lipoor1234 的回复:用我上面的方法没有解决么 那你先确定你所有的文件都有保存 然后重新rebuild看看  什么是打几个空格？

你试试全部重新编译

引用 11 楼 fang098 的回复:哦，知道了，你把你的myfile1.cpp中的#include "myfile1.h"去掉试下。  不行啊。  是不是myfile1.h没有通过编译，担忧为什么呢？

引用 8 楼 fang098 的回复:你的myfile1.h贴出来看下。 该不会也是 #ifndef __MYFILE_H__  #define __MYFILE_H__ #endif  这样定义的吧。 上面有，没饭这错误。。。

引用 7 楼 ds_guteng 的回复:[quote=引用 6 楼 lipoor1234 的回复:] 楼主 代码没有问题 vc下可以编译通过  怎么回事？？[/quote] 你把你的3个cpp文件,都打几个空格,保存了重新编译看看 或者你清理一下解决方案再编译看看 不知道能不能解决

引用 6 楼 lipoor1234 的回复:楼主 代码没有问题 vc下可以编译通过  怎么回事？？

楼主 代码没有问题 vc下可以编译通过

引用 2 楼 fang098 的回复://myfile.h #ifndef __MYFILE_H__  #define __MYFILE_H__ extern void fun1(); extern void fun2(); #endif 这样定义的话你的后面的宏不会执行。 //myfile1.h #ifndef __MYFILE1_H__ #define __MYFILE1_H__ extern void fun3(); extern void fun4(); #endif  改成下面的看看。  //myfile.h #ifndef __MYFILE_H__  #define __MYFILE_H__ extern void fun1(); extern void fun2(); extern void fun3(); extern void fun4(); #endif  这样该我知道肯定行. 为什么第二个头文件不能执行？？ 求大神解惑。谢谢！

看上去代码没有问题 。。。

引用 1 楼 user-5 的回复:没有问题，楼主再看看程序中的myfile1.h头文件包含是否正确!  没发现有什么问题！百思不解啊！！！！ 跟VC++6.0环境有关系吗？

没有问题，楼主再看看程序中的myfile1.h头文件包含是否正确!


Question: c语言 进程名称

把你生成的exe文件改个名字, 进程名自然就改变了撒, 不显示窗口, 在初始化的时候不要Show出来即可.

引用 4 楼 lubyam 的回复:[quote=引用 2 楼 ftd2013 的回复:] 第一个:属性->连接器->常规->输出文件 第二个：#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )  第2个是什么意思啊[/quote]  改变连接器选项 ,可以设置工程属性，连接器->系统->子系统 window->winmain ,console->main。一样的

引用 3 楼 zhao4zhong1 的回复:奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中！  这。。。。

引用 2 楼 ftd2013 的回复:第一个:属性->连接器->常规->输出文件 第二个：#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )  第2个是什么意思啊

奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中！

不想显示窗口 又改变进程名称 在后头偷摸做坏事 参考 http://wenku.baidu.com/view/93b26ce8e009581b6bd9ebf2.html 这里总有你需要的API


Question: 求高手解释一下这个程序

引用 11 楼 ftd2013 的回复:这里有详解http://www.cnblogs.com/sdphome/archive/2011/09/14/2176624.html 多谢

引用 10 楼 rocktyt2 的回复:[quote=引用 9 楼 qptimus 的回复:] [quote=引用 6 楼 rocktyt2 的回复:] {const typeof(((type *)0)->member) *__mptr = (ptr); //typeof(((type *)0)->member)获得结构体type内该member的类型  (type *)((char *)__mptr-offsetof(type,member));} //结构体成员指针的地址减去偏移值即为结构体首地址  #define offsetof(TYPE,MEMBER) ((int)&((TYPE *)0)->MEMBER) 请问这句为什么能得到偏移地址[/quote]将地址0当成TYPE类型的指针，用->获取成员变量（实际没有对该变量进行访问，所以没有问题）并取地址，得到的就是从0作为开始地址的TYPE结构体的MEMBER成员的地址，这个地址的值就是member的在type结构体里的相对偏移[/quote] 多谢大神讲解，获益匪浅

引用 9 楼 qptimus 的回复:[quote=引用 6 楼 rocktyt2 的回复:] {const typeof(((type *)0)->member) *__mptr = (ptr); //typeof(((type *)0)->member)获得结构体type内该member的类型  (type *)((char *)__mptr-offsetof(type,member));} //结构体成员指针的地址减去偏移值即为结构体首地址  #define offsetof(TYPE,MEMBER) ((int)&((TYPE *)0)->MEMBER) 请问这句为什么能得到偏移地址[/quote]将地址0当成TYPE类型的指针，用->获取成员变量（实际没有对该变量进行访问，所以没有问题）并取地址，得到的就是从0作为开始地址的TYPE结构体的MEMBER成员的地址，这个地址的值就是member的在type结构体里的相对偏移

引用 6 楼 rocktyt2 的回复:{const typeof(((type *)0)->member) *__mptr = (ptr); //typeof(((type *)0)->member)获得结构体type内该member的类型  (type *)((char *)__mptr-offsetof(type,member));} //结构体成员指针的地址减去偏移值即为结构体首地址  #define offsetof(TYPE,MEMBER) ((int)&((TYPE *)0)->MEMBER) 请问这句为什么能得到偏移地址

int main() { 	test_t *a = (test_t *)0x88010020; 	test_t *p; //	p=gd_type_get(&(a->count),test_t,count); 	const int *ptr = &(a->count); 	p = (test_t*)((char *)ptr - ((int)&((test_t *)0)->count)); 	printf("%x\n",p); 	return 0; } //调试得到ptr = 0x88010024, p = 0x88010020

获得结构体中成员相对结构体开始地址偏移

引用 2 楼 rocktyt2 的回复:这个应该是用了gcc的扩展吧  作用是根据一个成员的指针，结构体类型名和成员名来获取该结构体的首地址  大哥能不详细解释一下

请问const typeof是什么？

这是个什么东东？

替换一下不就出来了吗。。。 别替换错了 注意括号  不难的


Question: 以下代码是链表排序代码，请问它们是根据什么信息进行排序的?

引用 8 楼 huabinsir 的回复:[quote=引用 7 楼 AnYidan 的回复:] [quote=引用 3 楼 huabinsir 的回复:] [quote=引用 2 楼 user-6 的回复:] cmp是怎么实现的嘛，主要是看看这个函数！    1 double cmp(ListNode *p ,ListNode *q)  2 {return (p->keyVal - q->keyVal);}  这个主要是对数字进行排序的[/quote]  抓重点[/quote]  什么意思?[/quote] 要找排序的依据，自然看 cmp 函数了

目测是对ListNode里的keyVal大小进行排序

引用 7 楼 AnYidan 的回复:[quote=引用 3 楼 huabinsir 的回复:] [quote=引用 2 楼 user-6 的回复:] cmp是怎么实现的嘛，主要是看看这个函数！    1 double cmp(ListNode *p ,ListNode *q)  2 {return (p->keyVal - q->keyVal);}  这个主要是对数字进行排序的[/quote]  抓重点[/quote]  什么意思?

引用 3 楼 huabinsir 的回复:[quote=引用 2 楼 user-6 的回复:] cmp是怎么实现的嘛，主要是看看这个函数！    1 double cmp(ListNode *p ,ListNode *q)  2 {return (p->keyVal - q->keyVal);}  这个主要是对数字进行排序的[/quote]  抓重点

是通过节点的值域大小排序，不过感觉程序写的好啰嗦

引用 1 楼 huabinsir 的回复:想对许多文件的文件名进行排序(文件名中有数字 中文 英文等字符)，如何操作呢? 字符串排序。 std::vector<std::string> v; v.push_back("avdvsa"); v.push_back("fdsg"); v.push_back("asdff"); std::sort(v.begin(),v.end());

这是归并 排序吗？

引用 2 楼 user-6 的回复:cmp是怎么实现的嘛，主要是看看这个函数！    1 double cmp(ListNode *p ,ListNode *q)  2 {return (p->keyVal - q->keyVal);}  这个主要是对数字进行排序的

cmp是怎么实现的嘛，主要是看看这个函数！

想对许多文件的文件名进行排序(文件名中有数字 中文 英文等字符)，如何操作呢?


Question: ffmpeg工程如何添加自己的测试代码

修改makefile，但是难度太大


Question: 请教赶集网校招的一道笔试题

前排占坐思考！

典型dfs：  #include <stdio.h> #include <string.h> #define MAX 500 /×   a,b,...,z map to 1,2,...,26   num is a string composed by 1~9 ×/ char num[MAX], letter[MAX]; int lenOfNum;  void dfs(int nextOfLetter, int nextOfNum) {     int twoDigits;     if(nextOfNum == lenOfNum){ 	letter[nextOfLetter] = 0; 	puts(letter);         return;     }      //one digit definitely matches a letter     letter[nextOfLetter] = num[nextOfNum] - '1' + 'a';     dfs(nextOfLetter+1, nextOfNum+1);      //check if next two digits can match a letter     if(nextOfNum+1 < lenOfNum){ 	twoDigits = (num[nextOfNum] - '0') * 10 + (num[nextOfNum+1] - '0');         if(twoDigits < 27){ 	    letter[nextOfLetter] = twoDigits-1 + 'a'; 	    dfs(nextOfLetter+1, nextOfNum+2); 	}     } }  int main() {     while(gets(num)){ 	lenOfNum = strlen(num);         dfs(0, 0);     }     return 0; }  不知道dp能不能做， 用f(num, lenOfNum)表示num对应的字母串，则 f(num, lenOfNum) = f(num, i) + f(num+i, lenOfNum) 判重麻烦了就，记忆也是个问题

递归，两个分支，分别处理1个字符和2个字符的情况。 回家再写个代码。

大概写了下，不确定是否正确。 很笨的办法，用递归 假设输入n各字符，则将其划分成两份[0,1) [1, n) 设[0,1)中的数字为n0 将[1,n)所有的组合情况保存起来 然后将第一个数字插入上一步骤中的所有组合的第一位 如果n0*10+其中某一个组合的第一位<26，则将这个组合的第一位替换成这个<26的数字  int explainInput(string s, int* a[]) { 	if (s.length() == 0) 	{ 		return 0; 	} 	else if (s.length() == 1) 	{ 		a[0] = new int[2]; 		a[0][0] = 1; 		a[0][1] = s[0] - '0'; 		return 1; 	}  	int ret = explainInput(s.substr(1), a); 	int head = s[0] - '0'; 	int rise = 0; 	for (int n = 0; n < ret; ++n) 	{ 		if (a[n] != nullptr) 		{ 			a[ret+rise] = new int[a[n][0]+2]; 			a[ret+rise][0] = a[n][0] + 1; 			a[ret+rise][1] = s[0] - '0';  			for (int k = 1; k <= a[n][0]; ++k) 			{ 				a[ret+rise][k+1] = a[n][k]; 			} 			++rise;  			if ((a[n][1] <= 6 && head == 2) || (a[n][1] < 10 && head == 1)) 			{ 				a[ret+rise] = new int[a[n][0]+1]; 				a[ret+rise][0] = a[n][0]; 				a[ret+rise][1] = head * 10 + a[n][1]; 				for (int k = 2; k <= a[n][0]; ++k) 				{ 					a[ret+rise][k] = a[n][k]; 				} 				++rise; 			} 			delete[] a[n]; 			a[n] = nullptr; 		} 	}  	return ret+rise; }  int _tmain(int argc, _TCHAR* argv[]) { 	int* a[100];  	int ret = explainInput("11111", a); 	for (int j = 0; j < ret; ++j) 	{ 		int* arr = a[j]; 		if (arr == nullptr) 		{ 			continue; 		} 		for (int i = 1; i <= arr[0]; ++i) 		{ 			cout << arr[i] << " "; 		} 		delete[] arr; 		cout << endl; 	} }

3楼说的对，分成两种情况

用递归就很好做了

用递归做，第一层用1位 和2位划分，然后两种情况分别做递归

优点像台阶问题

1 位或者两位 对应一个字母。

估计得用递归


Question: qiu da shen jie da

char *str 改成      char str[10] 或者      char *str = (char *)malloc(sizeof(char) * 10)

楼上正解 第一  #include <string.h> 头文件 你都不加的 报警告  第二  void main() 这是什么写法 这种写法是不规范的 也是不提倡的 int main()  第三 #define MAX_SIZE 1024 char str[MAX_SIZE];  第四   int IfHappyNum(int n) 这个函数没有返回值  第五程序代码风格有问题  第六    既然前五条与你提问的qiu da shen jie da都有问题  我不得不怀疑楼主的逻辑有问题 需要学计算机需要严谨的逻辑及超乎常人的发散能力

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

char *str;  //这个指针没初始化 sprintf(str,"%d",n);  //给没初始化的指针赋值，很危险

内存错误···

str未分配空间，运行会报错，而且int型变量居然可以用strlen统计长度。。。。


Question: 数组、指针问题

本文适用于机器为32位，编译器为VC6.0。  先来看下面一个例子： main() { int a[5]={0x11121314,0x21222324,0x31323334,0x41424344,0x51525354}; int *ptr1=(int *)(&a+1); int *ptr2=(int *)(a+1); printf("%x,%x",ptr1[-1],*ptr2); getch(); } 打印输出的结果是多少？第4行&a是不是写错了？数组名怎么还取地址呢？ 你可以试着在软件中编译运行一下，结果是51525354，21222324，没错，就是它了。你可以试着写以下程序再在计算机中编译运行下：  main()  {  int a[5]={0x11121314,0x21222324,0x31323334,0x41424344,0x51525354};  printf("%p\n%p\n",a,&a);  printf("%d\n%d\n",sizeof(a),sizeof(&a));  printf("%p\n%p",&a+1,a+1);  getch();  }  你可以看到前两行a和&a打印的结果是一样的（比如0012FF6C），后两行的结果是都是20，而&a+1的结果是0012FF6C，即a的起始地址后移20字节。看到这里对于a和&a的区别是不是有些眉目了？不错，a和&a的值虽然一样，但是前者表示的是数组a的首地址，进阶为数组元素长度，而后者也是表示数组a的首地址（或许有些人不同意我这个观点，对地址取地址应该是指向指针的指针呀。不过你注意了没有，a和&a值是一样的，试想如果这里表示的是指向指针的指针，那么a的地址和指向a的指针的地址可能一样么？两个指针都指向数组首地址，怎么会是指向指针的指针？还有一点需要强调，对一个指针进行sizeof运算，32位系统下应该得到4，而对数组名进行sizeof运算得到的结果却是20，这说明了什么？很显然，数组名虽然能够拿出来代表一个地址，但是它和指针还是有区别的，对它进行sizeof运算也不会得到指针的大小。不信？你可以试试sizeof(&a[0])和sizeof(a)，看看结果是不是相同），但是是将整个数组作为一个对象来看待的，进阶为整个数组长度。也就是说，a和&a虽然值相同，但是a是将所有数组元素看成一个个不同的个体来对待的，而&a是将整个数组作为一个整体来对待的。这里要强调的是，a+1和&a[1]其实是一样的，都是代表a数组向后偏移一个元素的地址，你可以再用sizeof关键字打印一下两个的值。但是a和&a[0]的意义相同么？若打印地址的话，两者确实是一样的，但是你也用sizeof打印下两者，一样么？再试试a+0呢？很显然，a和a+0是有区别的，但是a+0和&a[0]是含义相同的。所以，你可以说a+i和&a[i]含义相同，但是绝不能说a和&a[0]或a+0含义相同。所以&a+1后移20位为&a+sizeof(&a)，而a+1却是a+sizeof(a[i])。（《C语言深度解剖》认为在32为系统下sizeof(&a)的值仍为4，我觉得是不对的。他觉得是VC6.0错了，其实不止VC，其他很多编译器得到的结果也不会是4，这说明a和&a在C中本来就不是作为指针来用的，只是具有指针的部分性质而已。）ptr1是将&a+1强转为int类型指针，此时打印ptr1[-1]即将ptr指针前移sizeof(int)个字节，故打印结果是5。这样一来后面的也明了了，a+1的值为在数组a的首地址上后移sizeof(int)个字节，然后强转为int类型指针（其实强转并没有改变什么，原来类型即为整型指针，可以去掉强转），最后输出结果为21222324。  再想一下，如果将第一例第五行改为int *ptr2=(int *)((int)a+1);打印结果会是什么？ 这里要考虑数据在计算机中的存储模式：大端模式和小端模式。解释一下： 大端模式（Big_endian）：字数据的高字节存储在低地址中，而字数据的低字节则存放在高地址中。 小端模式（Little_endian）：字数据的高字节存储在高地址中，而字数据的低字节则存放在低地址中。 在大端模式下，a在计算机中存储如下（从低地址到高地址，一个十六进制数代表内存的一个字节，下同）： 0x11 0x12 0x13 0x14 0x21 0x22 0x23 0x24 0x31 0x32 0x33 0x34 0x41 0x42 0x43 0x44 0x51 0x52 0x53 0x54 在小端模式下，a在计算机中存储如下： 0x14 0x13 0x12 0x11 0x24 0x23 0x22 0x21 0x34 0x33 0x32 0x31 0x44 0x43 0x42 0x41 0x54 0x53 0x52 0x51 (int)a表示将a的首地址强转为整型数据（若原来是0012FF6C，转换后仍为0012FF6C，但是这时已经不是表示地址而是一个十六进制整型数了），这时+1代表整型数(int)a加1（变为0012FF6D），再把结果强转为整形指针，故指向的数据地址为0012FF6D，即上述存储去的第二个字节开始处。此时输出*ptr2，即输出a数组存储区中第二到第五字节组成的一个整型数，若为大端模式则输出12131421，若为小端模式则输出24111213。  原文请见：http://blog.csdn.net/draw5230/article/details/6699431

谢谢大家热心的回复～　 继续努力学～

sizeof(*&a) = sizeof(a) =5 *sizeof(int) ; 因为： a --->int[5]-->int *; &a ---> int (*)[5];  所以：&a+1， 指向数组a，后面的拥有5个元素的数组。 所以 (int *)(&a +1) == a + 5; a+1 第二个元素。 a + 5 第六个元素。

是的！ &a +1 指向了a数组后面一位了！也就是 &a+1 的值是a数组后面的地址值！ 指针类型的步长是和它的数据类型息息相关的！ int *p = &a +1; //指向了数据的后一位 p -1 ; 相前移动p指针类型的步长，int长度， 所以 p -1 指向了 a数组最后一个元素！ 后面依次类推！


Question: C指针

求值顺序是函数调用中应该注意的一个问题。所谓求值顺序是指对实参表中各量是自左至右使用还是自右至左使用。各版本编译系统对此规定不一。 回到楼主的问题。p = a + 3;//p指向a[3] printf("%d,%d＼n",*p,*p++); 楼主所使用的编译器采用自右向左的求值顺序，先计算*p++的值，再计算*p的值，计算*p++得到9后， p指向a[4],所以*p的值为11。 再举个例子： #include<stdio.h>  int main(int argc,char *argv[]) {     int i = 8;     printf("%d\n%d\n",i = i + 3; i = i - 2);     return 0; } 这段代码在楼主的编译器上运行得到的结果应该是： 9 6 而不是 11 9 原因同上，先计算i = i - 2得到6，再计算i = i + 3得到9。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

printf函数是从后面往前输出。 a+3就是9了，*p++的值还是9， 再输出*p，由于*p++了，所以*p就为11了。

引用 4 楼 zaixiankaifa 的回复:函数参数压栈顺序，是从右向左。 觉得这句话最有用  这个是相对编译器来说的！和语法没什么关系的， 现在只是记得Windows和Linux函数参数压栈的顺序是相反的，具体的不记得了！

函数参数压栈顺序，是从右向左。 觉得这句话最有用

C,C++ 的缺省调用约定分别是cdecl,stdcall 函数参数压栈顺序，是从右向左。 所以一般来说，求值顺序，也可能是这样的，这是比较正常的做法。  但是也可能函数调用前，先求所有参数的值，然后按照从右向左压栈。 虽然这么做很别扭，但是不代表编译器，不会这么做。 那么，这么做的编译器，就可以任意选择，参数的求值顺序。  但是，这里和求值顺序有关，但是关系不大。  主要是 ++ 操作，是有副作用的，这里是这个副作用的，生效时机问题。 这个时机是未定义的。  那么编译器，可以选择，++ 何时生效。   int a[]={1,5,7,9,11,13};main(){int *p;p=a+3;printf("%d,%d＼n",*p,*p++) 为什么答案是11,9   这很好解释，这个编译器，比较正常， 按照参数入栈顺序，计算参数的值，并随着计算，让++的结果生效。  于是 *p++ =9 ,p=a+4      *p =*(a+4) = 11; 所以 结果就是 11，9；  虽然有点反直觉，却是最正常的结果。 别的编译器，未必这么正常，就会产生另外的结果。

undefined behaviour 编译器不同，结果可能是9，11或11，9或9，9或11，11


Question: 递归法比较最大值

没什么问题 要么需要加个getchar(); 要么大概是大括号没加

没啥问题，程序好着呢！

这不就是把循环改成尾递归么。

引用 3 楼 tsakang 的回复:没啥问题，程序好着呢！  lz 发现什么问题？

main.c  #include <stdio.h>  int getMax(int a[], int n, int max) { 	if (n <= 0) return max; 	return getMax(a, n-1, max > a[n-1] ? max : a[n-1]);  }  int main(void) { 	//int getMax(int a[],int n,int max); 	int a[][4] = { 		{1, 1, 1, 1}, 		{1, 1, 1, 2}, 		{1, 1, 1, 3}, 		{1, 1, 1, 4}, 		{1, 1, 2, 1}, 		{1, 1, 2, 2}, 		{1, 1, 2, 3}, 		{1, 1, 2, 4}, 		{1, 1, 3, 1}, 		{1, 1, 3, 2}, 		{1, 1, 3, 3}, 		{1, 1, 3, 4}, 		{1, 1, 4, 1}, 		{1, 1, 4, 2}, 		{1, 1, 4, 3}, 		{1, 1, 4, 4}, 		{1, 2, 1, 1}, 		{1, 2, 1, 2}, 		{1, 2, 1, 3}, 		{1, 2, 1, 4}, 		{1, 2, 2, 1}, 		{1, 2, 2, 2}, 		{1, 2, 2, 3}, 		{1, 2, 2, 4}, 		{1, 2, 3, 1}, 		{1, 2, 3, 2}, 		{1, 2, 3, 3}, 		{1, 2, 3, 4}, 		{1, 2, 4, 1}, 		{1, 2, 4, 2}, 		{1, 2, 4, 3}, 		{1, 2, 4, 4}, 		{1, 3, 1, 1}, 		{1, 3, 1, 2}, 		{1, 3, 1, 3}, 		{1, 3, 1, 4}, 		{1, 3, 2, 1}, 		{1, 3, 2, 2}, 		{1, 3, 2, 3}, 		{1, 3, 2, 4}, 		{1, 3, 3, 1}, 		{1, 3, 3, 2}, 		{1, 3, 3, 3}, 		{1, 3, 3, 4}, 		{1, 3, 4, 1}, 		{1, 3, 4, 2}, 		{1, 3, 4, 3}, 		{1, 3, 4, 4}, 		{1, 4, 1, 1}, 		{1, 4, 1, 2}, 		{1, 4, 1, 3}, 		{1, 4, 1, 4}, 		{1, 4, 2, 1}, 		{1, 4, 2, 2}, 		{1, 4, 2, 3}, 		{1, 4, 2, 4}, 		{1, 4, 3, 1}, 		{1, 4, 3, 2}, 		{1, 4, 3, 3}, 		{1, 4, 3, 4}, 		{1, 4, 4, 1}, 		{1, 4, 4, 2}, 		{1, 4, 4, 3}, 		{1, 4, 4, 4}, 		{2, 1, 1, 1}, 		{2, 1, 1, 2}, 		{2, 1, 1, 3}, 		{2, 1, 1, 4}, 		{2, 1, 2, 1}, 		{2, 1, 2, 2}, 		{2, 1, 2, 3}, 		{2, 1, 2, 4}, 		{2, 1, 3, 1}, 		{2, 1, 3, 2}, 		{2, 1, 3, 3}, 		{2, 1, 3, 4}, 		{2, 1, 4, 1}, 		{2, 1, 4, 2}, 		{2, 1, 4, 3}, 		{2, 1, 4, 4}, 		{2, 2, 1, 1}, 		{2, 2, 1, 2}, 		{2, 2, 1, 3}, 		{2, 2, 1, 4}, 		{2, 2, 2, 1}, 		{2, 2, 2, 2}, 		{2, 2, 2, 3}, 		{2, 2, 2, 4}, 		{2, 2, 3, 1}, 		{2, 2, 3, 2}, 		{2, 2, 3, 3}, 		{2, 2, 3, 4}, 		{2, 2, 4, 1}, 		{2, 2, 4, 2}, 		{2, 2, 4, 3}, 		{2, 2, 4, 4}, 		{2, 3, 1, 1}, 		{2, 3, 1, 2}, 		{2, 3, 1, 3}, 		{2, 3, 1, 4}, 		{2, 3, 2, 1}, 		{2, 3, 2, 2}, 		{2, 3, 2, 3}, 		{2, 3, 2, 4}, 		{2, 3, 3, 1}, 		{2, 3, 3, 2}, 		{2, 3, 3, 3}, 		{2, 3, 3, 4}, 		{2, 3, 4, 1}, 		{2, 3, 4, 2}, 		{2, 3, 4, 3}, 		{2, 3, 4, 4}, 		{2, 4, 1, 1}, 		{2, 4, 1, 2}, 		{2, 4, 1, 3}, 		{2, 4, 1, 4}, 		{2, 4, 2, 1}, 		{2, 4, 2, 2}, 		{2, 4, 2, 3}, 		{2, 4, 2, 4}, 		{2, 4, 3, 1}, 		{2, 4, 3, 2}, 		{2, 4, 3, 3}, 		{2, 4, 3, 4}, 		{2, 4, 4, 1}, 		{2, 4, 4, 2}, 		{2, 4, 4, 3}, 		{2, 4, 4, 4}, 		{3, 1, 1, 1}, 		{3, 1, 1, 2}, 		{3, 1, 1, 3}, 		{3, 1, 1, 4}, 		{3, 1, 2, 1}, 		{3, 1, 2, 2}, 		{3, 1, 2, 3}, 		{3, 1, 2, 4}, 		{3, 1, 3, 1}, 		{3, 1, 3, 2}, 		{3, 1, 3, 3}, 		{3, 1, 3, 4}, 		{3, 1, 4, 1}, 		{3, 1, 4, 2}, 		{3, 1, 4, 3}, 		{3, 1, 4, 4}, 		{3, 2, 1, 1}, 		{3, 2, 1, 2}, 		{3, 2, 1, 3}, 		{3, 2, 1, 4}, 		{3, 2, 2, 1}, 		{3, 2, 2, 2}, 		{3, 2, 2, 3}, 		{3, 2, 2, 4}, 		{3, 2, 3, 1}, 		{3, 2, 3, 2}, 		{3, 2, 3, 3}, 		{3, 2, 3, 4}, 		{3, 2, 4, 1}, 		{3, 2, 4, 2}, 		{3, 2, 4, 3}, 		{3, 2, 4, 4}, 		{3, 3, 1, 1}, 		{3, 3, 1, 2}, 		{3, 3, 1, 3}, 		{3, 3, 1, 4}, 		{3, 3, 2, 1}, 		{3, 3, 2, 2}, 		{3, 3, 2, 3}, 		{3, 3, 2, 4}, 		{3, 3, 3, 1}, 		{3, 3, 3, 2}, 		{3, 3, 3, 3}, 		{3, 3, 3, 4}, 		{3, 3, 4, 1}, 		{3, 3, 4, 2}, 		{3, 3, 4, 3}, 		{3, 3, 4, 4}, 		{3, 4, 1, 1}, 		{3, 4, 1, 2}, 		{3, 4, 1, 3}, 		{3, 4, 1, 4}, 		{3, 4, 2, 1}, 		{3, 4, 2, 2}, 		{3, 4, 2, 3}, 		{3, 4, 2, 4}, 		{3, 4, 3, 1}, 		{3, 4, 3, 2}, 		{3, 4, 3, 3}, 		{3, 4, 3, 4}, 		{3, 4, 4, 1}, 		{3, 4, 4, 2}, 		{3, 4, 4, 3}, 		{3, 4, 4, 4}, 		{4, 1, 1, 1}, 		{4, 1, 1, 2}, 		{4, 1, 1, 3}, 		{4, 1, 1, 4}, 		{4, 1, 2, 1}, 		{4, 1, 2, 2}, 		{4, 1, 2, 3}, 		{4, 1, 2, 4}, 		{4, 1, 3, 1}, 		{4, 1, 3, 2}, 		{4, 1, 3, 3}, 		{4, 1, 3, 4}, 		{4, 1, 4, 1}, 		{4, 1, 4, 2}, 		{4, 1, 4, 3}, 		{4, 1, 4, 4}, 		{4, 2, 1, 1}, 		{4, 2, 1, 2}, 		{4, 2, 1, 3}, 		{4, 2, 1, 4}, 		{4, 2, 2, 1}, 		{4, 2, 2, 2}, 		{4, 2, 2, 3}, 		{4, 2, 2, 4}, 		{4, 2, 3, 1}, 		{4, 2, 3, 2}, 		{4, 2, 3, 3}, 		{4, 2, 3, 4}, 		{4, 2, 4, 1}, 		{4, 2, 4, 2}, 		{4, 2, 4, 3}, 		{4, 2, 4, 4}, 		{4, 3, 1, 1}, 		{4, 3, 1, 2}, 		{4, 3, 1, 3}, 		{4, 3, 1, 4}, 		{4, 3, 2, 1}, 		{4, 3, 2, 2}, 		{4, 3, 2, 3}, 		{4, 3, 2, 4}, 		{4, 3, 3, 1}, 		{4, 3, 3, 2}, 		{4, 3, 3, 3}, 		{4, 3, 3, 4}, 		{4, 3, 4, 1}, 		{4, 3, 4, 2}, 		{4, 3, 4, 3}, 		{4, 3, 4, 4}, 		{4, 4, 1, 1}, 		{4, 4, 1, 2}, 		{4, 4, 1, 3}, 		{4, 4, 1, 4}, 		{4, 4, 2, 1}, 		{4, 4, 2, 2}, 		{4, 4, 2, 3}, 		{4, 4, 2, 4}, 		{4, 4, 3, 1}, 		{4, 4, 3, 2}, 		{4, 4, 3, 3}, 		{4, 4, 3, 4}, 		{4, 4, 4, 1}, 		{4, 4, 4, 2}, 		{4, 4, 4, 3}, 		{4, 4, 4, 4} 	}; 	int n, i, max;  	//printf("请输入四个数:"); 	//for (n = 0; n < 4; n++) 	//	scanf("%d", &a[n]); 	//for (n = 0; n < 4; n++) 	//	printf("%d ", a[n]);  	for (n = 0; n < 256; n++) { 		//printf("这4个数的最大值为:%d\n", getMax(a, 4, a[0])); 		printf("MAX["); 		for (i = 0; i < 4; i++) 		{ 			if (i != 3) 				printf("%d,", a[n][i]); 			else 				printf("%d", a[n][i]); 		} 		printf("] = "); 		printf("%d\n", getMax(a[n], 4, a[n][0])); 		//printf("这4个数的最大值为:%d\n", getMax(a[n], 4, a[n][0])); 	}  	getch(); 	return 0; }  输出： MAX[1,1,1,1] = 1 MAX[1,1,1,2] = 2 MAX[1,1,1,3] = 3 MAX[1,1,1,4] = 4 MAX[1,1,2,1] = 2 MAX[1,1,2,2] = 2 MAX[1,1,2,3] = 3 MAX[1,1,2,4] = 4 MAX[1,1,3,1] = 3 MAX[1,1,3,2] = 3 MAX[1,1,3,3] = 3 MAX[1,1,3,4] = 4 MAX[1,1,4,1] = 4 MAX[1,1,4,2] = 4 MAX[1,1,4,3] = 4 MAX[1,1,4,4] = 4 MAX[1,2,1,1] = 2 MAX[1,2,1,2] = 2 MAX[1,2,1,3] = 3 MAX[1,2,1,4] = 4 MAX[1,2,2,1] = 2 MAX[1,2,2,2] = 2 MAX[1,2,2,3] = 3 MAX[1,2,2,4] = 4 MAX[1,2,3,1] = 3 MAX[1,2,3,2] = 3 MAX[1,2,3,3] = 3 MAX[1,2,3,4] = 4 MAX[1,2,4,1] = 4 MAX[1,2,4,2] = 4 MAX[1,2,4,3] = 4 MAX[1,2,4,4] = 4 MAX[1,3,1,1] = 3 MAX[1,3,1,2] = 3 MAX[1,3,1,3] = 3 MAX[1,3,1,4] = 4 MAX[1,3,2,1] = 3 MAX[1,3,2,2] = 3 MAX[1,3,2,3] = 3 MAX[1,3,2,4] = 4 MAX[1,3,3,1] = 3 MAX[1,3,3,2] = 3 MAX[1,3,3,3] = 3 MAX[1,3,3,4] = 4 MAX[1,3,4,1] = 4 MAX[1,3,4,2] = 4 MAX[1,3,4,3] = 4 MAX[1,3,4,4] = 4 MAX[1,4,1,1] = 4 MAX[1,4,1,2] = 4 MAX[1,4,1,3] = 4 MAX[1,4,1,4] = 4 MAX[1,4,2,1] = 4 MAX[1,4,2,2] = 4 MAX[1,4,2,3] = 4 MAX[1,4,2,4] = 4 MAX[1,4,3,1] = 4 MAX[1,4,3,2] = 4 MAX[1,4,3,3] = 4 MAX[1,4,3,4] = 4 MAX[1,4,4,1] = 4 MAX[1,4,4,2] = 4 MAX[1,4,4,3] = 4 MAX[1,4,4,4] = 4 MAX[2,1,1,1] = 2 MAX[2,1,1,2] = 2 MAX[2,1,1,3] = 3 MAX[2,1,1,4] = 4 MAX[2,1,2,1] = 2 MAX[2,1,2,2] = 2 MAX[2,1,2,3] = 3 MAX[2,1,2,4] = 4 MAX[2,1,3,1] = 3 MAX[2,1,3,2] = 3 MAX[2,1,3,3] = 3 MAX[2,1,3,4] = 4 MAX[2,1,4,1] = 4 MAX[2,1,4,2] = 4 MAX[2,1,4,3] = 4 MAX[2,1,4,4] = 4 MAX[2,2,1,1] = 2 MAX[2,2,1,2] = 2 MAX[2,2,1,3] = 3 MAX[2,2,1,4] = 4 MAX[2,2,2,1] = 2 MAX[2,2,2,2] = 2 MAX[2,2,2,3] = 3 MAX[2,2,2,4] = 4 MAX[2,2,3,1] = 3 MAX[2,2,3,2] = 3 MAX[2,2,3,3] = 3 MAX[2,2,3,4] = 4 MAX[2,2,4,1] = 4 MAX[2,2,4,2] = 4 MAX[2,2,4,3] = 4 MAX[2,2,4,4] = 4 MAX[2,3,1,1] = 3 MAX[2,3,1,2] = 3 MAX[2,3,1,3] = 3 MAX[2,3,1,4] = 4 MAX[2,3,2,1] = 3 MAX[2,3,2,2] = 3 MAX[2,3,2,3] = 3 MAX[2,3,2,4] = 4 MAX[2,3,3,1] = 3 MAX[2,3,3,2] = 3 MAX[2,3,3,3] = 3 MAX[2,3,3,4] = 4 MAX[2,3,4,1] = 4 MAX[2,3,4,2] = 4 MAX[2,3,4,3] = 4 MAX[2,3,4,4] = 4 MAX[2,4,1,1] = 4 MAX[2,4,1,2] = 4 MAX[2,4,1,3] = 4 MAX[2,4,1,4] = 4 MAX[2,4,2,1] = 4 MAX[2,4,2,2] = 4 MAX[2,4,2,3] = 4 MAX[2,4,2,4] = 4 MAX[2,4,3,1] = 4 MAX[2,4,3,2] = 4 MAX[2,4,3,3] = 4 MAX[2,4,3,4] = 4 MAX[2,4,4,1] = 4 MAX[2,4,4,2] = 4 MAX[2,4,4,3] = 4 MAX[2,4,4,4] = 4 MAX[3,1,1,1] = 3 MAX[3,1,1,2] = 3 MAX[3,1,1,3] = 3 MAX[3,1,1,4] = 4 MAX[3,1,2,1] = 3 MAX[3,1,2,2] = 3 MAX[3,1,2,3] = 3 MAX[3,1,2,4] = 4 MAX[3,1,3,1] = 3 MAX[3,1,3,2] = 3 MAX[3,1,3,3] = 3 MAX[3,1,3,4] = 4 MAX[3,1,4,1] = 4 MAX[3,1,4,2] = 4 MAX[3,1,4,3] = 4 MAX[3,1,4,4] = 4 MAX[3,2,1,1] = 3 MAX[3,2,1,2] = 3 MAX[3,2,1,3] = 3 MAX[3,2,1,4] = 4 MAX[3,2,2,1] = 3 MAX[3,2,2,2] = 3 MAX[3,2,2,3] = 3 MAX[3,2,2,4] = 4 MAX[3,2,3,1] = 3 MAX[3,2,3,2] = 3 MAX[3,2,3,3] = 3 MAX[3,2,3,4] = 4 MAX[3,2,4,1] = 4 MAX[3,2,4,2] = 4 MAX[3,2,4,3] = 4 MAX[3,2,4,4] = 4 MAX[3,3,1,1] = 3 MAX[3,3,1,2] = 3 MAX[3,3,1,3] = 3 MAX[3,3,1,4] = 4 MAX[3,3,2,1] = 3 MAX[3,3,2,2] = 3 MAX[3,3,2,3] = 3 MAX[3,3,2,4] = 4 MAX[3,3,3,1] = 3 MAX[3,3,3,2] = 3 MAX[3,3,3,3] = 3 MAX[3,3,3,4] = 4 MAX[3,3,4,1] = 4 MAX[3,3,4,2] = 4 MAX[3,3,4,3] = 4 MAX[3,3,4,4] = 4 MAX[3,4,1,1] = 4 MAX[3,4,1,2] = 4 MAX[3,4,1,3] = 4 MAX[3,4,1,4] = 4 MAX[3,4,2,1] = 4 MAX[3,4,2,2] = 4 MAX[3,4,2,3] = 4 MAX[3,4,2,4] = 4 MAX[3,4,3,1] = 4 MAX[3,4,3,2] = 4 MAX[3,4,3,3] = 4 MAX[3,4,3,4] = 4 MAX[3,4,4,1] = 4 MAX[3,4,4,2] = 4 MAX[3,4,4,3] = 4 MAX[3,4,4,4] = 4 MAX[4,1,1,1] = 4 MAX[4,1,1,2] = 4 MAX[4,1,1,3] = 4 MAX[4,1,1,4] = 4 MAX[4,1,2,1] = 4 MAX[4,1,2,2] = 4 MAX[4,1,2,3] = 4 MAX[4,1,2,4] = 4 MAX[4,1,3,1] = 4 MAX[4,1,3,2] = 4 MAX[4,1,3,3] = 4 MAX[4,1,3,4] = 4 MAX[4,1,4,1] = 4 MAX[4,1,4,2] = 4 MAX[4,1,4,3] = 4 MAX[4,1,4,4] = 4 MAX[4,2,1,1] = 4 MAX[4,2,1,2] = 4 MAX[4,2,1,3] = 4 MAX[4,2,1,4] = 4 MAX[4,2,2,1] = 4 MAX[4,2,2,2] = 4 MAX[4,2,2,3] = 4 MAX[4,2,2,4] = 4 MAX[4,2,3,1] = 4 MAX[4,2,3,2] = 4 MAX[4,2,3,3] = 4 MAX[4,2,3,4] = 4 MAX[4,2,4,1] = 4 MAX[4,2,4,2] = 4 MAX[4,2,4,3] = 4 MAX[4,2,4,4] = 4 MAX[4,3,1,1] = 4 MAX[4,3,1,2] = 4 MAX[4,3,1,3] = 4 MAX[4,3,1,4] = 4 MAX[4,3,2,1] = 4 MAX[4,3,2,2] = 4 MAX[4,3,2,3] = 4 MAX[4,3,2,4] = 4 MAX[4,3,3,1] = 4 MAX[4,3,3,2] = 4 MAX[4,3,3,3] = 4 MAX[4,3,3,4] = 4 MAX[4,3,4,1] = 4 MAX[4,3,4,2] = 4 MAX[4,3,4,3] = 4 MAX[4,3,4,4] = 4 MAX[4,4,1,1] = 4 MAX[4,4,1,2] = 4 MAX[4,4,1,3] = 4 MAX[4,4,1,4] = 4 MAX[4,4,2,1] = 4 MAX[4,4,2,2] = 4 MAX[4,4,2,3] = 4 MAX[4,4,2,4] = 4 MAX[4,4,3,1] = 4 MAX[4,4,3,2] = 4 MAX[4,4,3,3] = 4 MAX[4,4,3,4] = 4 MAX[4,4,4,1] = 4 MAX[4,4,4,2] = 4 MAX[4,4,4,3] = 4 MAX[4,4,4,4] = 4  没发现什么问题。

//scanf前面加一个空格 scanf(" %d",&a[n]); //或者 加一个    getchar();  //其他还有什么问题


Question: 热烈庆祝本人受关注人数即将突破4000大关！散分！！＋征集各种语言实现“运行时修改代码”例子。

#pragma comment(linker,"/SECTION:.text,RW")  #include <stdio.h> int *p;  int p2()  {      	int a=87;  	a=a+15;      	return a;  }   int main()  {       	int o; 	p=(int *)((char *)p2+59);     *p=0xE883FC45; 	o=8; 	printf("p2()==%d\n",p2()); 	scanf("%d",p); 	return 0;  }  最后的输出结果是【p2()=72】，嘿嘿，坐等领分。。。

已经关注赵老师

不错……顶一个

接分走人

赵老师是我的偶像，生命不息，学习不止！

这位 赵老师经常见到。

送粉   这代码看不太懂...

仔细看，赵老的话其实很有道理呢。。

引用 83 楼 xiyuyan 的回复:首先祝贺，同时不知道4000关注群有啥好处？ 运行时修改代码不是好习惯，刚学指针的新手都会。 运行时能修改程序自身的可执行文件（修改硬盘文件）才叫本事。  习语言示例 〖 #包含 “习语言系统.接口”  无返回值  主函数(无参数) { 	整数  学员[50]，张三，修改标志=1;	 	格式输入（“%（整数）”，&张三）； 	学员[50] = 张三 + 100；   // 第一次修改程序； 	格式输出（“%（整数）”，张三）； }  〗  呵呵，来参观赵老师，呵呵，修改自身，可以的啊，不过麻烦很多，程序在运行，自身文件时无法写入的，不过可以强制写入(ring0下，强制去掉一些相关东东)，也可以用先寄托在其他进程内，然后结束进程，在其他进程内寄托的副本，来修改真实文件

刚刚注意到赵老师的帖子啊 呵呵

不明觉厉

老赵，屌炸天呀。

我晕，我明明看的是另外一个哥们的帖子，怎么突然跑赵老师这边来了

我这里有用thunk封装的windows类，用到了运行时修改代码。使用的MFC一样的技术，thunk. http://blog.csdn.net/sdhexu

新人表示看不明白！

自顶！

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

修改数据码段实现之 把数据当代码调用 数据段，改成代码段即可 Windows 加载程序就是这么干的。 你的程序，对他就是数据。 加载后，把你的程序当作代码启动。


Question: 结构体内函数指针以及const常量的赋值问题

#include <stdio.h> struct A {   const unsigned int a;   void (*set)(void); };  void set_enable(void) {    printf("set_enable!\n"); }    int main() {   struct A b=   {    9,    set_enable   };   return 0; }

引用 20 楼 miaoxiangbiancheng 的回复:引用 19 楼 z1179675084 的回复:这个和const常量赋值有什么关系呢？const常量是结构体内的成员 自己写的http://blog.csdn.net/z1179675084/article/details/12617711

const常量 不能赋值，只能初始化。  如果结构体含有常量，则常量部分，C只能初始化整个结构的时候，初始化常量，  C++还可以在构造函数的初始化表里初始化常量。 C++结构体也可以像类一样，有成员函数，包括析构函数，构造函数。 不过，有构造函数的结构体，初始化方式和类一样。和C的结构体就不一样了。  C++11，又添加了，新的初始化方式，即象C,又像C++，其实都不像。  常量只有一次初始化的机会。 C的结构体含有常量，无法直接整体赋值。 C++如果有，拷贝运算符，可以整体的，对非常量成员部分赋值。

dummy我建议你定义的一个宏 比如，#define dummy 0xAAAAAAAA

引用 3 楼 miaoxiangbiancheng 的回复:[quote=引用 1 楼 pbdwadr 的回复:] struct A b={    9,    set_enable, }; 或者用gcc编译（c语言，不是c++的规范）你的这种方式是有效的，解决对一个成员赋值的问题，谢谢了。   现在面临的另一个问题是，对含有多个成员的结构体中的任意少数接个成员赋值，其他不进行初始化，如何处理？[/quote]  直接指定给成员变量赋值即可。 struct A b; b.set = set_enable;

引用 12 楼 drlsdrls 的回复:哪个不用你就把哪个设为dummy不就行了 struct A b={    dummy,//point    9,//const };dummy表示什么?    可以表明我不使用它？

引用 8 楼 drlsdrls 的回复:struct A b={    9,    set_enable, };  既然已经是const了，那只能初始化，不能赋值。如果你只想对第二个变量初始化或者赋值，那么第一个就随便给一个值，比如你define一个dummy放到那里就行了没错，const变量只能初始化，如果它是在成员中的第一个位置，初始化是容易的，不是的话就很麻烦了。比如上面例子中的const unsigned int a;放在第二个位置，假设第一个成员 void (*set)(void);不需要使用，那么该如何初始化？

引用 9 楼 buyong 的回复:为什么吧一个宏（常数）赋值给一个void*这是代码移植过程中碰到的，属于bootloader（LK）的代码，我也是编译过程中发现问题的。但发现问题了就要解决啊，所以特来请教大家如何处理。

为什么吧一个宏（常数）赋值给一个void*

引用 5 楼 pbdwadr 的回复:[quote=引用 3 楼 miaoxiangbiancheng 的回复:] [quote=引用 1 楼 pbdwadr 的回复:] struct A b={    9,    set_enable, }; 或者用gcc编译（c语言，不是c++的规范）你的这种方式是有效的，解决对一个成员赋值的问题，谢谢了。   现在面临的另一个问题是，对含有多个成员的结构体中的任意少数接个成员赋值，其他不进行初始化，如何处理？[/quote]  直接指定给成员变量赋值即可。 struct A b; b.set = set_enable;[/quote]此种方法可行。  但如果使用宏对结构体成员赋值，会出现expression must be a modifiable lvalue 是何原因呢？ 在头文件中有如下声明： struct pll_vote_clk { 	unsigned long rate;  	void *const en_reg; 	const uint32_t en_mask;  	void *const status_reg; 	const uint32_t status_mask;  	struct clk *parent; 	struct clk c; }; 在源文件中先定义，在赋值初始化： static struct pll_vote_clk gpll0_clk_src; gpll0_clk_src.en_reg       = (void *) APCS_GPLL_ENA_VOTE; APCS_GPLL_ENA_VOTE是个宏， #define APCS_GPLL_ENA_VOTE                   (CLK_CTL_BASE + 0x1480) 出现了编译错误，如上面所说的。  请问，该如何赋值，或者对值进行什么调整呢？  特别是带有const的变量如何赋值。

抱歉 4)用 已经初始化的 变量，常量，给变量，常量赋值。 应该是： 4)用 已经初始化的 变量，常量，给变量赋值。

这个和const常量赋值有什么关系呢？

那四楼也说过了，不过第三种方法有特别需要注意的地方，比如结构体里面有指针。你直接复制相当于两个结构体中的指针指向了同一片内存，而动态申请的内存肯定会在程序中释放，假如其中的一个释放了，那另一个的指针指向就会有问题了。

结构体或者类的初始化只能跳过后面的参数, 而不能跳过前面的.  struct A b={1};//跳过第二个. struct A a={1,set_enable}; //全部赋值.  如果想跳过, 就只能一个一个赋值.  struct A b; b.a = xxx; b.set = set_enable;

引用 15 楼 z1179675084 的回复:这是搞啥呢？一楼说的很清楚了，你那个方法是gcc里面支持的，你用dev-c++编译器试试，肯定能过这个我知道，因为我也单独在Gcc里试过了，使用相同的服务器进行，是没问题的。     实际在工程中使用的是交叉编译器，使用相同的服务器进行编译，其他人编译LK没有问题，（LK中含有我要移植到boot_images上的CLK相关代码），而我移植过程中却出现这类的编译错误。       所以想找下是否有其他可行的替代方法。

引用 楼主 miaoxiangbiancheng 的回复:在头文件head.h中声明了结构体： struct A {   const unsigned int a;   void (*set)(void); };  在源文件source.c中先定义了函数，且定义了结构体并赋值： void set_enable(void) {    printf("set_enable!\n"); }  struct A b={    .a=9,    .set=set_enable, }; 编译的时候会出错，指出.a ,  .set这两行Error:  #29: expected an expression 说明，这是在工程中的一个编译错误，经过测试在头文件和源文件中就进行如上操作都会报这样的错误。 有谁碰过请帮忙指出错误，谢谢！  1) 初始化：  struct A b={    9,set_enable, };  2)用 已经初始化的 变量，常量，初始化变量，常量。 struct A a =b; 3) 直接对成员变量赋值。 struct A  c; c.a=9; c.set =set_enable; 4)用 已经初始化的 变量，常量，给变量，常量赋值。 struct A  d; d = b;  //======================= //  这个在pascal里，见过这种方法初始化。  //  //  struct A b={    .a=9,    .set=set_enable, };


Question: 求C语言对称函数程序

你看到的东西，都是一笔一笔的画出来的。

[quote=引用 5 楼 zhao4zhong1 的回复:] ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.WIN32COM.v10.en/gdicpp/GDIPlus/usingGDIPlus/usingimagesbitmapsandmetafiles/rotatingreflectingandskewingimages.htm 这是什么啊？？网址打不开

我想画象棋棋盘，线条，棋子能直接对称过去显示！

ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.WIN32COM.v10.en/gdicpp/GDIPlus/usingGDIPlus/usingimagesbitmapsandmetafiles/rotatingreflectingandskewingimages.htm Rotating, Reflecting, and Skewing Images   --------------------------------------------------------------------------------  You can rotate, reflect, and skew an image by specifying destination points for the upper-left, upper-right, and lower-left corners of the original image. The three destination points determine an affine transformation that maps the original rectangular image to a parallelogram. (The lower-right corner of the original image is mapped to the fourth corner of the parallelogram, which is calculated from the three specified destination points.)  For example, suppose the original image is a rectangle with upper-left corner at (0, 0), upper-right corner at (100, 0), and lower-left corner at (0, 50). Now suppose we map those three points to destination points as follows.  Original point Destination point  Upper-left (0, 0) (200, 20)  Upper-right (100, 0) (110, 100)  Lower-left (0, 50) (250, 30)   The following illustration shows the original image and the image mapped to the parallelogram. The original image has been skewed, reflected, rotated, and translated. The x-axis along the top edge of the original image is mapped to the line that runs through (200, 20) and (110, 100). The y-axis along the left edge of the original image is mapped to the line that runs through (200, 20) and (250, 30).    The following example produces the images shown in the preceding illustration.  Point destinationPoints[] = {    Point(200, 20),   // destination for upper-left point of original    Point(110, 100),  // destination for upper-right point of original    Point(250, 30)};  // destination for lower-left point of original Image image(L"Stripes.bmp"); // Draw the image unaltered with its upper-left corner at (0, 0). graphics.DrawImage(&image, 0, 0); // Draw the image mapped to the parallelogram. graphics.DrawImage(&image, destinationPoints, 3);  The following illustration shows a similar transformation applied to a photographic image.    The following illustration shows a similar transformation applied to a metafile.     --------------------------------------------------------------------------------  © 2005 Microsoft Corporation. All rights reserved.

TextOut

首先： 你对称 要对汉字的中心区域进行。 然后考虑汉字本身是否对称显示。 其次：要考虑如何对称 1）中心对称 2）轴对称 3）处理好对称后如何显示。    立体感强的三维图像是透视图。    其他一般是二维平面图形；    最多是个投影图形。

相对轴对称？相对远点对称？都是简单的数学吧....

楼主，请把问题描述清楚，越清楚越好！


Question: 结构体数组指针的使用

举例 VC6： //structs.c #include<stdio.h> typedef struct tag_div_type{ 	long q,r; }div_type;   div_type div_long( long x,long y) { 	div_type d; 	d.q =x / y; 	d.r =x % y; 	return d; }  void print(const div_type *pdiv) { 	printf("%ld,%ld\n",pdiv->q,pdiv->r ); }  int main(){ 	div_type a =div_long(100,37); 	div_type b,c; 	b = a; 	c= a; 	print(&a); 	print(&b); 	print(&c); 	getchar(); 	return 0; }  输出： 2,26 2,26 2,26

C++是可以的； C现在早就可以了吧？ 结构体不能进行整体赋值操作，似乎是老黄历了吧。  我等老古董，也许会说出这种话。 不知你说的可是标准？？？？

引用 5 楼 max_min_ 的回复:[quote=引用 3 楼 lubyam 的回复:] [quote=引用 1 楼 lubyam 的回复:] 不知道  是不是你想要的。。仅供参考！  struct AAA *tStr=new(struct AAA *)malloc(sizeof(struct AAA )); tStr.a1='a'; tStr.b1='b'; memcpy(tStr.yy,"Hello World!",sizeof("Hello World!"));   饿，，运算符用错了     struct AAA *tStr=new(struct AAA *)malloc(sizeof(struct AAA )); tStr->a1='a'; tStr->b1='b'; memcpy(tStr->yy,"Hello World!",sizeof("Hello World!")); [/quote]  用了new 就不要用malloc ，两个一起是怎么回事呢？释放都不晓得要怎么弄了！[/quote] 额。。弄错了。。。。使用malloc

引用 1 楼 lubyam 的回复:不知道  是不是你想要的。。仅供参考！  struct AAA *tStr=new(struct AAA *)malloc(sizeof(struct AAA )); tStr.a1='a'; tStr.b1='b'; memcpy(tStr.yy,"Hello World!",sizeof("Hello World!"));   god code

引用 3 楼 lubyam 的回复:[quote=引用 1 楼 lubyam 的回复:] 不知道  是不是你想要的。。仅供参考！  struct AAA *tStr=new(struct AAA *)malloc(sizeof(struct AAA )); tStr.a1='a'; tStr.b1='b'; memcpy(tStr.yy,"Hello World!",sizeof("Hello World!"));   饿，，运算符用错了     struct AAA *tStr=new(struct AAA *)malloc(sizeof(struct AAA )); tStr->a1='a'; tStr->b1='b'; memcpy(tStr->yy,"Hello World!",sizeof("Hello World!")); [/quote]  用了new 就不要用malloc ，两个一起是怎么回事呢？释放都不晓得要怎么弄了！

rxData* pData=new rxData[n]；//n为单元数

引用 1 楼 lubyam 的回复:不知道  是不是你想要的。。仅供参考！  struct AAA *tStr=new(struct AAA *)malloc(sizeof(struct AAA )); tStr.a1='a'; tStr.b1='b'; memcpy(tStr.yy,"Hello World!",sizeof("Hello World!"));   饿，，运算符用错了     struct AAA *tStr=new(struct AAA *)malloc(sizeof(struct AAA )); tStr->a1='a'; tStr->b1='b'; memcpy(tStr->yy,"Hello World!",sizeof("Hello World!"));

typedef struct AAA {     u_char a1;     u_char b1;     u_char yy[64];      }rxData;  int main() {     rxData rxArr[2] = {0};     rxData data1 = {'a', 'b', "test1\n"};     rxData data2 = {'c', 'd', "test2\n"};     rxArr[0] = data1;     rxArr[1] = data2;

结构体不能进行整体赋值操作的（只能初始化的时候做，而且，对于结构体中字符数组的部分，还必须用字面字符串），貌似C99中有严格规定，lz可以百度一下

你的意思是使用指针数组呗？  struct AAA **base = malloc(sizeof(struct AAA *)*N); 可以把这N个循环使用 收到一个数据时 分配结点空间，相应的填入数据 struct AAA *data = malloc(sizeof(struct AAA));  然后把data挂到base指针数组里面去 base[i] = data;

引用 9 楼 Jennypan2009 的回复:[quote=引用 8 楼 lubyam 的回复:]  struct AAA *tStr=(struct AAA *)malloc(sizeof(struct AAA )); tStr->a1='a'; tStr->b1='b'; memcpy(tStr->yy,"Hello World!",sizeof("Hello World!"));   如果有多个数据是不是将tStr++后,再进行赋值操作?[/quote]    struct AAA *tStr=(struct AAA *)malloc(sizeof(struct AAA )* n);//这里的n就是你想要几个 tStr->a1='a'; tStr->b1='b'; memcpy(tStr->yy,"Hello World!",sizeof("Hello World!"));   恩，上面写错了。。。

引用 9 楼 Jennypan2009 的回复:[quote=引用 8 楼 lubyam 的回复:]  struct AAA *tStr=(struct AAA *)malloc(sizeof(struct AAA )); tStr->a1='a'; tStr->b1='b'; memcpy(tStr->yy,"Hello World!",sizeof("Hello World!"));   如果有多个数据是不是将tStr++后,再进行赋值操作?[/quote]    struct AAA *tStr=(struct AAA *)malloc(sizeof(struct AAA * n));//这里的n就是你想要几个 tStr->a1='a'; tStr->b1='b'; memcpy(tStr->yy,"Hello World!",sizeof("Hello World!"));  [/ 恩

引用 8 楼 lubyam 的回复: struct AAA *tStr=(struct AAA *)malloc(sizeof(struct AAA )); tStr->a1='a'; tStr->b1='b'; memcpy(tStr->yy,"Hello World!",sizeof("Hello World!"));   如果有多个数据是不是将tStr++后,再进行赋值操作?


Question: 在windows上使用libevent

windows 下的标准输入不是套接字，而是一个句柄。

自已顶顶。。。


Question: 用什么软件可以画坐标系

win+R  mspaint

几何画板

引用 3 楼 JiMoKuangXiangQu 的回复:WORD, EXCEL, VISO, CAD都可以吧。 能具体说说怎么画布

WORD, EXCEL, VISO, CAD都可以吧。

引用 1 楼 u011779875 的回复:什么叫用什么软件   MATLAB  我现在用VS C++开发 Unity 3d 可以  directX 3d  opencv貌似也可以  我就想画个图，不需要软件编程

PhotoShop, word , CAD

引用 5 楼 zhao4zhong1 的回复:几何画板 提醒：这是一个软件的名字。

软件都有这个功能；

铅笔一支 2B牌的 纸一张   非卫生用的


Question: 最近写一些C语言入门算法方面的文章，有兴趣可以来看看

嗯嗯 看看

赞一个！推荐一个！

泪流满面

看你博客，是什么都搞啊！C语言相关博客写的不好！乱

支持啊，顶一个

赞一个mark

看不到主题！！！

mark

赞一个。 最近，也打算开个C语言系列的博客，从硬件系统，汇编，编译，操作系统角度来理解C。

mark,支持

这个必须mark一下

还不错！就是感觉想一个广告！

mark

干货什么的最有爱了

必须的支持，顶

学习一下


Question: 搜索文件并将文件按名称排序功能的问题

引用 17 楼 uuuououlcz 的回复:[quote=引用 14 楼 zhao4zhong1 的回复:] 用qsort函数。  qsort函数好像只能对连续存储的数组进行排序哦[/quote] 请先把文件列表保存到数组中。

引用 18 楼 zhao4zhong1 的回复:[quote=引用 17 楼 uuuououlcz 的回复:] [quote=引用 14 楼 zhao4zhong1 的回复:] 用qsort函数。  qsort函数好像只能对连续存储的数组进行排序哦[/quote] 请先把文件列表保存到数组中。[/quote]  嗯，貌似STL list排序时，也建议先保存到vector，再sort, 再存回list

用qsort函数。

就是一个排序就好，对链表进行排序

否则的话，在文件系统搜索结果的函数里面增加一个hook，然后再外面调用的时候把自己排序的函数hook进去，然后再返回结果。

引用 2 楼 huabinsir 的回复:和文件系统有关系吗? 若是jffs2 如何处理呢? 没了解楼主的意图，以为是要在文件系统里面增加这个功能。 如果不是，那按照楼上那些兄弟方法就行了。

引用 9 楼 buyong 的回复:std::list::sort  第三方的小系统，没有这些封装。 只能进行基础的排序.

std::list::sort

这和文件系统无关吧

搜索到文件之后，排列之前，进行一次排序操作！ 应该在链表中对文件名进行排序操作一次就好！

引用 5 楼 huabinsir 的回复:是对链表进行排序? 恩，对链表 按 文件名排序就好了。

是对链表进行排序?

搜索到的结果放到 链表中.

你搜索到的结果放到什么地方的呢？》  char* 数组？

和文件系统有关系吗? 若是jffs2 如何处理呢?

不知道楼主用的什么文件系统，jffs2吗？还是yaffs？

引用 14 楼 zhao4zhong1 的回复:用qsort函数。  qsort函数好像只能对连续存储的数组进行排序哦

写个了链表排序给你，可供参考：  typedef int (*pFun)(struct node* a, struct node* b); struct node* sortList(struct node* head, pFun cmp) {     struct node *p, *q, *pre;     if(head == NULL || head->next == NULL) return head;     //insertion sort     p = head->next;     head->next = NULL;     for(; p; ){				//p points to the node to be added into the ordered list         for(pre = NULL, q = head; q; pre = q, q = q->next){ 	    if(cmp(p, q) < 0) break;	//should put p in front of q 	}         if(pre == NULL){		//p should be the head 	    pre = p->next;             p->next = head; 	    head = p; 	    p = pre;			//p points to next node now 	}         else{				//p should be after pre and before q             pre->next = p; 	    pre->next->next = q;             p = p->next;		//p points to next node now 	}     }     return head; }

库中没有排序函数吗？  你也可以把搜索结果截取出来，自己排序。采用链表或者顺序表。顺序表建议采用记录索引方式排序，避免数据的移动


Question: 关于做界面的问题

引用 楼主 lilin_colin 的回复:这学期学的数据库，老师叫我们做一个学生管理系统，要结合数据库来做。  之前自己用纯C用链表和结构体做过相关系统，但是在是在DOS界面运行的，现在老师要求有界面。  数据库方面没有太大的问题，主要是做界面这个问题，用MFC做感觉好难，那些东西很多，而且感觉很难理解。  要求的功能也很简单，就是跟数据库相对应的增，删，改，查。网上没有具体项目的视频，全是 MFC教程。  不知道大神有没有好建议，真的要学习MFC吗？ 可以学习一下，了解一下思想，不要做过深的学习，毕竟这个框架现在使用面不是很广了。

引用 2 楼 lilin_colin 的回复:[quote=引用 1 楼 user-2 的回复:] 推荐从零开始学习下Qt 可以先有目的性的完成手动上的任务！后期好好学习Qt！学好了，再美化， 也算是以后找工作的一个亮点！  QT在ubuntu里用过，感觉很好，很方便，还真不知windows上也能装QT，我去查下资料，谢谢！[/quote]  qt是跨平台的！不像MFC那么局限的！

引用 1 楼 user-2 的回复:推荐从零开始学习下Qt 可以先有目的性的完成手动上的任务！后期好好学习Qt！学好了，再美化， 也算是以后找工作的一个亮点！  QT在ubuntu里用过，感觉很好，很方便，还真不知windows上也能装QT，我去查下资料，谢谢！


Question: 请教一个问题

引用 4 楼 max_min_ 的回复:[quote=引用 3 楼 u012207185 的回复:] [quote=引用 2 楼 max_min_ 的回复:] 直接用鼠标拖拽到里面就好了吧！ 试试 把代码拖到命令行里去？还是把什么拖到什么地方去？[/quote]  生成的可执行文件丢进去就好！ 如果还没生成repeat 则 项目   ----   属性   ----   链接器   ----   常规  ----   输出文件 （Release/xx.exe）  [/quote] 谢谢斑竹啊，成功了！

引用 3 楼 u012207185 的回复:[quote=引用 2 楼 max_min_ 的回复:] 直接用鼠标拖拽到里面就好了吧！ 试试 把代码拖到命令行里去？还是把什么拖到什么地方去？[/quote]  生成的可执行文件丢进去就好！ 如果还没生成repeat 则 项目   ----   属性   ----   链接器   ----   常规  ----   输出文件 （Release/xx.exe）

引用 2 楼 max_min_ 的回复:直接用鼠标拖拽到里面就好了吧！ 试试 把代码拖到命令行里去？还是把什么拖到什么地方去？

直接用鼠标拖拽到里面就好了吧！ 试试

搜 windows 命令行  编译c


Question: c语言向无参函数传参的困惑

没有为啥，无参的时候本来就可以传递任意参数的，所以一般推介写为void fun（void），不过C++里面严格匹配了编译是不会通过的

没有为啥啊 C语言本来就这么规定的。这就是cdecl的优势。

不仅你说的可以，亲测了一下，连下面的代码在C里也可以运行的说  typedef int (*pFun)(); int fun(int a) {     return a; } int main() {     pFun intFun = &fun;     printf("%d\n", intFun(10));     return 0; }  帮你google了一下，http://blog.csdn.net/ylgrgyq/article/details/6940602，看了觉得有用


Question: 串口的发送与发送需要多线程互斥，那么发送和接收呢？

现在2个线程去接收  OK,  一个线程接到了O,另一个线程接收到了K.     OK被分开了。

引用 4 楼 nice_cxf 的回复:看是总线是422，232还是485了，485是半双工，不能同时收发，其他两种可以  485半双工是属于串口之外的事情，内部还是全双工的

谢谢大家的答复，我现在发现串口怎么这么麻烦啊。。我现在用ANDROID开发板和串口设备进行通信，用开发板官方的API，只有4个API函数，open,  write ,read, select,  没有像windows上的那种异步事件通信。  现在发现串口互斥的太多了：  1.发送与发送互斥；2. 接收与接收互斥。   那我写代码就这样写吧：  只有1个线程 进行接收，其他线程发送间互斥就行了。  全双工，发送与接收不需要互斥。

串口自带Buffer的， 好像还是循环的， 注意不要溢出就行了。

引用 9 楼 gaoxiaoweiandy 的回复:全双工：  发送和接收  不需要互斥。   发送与发送 必须互斥。 接收与接收需要 互斥吗？我感觉还是对这点有点疑惑。  接收应该不是是不是要互斥的问题，应该是调度的问题，也就是接收的数据应该归谁处理，然后发送到对应的模块

接收与接收需要互斥

引用 2 楼 gaoxiaoweiandy 的回复:我现在也很疑惑，有的人说需要 串口  读写互斥，有的说不需要。 串口大部分都是半双工的，同一时间片要么发，要么收，不能即发又收的

引用 4 楼 nice_cxf 的回复:看是总线是422，232还是485了，485是半双工，不能同时收发，其他两种可以 惊现串口达人！膜拜！

全双工：  发送和接收  不需要互斥。   发送与发送 必须互斥。 接收与接收 实践证明 也应该互斥，但不知  道其原理， 我用2个线程 去接收 messageOk,结果 第一个线程接收到了messag,第二个线程接收到了eok.等于说  第二个线程将第一个线程该接收的数据抢过去了。   半双工：  发送 和  接收  必须互斥。  发送 与发送 必须互斥。 接收与接收 理论上 也应该互斥。

串口相关硬件也有是否支持全双工的区别？

引用 3 楼 zhao4zhong1 的回复:串口相关硬件也有是否支持全双工的区别？  硬件是基础，决定上层建筑

我现在也很疑惑，有的人说需要 串口  读写互斥，有的说不需要。

你想的是对的，没有共享资源的访问，也就不需要临界区！此外读但不修改，即使共享也不需要互斥，如果存在共享资源的写，那么有读写互斥问题。 你这里是发送-串口-接收地-读取，发到的地和接收的地不是一块地，也就不需要互斥了


Question: 链表 赋值后, 如何一条一条地显示链表内容?

引用 6 楼 huabinsir 的回复:[quote=引用 3 楼 lipoor1234 的回复:]  while(pList->Curitem) {     printf("%s\n" ,pList->Curitem->name);     pList->Curitem = pList->Curitem->next; }   		  pList->CurItem = pList->CurItem->next; 这样会不会改变链表的值?[/quote] 不会 表头指针依然保存在ListHeader中

引用 3 楼 lipoor1234 的回复: while(pList->Curitem) {     printf("%s\n" ,pList->Curitem->name);     pList->Curitem = pList->Curitem->next; }   		  pList->CurItem = pList->CurItem->next; 这样会不会改变链表的值?

//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

条件语句，如果链表不为尾，依次输出。

循环逐个遍历链表即可！ 根据链表的特性，比如单链表，双链表，循环链表，设置循环条件！


Question: 视频字幕问题

视频是用win media player 控件做的，现在想求视频流里时间的获取，和字幕同步的方法，求指导

引用 3 楼 xubbwd 的回复:视频流里面是有时间戳的，你可以把两个时间来做一下同步就可以了。  你是用的什么视频，什么格式的？  看看文档

你读的文件里面会有时间信息的，把时间信息提出来

能不能时间轴同步？ 视频中有总时间值，字幕lrc也是按字幕出现的时间来排字幕的吧，类似歌词编辑。


Question: C语言大面试题  寻最优解

引用 6 楼 my_live_123 的回复:先自己做出来，再尝试最优解！同意1L观点，基础题目！考察语言功底，算法性不强！ ++ 先实现，再优化； 这些都不是很难。

值得练手

很简单的题目啊

是的是的.....

我怎么觉得是学生拿作业上来套答案的。。。。是我太阴暗了么

先自己做出来，再尝试最优解！同意1L观点，基础题目！考察语言功底，算法性不强！

网上这些问题已经差不都是有源码的！楼主google下就好！

1、比较字符串，输入它们第一个不同字母的位置，大小写不敏感     先统一转换为大写或者小写，然后比较，比较的同时记录位置  2、判断一个数是不是回文数，数字 1234321。   使用字符串输入，然后a[i]与 a[strlen(a)-i] 比较，如果不同就返回  3、比较两字符串长短，并返回结果。   使用strlen？  4、给一个字符串，编程取其中一个特定的字符并输出。   使用sscanf格式提取字符串  5、是比较两个英文字符串的不相同的字符的位置（忽略字母大小写）   同第一题  6、主函数调用一函数     如：检索出字符串中出现次数最多的那个字符，不考虑大小写，然后返回该字符。                  先统一转换为大写或者小写                int a[26];                然后遍历这个字符串，同时a[str[i]-'a']++ ; 然后取出a数组里面值 最大的那个所代表的字符。                 7、查找字符串中出现次数最多的字符，并返回该字符，只考虑小写字母，不考虑不同字母出现次数一样多的情况 同第六题  8、输入一个整数n，计算不大于n的数中和7相关的数的个数，包括能被7整出的数和含有字符7的数。  遍历。。      例如：输入20，输出3（7、14、17）。  9、输入一个整数将每一位上的奇数放在一个新整数中，高位放在高位，地位在低位。  使用字符串输入，从高位开始判断，然后高位的字符转换为数字为奇数的 话，就把新整数*10加上该数字   10、输入一串数，将其最小的放在第一位，次小的放在最后一位，再小的放在第二位，再再小的放在倒数第二位，以此类推。  同第2题，交换位置   11、写一个函数，传入参数为应付钱数。返回值为买家最少付出的钱的张数int get MoneyNum(int  iInputMoney)例如：买家应付351元，最少张数为5.备注：可支付的钱币只有100、50、10、5、1不考虑2、20以及小数部分。    12、设有几个人围坐在一圈并按顺时针方向从1到几编号，从第S个人开始进行1到m的报数。报数到第M个人，此人出圈。再从他的下一个人重新开始1到M的报数，如此进行下一直到所有人都出圈为止，输出报数顺序。 参考约瑟夫环的问题   13、对姓氏进行排名Char str[ ]=”zhang   wang   li    zhao”                    Char str_ new[ ]=”li  wang   zhang   zhao”      接口：sort（str,len,str_new）  14、将一组整数中为奇数的数提取出来，高低位顺序不变。如：8 3 7 9 5 2 1 4-----》3 7 5 1  15、一组2n+1个元素的正整形数组，按升序排序，然后将小于中间数值的成员替换为中间的值。     （貌似还有：“位置不变”，不过实在不理解其含义，看了例子就不用关心它的意思了），例如：1,2,3,4,5，输出为：3,3,3,4,5，原型：int fun(int arry[],int n,char*output){return 0;}  16、输入一个四位的十进制整数，编程实现将这四位整数转化为十六进制的字符串，并输出十六进制的字符串（注意负数的处理）  17、输入：一个四位的整数，比如：2367，输出：2+3+6+7=18

目测了一下，没发现任何难题，应该说没有限制任何方法和时间复杂度，你随便写就好了

同意楼上！！！

都是基础题目。。。。


Question: C语言为什么不支持多个返回值

引用 楼主 wangjun403 的回复:如题 貌似编译型语言都不支持 多返回值主要是很多cpu寄存器资源宝贵,而且不如指针来的实在,指向一段公共缓冲区,这样的只需要一个寄存器就ok了

结构体可以解决~

很簡單的問題 那個我都不會回答,這問題我會  1.很繁雜,以組合語言角色來說.C也是要翻譯成組合語言再變成機氣碼的 2.不需要,可以用指針. 3.假如要,有多個返回值 i = ret(); 這裡回2個,1個i怎麼裝? 語言夠開發所用就好了,那麼繁雜干嘛

这个问题真蛋疼

类和结构体不就是多个值吗？若真要返回毫不相干的变量，直接用输出参数即可

引用 23 楼 blackkettle 的回复:[quote=引用 20 楼 zhao4zhong1 的回复:] 为什么所有语言都不支持返回整个互联网内容！  +1[/quote] 你抄外汇？

Linux的fork函数，就是一个特例，一次调用两次返回，lz可以研究。

引用 69 楼 wangjun403 的回复:[quote=引用 65 楼 cjfdqchwh 的回复:] 形式上，返回值只能返回一个对象。  可以返回一个数值  输出参数也是有“返回”的效果，win API中这种形式很多。  此外，这是数据结构设计问题，你要想返回 A 和 B 两个值，可以，你设计一个数据结构：  typedef struct {    int A;    double B; }DataType，*pDataType;  你返回一个 pDataType 就可以实现功能 这是可以实现返回多值的一个另类方法而已，和返回多值有本质区别  如果我只要返回两个结构体中的一个，怎么办呢？ 这样就不行了[/quote]   没必要纠结高级语言中的某些特性，因为这些特性都是封装而来的。封装的越多，你自己掌控的越少，反之则封装的越少，你掌控的越多。而C恰恰就是介于这个少和多之间的，这就是它存在的价值。 至于说C为什么不能返回多个值，这是设计语言及开发编译器时就定下来的，这也体现了它的封装相对少的一面，何必纠结呢。

引用 65 楼 cjfdqchwh 的回复:形式上，返回值只能返回一个对象。  可以返回一个数值  输出参数也是有“返回”的效果，win API中这种形式很多。  此外，这是数据结构设计问题，你要想返回 A 和 B 两个值，可以，你设计一个数据结构：  typedef struct {    int A;    double B; }DataType，*pDataType;  你返回一个 pDataType 就可以实现功能 这是可以实现返回多值的一个另类方法而已，和返回多值有本质区别  如果我只要返回两个结构体中的一个，怎么办呢？ 这样就不行了

2B问题，鉴定完毕

引用 69 楼 wangjun403 的回复:这是可以实现返回多值的一个另类方法而已，和返回多值有本质区别 如果我只要返回两个结构体中的一个，怎么办呢？ 这样就不行了  从现有的机制中，你都可以找到实现方法，别说返回多个值，就是返回一片内存，也是可以做到的。 要返回两个结构体中的一个，你就直接返回那一个不就完了？有什么不对的地方吗？

最根本的原因是，数学书上的等号左边从来只有一个东东。

引用 楼主 wangjun403 的回复:如题 貌似编译型语言都不支持 另辟蹊径啊，就像C也可以写成面向对象的风格

这是规矩。学C就要服从C的规则，这样才能事半功倍！

通过传递参数也是可以得到返回值的，孩子。

因为C语言不是脚本语言，需要顾及对硬件的最高利用度。  引用 楼主 wangjun403 的回复:如题 貌似编译型语言都不支持

多个返回值可以用数据结构返回啊，传参也是啊

因为掌握规则的老外没有这样做……

用结构体，毕竟不是脚本


Question: C语言匹配指定连接的正则表达式

引用 2 楼 zhao4zhong1 的回复:#include <stdio.h> char s[]="聚隆·城市花园VIP火热办理中"; char n[80],v[80]; int main() {     printf("%s\n",s);     if (2==sscanf(s,"%*[^?]?%79[^=]=%79[^\']",n,v)) {         printf("n=[%s],v=[%s]\n",n,v);     } else printf("Format Error!\n");     return 0; } //聚隆·城市花园VIP火热办理中 //n=[aid],v=[36145] //   学习了

是我的理解能力有问题吗？。。。


Question: 急求Battle Over Cities的变题的代码

2010成都regional的题，虽然规模没那么大，但是也不是朴素的O(mn)能过的。初学怎么能做这种题。


Question: 车载led广告屏如何实现广告同步算法

引用 楼主 juhekeji 的回复:出租车LED广告在播放广告的时候，广告下发成功后，在播放过程中有车断电上电，那么怎么让这个广告继续同步播放啊。Q 872665008  单片机有片内rom

如果广告内容更新的不太频繁，EEPROM

难道你的车载系统上连个flash都省掉了呀, 数据下载好, 存起来不是更好. 这个芯片又增加不了多少成本.

这个问题不难实现，在单片机的外面外挂一个E2PROM，当单片机断电的时候由于电容还有一定容量的电，足够你存储当前的数据了。

搞个小小的蓄电池我觉得是挺好的 毕竟这东西不算贵 不然的话 就像台式机突然断电一样  数据丢失！ 也可以在播放的时候不断的跟新记录 每次打开都先读记录 然后接着播放吧

不要企图优雅的结束（因为这是不可能办到的） 而要在烂的不能再烂的摊子上也能重整河山！

没搞过嵌入式，但结局这种问题的办法就是记录。 比如加个电池，保存程序运行的关键数据，就好。

坚决消灭零回复，谢谢您


Question: C语言，求教递归定义，随手写的代码，这算不算递归

引用 9 楼 WhiteBird99 的回复:当然是递归... 递归的特点就是自己调用自己, 并且最后能够结束. 谢谢，都说递归那就算是递归吧，刚结过贴，不好意思了

当然是递归... 递归的特点就是自己调用自己, 并且最后能够结束.

谢谢楼上各位，三人为众，本着这种思想应该是递归了 本人还是会写递归的，只是在我的程序中需要加个 return 返回不想让程序回来继续执行，写好程序后关于这段代码和朋友发生了分歧，特来此问一下，上面的程序也是临时写的，谢谢楼上各位

递归：自己调用自己，你说是不是？ 前几次执行return 把函数都给结束了，肯定不会输出a 了！

当然是递归了，只是前9次都被return掉了，所以才打印一个a罢了！

是递归。。。

我对递归的理解: 1.先从函数的语意上来理解你自己写的递归程序,一个能正常工作的递归程序,必然是从语意上是说得通的.比如 printfff(int i, char ch) //这个函数的语意思是打印i次,字符ch.根据这个语意,我可以做出如下: 当i=0时,什么都不打印,直接return了. 当i>0时,先打印一次,然后再打印i-1次,即 printfff(i-1,ch) 以此来写递归,会感到很流畅  2.递归一定要有一个"出口点",不能无限递归.

如果把 printf("%c\n", ch);  放到 if判断之前  估计又是另一番景象了 个人觉得 也算是递归

http://zh.wikipedia.org/wiki/%E9%80%92%E5%BD%92 对于递归的详细内容，参考资料《组合数学》中内容。 这是递归，深度是10 之所以输出一个a，因为   return printfff(i, ch);  有个return在头，所以深层调用返回来后函数就结束了 如果想每层调用都输出a，把return去掉即可

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


Question: 马上要实习了。面试安卓开发一般面试什么

楼主加油，方向对，有前途

进这个帖子本来只想说句,最先找到正确的地方问问题来着.发现有前辈了

如果是我面试的话，我肯定要问基础知识，上面所谓的开发都是不用经过思考就直接拿来用就行

非常感谢大家的回答

引用 楼主 ruanjianyujian 的回复:大四马上要实习了，我对安卓开发很感兴趣，想面试安卓，自己做过项目，项目中用了listview的优化，下拉刷新，分页加载，json解析数据库，pull解析xml，异步加载图片，软引用，本地存储sqllite,百度地图，分享到微博，空间，正在研究消息推送，但是不知道面试的时候，是面试的Java基础比较多，还是安卓技术比较多，对于Java基础的一些概念有些生疏了。。。  如果有开发过项目的经验的话，就比较好把握了！面试安卓应该也会代点java基础知识吧！ 主要还是开发的经验会问的比较多！楼主多注意就好了！

楼主做过项目，应该有不少思考和积累吧，抱着谦虚学习的心态去面试就好。

引用 4 楼 u011779875 的回复:[quote=引用 楼主 ruanjianyujian 的回复:] 大四马上要实习了，我对安卓开发很感兴趣，想面试安卓，自己做过项目，项目中用了listview的优化，下拉刷新，分页加载，json解析数据库，pull解析xml，异步加载图片，软引用，本地存储sqllite,百度地图，分享到微博，空间，正在研究消息推送，但是不知道面试的时候，是面试的Java基础比较多，还是安卓技术比较多，对于Java基础的一些概念有些生疏了。。。 自己做过项目，项目中用了listview的优化，下拉刷新，分页加载，json解析数据库，pull解析xml，异步加载图片，软引用，本地存储sqllite, 这已经很厉害了 关键问题是这些你用了多久学会的 如果你说你只用了半个月就把这些搞定了 相信 每一家公司都会给机会实习的[/quote]主要是问你时你得知道是怎么回事，能回答个123就差不多了。

引用 楼主 ruanjianyujian 的回复:大四马上要实习了，我对安卓开发很感兴趣，想面试安卓，自己做过项目，项目中用了listview的优化，下拉刷新，分页加载，json解析数据库，pull解析xml，异步加载图片，软引用，本地存储sqllite,百度地图，分享到微博，空间，正在研究消息推送，但是不知道面试的时候，是面试的Java基础比较多，还是安卓技术比较多，对于Java基础的一些概念有些生疏了。。。 自己做过项目，项目中用了listview的优化，下拉刷新，分页加载，json解析数据库，pull解析xml，异步加载图片，软引用，本地存储sqllite, 这已经很厉害了 关键问题是这些你用了多久学会的 如果你说你只用了半个月就把这些搞定了 相信 每一家公司都会给机会实习的

实习不会问很复杂的问题的。会根据你的作品来具体来问。面试前看看基础，了解下你要面试的公司，看看公司的案例，主要的还是要明白自己的做过什么，用到那些技术，就是实际的项目经验。

1、感觉来错区了 2、这个应该还要看公司了，有些公司不关心这个，进来以后都要再培训下什么的。不过你既然是做安卓的，应该这两方面都会问的吧。至于偏重哪一个，真不清楚。不过感觉应该是安卓为主，其次才是Java之类的语言。你既然做过那么多，应该没什么问题的。 3、实习不要太紧张，多去几家公司看看就知道了，一方面看看会问什么，一方面也看看公司环境、文化是否是你喜欢的。


Question: TDD 测试驱动开发艺术-如何编写测试

很有用，看一看反对派的意见也很能开拓思路

友情帮顶一下。

搜“拒绝测试驱动开发（TDD）的10个理由”


Question: /*输入一个个位数的数学表达式，如6+3*(9-5)/2-8，并将运行程序后将结果显示在屏幕上。*/为什么输出不了结果，哪出错了？帮忙看看，谢谢啦

仅供参考/*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数∧ 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);  (*iop)--;break;         case  8: x=cos(x);  (*iop)--;break;         case  9: x=tan(x);  (*iop)--;break;         case 10: x=sqrt(x); (*iop)--;break;         case 11: x=asin(x); (*iop)--;break;         case 12: x=acos(x); (*iop)--;break;         case 13: x=atan(x); (*iop)--;break;         case 14: x=log10(x);(*iop)--;break;         case 15: x=log(x);  (*iop)--;break;         case 16: x=exp(x);  (*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i;     if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     if (argc<=1) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0～.15表示将计算结果保留小数0～15位"<<endl<<"支持(),+,-,*,/,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         int a;         for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s         if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位             printf("%.*lf\n",pcs,calc(s,&endss));         } else {             strncat(s,argv[a],MAXLEN-1);             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }

x=*(--s->top); 看到这一句就觉得后面不用看了……

栈的实现有问题，基本的先搞好测试过没问题，再去写应用...

/* 在BC31下编译 或VC6.0*/ /* compile under Borland C++ 3.1 or Visual C++ 6.0*/  /*#include "stdafx.h"*/ #include "stdio.h" #include "string.h" #include "stdlib.h" #include "conio.h"  #define TRUE 1 #define FALSE 0 #define STACK_INIT_SIZE 100/*存储空间初始分配量*/ #define STACKINCREMENT 20/*存储空间分配增量*/  typedef struct { 	int *pBase;/*在构造之前和销毁之后,base的值为NULL*/ 	int *pTop;/*栈顶指针*/ 	int StackSize;/*当前已分配的存储空间,以元素为单位*/ }Stack;  typedef int BOOLEAN;  char Operator[8]="+-*/()#";/*合法的操作符存储在字符串中*/ char Optr;/*操作符*/ int Opnd=-1;/*操作符*/ int Result;/*操作结果*/  /*算符间的优先关系*/ char PriorityTable[7][7]= { 	{'>','>','<','<','<','>','>'}, 	{'>','>','<','<','<','>','>'}, 	{'>','>','>','>','<','>','>'}, 	{'>','>','>','>','<','>','>'}, 	{'<','<','<','<','<','=','o'}, 	{'>','>','>','>','o','>','>'}, 	{'<','<','<','<','<','o','='}, };  //数据对象的操作方法 //构造一个空栈,如果返回值为0,则表示初始化失败 Stack InitStack()/*这是个效率低的方法*/ { 	Stack S; 	S.pBase=(int*)malloc(STACK_INIT_SIZE*sizeof(int)); 	if(!S.pBase) 	{/*内存分配失败*/ 		printf("内存分配失败,程序中止运行\n"); 		exit(-1); 	} 	else 	{ 		S.pTop=S.pBase; 		S.StackSize=STACK_INIT_SIZE; 	} 	return S; } //销毁栈S,S不再存在 void DestoryStack(Stack *S) { 	if(S->pBase) 	{ 		free(S->pBase); 		S->pTop=S->pBase=NULL;  	} } //若栈不空,则用e返回S的栈顶元素 //注:由于应用的特殊,可以不检查栈是否为空 int GetTop(Stack S) { 	return *(S.pTop-1); } //插入元素e为新的栈顶元素,如果成功则返回1,否则返回0 int Push(Stack *S,int e) { 	if(S->pTop-S->pBase==S->StackSize) 	{//栈满,追加存储空间 		S->pBase=(int*)realloc(S->pBase,S->StackSize+STACKINCREMENT*sizeof(int)); 		if(!S->pBase) 			return 0;//存储分配失败 		S->pTop=S->pBase+S->StackSize; 		S->StackSize+=STACKINCREMENT; 	} 	*(S->pTop++)=e; 	return 1; }  int Pop(Stack *S,int *e) {//若栈不空,则删除S的栈顶元素,用e 返回其值,并返回1;否则返回0 	if(S->pTop==S->pBase) 		return 0; 	*e=*--(S->pTop); 	return 1;  } //主函数及其它函数的实现 //比较两个数学符号operator_1,operator_2的计算优先权,在算符优先关系表中查找相应的关系并返回'<','=',或'>' char CheckPriority(char operator_1,char operator_2) { 	int i,j;//用来查询算符间优先关系表的下标 	//char *ptr; 	i=strchr(Operator,operator_1)-Operator;//找到传入操作符在字符串Operators中的相对位置 	j=strchr(Operator,operator_2)-Operator; 	//返回算符优先关系表中相应值 	return PriorityTable[i][j]; }  BOOLEAN IsOperator(char ch) {//判断一个字符是否为打操作符 	if(strchr(Operator,ch)) 		return TRUE; 	else  		return FALSE;  } //从键盘获得输入 void GetInput(void) { 	char Buffer[20];//键盘输入缓冲区,用来处理输入多位数的情况 	char ch;//存放键盘输入 	int index;//存放Buffer的下标 	index=0; 	ch=getch();//从键盘读入一个字符 	while(ch!=13&&!IsOperator(ch)) 	{//如果输入的字符是回车符或是操作符,循环结束 		if(ch>='0'&&ch<='9') 		{//将字符回显到屏幕 			printf("%c",ch); 			Buffer[index]=ch; 			index++;  		} 		ch=getch(); 	} 	if(ch==13) 		Optr='#';//输入的表达式以回车符结束 	else 	{ 		Optr=ch; 		printf("%c",ch);  	} 	if(index>0) 	{ 		Buffer[index]='\0'; 		Opnd=atoi((Buffer)); 	} 	else 		Opnd=-1;//程序不支持输入负数,当Opnd为负数时,表示输入的字符为操作符 } //计算形如a+b之类的表达式,theta为操作符,a,b为操作数 int Calc(int a,char theta,int b) { 	switch(theta) 	{ 	case '+': 		return a+b; 	case '-': 		return a-b; 	case '*': 		return a*b; 	default: 		if(b==0)//除数为零的情况 		{ 			printf("除数不能为"); 			return 0;//返回0用以显示 		} 		else 			return a/b; 	} } /*表达式求值*/ BOOLEAN EvaluateExpression() { 	int temp;//临时变量 	char theta;//存放操作符的变量 	int itheta;//存放出栈的操作符的变量add by me 	int a,b;//存放表达式运算时的中间值 	int topOpnd;//栈顶操作数 	char topOptr;//栈顶操作符  	Stack OPTR=InitStack();//操作符栈 	Stack OPND=InitStack();//操作数栈  	if(!Push(&OPTR,'#'))//操作符栈中的第一个为#字符 		return FALSE;  	GetInput();//从键盘获得输入  	while(Optr!='#'||GetTop(OPTR)!='#') 	{//如果Optr>=0,表示有操作数输入 		if(Opnd>=0)Push(&OPND,Opnd); 		switch(CheckPriority(GetTop(OPTR),Optr)) 		{ 		case '<'://栈顶元素优先权低 			if(!Push(&OPTR,Optr))return FALSE; 			GetInput(); 			break; 		case '='://脱括号并接收键盘输入 			Pop(&OPTR,&temp);GetInput(); 			break; 		case '>'://退栈并将运算结果入栈 			//先用itheta得到操作符在赋给theta 			Pop(&OPTR,&itheta); 			Pop(&OPND,&b); 			Pop(&OPND,&a); 			theta = (char)( itheta ); 			Push(&OPND,Calc(a,itheta,b)); 			Opnd=-1; 			break;  		} 	} 	//本算法中,当输入只有一个操作数然后就输入回车符时, 	//OPND.pTop==OPND.pBase 	//如果OPND.pTop==OPND.pBase并且Opnd<0,则说明用户 	//未输入任何操作和操作符而直接输入[回车],程序直接 	//退出运行 	if(OPND.pTop==OPND.pBase&&Opnd<0) 	{ 		printf("\n\n感谢使用!\n"); 		exit(1);  	} 	else if(OPND.pTop==OPND.pBase) 		Result=Opnd; 	else 	{ 		Result=GetTop(OPND); 		DestoryStack(&OPND); 		DestoryStack(&OPTR); 	} 	return TRUE;  }  void Message(void) { 	printf("\n四则运算表达式求值演示\n"); 	printf("-------------------------------\n"); 	printf("使用方法:请从键盘上直接输入表达式,以回车键结束.如45*(12-2)[回车]\n"); 	printf("注0:不输入任何数而直接按[回车]键,将退出程序.\n"); 	printf("注1:本程序暂时不接受除数字键及四则运算符之外的任何其它键盘输入.\n"); 	printf("注2:本程序暂时只能处理正确的表达式,不支持输入负数.\n"); 	printf("-------------------------------\n\n"); } void main(void) { 	int i;//用来一些说明性信息 	Message(); 	for(i=1;;i++) 	{ 		printf("表达式%d:",i); 		if(EvaluateExpression()) 			printf("=%d\n",Result); 		else 			printf("计算中遇到错误\n");  	} }   我上网搜了一个 希望对楼主有所帮助 注释应该很清楚了

int firstvalue(char ch) { 	int k = 0; 	switch(ch) 	{ 	case '+':k=0;break; 	case '-':k=1;break; 	case '*':k=2;break; 	case '/':k=3;break; 	case '(':k=4;break; 	case ')':k=5;break; 	case '#':k=6;break; 	default : printf("error"); 	} 	return k; }  type count(char a,char b,char c) { 	int l=0; 	switch(c) 	{ 	case '+':l=(a-'0')+(b-'0');break; 	case '-':l=(a-'0')-(b-'0');break; 	case '*':l=(a-'0')*(b-'0');break; 	case '/':l=(a-'0')/(b-'0');break; 	default : printf("error"); 	} 	return(l+'0'); }    我这样修改楼主的代码 全部打印出error 楼主自己再研究一下吧

谢谢各位！真心谢谢啦，焦头烂额啊


Question: 一个类型转换的问题

转换为BYTE*类型，是为了与后面 pDosheader->e_lfanew+24相加 比如 hMod== 0xAAA0000, pDosheader->e_lfanew == 10 (BYTE*)hMod+pDosheader->e_lfanew+24 == 0xAAA0000 + 10 + 24 (int*)hMod+pDosheader->e_lfanew+24 == 0xAAA0000 + (10 + 24)*4

搜PE文件结构

难道是和平时我们使用（void*）一个意思？

《Windows PE权威指南》


Question: 一个吉比特面试题~求解~

开优化的话，生成的代码估计都一样吧。

教科书后的题目，看那一章是说什么的。就特么那个原因。。

引用 3 楼 nice_cxf 的回复:好垃圾的题目 顶

好垃圾的题目

1快于2 1.循环次数很少 ABC都很简单 2.ＡＢＣ后面跟个ｂｒｅａｋ之类的 ３．Ａ１执行完　要ｗａｉｔｅ　ｆｏｒ　Ｂ１　　Ｂ１　ｗａｉｔｅ　ｆｏｒＣ１　类似的吧！

5种情况？ 有没有例子？什么叫情况  我举一个吧  如果abc三个程序段很大，不能一次性放入内存，那么第一种慢 不知道对不对

最讨厌这种，咬文嚼字的题目了。

引用 6 楼 zhao4zhong1 的回复:profiler 靠模铣床？？？

profiler


Question: 关于strtok 的诡异问题，变量被奇异的重置为0

引用 6 楼 zhao4zhong1 的回复:Setting a Breakpoint When a Variable Changes Value To set a breakpoint when a variable changes value   From the Edit menu, click Breakpoints. Click the Data tab of the Breakpoints dialog box. In the Expression text box, type the name of the variable. Click OK to set the breakpoint.++

10 i = 10 11  你的11都输出完了。  while((buf[i] = strtok(NULL, delim))) 这样while永不退出

数组越界了   修改下越界的bug再试试

把char *buf[11] = {0};   改成 char *buf[12] = {0};   这样 应该 没有问题

数组越界了  最后一次 strtok(NULL, delim)返回值 NULL 写入buf[11] 然后 表达式 (buf[i] = strtok(NULL, delim))求值结果 NULL 退出循环  这里 只是恰好 buf[11] 和 i 重叠了

字符串分解函数，数组越界

学会debug很重要

仅供参考#include <stdio.h> #include <string.h> char string[80]; char seps1[3]; char seps2[3]; char *token; char *zzstrtok (     char *string,     const char *control1,//连续出现时视为中间夹空token     const char *control2 //连续出现时视为中间无空token     ) {     unsigned char *str;     const unsigned char *ctrl1 = control1;     const unsigned char *ctrl2 = control2;     unsigned char map1[32],map2[32];     static char *nextoken;     static char flag=0;     unsigned char c;     int L;      memset(map1,0,32);     memset(map2,0,32);     do {         map1[*ctrl1 >> 3] |= (1 << (*ctrl1 & 7));     } while (*ctrl1++);     do {         map2[*ctrl2 >> 3] |= (1 << (*ctrl2 & 7));     } while (*ctrl2++);      if (string) {         if (control2[0]) {             L=strlen(string);             while (1) {                 c=string[L-1];                 if (map2[c >> 3] & (1 << (c & 7))) {                     L--;                     string[L]=0;                 } else break;             }         }         if (control1[0]) {             L=strlen(string);             c=string[L-1];             if (map1[c >> 3] & (1 << (c & 7))) {                 string[L]=control1[0];                 string[L+1]=0;             }         }         str=string;     }     else        str=nextoken;      string=str;     while (1) {         if (0==flag) {             if (!*str) break;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 break;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 string++;                 str++;             } else {                 flag=1;                 str++;             }         } else if (1==flag) {             if (!*str) break;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 flag=0;                 break;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 flag=2;                 break;             } else str++;         } else {//2==flag             if (!*str) return NULL;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 str++;                 string=str;                 flag=0;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 str++;                 string=str;             } else {                 string=str;                 str++;                 flag=1;             }         }     }     nextoken=str;      if (string==str) return NULL;     else             return string; } void main() {    strcpy(string,"A \tstring\t\tof ,,tokens\n\nand some  more tokens, ");    strcpy(seps1,",\n");strcpy(seps2," \t");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234| LIYI|China | 010 |201110260000|OK");    strcpy(seps1,"|");strcpy(seps2," ");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234|LIYI||010|201110260000|OK");    strcpy(seps1,"");strcpy(seps2,"|");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234|LIYI||010|201110260000|OK");    strcpy(seps1,"|");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",a");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",a,,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,a,,b,,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,,");    strcpy(seps1,",");strcpy(seps2," ");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    } } // //[A      string          of ,,tokens // //and some  more tokens,] //Tokens: // <A>, <string>, <of>, <>, <tokens>, <>, <and>, <some>, <more>, <tokens>, <>, //[1234| LIYI|China | 010 |201110260000|OK] //Tokens: // <1234>, <LIYI>, <China>, <010>, <201110260000>, <OK>, //[1234|LIYI||010|201110260000|OK] //Tokens: // <1234>, <LIYI>, <010>, <201110260000>, <OK>, //[1234|LIYI||010|201110260000|OK] //Tokens: // <1234>, <LIYI>, <>, <010>, <201110260000>, <OK>, //[a] //Tokens: // <a>, //[a,b] //Tokens: // <a>, <b>, //[a,,b] //Tokens: // <a>, <>, <b>, //[,a] //Tokens: // <>, <a>, //[a,] //Tokens: // <a>, <>, //[,a,,b] //Tokens: // <>, <a>, <>, <b>, //[,,a,,b,,] //Tokens: // <>, <>, <a>, <>, <b>, <>, <>, //[,] //Tokens: // <>, <>, //[,,] //Tokens: // <>, <>, <>, //[,,,] //Tokens: // <>, <>, <>, <>,


Question: 用C将一个256位数转成64位的方法，求实现！

引用 16 楼 derekrose 的回复:[quote=引用 15 楼 u011717322 的回复:] [quote=引用 14 楼 derekrose 的回复:] 256除6除不尽啊  每六位操作 移位就可以了啊，很简单的 我也知道是移位，但是你不知道到底最后要加几个0. 这个问题我再去问问组长， 感觉他说256说的是给的数最大是256位， 就是说我现在不知道这个数有多少位。 懂我的意思了吗？[/quote]  256好办 位数不确定就必须要给出终止条件[/quote] 恩！用移位来判断有多少位应该可以。 向右移，每次移1位，当为0时就是移完了，就可以知道一共多少位了。 谢谢了哈！

引用 15 楼 u011717322 的回复:[quote=引用 14 楼 derekrose 的回复:] 256除6除不尽啊  每六位操作 移位就可以了啊，很简单的 我也知道是移位，但是你不知道到底最后要加几个0. 这个问题我再去问问组长， 感觉他说256说的是给的数最大是256位， 就是说我现在不知道这个数有多少位。 懂我的意思了吗？[/quote]  256好办 位数不确定就必须要给出终止条件

引用 14 楼 derekrose 的回复:256除6除不尽啊  每六位操作 移位就可以了啊，很简单的 我也知道是移位，但是你不知道到底最后要加几个0. 这个问题我再去问问组长， 感觉他说256说的是给的数最大是256位， 就是说我现在不知道这个数有多少位。 懂我的意思了吗？

256除6除不尽啊  每六位操作 移位就可以了啊，很简单的

另外你可以用sizeof去测试你的类型到底是多少位，例如： unsigned int a;  int bits = sizeof(a) * 8;  引用 8 楼 u011717322 的回复:[quote=引用 5 楼 turingo 的回复:] 给你举个例子吧，比如有 unsigned char a; unsigned char b;  你需要把a的高6位放到低位，b的低2位放到高位，组成新的 unsigned char c;  那么可以很简单的这样运算： c = ((a >> 2) & 0x3f) | ((b << 6) & 0xc0);  如果没有用过位运算的话，那么建议先去了解一下位运算的基本法则  [quote=引用 3 楼 u011717322 的回复:] [quote=引用 2 楼 turingo 的回复:] 需求再弄清楚一点吧，总的来说，你的问题只需要用数组和位运算就可以解决的。  [quote=引用 楼主 u011717322 的回复:] 组长叫我实现一个将256位的数转换为64位的数！ 大概的方法是：将256的数提取前6位，组合成新的数。 例如：0xC1 0xF5 0x41（1100 0001 1111 0101 0100 0001）转变成：      110000 011111 010101 000001，这样就变成了0X30 0X1F 0x15 0x01 再例如：0x31（0011 0001）转变成001100 010000，变成0x0C 0x10   大概就是这样的个情况！ 本人C语言写的不是很多，以前都是搞搞C++，写了半天都没有写出完整的。 希望能有人帮我实现下。 不胜感激！[/quote] 这个是具体的算法。后面还要转！不过后面的要简单点了。 就是这个左移6位写了半天没写出来。 256位转64位各位就当没说，主要是这个算法。 谢谢啊！[/quote][/quote] 这个我都知道。 就是感觉不知道怎么得到一个数到底有多少位。[/quote]

对于32位平台，一般来说： unsigned int 是 32位 unsigned short 是 16位 unsigned char 是 8位  引用 8 楼 u011717322 的回复:[quote=引用 5 楼 turingo 的回复:] 给你举个例子吧，比如有 unsigned char a; unsigned char b;  你需要把a的高6位放到低位，b的低2位放到高位，组成新的 unsigned char c;  那么可以很简单的这样运算： c = ((a >> 2) & 0x3f) | ((b << 6) & 0xc0);  如果没有用过位运算的话，那么建议先去了解一下位运算的基本法则  [quote=引用 3 楼 u011717322 的回复:] [quote=引用 2 楼 turingo 的回复:] 需求再弄清楚一点吧，总的来说，你的问题只需要用数组和位运算就可以解决的。  [quote=引用 楼主 u011717322 的回复:] 组长叫我实现一个将256位的数转换为64位的数！ 大概的方法是：将256的数提取前6位，组合成新的数。 例如：0xC1 0xF5 0x41（1100 0001 1111 0101 0100 0001）转变成：      110000 011111 010101 000001，这样就变成了0X30 0X1F 0x15 0x01 再例如：0x31（0011 0001）转变成001100 010000，变成0x0C 0x10   大概就是这样的个情况！ 本人C语言写的不是很多，以前都是搞搞C++，写了半天都没有写出完整的。 希望能有人帮我实现下。 不胜感激！[/quote] 这个是具体的算法。后面还要转！不过后面的要简单点了。 就是这个左移6位写了半天没写出来。 256位转64位各位就当没说，主要是这个算法。 谢谢啊！[/quote][/quote] 这个我都知道。 就是感觉不知道怎么得到一个数到底有多少位。[/quote]

引用 10 楼 derekrose 的回复:你的*位*指的是什么 就是bit。 这个你可以不管！ 看看例如后面的吧！ 例如后面的怎么实现。

你的*位*指的是什么

引用 7 楼 lubyam 的回复:没有看懂楼主的意思 就看例如后面的吧！ 不用管256转64了。

引用 5 楼 turingo 的回复:给你举个例子吧，比如有 unsigned char a; unsigned char b;  你需要把a的高6位放到低位，b的低2位放到高位，组成新的 unsigned char c;  那么可以很简单的这样运算： c = ((a >> 2) & 0x3f) | ((b << 6) & 0xc0);  如果没有用过位运算的话，那么建议先去了解一下位运算的基本法则  [quote=引用 3 楼 u011717322 的回复:] [quote=引用 2 楼 turingo 的回复:] 需求再弄清楚一点吧，总的来说，你的问题只需要用数组和位运算就可以解决的。  [quote=引用 楼主 u011717322 的回复:] 组长叫我实现一个将256位的数转换为64位的数！ 大概的方法是：将256的数提取前6位，组合成新的数。 例如：0xC1 0xF5 0x41（1100 0001 1111 0101 0100 0001）转变成：      110000 011111 010101 000001，这样就变成了0X30 0X1F 0x15 0x01 再例如：0x31（0011 0001）转变成001100 010000，变成0x0C 0x10   大概就是这样的个情况！ 本人C语言写的不是很多，以前都是搞搞C++，写了半天都没有写出完整的。 希望能有人帮我实现下。 不胜感激！[/quote] 这个是具体的算法。后面还要转！不过后面的要简单点了。 就是这个左移6位写了半天没写出来。 256位转64位各位就当没说，主要是这个算法。 谢谢啊！[/quote][/quote] 这个我都知道。 就是感觉不知道怎么得到一个数到底有多少位。

没有看懂楼主的意思

引用 4 楼 max_min_ 的回复:一个将256位的数转换为64位的数  这个具体是什么意思？ 要截取前面的还是后面的？ 不好意思，其实这个问题没说完， 但是具体的算法就是这个， 你就当没说256位转64位吧。 就是截取前面的6位，后面不足6位的在后面加0

给你举个例子吧，比如有 unsigned char a; unsigned char b;  你需要把a的高6位放到低位，b的低2位放到高位，组成新的 unsigned char c;  那么可以很简单的这样运算： c = ((a >> 2) & 0x3f) | ((b << 6) & 0xc0);  如果没有用过位运算的话，那么建议先去了解一下位运算的基本法则  引用 3 楼 u011717322 的回复:[quote=引用 2 楼 turingo 的回复:] 需求再弄清楚一点吧，总的来说，你的问题只需要用数组和位运算就可以解决的。  [quote=引用 楼主 u011717322 的回复:] 组长叫我实现一个将256位的数转换为64位的数！ 大概的方法是：将256的数提取前6位，组合成新的数。 例如：0xC1 0xF5 0x41（1100 0001 1111 0101 0100 0001）转变成：      110000 011111 010101 000001，这样就变成了0X30 0X1F 0x15 0x01 再例如：0x31（0011 0001）转变成001100 010000，变成0x0C 0x10   大概就是这样的个情况！ 本人C语言写的不是很多，以前都是搞搞C++，写了半天都没有写出完整的。 希望能有人帮我实现下。 不胜感激！[/quote] 这个是具体的算法。后面还要转！不过后面的要简单点了。 就是这个左移6位写了半天没写出来。 256位转64位各位就当没说，主要是这个算法。 谢谢啊！[/quote]

引用 2 楼 turingo 的回复:需求再弄清楚一点吧，总的来说，你的问题只需要用数组和位运算就可以解决的。  [quote=引用 楼主 u011717322 的回复:] 组长叫我实现一个将256位的数转换为64位的数！ 大概的方法是：将256的数提取前6位，组合成新的数。 例如：0xC1 0xF5 0x41（1100 0001 1111 0101 0100 0001）转变成：      110000 011111 010101 000001，这样就变成了0X30 0X1F 0x15 0x01 再例如：0x31（0011 0001）转变成001100 010000，变成0x0C 0x10   大概就是这样的个情况！ 本人C语言写的不是很多，以前都是搞搞C++，写了半天都没有写出完整的。 希望能有人帮我实现下。 不胜感激！[/quote] 这个是具体的算法。后面还要转！不过后面的要简单点了。 就是这个左移6位写了半天没写出来。 256位转64位各位就当没说，主要是这个算法。 谢谢啊！

需求再弄清楚一点吧，总的来说，你的问题只需要用数组和位运算就可以解决的。  引用 楼主 u011717322 的回复:组长叫我实现一个将256位的数转换为64位的数！ 大概的方法是：将256的数提取前6位，组合成新的数。 例如：0xC1 0xF5 0x41（1100 0001 1111 0101 0100 0001）转变成：      110000 011111 010101 000001，这样就变成了0X30 0X1F 0x15 0x01 再例如：0x31（0011 0001）转变成001100 010000，变成0x0C 0x10   大概就是这样的个情况！ 本人C语言写的不是很多，以前都是搞搞C++，写了半天都没有写出完整的。 希望能有人帮我实现下。 不胜感激！

问题能描述清楚点么？256位的数转换为64位，应该是数据变短，而后边的例子，是数据变长。。。。

引用 27 楼 lubyam 的回复:[quote=引用 25 楼 u011717322 的回复:] [quote=引用 23 楼 lubyam 的回复:] [quote=引用 22 楼 lubyam 的回复:]  仅供参考 不知道是不是楼主要的· #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h>  int main(int argc,char *argv[]) { 	int a,i,count,*num,j=0,k=0; 	int m=1; 	int n=0;  	char buf[100]={0},buf1[100]={0}; 	scanf("%x",&a); 	itoa(a,buf,2); 	if(strlen(buf)%4!=0) 	{ 		count=(strlen(buf)/4+1)*4%strlen(buf); 		memcpy(buf+count,buf,strlen(buf)); 		for (i=0;i<count;i++) 		{ 			buf[i]='0'; 		} 	}  	if (strlen(buf)%6!=0) 	{ 		a=a<<( (strlen(buf)/6+1)*2%(strlen(buf))); 	} 	itoa(a,buf,2); 	if(strlen(buf)%4!=0) 	{ 		count=(strlen(buf)/4+1)*4%strlen(buf); 		memcpy(buf+count,buf,strlen(buf)); 		for (i=0;i<count;i++) 		{ 			buf[i]='0'; 		} 	} 	 	num=(int *)malloc(strlen(buf)/6); 	memset(num,0,strlen(buf)/6); 	for (i=0;i<strlen(buf)/6;i++) 	{ 		num[i]=0; 	} 	i=0; 	j=5; 	while(buf[k]!='\0') 	{ 		count=pow(2.0,j); 		num[i]+=(buf[k]-'0')*count; 		j--; 		k++; 		if (j==-1) 		{ 			i++; 			j=5; 		} 	} 	for (i=0;i<strlen(buf)/6;i++) 	{ 		printf("%x \n",num[i]); 	} 	return 0; }    for (i=0;i<strlen(buf)/6;i++)    {        printf("%02x \n",num[i]);    }   如果要在前面补0的话可以向上面那么写[/quote] 刚刚运行了下！果然是对的啊！好犀利啊！ 太感谢了啊！ 我看你很多位置*4%strlen(buf);或者*2%strlen(buf);这个不是很懂！ 能讲下你的思路吗？ 太感谢你了！ 我写了半天都写不对！[/quote]   POW是系统的函数pow(x,y) 求x的y次幂。  思路大概是这样的。。  先输入一个 16进制的数，然后转换为2进制的。      if(strlen(buf)%4!=0)     {         count=(strlen(buf)/4+1)*4%strlen(buf);         memcpy(buf+count,buf,strlen(buf));         for (i=0;i<count;i++)         {             buf[i]='0';         }     }  这里是因为itoa会去掉2进制前面的0，所以得把前面的0补上    if (strlen(buf)%6!=0)     {         a=a<<( (strlen(buf)/6+1)*2%(strlen(buf)));     } 这里是 4位转6位然后补0   有一个缺点就是，输入的16进制数要在int的范围内，不然会出错[/quote] 知道了！ 太犀利了！ 怎么不知道谢好! 给你50分吧！ 再次谢了！

引用 25 楼 u011717322 的回复:[quote=引用 23 楼 lubyam 的回复:] [quote=引用 22 楼 lubyam 的回复:]  仅供参考 不知道是不是楼主要的· #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h>  int main(int argc,char *argv[]) { 	int a,i,count,*num,j=0,k=0; 	int m=1; 	int n=0;  	char buf[100]={0},buf1[100]={0}; 	scanf("%x",&a); 	itoa(a,buf,2); 	if(strlen(buf)%4!=0) 	{ 		count=(strlen(buf)/4+1)*4%strlen(buf); 		memcpy(buf+count,buf,strlen(buf)); 		for (i=0;i<count;i++) 		{ 			buf[i]='0'; 		} 	}  	if (strlen(buf)%6!=0) 	{ 		a=a<<( (strlen(buf)/6+1)*2%(strlen(buf))); 	} 	itoa(a,buf,2); 	if(strlen(buf)%4!=0) 	{ 		count=(strlen(buf)/4+1)*4%strlen(buf); 		memcpy(buf+count,buf,strlen(buf)); 		for (i=0;i<count;i++) 		{ 			buf[i]='0'; 		} 	} 	 	num=(int *)malloc(strlen(buf)/6); 	memset(num,0,strlen(buf)/6); 	for (i=0;i<strlen(buf)/6;i++) 	{ 		num[i]=0; 	} 	i=0; 	j=5; 	while(buf[k]!='\0') 	{ 		count=pow(2.0,j); 		num[i]+=(buf[k]-'0')*count; 		j--; 		k++; 		if (j==-1) 		{ 			i++; 			j=5; 		} 	} 	for (i=0;i<strlen(buf)/6;i++) 	{ 		printf("%x \n",num[i]); 	} 	return 0; }    for (i=0;i<strlen(buf)/6;i++)    {        printf("%02x \n",num[i]);    }   如果要在前面补0的话可以向上面那么写[/quote] 刚刚运行了下！果然是对的啊！好犀利啊！ 太感谢了啊！ 我看你很多位置*4%strlen(buf);或者*2%strlen(buf);这个不是很懂！ 能讲下你的思路吗？ 太感谢你了！ 我写了半天都写不对！[/quote]   POW是系统的函数pow(x,y) 求x的y次幂。  思路大概是这样的。。  先输入一个 16进制的数，然后转换为2进制的。      if(strlen(buf)%4!=0)     {         count=(strlen(buf)/4+1)*4%strlen(buf);         memcpy(buf+count,buf,strlen(buf));         for (i=0;i<count;i++)         {             buf[i]='0';         }     }  这里是因为itoa会去掉2进制前面的0，所以得把前面的0补上    if (strlen(buf)%6!=0)     {         a=a<<( (strlen(buf)/6+1)*2%(strlen(buf)));     } 这里是 4位转6位然后补0   有一个缺点就是，输入的16进制数要在int的范围内，不然会出错

引用 23 楼 lubyam 的回复:[quote=引用 22 楼 lubyam 的回复:]   for (i=0;i<strlen(buf)/6;i++)    {        printf("%02x \n",num[i]);    }   如果要在前面补0的话可以向上面那么写[/quote] 看懂*4strlen(buf)和*2strlen(buf)做什么了，是为了补齐添加0. 最后问下Pow函数式做什么？


Question: 关于static全局变量与普通全局变量的区别

引用 3 楼 baipv008 的回复:[quote=引用 楼主 qq283802332 的回复:] 定义该变量的源文件内有限(即在1.h中有限)。 你的核心错误在于： .h不是源文件，源文件是指.c或.cpp[/quote] 嗯，#include <*.h>语句的效果就是预处理时将*.h的全部内容复制到使用include语句的文件中

编译的过程有好几步的，在给gcc编译之前是预处理，预处理时把include包括的文件加进来，之后这个文件给gcc进行编译。这时候才是真正意义上的源文件。   定义与申明是不同的，申明可以放到头文件中去，但是定义是不能放到头文件中的。 定义与申明的不同在于申明是给编译器看的，但是定义会分配内存。你使用 static int s;这个时候就已经分配了一个内存。这是定义，怎么能放到内存里呢？

比如一个项目里面有2个.c源文件（互相不能#include，include .c文件不规范），一个文件定义了static全局变量a，另一个文件就无法用extern a声明这个外部变量，非static就可以。

函数体内static变量的作用范围为该函数体，改变量只被分配一次，其值在下次调用的时候扔维持上次调用的值。 模块内的static全局变量可以被模块内的所有函数访问，但不能被模块外的其他函数访问。 模块内的static函数只能被该模块内部的其他函数调用，这个函数的使用范围被限制在该模块内部。 C++中另有类： 类中static成员属于整个类所有，对类的所有对象只有一份拷贝 类中static成员函数属于整个类所有，这个函数不接受this指针，因而只能访问类的static成员变量。  你没搞清楚.h .c区别。.h仍是模块的一部分。include了.h就把.h的所有内容放在了.c中，直接使用命令行gcc -E file..c -o file.i看看结果

楼主只要知道 编译器是怎么处理#include的 就是直接把那些文件内容拷贝进来 然后再编译的 就是和你直接写在那个点c里是一样的

楼上几位都说得对 楼主你明明已经include了1.h，当然被视为同一个文件了

你的理解没有错，但是例子给错了，#include的话，展开之后相当于static在main中仍然是可见的。你把static放在.h文件中是无意义的，且很容易被重复引用而形成重复定义。正确的做法是在.c中定义全局变量，而在.h中用extern引出全局变量，当然static变量是无法extern的。  引用 楼主 qq283802332 的回复:这是在书上看到的一个static全局变量与普通全局变量的一个区别说明  1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式， 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序， 当一个源程序由多个源文件组成时，非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域， 即只在定义该变量的源文件内有效， 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内，只能为该源文件内的函数公用，因此可以避免在其它源文件中引起错误。  这是源文件1.h  int a = 2;                //普通全局变量 static int s = 5;         //static全局变量   这是源文件2.h  int b = 3;                //普通全局变量   这是main.c  #include <stdio.h> #include "1.h" #include "2.h"  int func() {     return s; }  int main() {     printf("%d\n", a);     printf("%d\n", b);      printf("%d\n", s);        //这里有问题 }   在printf("%d\n", s)中， s这个变量是我在1.h这个头文件中定义的一个static全局变量， 而从上面的说明中可以知道static去阿奴姐变量限制了其作用域， 即之灾定义该变量的源文件内有限(即在1.h中有限)。 在同一源程序的其它源文件中不能使用它。可是我却可以在main.c中使用这个变量， 这是不是矛盾了 这个是我现在理解不了的地方， 请各位code monkey讲解一下

引用 楼主 qq283802332 的回复:定义该变量的源文件内有限(即在1.h中有限)。 你的核心错误在于： .h不是源文件，源文件是指.c或.cpp

C:static 函数外部定义，是文件静态变量，作用域为文件，生命周期是程序生命期。 函数内定义，是函数内部的静态变量，作用域为函数，生命周期是程序生命期。 其中，函数中，语句组的内部静态变量，作用域为该语句组，生命周期是程序生命期。  C++：     文件内的，匿名命名空间内，定义的变量，相当于文件静态变量。     作用域为文件，生命周期是程序生命期。 类内部定义的静态变量，作用域为类，生命周期是程序生命期。 可以使用的区域是类，     友元类或友元函数，以及定义类的区域，这些和友元，访问权等有关。    类的作用域对友元是开放的。子类也有可能可以使用。    对定义类的区域是否开放和访问权限等有关。    其中 public 定义的静态变量， 在定义类的区域，可以通过类名访问。     和函数不同，函数内部定义的静态变量； 不可用在其他地方，只能通过函数调用访问。 类内部定义的静态变量，可以直接在类外部，通过类名引用。

头文件声明普通全局变量不妥，如果多个源文件引用会有重定义错误 一般头文件里面用extern 声明为外部全局变量吧，然后在某个源文件里面真正定义。

一般而言，定义变量在 c 文件中，声明变量在 h 文件中


Question: VC下写的一个链表操作，错误好多啊，是缺少什么头文件么？

编译器问题？我用的是VC"++6.0可以运行无措

楼上正解 改成.cpp 编译正确

cpp文件编译通过！楼主把文件名改成.cpp的吧！c++兼容c，但是c不兼容c++的！

改成.CPP文件,点c文件格式使用C编译器，C编译器不支持 &引用参数类型。


Question: 这个周末的一个非名牌大学的校级算法大赛，我该准备些什么？

引用 8 楼 liman65727 的回复:开来我猜错了，你也猜错了    交流交流下编程。

引用 8 楼 liman65727 的回复:开来我猜错了，你也猜错了 你的移动短号是多少？我的是646496

开来我猜错了，你也猜错了

引用 4 楼 liman65727 的回复:如果我没猜错的话楼主应该是贵阳学院的吧如果我没有猜错的话，你应该不是贵阳地区的。

准备的有点晚, 而且太低估对手了...

不用带任何准备 带着你那份自信与实力去比赛就了

如果我没猜错的话楼主应该是贵阳学院的吧

有个C算法100题，挺不错的。都是常用的算法，可用作燃眉之急吧。试试，挺有趣的。百度文库就有不少

楼主太过紧张了，大二还是先学好数据结构再说，这种校级的算法竞赛，难度都不会太大，主要是考编程能力。

引用 9 楼 zhang5476499 的回复:[quote=引用 8 楼 liman65727 的回复:] 开来我猜错了，你也猜错了 你的移动短号是多少？我的是646496[/quote] Q:657271181,短号666237

引用 1 楼 ak47_wz 的回复:上oj去刷题，或者直接去看《算法竞赛入门经典》。都能在短时间内快速提高。嗯，在当当网购了这本书，就是一直没有寄到手上，各种急啊。

上oj去刷题，或者直接去看《算法竞赛入门经典》。都能在短时间内快速提高。


Question: 笔试的时候做的，发现编译无错，运行到最后一句时出错

引用 7 楼 angel_su 的回复:s.p[1]=3把自己改了指向地址3，这个位置系统不让改的...++正解

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

引用 10 楼 z1179675084 的回复:这里没有数组越界，就是在那捣鼓地址里面内容，32位机下面，这个程序有问题，64位机并且是64位编译器的话不会有任何问题！ 怎么可能没问题？s.p[1]=3;这句执行之后s.p指向的地址为0x00000003，s.p[0]=4就相当于是对0x00000003这个地址进行操作，不出错才怪。

引用 11 楼 yulitingfeng 的回复:gcc打印出地址： s.i的地址：1961422464 p的地址：1961422464,p[1]的地址1961422468 s.p的地址：1961422464,s.p[1]的地址：1961422468 s.i=4,s.p[0]=4 ,s.p[1]=3,p[0]=4,p[1]=3  #include <stdio.h> struct S { 	int i; 	int *p; }; int main() { 	struct S s; 	int *p=&s.i; 	p[0]=1; 	p[1]=2; 	s.p=p; 	s.p[1]=3; 	s.p[0]=4; 	printf("s.i的地址：%d\n",&s.i); 	printf("p的地址：%d,p[1]的地址%d\n",p,&p[1]); 	printf("s.p的地址：%d,s.p[1]的地址：%d\n",&(s.p[0]),&(s.p[1])); 	printf("s.i=%d,s.p[0]=%d ,s.p[1]=%d,p[0]=%d,p[1]=%d\n",s.i,s.p[0],s.p[1],p[0],p[1]); }s.i，s.p[0]，p[0]地址都是1961422464。 p[1]和s.p[1]地址相同。

引用 1 楼 turingo 的回复:p[1]访问越界了，结果难料，出错很正常。  [quote=引用 楼主 ggyanjiang 的回复:] #include <stdio.h> struct S { 	int i; 	int *p; }; void main() { 	struct S s; 	int *p=&s.i; 	p[0]=1; 	p[1]=2; 	s.p=p; 	s.p[1]=3;         pritnf("aa"); 	s.p[0]=4; }[/quote] 这里没有数组越界，就是在那捣鼓地址里面内容，32位机下面，这个程序有问题，64位机并且是64位编译器的话不会有任何问题！

这个不是数组越界。问题如下： s.p[1] = 3==> *(&s.i + 1) = 3也就是s.p = 3,故其作用也就是s.p[0] 指向内存地址为 3的地方，你可以printf("%d\n",&s.p[0]);看看结果肯定为3 s.p[0] = 4==>*((int *)3) = 4不用我说你也知道不行了吧！ 这个是32位下的效果，64位下指针占8位，结构体内部还涉及到数据对齐和这个有区别！如果不用别的手段，这个程序不会有任何问题！

#include <stdio.h>  struct S { 	int i; 	int *p; }; int main() { 	struct S s; 	int *p=&s.i;//p指向s.i 	p[0]=1;//s.i=0 	p[1]=2;//s.p=2 	s.p=p;//s.p指向s.i 	s.p[1]=3;//s.p[1] == s.p = 3 --!!注意这里     printf("aa"); 	s.p[0]=4;//这里要把内存地址为3的位置的值 赋为4..... }  这是我的分析，不知道对不对..

s.p[1]=3把自己改了指向地址3，这个位置系统不让改的...

好乱。。。。。。。。。

嗯，楼上讨论的内存大小和字节对齐是有道理的，上述问题产生的原因还是使用s.p进行了不合法的读写，关键还是s.p[1] = 3这一步覆盖了s.p。 与指针是64位的类似，如果#pragma pack(8)之类的话上述问题也不会出现了

s.p[0]取值还没错，s.p[1]肯定是越界了，如果s.p[0]在前，还是能打印出数据的。支持s.p[1]会发生什么。。 undefine。。

貌似是这样子：  #include <stdio.h> struct S {     int i;     int *p; }; void main() {     struct S s;     int *p=&s.i;//p指向s.i，S结构体占用8个字节，现在*p = p[0] = s.i，由于结构体内存连续存放，则*(p+1) = p[1] = s.p     p[0]=1;     //由上知，现在s.i = 1     p[1]=2;	//由上知，现在s.p = 2（s.p这个指针现在指向地址为0x00000002这个不允许读写的内存块）     s.p=p;      //由上知，现在s.p = p = &s.i     s.p[1]=3;   //由上知，与p = &s.i时p[1] = s.p一样，现在是s.p = &s.i，则s.p[1] = s.p，从而现在s.p = 3， 		//即s.p这个指针现在指向地址为0x00000003这个不允许读写的内存块     printf("aa");     s.p[0]=4;	//s.p[0] = *s.p = *((int*)0x00000003) = 4，不合法写 }

同意楼上的解释

最后打印出s。p[1]地址是0x7，因为s。p[0]地址是0x3，加上4字节，所以是0x7

所以最后一句s.p[0]就是从地址0x3后退4字节，这部分区域不可访问的导致报错。  这句话说错了，s.p[0]应该就是0x3

11楼说的有点道理外，其他全是扯淡，经实验证明：  前面流程就不多说了，从s.p开始吧，s.p=p,也就是s.i的地址，就是s.p指针变量里面存的是s.i的地址，s.p[1]所指向的地址其实也就是结构体定义s.p变量的地址，也是s。p指针变量本身的地址，不要搞混，(一个是指针所指向也就是所保存的地址，一个是指针变量本身的地址，注意两者的区别)，当s。p[1]=3时候，也是往s.p指针变量里面保存3这个数值，这样就好理解了，那么s。p指针变量所指向的地址就是0x3，所以最后一句s.p[0]就是从地址0x3后退4字节，这部分区域不可访问的导致报错。  lz的另一种情况，假如s。p[0]放在s.p[1]的前面赋值，因为s。p[0]指向是s.i的地址，所以赋值没有错误，s。p[1]指向是s.p指针变量的地址，所以给s.p指针变量赋值是没有错的，就是改变s。p指向而已。   以上都是经过程序验证得出的，没有错误，lz自己可以读出s。p变量本身的地址和内容就知道了。谢谢

引用 18 楼 L812234929 的回复:[quote=引用 17 楼 z1179675084 的回复:] 你认真读一下我9楼的回复，你说的这个我已经在9楼回答过了，我说的没问题是指64位机，64位编译器下面，如果就这样写绝对不会有问题，不信你按我的条件编译试试，或者我给你画个图你就明白了。 我好像记得标准里面int型在64位机器下面也战了8个字节吧，当然我这没有64为机器，我也没法测试。如果你用64位机器测试过，那么我错了。[/quote] 呵呵，我是个学生，回答问题不多，但是所有我回答的，都是认真思考验证过的。

引用 17 楼 z1179675084 的回复:你认真读一下我9楼的回复，你说的这个我已经在9楼回答过了，我说的没问题是指64位机，64位编译器下面，如果就这样写绝对不会有问题，不信你按我的条件编译试试，或者我给你画个图你就明白了。 我好像记得标准里面int型在64位机器下面也战了8个字节吧，当然我这没有64为机器，我也没法测试。如果你用64位机器测试过，那么我错了。

引用 13 楼 L812234929 的回复:[quote=引用 10 楼 z1179675084 的回复:]  这里没有数组越界，就是在那捣鼓地址里面内容，32位机下面，这个程序有问题，64位机并且是64位编译器的话不会有任何问题！ 怎么可能没问题？s.p[1]=3;这句执行之后s.p指向的地址为0x00000003，s.p[0]=4就相当于是对0x00000003这个地址进行操作，不出错才怪。[/quote] 你认真读一下我9楼的回复，你说的这个我已经在9楼回答过了，我说的没问题是指64位机，64位编译器下面，如果就这样写绝对不会有问题，不信你按我的条件编译试试，或者我给你画个图你就明白了。


Question: 【求助】C语言编的程序，怎么让那个EXE文件默认全屏运行？

#include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     PAINTSTRUCT ps;     HDC hdc;     HFONT hfont,ohfont;     RECT r;     COLORREF oc;      switch(message) {     case WM_CLOSE://按Alt+F4退出         PostQuitMessage(0);         break;     case WM_PAINT:         BeginPaint(hWnd, &ps);         hdc = ps.hdc; // the device context to draw in         GetClientRect(hWnd, &r); // Obtain the window's client rectangle         hfont = CreateFont(240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");         ohfont=SelectObject(hdc,hfont);         oc=SetTextColor(hdc,0x00C080FF);         SetBkMode(hdc, TRANSPARENT);         TextOut(hdc,r.left+r.right/2-720, r.top+r.bottom/2-120,"最短画图程序",12);         SelectObject(hdc,ohfont);         SetTextColor(hdc,oc);         DeleteObject(hfont);         EndPaint(hWnd, &ps);         break;     default:         return DefWindowProc(hWnd, message, wParam, lParam);     }     return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {     MSG msg             = {0};     WNDCLASS wc         = {0};     HBRUSH hbrh;     hbrh=CreateSolidBrush(0x00000000);     wc.lpfnWndProc      = WndProc;     wc.hInstance        = hInstance;     wc.hbrBackground    = hbrh;     wc.lpszClassName    = "minwindowsapp";     wc.hCursor          = LoadCursor(NULL,IDC_ARROW);     if( FAILED(RegisterClass(&wc)) ) return 1;      if(FAILED(CreateWindow(wc.lpszClassName,                         "Minimal Windows Application",                         WS_POPUP|WS_VISIBLE,                         0,                         0,                         GetSystemMetrics(SM_CXSCREEN),                         GetSystemMetrics(SM_CYSCREEN),                         0,                         0,                         hInstance,                         NULL)))         return 2;      while( GetMessage( &msg, NULL, 0, 0 ) > 0 ) {         DispatchMessage( &msg );     }     DeleteObject(hbrh);     return 0; }

引用 楼主 u012605940 的回复:C语言编的程序，完成后出现一个EXE文件，怎么让那个EXE文件默认全屏运行？不管到哪个电脑上，都是全屏运行、、？ 可以调整的，可以用鼠标点击窗口上边缘白色部分，右键有属性，可以修改字体大小与布局大小，可以看一下下面的图片，我测试了一下，修改了可以再次打开就是你上次设置的值！


Question: 变长参数(printf的形参那种)，移植性如何？

C标准库可以跨平台.

引用 2 楼 NE_Demon 的回复:还有，除了可变参数外，还有什么办法可以在调用函数的时候，传递任意类型的实参，而不警告？ 比如： int i; int *pi; test(i); test(pi); 我不想让第三和第四句有报警 test的定义，无论是test(long v);还是test(void* v); 都会有一条语句要报警的。  void test(int v);  int i; int *pi; test(i); test((int)pi);

上C++函数重载，也可以不确定类型。

标准c里面的，当然能跨平台

是C语言标准，当然需要编译器支持

仅供参考#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中


Question: 看看数据结构的单链表逆转 出错了

typedef struct LinkNode{ 	char c; 	struct LinkNode *next; }LinkNode,*LinkList;  void reserse(LinkList *head) { 	LinkList p=*head; 	LinkList q=NULL; 	while(p) 	{ 		LinkList l=p->next; 		p->next=q; 		q=p; 		p=l; 	} 	*head=q; } 不知道你的linklist是节点还是指针，节点的话为什么还有个node，指针的话赋值就出错了。以上供参考。

用递归或者栈

引用 1 楼 envenler 的回复:p=L->next ;  L->next= NULL;  这不是直接p = NULL吗？ 不是吧。。。。

单链表，有很多种哦，带不带空头结点，，是否循环链表。都会影响算法的。  带头节点的，只要传递链表的头结点即可。 不带的要改变头结点，可能需要传递头结点的指针，或者引用。 C++ 引用传递，除了参数是头结点的引用，形参类型为节点（指针类型）的引用。 不带和带头节点差不多，只是不带的头结点要在逆转后变成尾节点。  不带头节点，C需要传递， 节点（指针类型）的指针，实质是二级指针。 所以语法就有点别扭。  循环链表，一般是尾指针表示，也可以双指针表示。 逆转时，注意一下，别在链表中插入环，否则有可能无限循环。 程序死循环了，一般这种情况，称为死机。

引用 5 楼 lubyam 的回复:没有调试，仅供参考   LinkList reserse(LinkList *L)  { 	 	Node *p,*q;    	p=L->next ;     	q=p->next; 	L->next=NUll;    	while(p!=NULL) 	{ 		p->next=L; 		L=p; 		p=q; 		q=q->next;     	}  }  总是提示p=L->next ; 出错

引用 1 楼 envenler 的回复:p=L->next ;  L->next= NULL;  这不是直接p = NULL吗？  你确定p=NULL?

引用 3 楼 jemii 的回复:在while循环里  p->next=L->next; 在之前L->next已经被你置为空了, 我的想法是增加一个值来保存逆序前的节点,我默认函数的参数就是链表第一个元素了,以下是我的代码   LinkList reserse(LinkList *L) { 	LinkList *t,*p,*q; 	if(L == NULL ||L->next == NULL) 		return L; 	t=L;                                   //t指向链表的第一个节点                                                   	p=t->next; 	t->next = NULL; 	while(p) 	{ 		q=p->next; 		p->next = t; 		t=p; 		p=q; 	} 	 	L=t;                                  //将链表第一个节点指向t 	return L; }  好吧 返回值少了个*

引用 7 楼 qing498745097 的回复:[quote=引用 5 楼 lubyam 的回复:] 没有调试，仅供参考   LinkList reserse(LinkList *L)  { 	 	Node *p,*q;    	p=L->next ;     	q=p->next; 	L->next=NUll;    	while(p!=NULL) 	{ 		p->next=L; 		L=p; 		p=q; 		q=q->next;     	}  }  总是提示p=L->next ; 出错[/quote]  额。。。。。你这next应该是一个LinkList  的指针？

引用 8 楼 qing498745097 的回复:[quote=引用 4 楼 jemii 的回复:] [quote=引用 3 楼 jemii 的回复:] 在while循环里  p->next=L->next; 在之前L->next已经被你置为空了, 我的想法是增加一个值来保存逆序前的节点,我默认函数的参数就是链表第一个元素了,以下是我的代码   LinkList reserse(LinkList *L) { 	LinkList *t,*p,*q; 	if(L == NULL ||L->next == NULL) 		return L; 	t=L;                                   //t指向链表的第一个节点                                                   	p=t->next; 	t->next = NULL; 	while(p) 	{ 		q=p->next; 		p->next = t; 		t=p; 		p=q; 	} 	 	L=t;                                  //将链表第一个节点指向t 	return L; }  好吧 返回值少了个*[/quote] 提示 if(L == NULL ||L->next == NULL)出错了[/quote] 是编译报错了么 报了什么错 我没有调试 所以不知道 这个只是判断你传进来的是不是空链表或者链表只有一个节点

引用 4 楼 jemii 的回复:[quote=引用 3 楼 jemii 的回复:] 在while循环里  p->next=L->next; 在之前L->next已经被你置为空了, 我的想法是增加一个值来保存逆序前的节点,我默认函数的参数就是链表第一个元素了,以下是我的代码   LinkList reserse(LinkList *L) { 	LinkList *t,*p,*q; 	if(L == NULL ||L->next == NULL) 		return L; 	t=L;                                   //t指向链表的第一个节点                                                   	p=t->next; 	t->next = NULL; 	while(p) 	{ 		q=p->next; 		p->next = t; 		t=p; 		p=q; 	} 	 	L=t;                                  //将链表第一个节点指向t 	return L; }  好吧 返回值少了个*[/quote] 提示 if(L == NULL ||L->next == NULL)出错了

Ｐ指向Ｌ，Ｌ指向Ｐ　，ＮＵＬＬ＝ＮＵＬＬ，这不是０等于０


Question: 由GETCHAR和DO。。。WHILE引起的死循环

改过后通过了

在上述程序中，break之后少了分号。 在rand之前，去掉int . 将getchar改为getchar. 不知理由。

a=int rand();b=int rand(); 编译通过了？


Question: 如何在linux下用c语言实现对键盘的监听

引用 3 楼 yulitingfeng 的回复:在《linux程序设计》中有一个用监听键盘在终端上输入的代码。 如果有这本书可以看看源码是怎么实现的。 恩恩，我看看

引用 2 楼 yulitingfeng 的回复:可以看看hook函数，不过对于这种危险级别的东西需要谨慎点。 是参照win下hook来写一个linux下的吗

引用 4 楼 fantasy_l 的回复:[quote=引用 楼主 SH471630654 的回复:] 在学习操作系统的东西，想在linux下用c语言实现： 一个父进程创建二个子进程，其中一个子进程来监听键盘，另一个子进程将监听到的信息存入文件。  在linux中，如何实现对键盘的监听呢，没有像win中现成的函数吗？？ 你是山东科技大学的吧[/quote] 还真是，我网络的，你哪个专业？

引用 楼主 SH471630654 的回复:在学习操作系统的东西，想在linux下用c语言实现： 一个父进程创建二个子进程，其中一个子进程来监听键盘，另一个子进程将监听到的信息存入文件。  在linux中，如何实现对键盘的监听呢，没有像win中现成的函数吗？？ 你是山东科技大学的吧

可以看看hook函数，不过对于这种危险级别的东西需要谨慎点。


是第三方库自定义的消息，请问这个消息是如何产生的? typedef enum MGUI_MSGID {     GUI_MSG_CREATE = 0,     GUI_MSG_DESTROY,     GUI_MSG_PAINT,      GUI_MSG_CLOSE,     GUI_MSG_QUIT,     GUI_MSG_KEY,     GUI_MSG_TOUCH,     GUI_MSG_COMMAND,     GUI_MSG_SYSTEM,     GUI_MSG_NOTIFY_CHILD_DELETED,     GUI_MSG_SET_FOCUS, }mgui_msgid_e;

被放入消息队列里面  然后被取出来  然后你就发现他产生了

第三方库自定义的消息，研究一下库的文档。  引用 楼主 huabinsir 的回复:请问GUI_MSG_COMMAND这个消息是如何产生的? 是点击某个标签产生的吗?  static __s32 __FileExplorerProc(mgui_msg_t * msg) { 	APP_DEBUG_CBMSGEx;  	switch(msg->id) 	{ 	case GUI_MSG_CREATE: 	case GUI_MSG_DESTROY: 	case GUI_MSG_QUIT: 		break; 	case GUI_MSG_POWER_LOW: 	     return 0;		 	case GUI_MSG_KEY: 		break; 	case GUI_MSG_COMMAND: 		return OnFileExplorerCommand(msg); 	case GUI_MSG_PAINT: 	case GUI_MSG_IME_CHAR: 	case GUI_MSG_IME_CTRL_CHAR: 		App_FileExplorerOnImeMsg(msg); 	return 0; 	case GUI_MSG_TIMER: 	default: 		break; 	} 	return MGUI_WinDefaultProc(msg); }

应该是那种Gui下命令消息吧！ 在对应的IDE中，右键看看是否有相关信息，可以看看！


Question: truecrypt 7.1 二次开发 c#

引用 1 楼 user-1 的回复:还是找找C#上的加密库吧谢谢您！

还是找找C#上的加密库吧