Question: 讨论：跨3大手机平台的Framework

用特性（Attribute）实现metadata与C符号的连接，就像C#一样：  [DllImport("kernel32.dll")] int MessageBoxW( ....省略... );   用metadata生成C头，如：  metadata file: class People : public Animal { public:     [extern_c]     int foo();   };   C header: struct People_st {     struct People_vtable *_vtable;     struct Animal_st      _animal_stub; };  extern People_foo( struct People_st * ); // user need implememt it  当然也可以是其他模样，总之制定一个二进制兼容标准就好。

我请大家继续关注。 我近来也思考了许久。  我提出了一个简单一点的实现方案。  1. 定义一个metadata的二进制标准，包括类、域、方法、属性、特性、名空间、继承相关、接口、甚至包括类似C++饱受诟病的多重继承、虚继承等等。  2. 写一个metadata编译器，从源码编译为二进制表示，提供utily tool functions，让C可以读metadata（相当于提供了反射机制）。  3. 写一个metadata二进制到C的头文件的编译器，让C可以二进制兼容metadata。  基于我现有的gc堆，我可以实现一个带metadata 和 GC 的 C 语言体系。  4. 我在各个平台移植metadata的utily tool functions以及基础库代码，以提供一个基于metadata的framework，我的framework平台就可以搭建出来了。  这样我就避免要实现一个类似C#的编译器和JIT（尽管我现在有一个，但不是生成优化代码，要加优化需要做很多工作）。

cocos?

ding more

引用 23 楼 sinservice 的回复:[quote=引用 22 楼 N_sev7 的回复:] 很值得深入做，即使产品未获得预想的成效 但是技术上绝对大大的进步了 但是一个项目的成功与失败， 决定的因素太多了 <个人意见，纯属扯淡>  我也花了些时间了解了下Unity3D， U3D的确为3D（2D）游戏开发提供了绝佳的平台，连UDK都正在被逐渐踢出市场。傲游新出的免费平台Genesis3D也直接面临被踢的局面。U3D大有一统天下的前景。  我觉得，在企业应用上，还是有很大的空间可以开发，而这个空间是U3D目前不想进入的。  [/quote] 祝LZ成功！！！敢想-敢做-能做，就值得学习 任何一件事情在没有失败之前都是成功的

引用 22 楼 N_sev7 的回复:很值得深入做，即使产品未获得预想的成效 但是技术上绝对大大的进步了 但是一个项目的成功与失败， 决定的因素太多了 <个人意见，纯属扯淡>  我也花了些时间了解了下Unity3D， U3D的确为3D（2D）游戏开发提供了绝佳的平台，连UDK都正在被逐渐踢出市场。傲游新出的免费平台Genesis3D也直接面临被踢的局面。U3D大有一统天下的前景。  我觉得，在企业应用上，还是有很大的空间可以开发，而这个空间是U3D目前不想进入的。

祝福楼主吧，坚持自己的理想，总会有回报的

前景黯淡

值得坚持, 不要只向钱看, 先做出东西来, 有钱图自然会来的

mono，还开源的呢，你说的这些不都实现了吗

引用 14 楼 taodm 的回复:说实话，没有意义。最好的情况就是能做个demo，然后坐等收购。  why?

说实话，没有意义。最好的情况就是能做个demo，然后坐等收购。

引用 11 楼 sinservice 的回复:u3d确实挺好，但我没法做成那样，它的团队有100人左右，我只有2个人。 那估计你要花更多的精力和时间了！ 兼容性一直软件比较头疼的东西！考虑的东西多了，自然一些处理就复杂了！

引用 9 楼 sinservice 的回复:不现实 没有哪家公司会支持你这样的运行时的，他们甚至会打压 看看flash吧，基本上就是你所做的东西，但adobe不得不黯然放弃  --------------  我在三个平台上做三个XAP，XAP运行起来就是我这个平台。开发者可以基于这个平台开发，开发之后的包是个Zip，这个Zip可以在这三个XAP里运行。 那么你是带上运行库的方式了，这个可以参考QT，体积，性能目前是瓶颈

u3d确实挺好，但我没法做成那样，它的团队有100人左右，我只有2个人。

引用 5 楼 akirya 的回复:unity3d不就是么  确实是哦。

引用 楼主 sinservice 的回复:本人近年来一直在写一个准备跨三大手机平台（爱疯、安卓疯、闻疯）的Framework，就是类似dotnet，但可以移植，并支持一次编译（生成集合），便可以在所有平台上跑。  已经完成的部分：  1. TTF字体引擎 2. 2D矢量图形引擎 3. 桌面UI引擎及标准控件 4. 高级语言（类似C#）的Compiler，编译为字节码 5. 字节码的JIT 6. 并行并发GC Heap   未完成部分： 6. metadata （正在开发中——） 7. x64（for windows）支持（原来仅支持x86） （正在重构最底层库——）  我想做到的是，以后开发者仅在一个Framework的环境里开发，底层都被抽象，语言只用一个，代码只写一次。  我想征求一下诸位的意见。诸位对我这个产品的前景有何看法？  对真知灼见，本人必高分相赠。（但最多只能用200分，我还有5000多分，不知怎么能加上。） 不现实 没有哪家公司会支持你这样的运行时的，他们甚至会打压 看看flash吧，基本上就是你所做的东西，但adobe不得不黯然放弃

多高级语言肯定可以加，我说一种语言，主要指一种IL。


Question: 关于返回char指针的函数

有没有哪位可以说明一下最适合返回指针类型函数的应用场景？ 或者这么问:我想利用某个函数构造一个字符串，函数的形参是一些构建字符串的辅助数据， 最后返回这个串的首地址，常用的方法有哪些？

返回局部变量。结果不可预知...

计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

引用 楼主 zhao286 的回复:1.下面函数返回的局部变量str数组的地址，所以在调用的地方打印乱码是可以理解的。    不理解的是，为什么重复调用后，都会正常显示。    而且我在调用的地方用一个char指针接收sub_int函数返回值竟然也等于返回时pch的值，不理解。   char *sub_int(int x,int y) { 	char str[256]; 	char *pch = str; 	memset(str,0,sizeof(str)); 	snprintf(str,sizeof(str),"sub_int(%d,%d)",x,y);  	return pch; }  2.main函数  int main() { 	int x,y; 	x=5; 	y=2; 	printf("%s\n",add_int(x,y)); 	printf("%s\n",add_int(x,y));  	return 0; }  3.运行结果第一行乱码，之后都正常显示： ??$! add_int(5,2)  返回局部指针地址是危险的！因为它的生命周期到函数调用结束也就结束了！ 返回偶尔能获取到有效数据，只是说明数据没有及时擦除而已！但是结果还是不可预知的！

打印出来只是碰巧

char str[size]; 这个问题取决于你的size是多少 要深入考虑你这个char str申请的空间在哪了 怎么存的连续的？ 局部变量的数组 str的内存存放 什么时候会释放 什么时候不释放 当size为一定值时 可能出现三种都打印 三种都不打印 乱码等可能

栈内的数据随时可以被改变，这样做是不可预料的，只是碰巧有正确的结果而已，深究下去没有意义。   引用 楼主 zhao286 的回复:1.下面函数返回的局部变量str数组的地址，所以在调用的地方打印乱码是可以理解的。    不理解的是，为什么重复调用后，都会正常显示。    而且我在调用的地方用一个char指针接收sub_int函数返回值竟然也等于返回时pch的值，不理解。   char *sub_int(int x,int y) { 	char str[256]; 	char *pch = str; 	memset(str,0,sizeof(str)); 	snprintf(str,sizeof(str),"sub_int(%d,%d)",x,y);  	return pch; }  2.main函数  int main() { 	int x,y; 	x=5; 	y=2; 	printf("%s\n",add_int(x,y)); 	printf("%s\n",add_int(x,y));  	return 0; }  3.运行结果第一行乱码，之后都正常显示： ??$! add_int(5,2)

返回局部变量的内存地址，只要以后这块内存系统不占用，那里面的值就不会改变，你第一行返回了乱码，说明在函数返回后系统占用了这块内存，改变了里面的值，之后正常显示，则系统一直没有占用，但无法保证在将来的某个时刻不占用。   其实函数返回局部变量的地址没有什么不可，它属于进程地址空间中的合法内存，因此我们可以放心的使用，之所以不提倡这样做，是因为我们不知道系统何时会占用这块内存并导致里面的值改变，


Question: 我的问题

计算机语言有什么本质的共同点吗 实现逃不出冯诺依曼结构  计算机语言未来的总发展方向是什么 声明式（DSL和函数式） 动态 并发 这是C#（Turbo Pascal）之父的总结，可以参考，详见： http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html  对语言感兴趣，可以看看 Concepts of Programming Languages Programming Language Concepts 这样的书

两个c语言都解决不了！  自己多注意IT方向的动态就好了！

都是工具 都是逻辑规约

图灵机


Question: 弱弱的问一个问题

c语言版 数据结构！

《数据结构与算法分析 -C语言描述》

视频0清华大学 数据结构 严蔚敏 书籍呢 其实任何一本数据结构的书都是很好的 我不记得我看过哪本书了 数据结构学习 主要是自己的逻辑思维 把书上的视频的 在你脑子你过个无数遍 你脑袋会变得越来越快 剩下的我就没怎么用过太多 关键是处理一个问题的逻辑处理模型  数据结构最终目的不是学它们的 而是可以自己在脑海里很快创建 只属于你自己的 不好解释 至少有一天你会感觉到的

《算法导论》

为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。


Question: C语言---菜鸟求助！！！！！

看着你的排序方法不像冒泡哦，但你想用冒泡的排序方法。 可以看一下三楼的冒泡排序

在值传递方式中，在说明和定义函数时，要在数组参数的尾部加上一对方括号([])，调用函数时只需将数组的地址(即数组名)传递给函数

#include<stdio.h> #define n 10  void sort(int score[n]); int main() { 	int i; 	int score[n]; 	printf("please enter the score:"); 	for (i = 0; i<n; i++) 	{ 		scanf("%d", &score[i]); 	} 	sort(score); 	printf("the result is:"); 	for (i = 0; i<n; i++) 	{ 		printf("%d,%d\n", i, score[i]); 	} 	return 0; } void sort(int a[n]) { 	int i, j, term; 	for (i = 0; i<n; i++) 	{ 		for (j = i + 1; j<n; j++) 		{ 			if (a[j]<a[i]) 			{ 				term = a[j]; 				a[j] = a[i]; 				a[i] = term; 			} 		} 	} }

有何问题？？？？

稍微修改了一下啊  #include <stdio.h> #define n 10  void my_sort(int *a); // n定义了宏，可以不需要传参数了的 int main() {     int i;     int score[n];     printf("please enter the score: \n");     for (i = 0; i<n; i++)     {            scanf("%d", &score[i]);         getchar(); // 吃掉每次输入的回车符     }        my_sort(score);     printf("the result is:\n");     for (i = 0; i<n; i++)     {            printf("%d,%d\n", i, score[i]);     }    } void my_sort( int *a)  {     int i, j , temp;     for(i =0; i< n ;i ++)      {            for(j =0 ; j < n-i-1; j++)         {                if( a[j] > a[j+1])             {                    temp = a[j];                 a[j] = a[j+1];                 a[j+1] = temp;             }            }        }    }

引用 4 楼 u012848622 的回复:二楼跟三楼的代码都行，可我就讷闷了，我的怎么就不行了呢？百思不得其解。我感觉我的代码跟楼上的两位基本一样。 你函数形参写的有问题啊，void sort(int score[n],int n)；大小n，这样是不行的 数组作参数传递的时候和指针是一样的！ 下面的几个试试 void sort(int score[],int n)； void sort(int *score,int n)

引用 4 楼 u012848622 的回复:二楼跟三楼的代码都行，可我就讷闷了，我的怎么就不行了呢？百思不得其解。我感觉我的代码跟楼上的两位基本一样。  正因为基本一样才帮你改改。要是基本都不行那就懒得理你了。


Question: C语言继续求

引用 1 楼 u012407856 的回复:求大神救援，新人不懂事 http://download.csdn.net/detail/n_sev7/3610885   学生成绩管理系统

这个题目网上到处都是，好好看看书

求大神救援，新人不懂事


Question: 怎样用c语言控制时间

linux下有localtime/mktime/time等函数可以调用。

有时间函数调用

实时刷新获取时间  #include <stdio.h> #include <time.h> #include <unistd.h> int main (void ) {     time_t Curtime;     tm sTime = {0};     while(1)     {            time(&Curtime);          tm *RetTime = localtime( &Curtime );         printf("Time: %04d-%02d-%02d %02d:%02d:%02d \r"                 ,RetTime->tm_year + 1900                 ,RetTime->tm_mon + 1                  ,RetTime->tm_mday                 ,RetTime->tm_hour                 ,RetTime->tm_min                 ,RetTime->tm_sec);         sleep(1);         fflush(stdout);     }         return 0; }

调用时间函数接口即可

这个要调用windows的api。设置一个定时器，没隔一段时间（<=1s）获取一下系统时间，再显示出来。

#include <time.h>  #include <stdio.h>  int main( void )  {  time_t t = time(0);  char tmp[64];  strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A 本年第%j天 %z",localtime(&t) );  puts( tmp );  return 0;  }  size_t strftime(char *strDest, size_t maxsize, const char *format, const struct tm *timeptr);   这个可以精确到秒，还有精确去网上找代码，很多了

仅供参考#include <graphics.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dos.h> #include <conio.h> #include <time.h> #include <math.h> time_t t; char timestr1[30];//DDD MMM dd hh:mm:ss YYYY char timestr2[30];//DDD MMM dd hh:mm:ss YYYY char hhmmss[9]; int graphdriver,graphmode,page; int i,xo,yo,r0,r1,r2,r3,r4,r5,r6,r7; int x1,y1,x2,y2; int hh,mm,ss; double c,s; int xasp,yasp; void main() {     xo=60;yo=60;     r0=5; //轴     r1=20;//时针     r2=36;//分针     r3=45;//秒针     r4=50;//时刻度     r5=53;//分刻度     r6=55;//刻度外     r7=59;//表盘     graphdriver=VGA;     graphmode=VGAMED;     initgraph(&graphdriver,&graphmode,"D:\\BC\\BGI");     getaspectratio(&xasp, &yasp);     page=0;     timestr2[0]=0;     while (1) {         if (kbhit()) break;         time(&t);         strcpy(timestr1,ctime(&t));         if (strcmp(timestr1,timestr2)) {             strcpy(timestr2,timestr1);             hh=atoi(timestr2+11);             mm=atoi(timestr2+14);             ss=atoi(timestr2+17);             setvisualpage(page);             setactivepage(1-page);             cleardevice();             sprintf(hhmmss,"%02d:%02d:%02d",hh,mm,ss);             outtextxy(28,0,hhmmss);             pieslice(xo,yo,0,360,r0);             circle(xo,yo,r7);             for (i=0;i<60;i++) {                 c=cos(i*6*3.14159265/180);                 s=sin(i*6*3.14159265/180)*xasp/yasp;                 if (0==(i%5)) {                     x1=xo+r4*c;                     y1=yo+r4*s;                 } else {                     x1=xo+r5*c;                     y1=yo+r5*s;                 } 				x2=xo+r6*c; 				y2=yo+r6*s; 				line(x1,y1,x2,y2); 				if (((hh%12)*5+mm/12+45)%60==i) { 					x2=xo+r1*c; 					y2=yo+r1*s; 					setlinestyle(0,-1,3); 					line(xo,yo,x2,y2); 					setlinestyle(0,-1,1); 				} 				if ((mm+45)%60==i) { 					x2=xo+r2*c; 					y2=yo+r2*s; 					setlinestyle(0,-1,3); 					line(xo,yo,x2,y2); 					setlinestyle(0,-1,1); 				} 				if ((ss+45)%60==i) { 					x2=xo+r3*c; 					y2=yo+r3*s; 					line(xo,yo,x2,y2); 				} 			} 			page=1-page; 		}         delay(100);     }     getch();     closegraph(); }

有时间调用函数的，直接调用就可以了。你可以到资源里找一个做参考，应该有很多。


Question: 新手C语言求教

看到LZ的要求，觉得要用到设置光标的函数及sleep休眠函数，以下是我的代码（在VC6运行），LZ看看符不符合要求： #include <stdio.h> #include <conio.h> #include <windows.h>  void setPosition(int x, int y) { 	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);//获取控制台的句柄 	COORD newPosition = {x, y};//COORD是个结构体，包含列，行的坐标 	SetConsoleCursorPosition(hConsole, newPosition); 	return ; }  int main(int argc, char **argv) { 	int i;  	for (i=1; i<=3; i++) 	{ 		printf("%2d", i); 		Sleep(1000); 	}  	setPosition(0, 0); 	for (i=1; i<=3; i++) 	{ 		printf("%2d", ((i+1) == 4) ? 1 : i+1); 		Sleep(1000); 	} 	return 0; }

引用 10 楼 u012632434 的回复:[quote=引用 9 楼 hanlingxia 的回复:] #include <stdio.h> #include <windows.h>  void main() { 	printf("%d ", 1);  	Sleep(1000); 	printf("%d ", 2); 	Sleep(1000); 	printf("%d ", 3);  	system("cls"); 	Sleep(1000); 	printf("1"); 	Sleep(1000); 	system("cls"); 	Sleep(1000); 	printf("2"); 	Sleep(1000); 	system("cls"); 	Sleep(1000); 	printf("3"); } 是这样吗？ 3q,虽然最后没有输出2,3,1，只输出了3，我自己改改[/quote]不客气~~

加个sleep就可以了

运行的时候休眠下应该可以啊 #include<stdio.h> #include <windows.h> void main() {  printf("1");  Sleep(1000);  printf("2"); }

引用 5 楼 junlinfushi 的回复:这需要用的时间函数 Sleep(1000*15)？这个应该可以吧

这需要用的时间函数

引用 9 楼 hanlingxia 的回复:#include <stdio.h> #include <windows.h>  void main() { 	printf("%d ", 1);  	Sleep(1000); 	printf("%d ", 2); 	Sleep(1000); 	printf("%d ", 3);  	system("cls"); 	Sleep(1000); 	printf("1"); 	Sleep(1000); 	system("cls"); 	Sleep(1000); 	printf("2"); 	Sleep(1000); 	system("cls"); 	Sleep(1000); 	printf("3"); } 是这样吗？ 3q,虽然最后没有输出2,3,1，只输出了3，我自己改改

我表述有误，是运行程序后，先看到1,2,3依次出来，然后看到1变成2,2变成3，3变成1  引用 1 楼 junlinfushi 的回复:要编译器看到变化过程???????? 不是，我表述有误，是运行程序后，先看到1,2,3依次出来，然后看到1变成2,2变成3，3变成1

引用 楼主 u012632434 的回复:输出1,2,3，并把1变成2,2变成3，3变成1，要编译器看到变化过程 我表述有误，是运行程序后，先看到1,2,3依次出来，然后看到1变成2,2变成3，3变成1

不太明白题目是什么意思。 难道是: if (a==1) {   printf("修改前a==%d\n",a);    a = 2;    printf("修改后a==%d\n",a); } 这样？

要编译器看到变化过程????????


Question: 帮我看下多文件关系问题

root@kali:~# make clean makefile:8: *** 遗漏分隔符 。 停止。  这makefile随它去，我想问下什么情况用#include，什么情况用extern。

引用 3 楼 u012453424 的回复:[quote=引用 1 楼 user-1 的回复:]  CC =gcc #如果头文件和源文件都在同一级目录下,如果不是后面相对源文件的路径 CFLAGS = -I./ OBJS = main.o 64.o 54.o TARGET = 64   $(TARGET):$(OBJS)     $(CC) -o $(TARGET) $(OBJS) $(CFLAGS) $(OBJS):%.o:%.c     $(CC) -c $(CFLAGS) $< -o $@ clean:     rm 64 $(OBJS)  你的makefile第8行遗漏东西了[/quote] 其实的代码感觉有点累赘，包含下头文件就好了！没必要extern了 另外 第8行少了什么呢？

引用 1 楼 user-1 的回复: CC =gcc #如果头文件和源文件都在同一级目录下,如果不是后面相对源文件的路径 CFLAGS = -I./ OBJS = main.o 64.o 54.o TARGET = 64   $(TARGET):$(OBJS)     $(CC) -o $(TARGET) $(OBJS) $(CFLAGS) $(OBJS):%.o:%.c     $(CC) -c $(CFLAGS) $< -o $@ clean:     rm 64 $(OBJS)  你的makefile第8行遗漏东西了

除了makefile，别的地方没一点问题了吗？


strtok函数有不安全的地方，建议不要用这个函数，可以考虑用strsep函数代替

#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: 在while循环中能循环调用函数，怎么调用一次后不调用啦？

你可以把你的函数体改成有条件执行的 在while循环之前定义static a = 0; type func(args) {   if (a == 0)   {       函数体   }   ++a; } 这样第一次调用后的调用执行的都是空操作

你的程序我虽然不知道你在干嘛，因为数学问题我不懂。 但是你的程序我能运行，输出结果也近似于无限输出。 不过我提个建议就是，变量声明的时候最好初始化。或者赋初始值。这样会少不少不明错误

代码又长又乱 你把while标成红色啊 出问题的地方是红色的 在while循环中能循环调用函数，怎么调用一次后不调用啦？ 肯定是 条件为假  跳出了  ifZ( a, b, iAexplain ,fA, fC, fZ); int swap=1; while(swap ==1) { circulate( a, b, iAexplain , fB, fC, fZ, fA); output(fA,  iAexplain,fC, fB, a, b,fZ); if(mm(fZ,b)==1) swap=0; else swap=1; } 执行一次 if(mm(fZ,b)==1) swap=0; 直接就是swap是0了 推理mm(fZ,b) 这个函数永远返回1 继续推理  int mm(float fz[],int a) { int h=0; for(int i=0;i<a;i++) { if(fz[i]<=0) h++; } if(h==a) return 1; else  return 0; } 推理 if(h==a) return 1; h永远等于a 继续推理 int h=0; for(int i=0;i<a;i++) { if(fz[i]<=0) h++; } 继续推理 if(fz[i]<=0) 这个永远小于等于0 推理出  fz[] 传参到底是什么东西 检查  你写的代码太乱了 数学功底太深了 真是大神级人物啊 、 以上推理纯属主观臆断 没有debug 我也不敢说你问题出在哪 仅供参考

太长了，不想看


Question: 求助各位大神，计算机如何判断我们访问的一个地址是非法地址呢？

引用 14 楼 u011416173 的回复:[quote=引用 3 楼 user-12 的回复:] 汇编问题去汇编子版。 去了，没人回，着急了就回这发了，各位的回复我尽快看，刚看到。 谢谢各位了！[/quote] 还是会有非法的，无论你用什么语言，都是MMU来管理内存，不是实模式下的内存都需要经过那套复杂的映射过程。

引用 3 楼 user-12 的回复:汇编问题去汇编子版。 去了，没人回，着急了就回这发了，各位的回复我尽快看，刚看到。 谢谢各位了！

引用 楼主 u011416173 的回复:在汇编语言层次，还存在所谓的非法地址么？我的意思是cpu对任何地址都可以访问，读取或者修改。  汇编层次一样有非法地址啊，关键是看系统有没有介入，os有个功能叫内存管理，是os的核心功能之一，你对内存的访问都要通过一个在计算机上叫mmu的玩意儿，这是一个设备，os在启动系统的过程中接管了mmu，并且通过内存管理单元，os会对内存做一个全局的管理。 比如那段是程序a的，哪段是程序b的，哪段是内核的，自然你越界了，os就有各种反应 裸板没有os，但是你越界的话 一样会造成不可挽回的错误

exe编译好了, 里面也是汇编代码, 所以你直接使用汇编代码同样会访问非法. 这是操作系统规定好的, 只有在系统内核中限制才会少一些.  这可能涉及到权限和内存管理机制了.

每个运行在操作系统上的程序，其内存都是操作系统分配的，以Win32为例，每个程序所拥有的是一个4G的地址空间，也就是你的地址是4个G，但并不代表你真的有这么多内存可访问，你要用内存就必须向操作系统申请，由它分配给你一块真实的内存，对应地址空间里的一段。如果你访问一个实际上它没有分配给你的地址，那就是非法地址。

跟汇编没关系  关键是看你调用的api是什么，你在r0还是r3，你使用的os是什么，你使用的硬件要求  从上往下，一路过去，谁都可以说，你访问非法

win32 API:  IsBadCodePtr IsBadReadPtr IsBadStringPtr IsBadWritePtr

参考Intel CPU手册，内存区段管理。

引用 8 楼 nadleeh123 的回复:[quote=引用 楼主 u011416173 的回复:] 在汇编语言层次，还存在所谓的非法地址么？我的意思是cpu对任何地址都可以访问，读取或者修改。  汇编层次一样有非法地址啊，关键是看系统有没有介入，os有个功能叫内存管理，是os的核心功能之一，你对内存的访问都要通过一个在计算机上叫mmu的玩意儿，这是一个设备，os在启动系统的过程中接管了mmu，并且通过内存管理单元，os会对内存做一个全局的管理。 比如那段是程序a的，哪段是程序b的，哪段是内核的，自然你越界了，os就有各种反应 裸板没有os，但是你越界的话 一样会造成不可挽回的错误[/quote] +1

引用 楼主 u011416173 的回复:在汇编语言层次，还存在所谓的非法地址么？我的意思是cpu对任何地址都可以访问，读取或者修改。  CPU可以访问任何地址，但你的程序不行。这里有个权限的问题。

其实判断不了。但是如果你访问的太出格，比如操作系统都没有分配的内存，保留的地址，标记为不可访问的地址，等等，OS会拦截下来给Runtime报告你这个是非法地址。

32位程序，可以用4G的内存。 如果系统给足够4G的内存的话，除了系统保护的地址外（一般前64k）都不会非法操作的。 但系统怎么会给够一个进程4G，虽说内存便宜，但几百G还是不少钱的。

汇编问题去汇编子版。

顶个，大神帮帮忙

还望各位大神不吝赐教啊


Question: 结构体的成员变量是指针的地址问题

指针变量本身的地址 指针变量中存储的数值（地址）

typedef struct {     int *a;     int *b;     int c; }test;  int main( void ) {     test *t = ( test * )malloc( sizeof( test ) );     printf( "%x\n", t );//t的地址     printf( "%x\n", t->a );//成员a的值，你又没赋值，谁知道什么内容，地址t+0     printf( "%x\n", t->b );//同上 地址 t+4     printf( "%x\n", &t->c ); //地址 t+8 }

指针变量都要程序员自己给它申请地址空间的。lz这只对结构体指针t申请了地址空间，而结构体内的指针a和b没有申请地址空间。

typedef struct {     int *a;     int *b;     int c; }test;   int main( void ) {     test *t = ( test * )malloc( sizeof( test ) );     printf( "%x\n", t );             //因为t是结构体，所以t=&t，用t能打印t结构体的首地址。     printf( "%x\n", t->a );       //t->a是一个成员，该成员本身占用4个字节，这4个字节的内容为他指向的变量的地址。因为这里没显示赋初值（即该指针没指向任何变量），初值依赖于编译器的实现。     printf( "%x\n", t->b );       //同上     printf( "%x\n", &t->c );      //这里用了地址符，指的是t->c这个成员的地址，没问题。 }   正确代码应为：  typedef struct {     int *a;     int *b;     int c; }test;   int main( void ) {     test *t = ( test * )malloc( sizeof( test ) );     printf( "%x\n", &t );       //加上地址符使代码易读性更好     printf( "%x\n", &(t->a) );  //加上&才是t->a这个 类型为指针的结构体成员 的本身地址     printf( "%x\n", &(t->b) );  //同上     printf( "%x\n", &(t->c) );  //代码少依赖于优先级顺序更好     free(t);                    //要养成好习惯哦 }

引用 3 楼 max_min_ 的回复:那是因为它指向还没有，随机值！ 但是打印它指针本身递地址都是间隔4个字节是对的！  printf("s = %p \n", pTest);     printf("a = %p \n", &(pTest->a));     printf("b = %p \n", &(pTest->b));     printf("c = %p \n", &(pTest->c));  //结果 s = 0x8526008  a = 0x8526008  b = 0x852600c  c = 0x8526010  正解


Question: 程序出现如下问题，求破。。。

debug，单步调试，现追到出错点，再查找出错原因

heap crash, 堆损毁

点击 中止，然后在调试菜单中，查看一下调用堆栈。就能定位出错点了

貌似数组越界，检查一下吧，检查不出来就debug

引用 2 楼 wangdahu888 的回复:点击 中止，然后在调试菜单中，查看一下调用堆栈。就能定位出错点了  不是点击中止，是点击重试...然后查看堆栈...

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

这是调试的情况：


Question: 新手小白求指教C语言编程

printf wrong  ...

\n是转移字符，也是字符串的一部分。

引用 3 楼 max_min_ 的回复:注意：细心点，多调试代码！根据编译器提示的错误联系上下文找可能的语法错误！ printf("help,world!\n");+1

我也是刚入门  那个\n要写在""里面的

引用 1 楼 keiy 的回复:#的地方没错,可能是你编译器设置的问题,程序在printf处有错 #include<stdio.h>   int main()  {         printf("help,world!\n");         return 0;  }  注意 printf()中 “”的位置


Question: 二叉树运行结果有误~求修改

cd[n-1]='\0';//从右向左逐位存放编码，首先存放编码结束符 上面这行要移到下一行后面:   cd=(char *)malloc(n*sizeof(char));//分配求当前编码的工作空间   cd[n-1]='\0';//从右向左逐位存放编码，首先存放编码结束符  以下2行:   int min1=INT_MIN;//最小值,INT_MAX在<limits.h>中定义   int min2=INT_MIN;//次小值 要改为:   int min1=INT_MAX;//最小值,INT_MAX在<limits.h>中定义   int min2=INT_MAX;//次小值


Question: 如何判断一个.o文件是否有gdb信息

用如下命令：  objdump -t a.o   如果出现如下的.debug_段，则表示里面有调试信息，可以用gdb进行调试：  00000000 l    d  .debug_aranges	00000000              .debug_aranges 00000000 l    d  .debug_pubnames	00000000              .debug_pubnames 00000000 l    d  .debug_info	00000000              .debug_info 00000000 l    d  .debug_abbrev	00000000              .debug_abbrev 00000000 l    d  .debug_line	00000000              .debug_line 00000000 l    d  .debug_frame	00000000              .debug_frame 00000000 l    d  .debug_str	00000000              .debug_str 00000000 l    d  .debug_loc	00000000              .debug_loc  引用 楼主 nbda1121440 的回复:假设有一个文件a.c  我可以这么编译：gcc -o a.o -c a.c 也可以这么编译：gcc -o a.o -c a.c -g  请问我如何根据已有的a.o判断到底是上面两种中哪一种方式编译的？

objdump -参数 man objdump 我记不住了 汇编成二进制 可以看到区别 还是怎么搞了 很久不弄这个了 你可以试试 实验下

没有调试信息，也可以用gdb调试。


Question: 如何用数组指针传值

引用 2 楼 u011922164 的回复:果然厉害，为什么地址操作不可以，是因为分配的内存不连续吗？  p=a;  //数组a 此时退化为指针  If the type of an expression or subexpression is ``array of T,'' for some type T, then the value of the expression is a pointer to the first object in the array, and the type of the expression is altered to ``pointer to T.'' This conversion does not take place if the expression is in the operand of the unary & operator, or of ++, --, sizeof, or as the left operand of an assignment operator or the . operator. Similarly, an expression of type ``function returning T,'' except when used as the operand of the & operator, is converted to ``pointer to function returning T.''

果然厉害，为什么地址操作不可以，是因为分配的内存不连续吗？

include <stdio.h> fun(double*p) {  double a[10]={0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0}; //p=a; //这里只是地址操作而已 memcpy((void*)p, (void*)a, sizeof(double) * 10); //用这个试试 return 0; }


Question: c语言语句理解问题

引用 2 楼 max_min_ 的回复: int  x=10,*p=&x; // 这里首先让p指向指向x，x的内容是10 printf("%d",(*p)++);// （*p）解引用取p指向指向的内容值，                   //然后执行此语句操作后 再进行+1操作                  //所以不考虑编译环境文件，打印出来 是10 ，实际p的内容为 11;+1

引用 5 楼 junlinfushi 的回复:[quote=引用 2 楼 max_min_ 的回复:]  int  x=10,*p=&x; // 这里首先让p指向指向x，x的内容是10 printf("%d",(*p)++);// （*p）解引用取p指向指向的内容值，                   //然后执行此语句操作后 再进行+1操作                  //所以不考虑编译环境文件，打印出来 是10 ，实际p的内容为 11;+1[/quote] +1

先取p指向的那个东西给printf用，然后让p指向的那个东西加一。

*p是取p的值。 (*p)++，这个是后缀++，会先取元素的值，等语句结束后（遇到结算点，详情看置顶贴）再进行自增运行。 所以打印的还是10，但打印后*p已经递增到11了。

跟踪，调试，查看变量，查看内存。  不行的话就反汇编。看指令。

printf("%d",(*p)++); (*p)为x 的值 (*p)++相当于x++,(*p)的值(也就是x的值)+1;


Question: 耶稣的叛徒（下标）

回楼上，用链表实现。

问题是什么？？


Question: gcc #include与多文件编译

一般都是丢在头文件里，然后包含头文件就好的！头文件加 重定义保护的！ 如果多处用到的宏的话，最好也放在共用的头文件里面的！ 至于多文件编译的话，可以看看makefile的基本规则依赖关系

max.h

好了我已经知道了，不过说说你们的答案验证一下也无所谓


Question: 【救急】Sublime Text3 运行c显示Decode error - output not utf-8

不行

LZ下面这个网页好像有你这个问题解决的方法 http://blog.csdn.net/chszs/article/details/8232077


Question: 指针的打印问题

出现乱码是引文，返回的是局部指针的吧！函数返回的是s1的地址，局部指针！ 修改了下，看看  #include <stdio.h> #include <string.h>   char *app(char *string1, char *string2) {     char s2[20] = {0};  //  strcpy(s1,string1);     strcpy(s2,string2);      return strcat(string1,s2); }  int main(void) {     char p1[20] = "abcd";     char *p2 = "cde";     char *p;       p = app(p1,p2);     printf("%s\n", p);       return 0; }


Question: 这道题的输出是什么呢？为什么？

引用 17 楼 Adol1111 的回复:[quote=引用 16 楼 aoqqq 的回复:] [quote=引用 14 楼 AzraelLamber 的回复:] [quote=引用 11 楼 Adol1111 的回复:] [quote=引用 10 楼 wyc6668205 的回复:] 这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。[/quote] 嗯cpu定的[/quote]  administrator@ubuntu:~/Desktop/aoqianglin $ vi Test3.c  administrator@ubuntu:~/Desktop/aoqianglin $ gcc -o Test3 Test3.c  administrator@ubuntu:~/Desktop/aoqianglin $ ./Test3  -1217265398       就是把这个在linux下测试的，[/quote] 这个还真不能这样说，-1217265398的16进制的64位值是FFFF FFFF B772010A。算32位的话，去掉前面的FFFF FFFF也就是B772 010A，你可以最后4位是 010A 和 你的设置是符合的。有问题的是前面的4位是B772，问题就在于你没给它指定值，所以他里面的值是无法保证的。你应该声明char[4]，然后先全部清0，再赋值。[/quote] 分析非常到位，赞

引用 楼主 aoqqq 的回复:union {  int i;  char x[2]; }a;   void main() {  a.x[0] = 10;   a.x[1] = 1;  printf("%d",a.i); }   联合体啊 就像int 你也可以看作char x[4] = {...}

引用 20 楼 jiandingzhe 的回复:输出是不定的。跟系统的大小端有关，还跟int的尺寸有关。 大小端跟CPU有关，和系统无关

引用 19 楼 u011930458 的回复:问下，大端小端，高字节，低字节，大尾端，小尾端，的对应关系  [quote=引用 11 楼 Adol1111 的回复:] [quote=引用 10 楼 wyc6668205 的回复:] 这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。[/quote][/quote] 大端应该就是大尾端，是指：高位在低地址 小端应该就是小尾端，是指：尾位在低地址 如图：

输出是不定的。跟系统的大小端有关，还跟int的尺寸有关。

问下，大端小端，高字节，低字节，大尾端，小尾端，的对应关系  引用 11 楼 Adol1111 的回复:[quote=引用 10 楼 wyc6668205 的回复:] 这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。[/quote]

关键是Union会共享空间，你给char数组赋值的时候，其实就等于是给int i赋值了。当然仅从i的角度来看，这个是无法预估的值，因为你是给char数组赋值，而不是i。

计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

测试的结果依然是一个小端CPU，在测试的时候记得去掉干扰。不要让系统帮你取默认环境。

引用 16 楼 aoqqq 的回复:[quote=引用 14 楼 AzraelLamber 的回复:] [quote=引用 11 楼 Adol1111 的回复:] [quote=引用 10 楼 wyc6668205 的回复:] 这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。[/quote] 嗯cpu定的[/quote]  administrator@ubuntu:~/Desktop/aoqianglin $ vi Test3.c  administrator@ubuntu:~/Desktop/aoqianglin $ gcc -o Test3 Test3.c  administrator@ubuntu:~/Desktop/aoqianglin $ ./Test3  -1217265398       就是把这个在linux下测试的，[/quote] 这个还真不能这样说，-1217265398的16进制的64位值是FFFF FFFF B772010A。算32位的话，去掉前面的FFFF FFFF也就是B772 010A，你可以最后4位是 010A 和 你的设置是符合的。有问题的是前面的4位是B772，问题就在于你没给它指定值，所以他里面的值是无法保证的。你应该声明char[4]，然后先全部清0，再赋值。

引用 14 楼 AzraelLamber 的回复:[quote=引用 11 楼 Adol1111 的回复:] [quote=引用 10 楼 wyc6668205 的回复:] 这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。[/quote] 嗯cpu定的[/quote]  administrator@ubuntu:~/Desktop/aoqianglin $ vi Test3.c  administrator@ubuntu:~/Desktop/aoqianglin $ gcc -o Test3 Test3.c  administrator@ubuntu:~/Desktop/aoqianglin $ ./Test3  -1217265398       就是把这个在linux下测试的，

引用 13 楼 wyc6668205 的回复:[quote=引用 11 楼 Adol1111 的回复:] [quote=引用 10 楼 wyc6668205 的回复:] 这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。[/quote]  sorry，我整错了，没经过测试道听途说的，确实不靠谱。[/quote]  我电脑的windows输出为266，linux输出为-1217396470，这不是跟系统有关啊

引用 11 楼 Adol1111 的回复:[quote=引用 10 楼 wyc6668205 的回复:] 这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。[/quote] 嗯cpu定的

引用 11 楼 Adol1111 的回复:[quote=引用 10 楼 wyc6668205 的回复:] 这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。[/quote]  sorry，我整错了，没经过测试道听途说的，确实不靠谱。

我怪自己分不够多啊，真想都给高分，我这算是抛砖引玉啊

引用 10 楼 wyc6668205 的回复:这个得分系统，在windows系统是低字节在前，高字节在后，得出的结果是266(010A) 在linux系统是高字节在前，低字节在后，得出的结果是167837696(0A010000) 联合体的内存是共享的，所有变量共用一块内存，为最大内存空间变量的内存空间 大小端应该和系统无关吧，是硬件决定的吧。

引用 7 楼 Adol1111 的回复:[quote=引用 5 楼 AzraelLamber 的回复:] 看内存嘛 赋值 char[0]内存 0x0a char[1]内存 0x01  int内存就是： 0x00 00 01 0a 这就是266 +1[/quote] 这么一讲确实清楚多了，为什么不是0a01呢

引用 5 楼 AzraelLamber 的回复:看内存嘛 赋值 char[0]内存 0x0a char[1]内存 0x01  int内存就是： 0x00 00 01 0a 这就是266 +1


Question: C语言求救

CSDN资源下载，搜索一下，一大堆可以下载。

这个问题确实有点。。不好解决

还是这个帖子啊，我怎么有看到了 你把他分成几个模块就行了，菜单，输入，查询，输出，修改，只是你需要用个文件，每次对文件进行操作，简单写写就好了，没什么意义

这种题目资源里应该有很多吧，下一个回去简单改改就好了，有必要开价么...

好悲伤，好悲伤

引用 1 楼 xihu1364 的回复:1.只有40分... 2.居然还4个题目.（每题只有10分，还排除LZ可能给其他人分）  直接了当，给个价吧。论坛里肯定很多人会接活...开价是怎么开的，第一次发帖，不懂

怎么开价的啊

引用 3 楼 max_min_ 的回复:点这里 输入：c语言学生成绩管理系统    回车

开价很多人都会做的，说不定很多人直接给你好几种语言的实现。

点这里 输入：c语言学生成绩管理系统    回车

大家都很忙 开个价吧


Question: 求C语言下改文件名或改目录名的函数

引用 3 楼 max_min_ 的回复:  #include <stdio.h>  int rename(const char *oldpath, const char *newpath); 学习了

调用stdlib头文件中的system函数， system函数原型 int system (const char *str) system自动把str指向的字符串发送给系统的命令解释器， win下为dos， linux下为系统shell，也就是说在system形参中写改文件名的相应命令。  实例： linux bash ：   #include <stdlib.h>  int main () {    system("mv /home/john/123.cpp /home/john/999.cpp");     return 0; } 把文件名123改为999  也可加入命令行参数修改程序 使得程序专门用来作为修改文件名 不过实质还是调用系统命令


Question: 请各位大神帮我看看书上的一道习题

我感觉挺有意思的，也写了一个！申明下 我不会算法，只是简单的实现  #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <unistd.h>  #define LEFT_MOVE  0 #define RIGHT_MOVE 1  #define UP_MOVE    2 #define DOWN_MOVE  3 void PrintArray( char (*arr)[10], int llen, int rlen ) {     int i, j;     for( i = 0; i < llen; i++)     {            for(j = 0; j < rlen; j++)             printf("%c ", arr[i][j]);         printf("\n");     }    }  void CreateArray( char (*arr)[10], int llen, int rlen ) {     int i, j;     for( i = 0; i < llen; i++)     {            for(j = 0; j < rlen; j++)             arr[i][j] = '*';     }    }  void CreateMaze (char (*arr)[10], int llen, int rlen ) {     static char Head = 'A';     int i = 0, j = 0;     while( i < llen && j < rlen && Head < 'Z')     {            arr[i][j] = Head;         int  direction = -1 ,times = 4;         bool timesflag = true; //每一个点最多轮询四次，符合条件后则跳出         bool directionflag[4] = {false}; // 每个方向值轮询一次.避免多此轮询同一个方向         srand(time(NULL));       // 产生随机种子         while( times > 0 && timesflag)           {             direction = rand()%4;             switch( direction )             {                 case UP_MOVE:                     {                         if((i - i) >= 0 && arr[i-1][j] == '*')                         {                              i = i -1;                             Head = Head +1;                             arr[i][j] = Head;                             timesflag = false;                         }                         if (!directionflag[0] )                         {                             times--;                         }                         directionflag[0] = true;                         break;                     }                 case DOWN_MOVE:                     {                         if((i+1) < 10 && arr[i+1][j] == '*')                         {                             i = i +1;                             Head = Head +1;                             arr[i][j] = Head;                             timesflag = false;                         }                         if (!directionflag[2] )                         {                             times--;                         }                         directionflag[2] = true;                         break;                     }                 case LEFT_MOVE:                     {                         if( (j -1) >= 0 && arr[i][j-1] == '*')                         {                             j = j -1;                             Head = Head +1;                             arr[i][j] = Head;                             timesflag = false;                         }                         if (!directionflag[1] )                         {                             times--;                         }                         directionflag[1] = true;                         break;                     }                 case RIGHT_MOVE:                     {                         if((j+1) < 10 && arr[i][j+1] == '*')                         {                             j = j+1;                             Head = Head +1;                             arr[i][j] = Head;                             timesflag = false;                         }                         if (!directionflag[3] )                         {                             times--;                         }                         directionflag[3] = true;                         break;                     }             }         }         if( times == 0 && timesflag ) //出口         {             return;         }         sleep(1);     } } int main(void) {     int RunTimes = 10;     char arr[10][10] = {0};     CreateArray(arr, 10, 10);      CreateMaze(arr, 10 ,10);      PrintArray(arr, 10, 10);     return 0; }

引用 楼主 u012857025 的回复: 这是书上的习题  #include <stdio.h> #include <time.h> #include <stdlib.h> #include <stdbool.h>  #define N 10 #define CURRENTLETTER ch[x][y] #define NEXTLETTER ch[x][y]+1 #define FILLER '.'  /**********************************  * used to judge whether the      *  * place is legal to put a letter *  **********************************/ 	  bool legal(int x, int y){ 	char ch[x][y]; 	if( ch[x][y]==FILLER && 		x>0 && x<=10 && 		y>0 && y<=10) 		return true; 	else return false; }  int main(){ 	char ch[N][N]={0}; 	int x, y, movesTried = 0; 	 	for(x=1;x<=N;x++) 		for(y=1;y<=N;y++) 			ch[x][y]=FILLER; 	 	srand((unsigned)time(NULL)); 	 	x=1; 	y=1; 	CURRENTLETTER='A'; 	 	while(CURRENTLETTER < 'Z' && movesTried < 4){ 		switch(rand()%4){ 			case 0: 			if(legal(x+1,y)){ 				x++ ; 				CURRENTLETTER = NEXTLETTER ; 				movesTried = 0; 			}else movesTried++; 			break; 		 			case 1: 			if(legal(x-1,y)){ 				x-- ; 				CURRENTLETTER = NEXTLETTER ;  				movesTried = 0; 			}else movesTried++; 			break; 			 			case 2: 			if(legal(x,y-1)){ 				y-- ; 				CURRENTLETTER = NEXTLETTER ; 				movesTried = 0; 			}else movesTried++; 			break; 		 			case 3: 			if(legal(x,y+1)){ 				y++; 				CURRENTLETTER = NEXTLETTER ; 				movesTried = 0; 			}else movesTried++; 			break; 		} 	} 	 	for(x=1;x<=N;x++){ 		for(y=1;y<=N;y++){ 			printf("%c ",CURRENTLETTER); 		} 		printf("\n"); 	} 	 	return 0; }  这是我的代码，我这几天反反复复查了好几次，都没有查出问题在哪里，劳请各位大大帮我看一看难道你没有设置断点，逐步调试？

引用 2 楼 JiMoKuangXiangQu 的回复:函数legal()应该是这样修改吧： bool legal(char [10][10], int x, int y) {     //char ch[x][y]; // 这里是在另外开辟了一个数组，和main里面不是同一个了     //另外如楼上的注意边界检查 }  写错了，修正如下： bool legal(char ch[10][10], int x, int y) {     //char ch[x][y]; // 这里是在另外开辟了一个数组，和main里面不是同一个了     //另外如楼上的注意边界检查 }

bool legal(int x, int y){     char ch[x][y];     if( ch[x][y]==FILLER &&         x>0 && x<=10 &&    ////x >= 0  && x < 10??         y>0 && y<=10)      ////y >= 0  && y < 10??         return true;     else return false; }

很有意思的小程序

#include <stdio.h> #include <time.h> #include <stdlib.h> #define MAXX 10 #define MAXY 10 void main() {     char MAP[MAXX][MAXY];     char str;     int x,y,z,f,n;      for (x=0;x<MAXX;x++) {         for (y=0;y<MAXY;y++) {             MAP[x][y]='.';         }     }      for (x=0;x<MAXX;x++) {         printf("\n");         for (y=0;y<MAXY;y++) {             printf("%c",MAP[x][y]);         }     }     printf("\n");      srand((unsigned) time(NULL)); RETRY:     x=0;y=0;str='A';MAP[x][y]=str;      for (str='B';str<='Z';str++) {         n=0;         f=1;         while (1) {             n++;             z=rand()%4;             switch (z) {                 case 0: if (y+1<MAXY && MAP[x  ][y+1]=='.') {y++;MAP[x][y]=str;f=0;} break;                 case 1: if (x+1<MAXX && MAP[x+1][y  ]=='.') {x++;MAP[x][y]=str;f=0;} break;                 case 2: if (y-1>0    && MAP[x  ][y-1]=='.') {y--;MAP[x][y]=str;f=0;} break;                 case 3: if (x-1>0    && MAP[x-1][y  ]=='.') {x--;MAP[x][y]=str;f=0;} break;             }             if (f==0) break;             if (n>20) {//钻入死胡同                 for (x=0;x<MAXX;x++) {                     for (y=0;y<MAXY;y++) {                         MAP[x][y]='.';                     }                 }                 goto RETRY;             }         }//while         if (x==MAXX-1 || y==MAXY-1) break;     }//for      for (x=0;x<MAXX;x++) {         printf("\n");         for (y=0;y<MAXY;y++) {             printf("%c",MAP[x][y]);         }     }     printf("\n"); }


Question: 指针赋值 warning: assignment from incompatible pointer type

去掉   -Wold-style-cast        Warn if a C style cast is used in a program

引用 3 楼 oN5GrzoN 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] VC6和VS2010都编译通过无警告错误。 gcc 有啊[/quote]   -Wno-traditional          Do not warn about traditional C

引用 1 楼 zhao4zhong1 的回复:VC6和VS2010都编译通过无警告错误。 gcc 有啊

可以忽视掉！没有关系！

VC6和VS2010都编译通过无警告错误。


Question: 实参可以是任意类型吗

据我所学到的知识，形参和实参的类型，数量都要保持一致。 只不过形参是自己定义的。

自己写demo测试吧！

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

编译器说了算。


Question: 有人会matlab的么？高分求救啊

来人啊  别就这么沉了啊

引用 2 楼 N_sev7 的回复:下一本关于matlab编程的书，找一找实例应该是没有，要不就是相当不好找，明天就要交作业了，求帮忙啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

引用 1 楼 wangdahu888 的回复:不是有内置函数吗？ 好像是dct2()，具体记不清了，找一本MATLAB图像处理书查查就知道了这还是别人问我的，我完全没学过，他那边学了跟我没学一个样，明天他就得交作业……好不容易有人回复了，能说说具体解答下么，求帮忙啊

下一本关于matlab编程的书，找一找实例


Question: 问个C语言符号表的问题

符号名称只是代表地址，楼主说的 i，就是代表一个地址空间。 上面几位说的对，i只是给编译器来用的，方便编程者。你如果接触过反汇编，就很容易明白这个道理。

还有，所有的符号都会有自己的符号表，常数表，变量名表，数组名表等等。自己去看下编译原理，上面应该有讲的。

变量名只是给内存空间起了一个名字，方便你使用。不要想着存放在哪里，没有意义，除非你是做编译器开发的。  如果你一定要想知道的话，就去看下编译原理吧。编译器会生成一张符号表，符号表有相关的信息，变量名对应的地址什么的。至于这张表存在哪个内存分区我也不太清楚。

解释执行，符号表，可能和程序在一起，也可能在解释器内部。 编译执行，符号表只是编译器需要，应用程序，就不需要了。  编译以后，符号表基本上就丢弃了。

变量实际上是一段内存，变量名就是内存的名字，只要知道的实际地址，其名字也就没有存在的价值了

i 只是给编译器用的, 制品里头的 i 是作为辅助信息用, 对运行无意义. 都是数据, 有的是数据, 有的是地址.

存储变量的四个区： 常量区：常量存放处 静态区：静态变量，全局变量等存放处 栈区：局部变量等存放区 堆区：申请的内存。

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对应的汇编并单步执行观察相应内存和寄存器变化。）  弄清楚编译期和运行期的区别。  了解一下gcc源代码，嫌大的话换Tiny C Compiler也行。


Question: 不知道如何查程序哪里重复定义，希望大家能够指点一下。

project该如何设置呢

重建所有是什么意思？

有多个 main, 是否project 设置有问题

重建所有

引用 2 楼 u012523688 的回复:大概就是这个样子 1>  ConnectTest.vcxproj -> D:\Personal\Administrator\桌面\新建文件夹 (2)\ConnectTest\Debug\ConnectTest.exe 1>FinalizeBuildStatus: 1>  Deleting file "Debug\ConnectTest.unsuccessfulbuild". 1>  Touching "Debug\ConnectTest.lastbuildstate". 1> 1>Build succeeded. 1> 1>Time Elapsed 00:00:02.49 ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========   这是我编译的结果  编译成功

大概就是这个样子

直接编译看哪报错，根据报错信息改


Question: 不知道学什么语言好？

哪个喜欢学哪个

Windows :C++ Web:C# Mobile：Java

有了C基础，先学C++吧，通用性强一些，既是面向对象，又能掌握细节（比如内存模型），学会了上手其它语言就很容易了。不一定要看大部头的C++ Primer，清华郑莉的教材我感觉也不错，可以先看打下基础。

引用#6 为什么建议学cmd下的批处理命令？

#6 为什么建议学cmd下的批处理命令？

引用 7 楼 maoshuoqiong 的回复:站在那儿别动，伙计！ 瞧你那一脸邋遢的络腮胡... 那两根吊带，还有那洋洋得意的表情。 十足一副高人一等的UNIX电脑用户的样子！   都可以！兴趣喜欢那个就钻研那个！都学也可以的！

建议学cmd下的批处理命令。

英语是基本,学点法语日语的,肯定吃香

C语言+数据结构+操作系统+算法设计  学通了基本可以毕业工作了 平台和业务相关的就很多方向了，这是最基础的 java或C++ + 面向对象程序设计+模式应用  脱离了底层，更多的注意是高层处理上 看你喜欢哪个方向了 其他的没怎么接触过，很多语言都是类C语言的 PHP貌似...只是听说，你把我说的话当做听说就行了

你要先清楚自己的需求，什么方面的？ web的话有ASP.NET、Java、PHP 手机有Objective-C、Java等 不一一列举了。

用途不同，没有哪个好不好 不过英语肯定不错的


Question: 这个函数存在什么问题？

fp没问题，buf有问题，出了函数就没了的东西。

FILE *open_data(void) {     FILE *fp;     static char buf[BUFSIZ];      if (NULL == (fp=fopen("2.in", "r"))) {         return (NULL);     }     if (0!=setvbuf(fp, buf, _IOLBF, BUFSIZ)) {         fclose(fp);         return (NULL);     }     return (fp); }

buf是局部变量，离开后FILE内部操作就非法操作了。  另外if(setvbuf(fp, buf, _IOLBF, BUFSIZ) != 0)         return (NULL);  没有关闭fp。

局部变量释放的问题，建议去看看《c程序设计语言》，很经典的一本书

高质量 C++& C 编程指南 有详细解释

引用 楼主 qdlgdx_lsy 的回复:这是unix环境高级编程中的一个函数：  FILE *open_data(void) { 	FILE *fp; 	char buf[BUFSIZ]; 	if((fp=fopen("2.in", "r")) == NULL) 		return (NULL); 	if(setvbuf(fp, buf, _IOLBF, BUFSIZ) != 0) 		return (NULL);	 	return (fp); } 这个函数存在什么问题呢？  问题在char buf[BUFSIZ]上吧，你打开文件指针，设置buf缓冲区，当出了这个函数后，buf会被释放，外部对文件指针的操作会出现错误吧！

引用 5 楼 cfjtaishan 的回复:[quote=引用 1 楼 turingo 的回复:] fp是局部变量，函数返回后其内容是不受控制的。  [quote=引用 楼主 qdlgdx_lsy 的回复:] 这是unix环境高级编程中的一个函数：  FILE *open_data(void) { 	FILE *fp; 	char buf[BUFSIZ]; 	if((fp=fopen("2.in", "r")) == NULL) 		return (NULL); 	if(setvbuf(fp, buf, _IOLBF, BUFSIZ) != 0) 		return (NULL);	 	return (fp); } 这个函数存在什么问题呢？[/quote] 这个可以返回fp，FILE是全局的，只不过fp指针变量时局部的，在调用函数里可以定义另一个FILE*类型的指针，用于接收它。 setvbuf是用于设置缓冲区的。[/quote]+1

man setbuf         You must make sure that both buf and the space it points to still exist by the  time  stream  is  closed,        which also happens at program termination.         For example, the following is illegal:         #include <stdio.h>        int main()        {            char buf[BUFSIZ];            setbuf(stdin, buf);            printf("Hello, world!\n");            return 0;        }

引用 1 楼 turingo 的回复:fp是局部变量，函数返回后其内容是不受控制的。  [quote=引用 楼主 qdlgdx_lsy 的回复:] 这是unix环境高级编程中的一个函数：  FILE *open_data(void) { 	FILE *fp; 	char buf[BUFSIZ]; 	if((fp=fopen("2.in", "r")) == NULL) 		return (NULL); 	if(setvbuf(fp, buf, _IOLBF, BUFSIZ) != 0) 		return (NULL);	 	return (fp); } 这个函数存在什么问题呢？[/quote] 这个可以返回fp，FILE是全局的，只不过fp指针变量时局部的，在调用函数里可以定义另一个FILE*类型的指针，用于接收它。 setvbuf是用于设置缓冲区的。

问题出在 char buf[BUFSIZ];  buf是局部变量，缓冲区设置一个失控的位置上了，fp应该没有问题，它指向的位置应该在全局堆上

引用 1 楼 turingo 的回复:fp是局部变量，函数返回后其内容是不受控制的。  [quote=引用 楼主 qdlgdx_lsy 的回复:] 这是unix环境高级编程中的一个函数：  FILE *open_data(void) { 	FILE *fp; 	char buf[BUFSIZ]; 	if((fp=fopen("2.in", "r")) == NULL) 		return (NULL); 	if(setvbuf(fp, buf, _IOLBF, BUFSIZ) != 0) 		return (NULL);	 	return (fp); } 这个函数存在什么问题呢？[/quote] +1  绝对不能返回局部变量的指针，即使是malloc的指针最好也不要返回，不然忘记free了会内存泄漏的。

不知道buf是用来干嘛的

fp是局部变量，函数返回后其内容是不受控制的。  引用 楼主 qdlgdx_lsy 的回复:这是unix环境高级编程中的一个函数：  FILE *open_data(void) { 	FILE *fp; 	char buf[BUFSIZ]; 	if((fp=fopen("2.in", "r")) == NULL) 		return (NULL); 	if(setvbuf(fp, buf, _IOLBF, BUFSIZ) != 0) 		return (NULL);	 	return (fp); } 这个函数存在什么问题呢？


Question: 常量操作数的算术运算

应该跟编译器有关,有的(我想应该是大多数)编译器可能直接把它忽略了

这个连汇编语言也有可能，直接计算为 7. 何况C,C++

常量折叠，大概就算不优化也看不到3＋4，直接就是7

编译器优化，就没这句话了，汇编中就直接忽视吧。


Question: java 转C的问题

直接转成C语言代码比较长。  引用 楼主 aaadddzxc 的回复:有没有对JAVA熟悉的，帮忙转下代码   current = (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3));  这个怎么表示？用C语言  完成代码如下：     import java.text.StringCharacterIterator; import java.text.CharacterIterator;  /**  * See the BASE64MailboxEncoder for a description of the RFC2060 and how  * mailbox names should be encoded.  This class will do the correct decoding  * for mailbox names.  *  * @author	Christopher Cotton  */  public class BASE64MailboxDecoder {          public static String decode(String original) { 	if (original == null || original.length() == 0) 	    return original;  	boolean changedString = false; 	int copyTo = 0; 	// it will always be less than the original 	char[] chars = new char[original.length()];  	StringCharacterIterator iter = new StringCharacterIterator(original); 	 	for(char c = iter.first(); c != CharacterIterator.DONE;  	    c = iter.next()) {  	    if (c == '&') { 		changedString = true; 		copyTo = base64decode(chars, copyTo, iter); 	    } else { 		chars[copyTo++] = c; 	    } 	} 	 	// now create our string from the char array 	if (changedString) { 	    return new String(chars, 0, copyTo); 	} else { 	    return original; 	}	     }       protected static int base64decode(char[] buffer, int offset, 				      CharacterIterator iter) { 	boolean firsttime = true; 	int leftover = -1;  	while(true) { 	    // get the first byte 	    byte orig_0 = (byte) iter.next(); 	    if (orig_0 == -1) break; // no more chars 	    if (orig_0 == '-') { 		if (firsttime) { 		    // means we got the string "&-" which is turned into a "&" 		    buffer[offset++] = '&'; 		} 		// we are done now 		break; 	    } 	    firsttime = false; 	     	    // next byte 	    byte orig_1 = (byte) iter.next();	     	    if (orig_1 == -1 || orig_1 == '-') 		break; // no more chars, invalid base64 	     	    byte a, b, current; 	    a = pem_convert_array[orig_0 & 0xff]; 	    b = pem_convert_array[orig_1 & 0xff]; 	    // The first decoded byte 	    current = (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3));  	    // use the leftover to create a Unicode Character (2 bytes) 	    if (leftover != -1) { 		buffer[offset++] = (char)(leftover << 8 | (current & 0xff)); 		leftover = -1; 	    } else { 		leftover = current & 0xff; 	    } 	     	    byte orig_2 = (byte) iter.next(); 	    if (orig_2 == '=') { // End of this BASE64 encoding 		continue; 	    } else if (orig_2 == -1 || orig_2 == '-') { 	    	break; // no more chars 	    } 	    	     	    // second decoded byte 	    a = b; 	    b = pem_convert_array[orig_2 & 0xff]; 	    current = (byte)(((a << 4) & 0xf0) | ((b >>> 2) & 0xf));  	    // use the leftover to create a Unicode Character (2 bytes) 	    if (leftover != -1) { 		buffer[offset++] = (char)(leftover << 8 | (current & 0xff)); 		leftover = -1; 	    } else { 		leftover = current & 0xff; 	    }  	    byte orig_3 = (byte) iter.next(); 	    if (orig_3 == '=') { // End of this BASE64 encoding 		continue; 	    } else if (orig_3 == -1 || orig_3 == '-') { 	    	break;  // no more chars 	    } 	     	    // The third decoded byte 	    a = b; 	    b = pem_convert_array[orig_3 & 0xff]; 	    current = (byte)(((a << 6) & 0xc0) | (b & 0x3f)); 	     	    // use the leftover to create a Unicode Character (2 bytes) 	    if (leftover != -1) { 		buffer[offset++] = (char)(leftover << 8 | (current & 0xff)); 		leftover = -1; 	    } else { 		leftover = current & 0xff; 	    }	     	} 	 	return offset;     }      /**      * This character array provides the character to value map      * based on RFC1521, but with the modification from RFC2060      * which changes the '/' to a ','.      */        // shared with BASE64MailboxEncoder     static final char pem_array[] = { 	'A','B','C','D','E','F','G','H', // 0 	'I','J','K','L','M','N','O','P', // 1 	'Q','R','S','T','U','V','W','X', // 2 	'Y','Z','a','b','c','d','e','f', // 3 	'g','h','i','j','k','l','m','n', // 4 	'o','p','q','r','s','t','u','v', // 5 	'w','x','y','z','0','1','2','3', // 6 	'4','5','6','7','8','9','+',','  // 7     };      private static final byte pem_convert_array[] = new byte[256];      static { 	for (int i = 0; i < 255; i++) 	    pem_convert_array[i] = -1; 	for(int i = 0; i < pem_array.length; i++) 	    pem_convert_array[pem_array[i]] = (byte) i;     }     }

current = (byte)(((a << 2) & 0xfc) | ((b >> 4) & 3));  这个怎么表示？用C语言  这个用c语言标识，也是这样的，没什么区别

单纯那句, 看不出是什么语言. thinking in java 的预科, 直接 java 上手的程序员还是欠一些.

BYTE current = (BYTE)(((a << 2) & 0xfc) | ((b >>> 4) & 3));

引用 8 楼 zhao4zhong1 的回复:#include <stdio.h> #include <string.h> #include <stdlib.h>  #define BASE64_VALUE_SZ 256 int     base64_value[BASE64_VALUE_SZ]; const unsigned char alphabet[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; class Base64Utility { public:     Base64Utility();     int base64_encode(char *src, int srclen, char *dst, int tail);     int base64_decode(char *src, int srclen, char *dst); private:     void base_64_init(void); }; Base64Utility::Base64Utility() {     base_64_init(); } void Base64Utility::base_64_init(void) {     int i;      for (i = 0; i < BASE64_VALUE_SZ; i++) base64_value[i] = -1;     for (i = 0; i < 64; i++) base64_value[(int) alphabet[i]] = i;     base64_value['='] = 0; } int Base64Utility::base64_encode(char *src, int srclen, char *dst, int tail) {     int     bits, char_count, len;     char    *o_char, *lim, *o_lim;     unsigned char   c;      if ( !src || !dst) return 0;     len = srclen;     lim = src + len;     o_char = dst;     o_lim  = dst + (len*4)/3 + 1;     char_count = 0;     bits = 0;     while ( (src < lim) && (o_char < o_lim)) {         c = *(src++);         bits += c;         char_count++;         if (char_count == 3) {             *(o_char++) = alphabet[bits >> 18];             *(o_char++) = alphabet[(bits >> 12) & 0x3f];             *(o_char++) = alphabet[(bits >> 6) & 0x3f];             *(o_char++) = alphabet[bits & 0x3f];             bits = 0;             char_count = 0;         } else {             bits <<= 8;         }     }     if (char_count != 0) {         bits <<= 16 - (8 * char_count);         *(o_char++) = alphabet[bits >> 18];         *(o_char++) = alphabet[(bits >> 12) & 0x3f];         if (char_count == 1) {             if (tail) {                 *(o_char++) = '=';                 *(o_char++) = '=';             }         } else {             *(o_char++) = alphabet[(bits >> 6) & 0x3f];             if (tail) {                 *(o_char++) = '=';             }         }     }     *(o_char) = 0;     return strlen(dst); } int Base64Utility::base64_decode(char *src, int srclen, char *dst) {     int j;     unsigned int k;     int c, base_result_sz;     long val;      if (!src || !dst) return 0;     base_result_sz = srclen;     val = c = 0;     for (j = 0; *src; src++) {         k = (int) *src % BASE64_VALUE_SZ;         if (base64_value[k] < 0) continue;         val <<= 6;         val += base64_value[k];         if (++c < 4) continue;         dst[j++] = (char) (val >> 16);         dst[j++] = (val >> 8) & 0xff;         dst[j++] = val & 0xff;         val = c = 0;     }     switch (c) {         case 2://xxxxxx xx0000             dst[j++] = (val >> 4) & 0xff;         break;         case 3://XXXXXX XXxxxx xxxx00             dst[j++] = (char) (val >> 10);             dst[j++] = (val >> 2) & 0xff;         break;     }     return j; } Base64Utility b64u; #define MAXLENS 1024768 #define MAXLEND 1366360 char bufd[MAXLEND]; char bufs[MAXLENS]; FILE *fs,*fd; int fsize; int main(int argc,char *argv[]) {     if (argc<4) {     USE:         printf("%s <-e|-E|-d> srcfile desfile\n",argv[0]);         return 1;     }     if (stricmp(argv[1],"-e") && stricmp(argv[1],"-d")) goto USE;     if (0==stricmp(argv[1],"-e")) {         fs=fopen(argv[2],"rb");         if (NULL==fs) {             printf("Can not open file %s!\n",argv[2]);             return 2;         }         fsize=fread(bufs,1,MAXLENS,fs);         if (fsize<=0) {             fclose(fs);             printf("Can not read file %s!\n",argv[2]);             return 3;         }         if (MAXLENS==fsize) printf("Warning: Up to %d bytes.\n",MAXLENS);         fclose(fs);         b64u.base64_encode(bufs,fsize,bufd,('E'==argv[2][1]));         fd=fopen(argv[3],"w");         if (NULL==fd) {             printf("Can not create file %s!\n",argv[3]);             return 4;         }         fprintf(fd,"%s",bufd);         fclose(fd);     } else {//0==stricmp(argv[1],"-d")         fd=fopen(argv[2],"rb");         if (NULL==fd) {             printf("Can not open file %s!\n",argv[2]);             return 2;         }         fsize=fread(bufd,1,MAXLEND,fd);         if (fsize<=0) {             fclose(fd);             printf("Can not read file %s!\n",argv[2]);             return 3;         }         if (MAXLEND==fsize) printf("Warning: Up to %d bytes.\n",MAXLEND);         fclose(fd);         fsize=b64u.base64_decode(bufd,fsize,bufs);         fs=fopen(argv[3],"wb");         if (NULL==fs) {             printf("Can not create file %s!\n",argv[3]);             return 4;         }         if (fsize!=(int)fwrite(bufs,1,fsize,fs)) {             printf("Write %s error!\n",argv[3]);             fclose(fs);             return 5;         }         fclose(fs);     }     return 0; }

解不出来  编码是：&ZbBe+k4ATiplh072WTk-123123   int main(int argc,char *argv[]) {     memset(bufd,'\0',MAXLEND);     memset(bufs,'\0',MAXLENS);      strcpy(bufd,"&ZbBe+k4ATiplh072WTk-123123");     b64u.base64_decode(bufd,strlen(bufd),bufs);     printf("%s\n",bufs);   上面JAVA代码就可以

有没有谁知道怎么把上面的代码转成C或者C++  或者有没有人有IMAP协议的 BASE64 解码代码？

C语言没有>>> C语言只保证unsigned是逻辑右移，对于signed要看编译器实现了。

C语言没法表示 >>>  编译出错  expected primary-expression before ‘>’ token


Question: 一个c语言问题,困惑

这里既可以是3 4也可以是4 3，看你做什么，因为它和前面那个4压根没有任何关系。

有什么区别吗，没看出来，地址是连续的

引用 8 楼 AnYidan 的回复:指针也有类型，c++ 的 编译器会检查类型是否匹配  int (*a)[4] a 是一个指针，指向一个4个元素的一维数组  int (*a)[4] a 是一个指针，解运算后 指向一个4个元素的一维数组

一般是int (*a)[3]= new int[3][4]; 但是int (*a)[4]= new int[3][4];多定义一个单元，也无所谓，反正够用，那个不过是多出来的

int (*a)[4]= new int[3][4];//这条语句不会抛错 int (*a)[4] = new int[4][3]; //这条语句会抛错  使用的是DevC++编译器

没这样用过！分配的时候都是和前面对应起来的！ 但是如果从地址连续上面来讲的话，应该效果是一样的！

没这样用过，是不是为int的指针数组（4个单元），为数组每个单元申请三个int单元？


Question: 请教大牛们一个算法问题

C++  //这个是 模仿 C++库函数写的 inline unsigned int countBitsHalfByte(unsigned char x){             //  0 1 2 3 4 5 6 7 8 9 a b c d e f     return "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4"[x]; } inline unsigned int countBitsByte(unsigned char x){     return countBitsHalfByte(x& 0xF) +countBitsHalfByte((x&0xF0)>>4); }  template<typename intT >unsigned int countBits(intT x){     int n=0;     union{ intT d;unsigned char by[sizeof(x)];}v;     v.d =x;     for(int i = 0;i < sizeof(x); i++){         n +=countBitsByte(v. by[ i ]);     }     return n; }  int32_t tab_all_1[] =        { 0,          0x00000001,0x00000003,0x00000007,0x0000000f,0x0000001f,0x0000003f,0x0000007f,0x000000ff,          0x000001ff,0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,0x00007fff,0x0000ffff,          0x0001ffff,0x0003ffff,0x0007ffff,0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,          0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff,        };

某些  mcu 中有一个求前导零的指令

引用 7 楼 breakfisher 的回复:谢谢哈！ 这个还是需要循环吧  [quote=引用 5 楼 AnYidan 的回复:]  int lowbit(int x)  { 	return (x & (-x)); }   --网上的一个函数，可以返回 x 最低位是 0 还是 1  同时右移 data 和 mask_flag，当mask_flag的最低位是1时，记录data 的最低位并计算[/quote]  只是一段合用的程序，mcu 中有一个求前导零的指令，对数字的前导零进行计数，并将结果返回，虽然可能仍需用到循环，但应该可以大幅提高效率

引用 6 楼 breakfisher 的回复:恩，谢谢！ 考虑过查表， 表要是二维的， 现在只需要8位， 但是担心后面位数多了不好扩展  [quote=引用 4 楼 lm_whales 的回复:] 对于你这个只有5位或者8位的，可以生成一个表，然后查表。 如果位数较多，就不好使用。 [/quote] 想到一个查表方法，不一定比移位逐位处理快 位数比较多，表里可以同时有1的个数和最后的结果值 然后合并每个字节的结果。

谢谢哈！ 这个还是需要循环吧  引用 5 楼 AnYidan 的回复: int lowbit(int x)  { 	return (x & (-x)); }   --网上的一个函数，可以返回 x 最低位是 0 还是 1  同时右移 data 和 mask_flag，当mask_flag的最低位是1时，记录data 的最低位并计算

恩，谢谢！ 考虑过查表， 表要是二维的， 现在只需要8位， 但是担心后面位数多了不好扩展  引用 4 楼 lm_whales 的回复:对于你这个只有5位或者8位的，可以生成一个表，然后查表。 如果位数较多，就不好使用。

这个用嵌入汇编实现即可。

一楼这个不对，  发现例子里面漏了一个字， 更正一下 例1： data ：  10001 mask_flag  10101 这样结果就是取出data的1,3,5位的数值为101,值为5  例2： data ：  10001 mask_flag  10111 这样结果就是取出data的1,2,3,5位的数值为1001,值为9

n=data &  mask_flag;// 10001 //mask_flag  10101

必须用到循环：  int extract(int data, int mask) { 	int value = 0; 	int i; 	int j = 0;  	for(i = 0; i < 32; i++) 	{ 		if(mask & (1 << i)) 		{ 			if(data & (1 << i)) 				value |= 1 << j; 			j++; 		} 	}  	return value; }  引用 楼主 breakfisher 的回复:给定一个二进制数data， 要取出对应mask_falg上值为1的位组成一个新数， 比如：  例1： data ：  10001 mask_flag  10101 这样结果就是取出data的1,3,5的数值为101,值为5  例2： data ：  10001 mask_flag  10111 这样结果就是取出data的1,2,3,5的数值为1001,值为9   有没有不需要循环， 直接通过位运算就可以得出结果的方法？


Question: 这个程序为什么不能正常工作？

fopen不是2.txt 什么时候变成.in了 windows识别后缀名  linux下 不识别后缀名 俩个操作系统的机制是不同的  这个为什么是这样 你可以在开个帖子 给予解释 这不是一个小问题

我想关键的地方应该在这 如果在windows和linux都能编译通的话 问题可能是这里  if((fp=fopen("2.in", "r")) == NULL)  就是当前目录问题 windows是集成环境你可能放错位置了 写绝对路径测试下 当然如果是菜鸟的话  绝对路径写对也可能是个问题 因为它们有的不懂转义字符 而在linux下的 shell 你是用命令操作的 当然 你不会在这个目录下编译.c 之后你在cd 到另一个目录下 vi 2.in

楼主你返回局部指针变量的目的是什么


Question: 问一个C primer plus程序在VS中运行问题

引用 5 楼 manjucaka 的回复:引用 4 楼 max_min_ 的回复:[quote=引用 2 楼 manjucaka 的回复:] [quote=引用 1 楼 czarten 的回复:] 你定义的fp是什么类型？FILE *fp if(fp = fopen(file, "rb") ==NULL)  改成  if((fp = fopen(file, "rb")) ==NULL) [/quote] 不行，应该是编译器的问题吧，在VC6.0上可以运行，就是不能打开文件[/quote] windows下路径要记得 加双斜杠的哦！例如：D:\\test.txt

引用 4 楼 max_min_ 的回复:引用 2 楼 manjucaka 的回复:[quote=引用 1 楼 czarten 的回复:] 你定义的fp是什么类型？FILE *fp if(fp = fopen(file, "rb") ==NULL)  改成  if((fp = fopen(file, "rb")) ==NULL) [/quote] 不行，应该是编译器的问题吧，在VC6.0上可以运行，就是不能打开文件

引用 2 楼 manjucaka 的回复:引用 1 楼 czarten 的回复:你定义的fp是什么类型？FILE *fp if(fp = fopen(file, "rb") ==NULL)  改成  if((fp = fopen(file, "rb")) ==NULL)

难道是这个？ (fp=fopen(...))==null

引用 4 楼 max_min_ 的回复:引用 2 楼 manjucaka 的回复:[quote=引用 1 楼 czarten 的回复:] 你定义的fp是什么类型？FILE *fp if(fp = fopen(file, "rb") ==NULL)  改成  if((fp = fopen(file, "rb")) ==NULL) [/quote]  ==的优先级比=高

引用 1 楼 czarten 的回复:你定义的fp是什么类型？FILE *fp

你定义的fp是什么类型？


Question: 强力散分，能者得之，不够追加

道路测量，应该属于水准测量吧。 我个人认为， 首先是名称，和等级匹配，然后 找到测量依据的水准原点和地标（建筑，数目，等）匹配最方便。  如果这些都，不能区分，再去做最小二乘法曲线拟合匹配，最合适。 只有极少数，道路是并行道路（一般只有2条，4条就很多了）  数据库里，大部分数据都不需要，曲线拟合匹配。

引用 14 楼 zilaishuichina 的回复:[quote=引用 12 楼 N_sev7 的回复:] [quote=引用 10 楼 zilaishuichina 的回复:] 我觉得这要看你误差怎么评判 不同的误差评价标准，可能就会有不同的处理方法了    比如上图中  中间的绿色的那根线是跟 蓝色的那根线算匹配呢？还是跟黑色的那根直线算匹配呢？ 嗯，是啊 我现在就想用什么评判的标准呢 不可能完全匹配上，只能说特别相近，然后去特别相近中的最相近的最为匹配结果了[/quote]  如果说lz是想要一个评判标准   我想是否可以用标准差来做评价标准  在折线A上 等距离取N个点 （Ax1，Ay1）（Ax2，Ay2）（Axn，Ayn） 折线B上 等距离取N个点 （Bx1，By1）（Bx2，By2）（Bxn，Byn） 然后两两算距离 得出 s1，s2，sn，然后对其算标准差 （无法确定哪一点算起点，哪一点算终点，你可以两个方向都算一下）  标准差越小 说明两条折线的平行度越高，那就越匹配  [/quote] 呵呵，现在这貌似是唯一的方法了，我想的也是这样做，但是就像问问有没有更好的方法 比如说数学中有没有计算两个多项式（道路是一段一段的，可以表示成一个多项式吧）相似程度的理论什么的 或者说取那些离散的点，做成连续的曲线，然后对曲线进行比较等，只是有个想法，但是找不到相关的知识啊

引用 12 楼 N_sev7 的回复:[quote=引用 10 楼 zilaishuichina 的回复:] 我觉得这要看你误差怎么评判 不同的误差评价标准，可能就会有不同的处理方法了    比如上图中  中间的绿色的那根线是跟 蓝色的那根线算匹配呢？还是跟黑色的那根直线算匹配呢？ 嗯，是啊 我现在就想用什么评判的标准呢 不可能完全匹配上，只能说特别相近，然后去特别相近中的最相近的最为匹配结果了[/quote]  如果说lz是想要一个评判标准   我想是否可以用标准差来做评价标准  在折线A上 等距离取N个点 （Ax1，Ay1）（Ax2，Ay2）（Axn，Ayn） 折线B上 等距离取N个点 （Bx1，By1）（Bx2，By2）（Bxn，Byn） 然后两两算距离 得出 s1，s2，sn，然后对其算标准差 （无法确定哪一点算起点，哪一点算终点，你可以两个方向都算一下）  标准差越小 说明两条折线的平行度越高，那就越匹配

引用 9 楼 lm_whales 的回复:这样，你可以用最小二乘法呀 这就是我说的备用方案了，感觉有很多的限制，实在没有更好的方法只能用这样的方法了啊，呵呵

引用 10 楼 zilaishuichina 的回复:我觉得这要看你误差怎么评判 不同的误差评价标准，可能就会有不同的处理方法了    比如上图中  中间的绿色的那根线是跟 蓝色的那根线算匹配呢？还是跟黑色的那根直线算匹配呢？ 嗯，是啊 我现在就想用什么评判的标准呢 不可能完全匹配上，只能说特别相近，然后去特别相近中的最相近的最为匹配结果了

引用 7 楼 ForestDB 的回复:这还是你的模型，什么叫“道路的形状点”？数据库存的什么？，何为匹配？ 所以，还是请说说你这模型想解决什么问题。 道路：名称，级别，道路在现实中的一系列点坐标等 数据库：一个城市的所有道路  现在有一条道路记录，我要去数据库中找这条路最可能是数据库中的哪一条记录！！！（名字级别等属性暂不考虑） 这样行吗？ 我可能表达能力有些差

这样，你可以用最小二乘法呀

红线代表路径，方框代表扩展后的区域 如果直线在区域内部，就是完全匹配 否则不完全匹配 简单点的，可以只判断点是否和路径匹配 复杂点的，可以判断线段是否和路径匹配 如图：

引用 5 楼 ForestDB 的回复:不要说你的建模，说你的问题。 有一条道路 现在给出这条道路的形状点，用这条路去数据库中匹配，找到最有可能是哪一条路！！！ 这就是问题

不要说你的建模，说你的问题。

引用 2 楼 lm_whales 的回复:如果记录了名称，和级别 感觉用这两个信息匹配比较好。 如果这两者不在U中（比如，U中只记录了道路形状点信息），也只能曲线拟合了，不过不会正好相同的。 这只能看误差了，在误差范围内，就认定一致。  其实个人感觉： 把U集合中的路线扩展成矩形区域集合（比如40米宽度，每两个点形成一个矩形区域）， 如果A的所有点都在区域集合内，可以判定是一条路径；  如果有若干点不在内，那么只有一部分匹配。 也可以反过来，把A 扩展成矩形区域集合，用U中的每条路线匹配。 现在只能用形状点匹配，因为其他信息都有可能不一致， 但是却是同一条路，只有形状点不会差别太大 扩展成为矩形区域不太可行，因为现实中有的路基本上是并行的 （高速公路两个方向上就是两条路，但是离的就特别近了啊，这样就会匹配出来两条结果了） 感谢您的回答，希望您能给出更好的思路，谢谢

引用 1 楼 lm_whales 的回复:相似度?难道和误差没有关系？？ 曲线进行拟合不会正好一致吧！ 还是要计算误差的吧！ 误差是肯定存在的， 所以就想有没有什么数学上的公式什么的能计算出来吻合度 吻合度最高的就是带查找的目标了！！！ 而且所有的线都是离散的点构成的 希望您能给出点思路，现在其实有一个方案，不过想找个更好的方案

引用 32 楼 zhao4zhong1 的回复:[quote=引用 29 楼 N_sev7 的回复:] [quote=引用 28 楼 zhao4zhong1 的回复:] 《学习OpenCV中文版》 哎呀，赵老师你终于现身了啊 能不能给点具体的思路啊 两周之内要做出来成果，，， 压力倍感大 我看到OpenCV中有一个介绍freeman码的， 感觉不是很好用的样子啊[/quote] 我猜OpenCV里面已经有各种大牛发明的比较成熟的算法了。 我们平民百姓只要学会怎么用就行了。 [/quote]  额，好吧，居然赵老师都如是说了，看来真的没什么更好的办法了 对了，赵老师这头像是您的尊荣呢？我看着咋那么像濮存昕呢？？？！！！

引用 29 楼 N_sev7 的回复:[quote=引用 28 楼 zhao4zhong1 的回复:] 《学习OpenCV中文版》 哎呀，赵老师你终于现身了啊 能不能给点具体的思路啊 两周之内要做出来成果，，， 压力倍感大 我看到OpenCV中有一个介绍freeman码的， 感觉不是很好用的样子啊[/quote] 我猜OpenCV里面已经有各种大牛发明的比较成熟的算法了。 我们平民百姓只要学会怎么用就行了。

引用 26 楼 bedynamic 的回复:原始数据与目标数据差，求平均，找最小的行不。。。 道路存储的是一系列的点坐标，用点坐标计算欧式是一种方法 但是感觉不是很好用，因为如果路的起始点就差距很大，那么基本上就没必要做下去了 可是结果也许就是这条路就是要查找的路了 不过还是谢谢

引用 27 楼 ml0719787 的回复:帮顶 谢谢了！！！


Question: 请教个问题

都不完全支持的吧!可以考虑换个环境的、、

可以挂接第三方编译器，比如GNUC  http://stackoverflow.com/questions/14768073/how-to-use-gcc-with-microsoft-visual-studio

之前的帖子 http://bbs.csdn.net/topics/380160403

没办法，微软又不做，C99又不是库，你要用其他编译器那就不属于VS了，节哀吧


Question: openssl的AES解密算法的EVP_DecryptFinal_ex(&ctx,out+outl,&outltmp);的使用

楼主，问题解决了吗？

那这个怎么处理，一旦遇上16的倍数，后面的块就解密不出来了？  引用 4 楼 hhh_yang 的回复:楼主颤一下outl的值，应该是16的倍数，所以没有padding，所以final函数可加密的padding，所以outltmp值为0这个

我也遇到了。。

man EVP_DecryptFinal_ex


Question: C语言++和--运算符问题

引用 楼主 u010133536 的回复:#include<stdio.h> int main(void) { 	int x=8; 	for(;x>0;x--) 	{ 		if(x%3) 		{ 			printf("%d,",x--); 			continue; 		} 		printf("%d,",--x); 	} 	return 0; } 为什么输出的第一个结果为8，谢谢  曾经有和你一样的想法，楼主同学！ 因为for循环里的x--实在执行完printf函数后才去执行的！

引用 1 楼 max_min_ 的回复:http://bbs.csdn.net/topics/370153775 看看置顶帖！何必为难自己！以后我也会想不透，多用几个编译器也就不想了！ 也不会写那样的代码了！和置顶说的 没关系  楼主的代码 也不涉及UB 这里输出 8 只是因为 i-- 求值结果 的的确确是 8

好吧，是8啊，有为什么？

x--,是先取 X 的值后再 --；  --x 是先--，再来取 X

x=8，x%3=2//true 执行printf("%d,",x--);输出8，,x变为7 continue语句继续执行 x=7，x%3=1；输出7，x变为6 x=6，x%3=0//flase 执行printf("%d,",--x);输出5，x变为5

因为你有continue;语句，然后执行了for(;x>0;x--)中的X--语句。

.。。。。。。。。。。。。。。。。第一个结果输出8不是很明显的结果？详情见3L

++, -- 浪费了多少光阴

引用 3 楼 lm_whales 的回复:第一个结果为8 只要知道第一次执行那个输出语句，自然就明白了 8 %3 = 2 // true  if(x%3){ printf("%d",x--); //x-- 先得到 x 的当前值8，用于输出，再执行自减操作。 //输出结果自然就是 8了。 }  当然，你这个程序的代码风格，不是太好。 估计你自己，对于这个代码的逻辑，也是比较糊涂的。 ++


Question: 请帮我解释一下这个scanf的读取方法

我明白了，书上有一句话我开始没有理解到。“如果您使作带有多个说明符的scanf()语句，ANSI C 要求函数在第一个出错的地方停止读入。”这时再看我的这个程序确实在第一个出错的地方停止读入。

查看一下scanf() 函数的返回值，估计你就应该明白了。

因为你输入数据，以ENTER键结束输入时，它把ENTER键当做CH输入值，ENTER在系统里当成0

一下是个参考代码： #include "stdafx.h" #include "stdio.h"  int main(void) { 	int a, b; 	char ch;  	scanf("%d%c%d", &a, &ch, &b); 	printf("a = %d b = %d ch = %c\n", a, b, ch); 	 	return 0; }  输入 &　输出： 12ah a = 12 b = -858993460 ch = a


Question: UDP C/S模型实现问题

udp是无连接的！所以不需要后台接受数据什么的！需要的时候就直接发送接受就好！

你的描述可以实现 但是跨网段会出现问题，内网，或者本机是可以的 具体怎么设置，一样的 将所有客户端都增加服务端接受的功能  跨网段的话 就需要各自穿透技术了..楼主自行查阅相关资料

UDP 是非面向连接的干嘛还接收客户端的请求再处理数据再发送数据给客户端呢？ UDP 不是以广播的形式发送数据到互联网上，然后就不用管数据的流向了吗？ 如果要阻塞等待客户端的请求的话那应该用TCP面向连接的SOCKET啊。！


Question: signed关键字的目的

“就想明确的告诉你是有符号的”

我觉得这是为标准定义的严密性考虑的 万一哪天int默认表示的是unsigned int 那么signed关键字就是必要的了

signed 是默认的有符号的；unsigned 才是要注意的 正符号

关键是编译器可以指定默认char是unsigned或signed cl.exe:   /J default char type is unsigned    gcc/g++:   -fsigned-char           Make 'char' be signed by default   -funsigned-char         Make 'char' be unsigned by default

其实也就跟char有关（实际主流编译器char都是当signed char 处理的），其他用跟不用无所谓 还有一个类似关键字auto也一样很少用了

丢到内存中 不都是一堆01吗 只是你想让计算机怎么来解释这串数据的问题而已

貌似标准没有规定char是signed还是unsigned的。

另外char默认不是signed char 而且char、signed char、unsigned char是不一样的类型（很奇怪，也没搞懂标准怎么想的）

引用 2 楼 Adol1111 的回复:[quote=引用 1 楼 user-11 的回复:] 就是有符号类型的！只不过默认情况下都是signed所以就没有写而已！ 目的就是告诉有符号类型的啊 +1[/quote]+1

为了强调  如果你使用有符号整数，建议写上

引用 1 楼 user-11 的回复:就是有符号类型的！只不过默认情况下都是signed所以就没有写而已！ 目的就是告诉有符号类型的啊 +1


Question: 一家人

非常感谢，能加一下你Q吗？

#include <stdio.h>  int main(void) { 	int   N, M, Q; 	int   p, i, j, a, b; 	/* 用二维表来表示a和b之间的关系，0表示没有关系，1表示有关系 */ 	int   buf[100][100] = {0};  	scanf("%d%d%d", &N, &M, &Q); 	for (p = 0; p < M; p++) { 		scanf("%d%d", &a, &b); 		/* a和b有关系，则b和a也有关系 */ 		buf[a-1][b-1] = 1; 		buf[b-1][a-1] = 1; 		/* 对于每次输入，检测a和b与其他人的关系 */ 		for (i = 0; i < N; i++) { 			for (j = 0; j < N; j++) { 				/* 检测a行关系 */  				if (buf[a-1][i] == 1 && buf[a-1][j] == 1) 					buf[i][j] = 1; 				/* 检测b行关系 */  				if (buf[b-1][i] == 1 && buf[b-1][j] == 1) 					buf[i][j] = 1;	 			} 		} 	} 	 	for (p = 0; p < Q; p++) { 		scanf("%d%d", &a, &b); 		if (buf[a-1][b-1]) 			printf("Yes\n"); 		else 			printf("No\n"); 	}  	return 0;	 }  /* 输出结果： 3 1 2 1 2 1 2 Yes 1 3 No */


Question: 求大神帮忙

没有 qq

能不能加个qq：568519177，方便问问题

如果中断过快影响别的，也可以改  if(v==2)  或 miao +=10; if(miao > = 60) {miao -= 60; ...}

判断按键 if (按键压下）  {   TH0=(65536-5000)/256;   TL0=(65536-5000)%256; //定时器初值，定时5ms（12M晶振） } else {   TH0=(65536-50000)/256;   TL0=(65536-50000)%256; //定时器初值，定时50ms（12M晶振） }

#include<reg52.h> #define uint unsigned int #define uchar unsigned char uchar v,miao,fen,shi; sbit  add=P1^3;//加速度键 uchar code table[]={  0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f}; void display(uchar miao,uchar fen,uchar shi); void delay(uint ); void little(); void main() {    little();//初始化子程序   miao=0;   shi=0;   fen=0;   while(1)   {    display(miao,fen,shi);    if(v==20)      {   miao++;   v=0;   if(miao==60)   {    fen++;  //  满60S, 分加1,秒清0    miao=0;    if(fen==60)     {      shi++; // 小时加1      fen=0;      if(shi==24)  	 shi=0; //小时满     }    }  }   }  } void delay(uint z) {   uint i,j;   for(i=z;i>0;i--)    for(j=110;j>0;j--); } void display(uchar miao,uchar fen,uchar shi)  //  显示子函数 {     P2=0x7f;   P0=table[miao%10];   delay(1);     P2=0xbf;   P0=table[miao/10];   delay(1);       P2=0xdf;   P0=0x40;   delay(1);    P2=0xef;   P0=table[fen%10];   delay(1);      P2=0xf7;   P0=table[fen/10];   delay(1);      P2=0xfb;   P0=0x40;   delay(1);    P2=0xfd;   P0=table[shi%10];   delay(1);       P0=0x30;          P2=0xfe;   P0=table[shi/10];    delay(1); } void little()   // 初始化子函数 {   TMOD=0x01;  TH0=(65536-50000)/256;  TL0=(65536-50000)%256; //定时器初值，定时50ms（12M晶振）  EA=1;  ET0=1;  TR0=1;  } void timer0() interrupt 1 //定时计数器中断 {  TH0=(65536-50000)/256;  TL0=(65536-50000)%256;   v++;    } 代码已上传，求大神帮帮忙

引用 2 楼 u012887645 的回复:能不能写个程序给我呢，我新手，谢谢   你上传代码，会有人帮你改的

能不能写个程序给我呢，我新手，谢谢

时钟的写好了的话，按键调整速度应该很好写啊


Question: socket编程转换函数的问题？

引用 1 楼 hnwyllmm 的回复:for(power=1;j>=10;j/=10)      power*=10; 循环结束后power就变成i的位数^power了，比如293，power就是100  for(;power>0;power/=10)    {      *string++='0'+i/power;      i%=power;    } 每次取出来第一位，转换成数字字符 明白了。。谢谢讲解！！！

引用 2 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 可是如果底子比较薄的话，我觉得还是需要别人给个提示和大致的思考方向的


Question: 帮个小忙!一个简单的C语言程序

引用 10 楼 u012877259 的回复:先看一些入门书籍再来练手吧 +1

先看一些入门书籍再来练手吧

#include <stdio.h> int main(void) { 	char ch;         while (scanf("%c", &ch) )     {         getchar();         printf("%d\n", ch);     } 	return 0; }

引用 6 楼 max_min_ 的回复:先找一本c语言的基础书籍看看基本的理论知识再动手吧！ +1

引用 1 楼 cfjtaishan 的回复:#include <stdio.h>  int main(int argc, char *argv[]) { 	char ch; 	int rtval = -1; 	 	while ((rtval = scanf("%c", &ch)) == 1) 	{ 		getchar();    //接收换行符 		fprintf(stdout, "%d\n", ch); 	} 	return 0; }

先找一本c语言的基础书籍看看基本的理论知识再动手吧！

char ch; scanf("%c", &ch); printf("%d",ch);  不知道会不会把char里的'/0'也打出来

引用 2 楼 u012887866 的回复:谢谢你的解答 但是不太懂stdout是什么意思 为什么= -1 呢???才学C不久 看一下scanf的返回值。若stdout（Standard Output)不是特别懂，那么就用printf吧。

标准输出，通常就是你的屏幕


Question: 帮忙一下！！！

就是一个编码的转换吧！

//GBK汉字内码范围（不包括A1xx～A9xx的标点符号英文字母特殊符号等）    //区码  ,位码    //81-A0 ,40-7E 80-FE    //AA-AF ,40-7E 80-A0    //B0-D6 ,40-7E 80-FE    //D7    ,40-7E 80-F9    //D8-F7 ,40-7E 80-FE    //F8-FE ,40-7E 80-A0

/*区码=内码(高字节)-160  位码=内码(低字节)-160*/ /*10进制的160等于16进制的A0*/ /*获得区码与位码*/ /*计算该汉字在字库中偏移量*/  /*将文件指针移动到偏移量的位置*/


Question: 求助：一个超简单的宏定义。

引用 9 楼 u012559195 的回复:[quote=引用 8 楼 caojian005 的回复:] 可以跑下 UNUSED(x)+1看结果，反正不这么用 #define UNUSED(x) ((x)=(x))  #define UNUSED(x) (x)=(x)  运行了一下，这两种用法没什么差别。[/quote] #define UNUSED1(x) ((x)=(x))  #define UNUSED2(x) (x)=(x) int iBuf = 0; UNUSED1(iBuf)+1; cout<<iBuf<<endl; UNUSED2(iBuf)+1; cout<<iBuf<<endl;

引用 6 楼 Adol1111 的回复:[quote=引用 5 楼 derekrose 的回复:] [quote=引用 4 楼 u012559195 的回复:] [quote=引用 1 楼 user-8 的回复:] 避免一些编译器的警告。 对于未使用的变量，很多编译器都会警告“未使用的变量x”。 但是它没有赋值，这样它自己赋值给自己，这样不会有问题吗？[/quote] 这就是赋值了[/quote] +1 虽然赋的值无法预料，但就是赋值。只要你不直接用这些变量就没事了，主要就是消除编译器警告。[/quote]+1

有些编译器，你定义了变量，没去赋值的话，它会有警告

主要是为了避免编译器和lint的告警，也有这样写的 #define UNUSED(x) ((void)(x))

引用 8 楼 caojian005 的回复:可以跑下 UNUSED(x)+1看结果，反正不这么用 #define UNUSED(x) ((x)=(x))  #define UNUSED(x) (x)=(x)  运行了一下，这两种用法没什么差别。

OK，谢谢大家。

引用 5 楼 derekrose 的回复:[quote=引用 4 楼 u012559195 的回复:] [quote=引用 1 楼 user-8 的回复:] 避免一些编译器的警告。 对于未使用的变量，很多编译器都会警告“未使用的变量x”。 但是它没有赋值，这样它自己赋值给自己，这样不会有问题吗？[/quote] 这就是赋值了[/quote] +1 虽然赋的值无法预料，但就是赋值。只要你不直接用这些变量就没事了，主要就是消除编译器警告。

引用 4 楼 u012559195 的回复:[quote=引用 1 楼 user-8 的回复:] 避免一些编译器的警告。 对于未使用的变量，很多编译器都会警告“未使用的变量x”。 但是它没有赋值，这样它自己赋值给自己，这样不会有问题吗？[/quote]  这就是赋值了

引用 1 楼 user-8 的回复:避免一些编译器的警告。 对于未使用的变量，很多编译器都会警告“未使用的变量x”。 但是它没有赋值，这样它自己赋值给自己，这样不会有问题吗？

百度一下，你就知道。 http://www.baidu.com


Question: 关于数据存储的疑惑（变量，常量）100分求讲解。。。。

引用 32 楼 u012348978 的回复:你在临阵磨枪，但这把枪不好磨。c不仅需要广泛的知道，还需要实践的经验。快速掌握c不太容易。  1）编译时和运行时。 编译时刻可以确定的量，就是常量。否则就是变量。  2）值，对象。 值；是一个计算过程，他是不需要储存空间。如；（1+1）这个2是不需要储存空间。同理（2）这个被认为是一个值的话，也是不需要储存空间的。"hello,world"这个字符串被解释为值，在任意时刻唯一确定的。不能有储存空间。这是规则，就像禁止闯红灯一样。  int a = 3；"hello,world"；他们都是值，他是不需要储存空间的，只能怎么理解。因为这是规则。  对象；没什么好解释的，就是一块储存区。  3）指针； 指针有两个意思，一个是指针变量，如；（char  *ch ）一个是指针的值。如； ch = "hello,world"； ch = &c； ch = NULL； ch = 0；  "hello,world"， &c， NULL ，0 ，他们都是指针，也就是指针值；  你知道的太多了，这对你不好，关了电脑出去走走吧。 不是临阵磨枪，我刚开始学习c，认真看了半个月左右。所以是在刚起步阶段。而且打算坚持学习下去，所以不是为了应付考试什么的，只是喜欢，想学习。遇到疑惑，周围没人交流，书上又没写到。所以想搞清楚，就来问各位大神。

为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。

其实电脑开机后物理内存的每个字节都是可读写的，区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

引用 30 楼 Adol1111 的回复:[quote=引用 24 楼 u010412073 的回复:] 	char a[10]="abcd";对于这种情况，此时是不是不能把字符串和char *p=“abcd”中的等价，因为此时可以对字符串内容进行修改。是不是此时就理解成把n个数组元素分别作为立即数存在是存在寄存器中的。 这个属于第二点，就是先生成指定的空间，然后再把值丢进这些空间里。这些空间都是在栈上的。 后者的话，就不一样了，这个是先生成指定的字符串，然后再取出地址给指针p。而这些字符串是在分配在文字常量区的，而不是在栈上的，所以无法修改。  还有就是多次生成的字符串常量是不能保证一定是一个地址的。 比如if("abc"=="abc")这两者会比较地址，而不是比较两者的内容，这要依靠编译器的实现了，如果编译器允许的话，会直接取文字常量区已有的地址，如果不行的话会重新生成一个"abc"，所以会有可能不相等。[/quote] 嗯嗯，明白了。真心太感谢了。终于可以不这么纠结了。。。。必须给高分。。嘿嘿。。。可以去外面转一圈了，o(︶︿︶)o ~~

引用 24 楼 u010412073 的回复:char a[10]="abcd";对于这种情况，此时是不是不能把字符串和char *p=“abcd”中的等价，因为此时可以对字符串内容进行修改。是不是此时就理解成把n个数组元素分别作为立即数存在是存在寄存器中的。 这个属于第二点，就是先生成指定的空间，然后再把值丢进这些空间里。这些空间都是在栈上的。 后者的话，就不一样了，这个是先生成指定的字符串，然后再取出地址给指针p。而这些字符串是在分配在文字常量区的，而不是在栈上的，所以无法修改。  还有就是多次生成的字符串常量是不能保证一定是一个地址的。 比如if("abc"=="abc")这两者会比较地址，而不是比较两者的内容，这要依靠编译器的实现了，如果编译器允许的话，会直接取文字常量区已有的地址，如果不行的话会重新生成一个"abc"，所以会有可能不相等。

引用 27 楼 Adol1111 的回复:[quote=引用 21 楼 u010412073 的回复:] 第三点讲的太好了，也就说果然字符串比较特殊了，是一个左值，可以取地址，所以char *p=“abcd”就是取了首地址，而1，2，‘a’在c语言中是立即数，是右值，是没有地址所以int *p=‘a’这样的操作不允许了。。。我一直就是想知道为什么字符串这么特殊。。谢谢啦! 因为只有字符串不能直接用寄存器直接生成啊，总不可能单单用一个数就生成一个字符串吧。比如我说'ABC'那么对应的值就是65、66、67，这样寄存器生成了3次，那么我直接说198你能告诉我这是个怎样的字符串么？  所以单单一个寄存器不可能生成一个字符串。那么多用几个寄存器呢？计算机总共就那么几个寄存器，而字符串的长度有的长有的短，长度超过寄存器个数怎么办？最简单的办法就是先写入到一个内存中，每生成一个就插入到指定的空间中，这样就能保证在大部分情况下都能生成有效的字符串了。  既然写入了内存，那么就会有所谓的地址，就可以进行一定的操作了，这至少符合了左值的标准。当然是否是右值还是左值，要看标准的规定了。临时变量也有地址（但地址很快就会无效），却是右值。[/quote] 恩呢，真是太好了。越来越清楚了，然后就可以去认真看看汇编的书，详细了解下了。 还有就是就是不知道如何看待char a[4]=“abc”这种情况，是不是此时不同于直接给指针赋值的那种字符串，此时相当于看作数组，因为我们知道对于char *p=“abc”内容不可以修改。而此时的可以修改。。（所以此时和一般数组一样，不作为字符串常量看待？）

引用 25 楼 user-4 的回复:3） 是这样的，因为，到目前为止 {。。。。} 的类型是不确定的，可能是结构，数组等 所以，不能看作某一类型的数组常量。  而字符串的类型，是确定的，字符串是带结束符的字符数组。 所以和字符指针，类型是兼容的，而且也比较方便，所以可以这样做。  C是强类型和弱类型并存的语言，所以可以用常量字符串（字符串字面值）初始化字符指针， 也可以用常量字符串（字符串字面值）给字符指针赋值。  C++，由于强类型，把这看成对C的让步； 早期是可以的。  现在C++， 认为只有常量字符指针，才可以常量字符串（字符串字面值）初始化，赋值。  变量的地址，是不可以改变的，因为改变后的地址和这个变量无关。  变量是地址和值的统一体。  没有初始化，也没有赋值的变量，它的值是未指定的。 他的地址不变，才能访问。 随便改变的话，就难以访问了。  指针变量，也是一个变量，所以它的值可以改变。 他自己的地址也是不能改变的。  变量就是一个名字，和一个地址（一块内存），建立的一种映射关系， 一个变量名字，对应一块内存区域，这块内存的位置，就是它的地址。  变量的值，就是这块内存中的数据。  数组是一批变量，所以数组名，会表示他的首元素的地址。 数组名不代表它的值，因为它是一批数据。  C 语言中数组，没有一个单一的值。 他有一批值，他的每个元素有一个值。  C++继承了C的这种表示方法，所以不能整体赋值。 只能整体初始化。谢谢，让我更加明确了。。。自己这样理解，就是担心会错。书上又没有这方面的，所以才请各位大神，给我确定，是不是这样的，你解释的很细致。让我更加确定了。谢谢。然后对于不可以int *p=3或者等等（不是用字符串赋值的情况），我感觉楼上的有一个解释说，字符串是比较特殊的是左值，是有地址的，其它类型的是立即数，是没有地址所以才不可以。这样比较好。。就是不知道如何看待char a[4]=“abc”这种情况，是不是此时不同于直接给指针赋值的那种字符串，此时相当于看作数组，因为我们知道对于char *p=“abc”内容不可以修改。而此时的可以修改。。（所以此时和一般数组一样，不作为字符串常量看待？）

引用 21 楼 u010412073 的回复:第三点讲的太好了，也就说果然字符串比较特殊了，是一个左值，可以取地址，所以char *p=“abcd”就是取了首地址，而1，2，‘a’在c语言中是立即数，是右值，是没有地址所以int *p=‘a’这样的操作不允许了。。。我一直就是想知道为什么字符串这么特殊。。谢谢啦! 因为只有字符串不能直接用寄存器直接生成啊，总不可能单单用一个数就生成一个字符串吧。比如我说'ABC'那么对应的值就是65、66、67，这样寄存器生成了3次，那么我直接说198你能告诉我这是个怎样的字符串么？  所以单单一个寄存器不可能生成一个字符串。那么多用几个寄存器呢？计算机总共就那么几个寄存器，而字符串的长度有的长有的短，长度超过寄存器个数怎么办？最简单的办法就是先写入到一个内存中，每生成一个就插入到指定的空间中，这样就能保证在大部分情况下都能生成有效的字符串了。  既然写入了内存，那么就会有所谓的地址，就可以进行一定的操作了，这至少符合了左值的标准。当然是否是右值还是左值，要看标准的规定了。临时变量也有地址（但地址很快就会无效），却是右值。

引用 22 楼 zhao4zhong1 的回复:拼！ 计算机组成原理→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、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  恩呢，我就是想从本质上了解，发现需要学的东西越来越多。。。。 必须努力学习这些。。。。 话说能不能先对这个问题稍微解释下。。。都不知道Alt+8、Alt+7、Alt+6和Alt+5,这些情况，需要从最简单的程序看起、现在这个问题不合适这样观察啊，水平还不足、、、可是又想现在解决。。。

引用 20 楼 Adol1111 的回复:1、int a=3中，a变量分配在栈上，然后把3存储在这块区域内。就好比，我在内存上租了一个房间（分配了一块内存空间给a），然后让张三住到了这个房间中（张三就是你要存储的值3），如果你要修改里面的值，就等于把张三赶出来，然后让其他人进去。 如果是单纯的3，则是一个立即数，是存在寄存器中的。赋值的操作其实就是先在寄存器上生成这个数，然后再把这个数写入到指定的空间内。你可以去看下汇编了解下。  2、这是声明一个数组，然后把这些常量丢到一个指定的空间内，理解同上。  3、C/C++的常量只的是字面值常量，其中只有字符串比较特殊，其他的常量都是立即数，他们属于右值，不存在所谓的地址。（立即数的地址即寄存器地址，寄存器地址再CPU中，而不是在内存上，具体的可以看汇编中的几种寻址方式。） 在C/C++中，只有左值可以取地址，右值是不可以取地址的，当然右值不一定是指常量，临时变量等等也属于右值。  4、++&a不一样&a是一个右值，不能对右值进行操作。至于普通的变量的地址，也可以++但++后的地址不保证可以正常使用，要么是段错误，要么就是访问了其他地址。 	char a[10]="abcd";对于这种情况，此时是不是不能把字符串和char *p=“abcd”中的等价，因为此时可以对字符串内容进行修改。是不是此时就理解成把n个数组元素分别作为立即数存在是存在寄存器中的。

引用 20 楼 Adol1111 的回复:1、int a=3中，a变量分配在栈上，然后把3存储在这块区域内。就好比，我在内存上租了一个房间（分配了一块内存空间给a），然后让张三住到了这个房间中（张三就是你要存储的值3），如果你要修改里面的值，就等于把张三赶出来，然后让其他人进去。 如果是单纯的3，则是一个立即数，是存在寄存器中的。赋值的操作其实就是先在寄存器上生成这个数，然后再把这个数写入到指定的空间内。你可以去看下汇编了解下。  2、这是声明一个数组，然后把这些常量丢到一个指定的空间内，理解同上。  3、C/C++的常量只的是字面值常量，其中只有字符串比较特殊，其他的常量都是立即数，他们属于右值，不存在所谓的地址。（立即数的地址即寄存器地址，寄存器地址再CPU中，而不是在内存上，具体的可以看汇编中的几种寻址方式。） 在C/C++中，只有左值可以取地址，右值是不可以取地址的，当然右值不一定是指常量，临时变量等等也属于右值。  4、++&a不一样&a是一个右值，不能对右值进行操作。至于普通的变量的地址，也可以++但++后的地址不保证可以正常使用，要么是段错误，要么就是访问了其他地址。 第三点讲的太好了，也就说果然字符串比较特殊了，是一个左值，可以取地址，所以char *p=“abcd”就是取了首地址，而1，2，‘a’在c语言中是立即数，是右值，是没有地址所以int *p=‘a’这样的操作不允许了。。。我一直就是想知道为什么字符串这么特殊。。谢谢啦!

变量名代表一个确定的地址和其中的数据，虽然自动变量是在函数调用时，确定地址的；  但是在每次调用时地址是固定的。 相当于常量。 而 &a 不是可修改的数据，所以 ++ &a 是不允许的。   至于 int a =10 ;这种内置类型的自动变量，可以直接当作指令的操作数， 编译后10 就嵌入到代码中了（10 成了指令中的立即数），所以就不会存储10这个常量了。  而数组初始化，直接把操作数嵌入指令中，代码太长，而且方法也不统一； 所以直接存储到数据区或者常量区。  在函数调用后复制过来，实现初始化，既方便，方法也统一，代码量也比较少，显然是更好的安排。

来人啊。。。。帮忙确认下。。。。新手表示很疑惑。。。

引用 4 楼 max_min_ 的回复:1 int a =3;是在栈分配的空间的，具体的常量也看怎么定义的！如果是3 这个一个，是没有存储空间的！         当需要存储起来才会用对应的类型变量申请空间存储      2 int a[3]={1,2,3}不是常量，这里只是初始化操作，然后把这几个值赋值给 int a 数组而已！      3 不是的！指针可以指向任何有效的内存地址都是可以的！        int  a= 10;  int *p = &a;        char a[] = "hello", char *p = a;        这些操作都是可以的！只要指向的地址是有效，但是注意指向不同，可能导致某些操作出错而已！       4 是不是可以理解变量的话，就是开辟一个区域。前面部分勉强可以这么理解！          地址也是可以++操作的，只是如果跨变量访问的话，只是可能得不到有效数据而已!如果空间申请的是连续的地址空间的，         地址++操作来访问对象是可以的！ 1.你说的这些我都明白，我的意思是直接利用指针只能指向字符串常量，不可以指向别的常量？比如 int *p=1；char *p=‘2’；int *p=｛1，2，3｝这样的表述肯定是不可以的吧，我就是看到char *p=“abcd”就再想为什么只能字符串不能用别的数据类型呢？所以才会这样问。强调的是直接，类似于字符串这样的形式，把字符串换成别的类型。原因我是这样理解字符串在此处表示了首地址，所以可以用指针变量直接赋值，别的数据类型没有这种特点。比如3 ，‘a’直接这样赋给int *p或cha *p 不能给p一个地址。所以不可以。虽然这种问题感觉没意义，我就是想对比深究一下。从而形成一个完整的体系。然后就意味可以把char *p="abcd"作为一种特殊情况看待。 2.然后还有就是int a=3；这个3到底如何理解。是在栈中分配好的区域内存入数据3，可读可写。和常量3有关系么? 有关系的话，到底如何实现？ 没关系的话，就理解成这里分配空间然后自己写入3，可读可写，那么自然也不必深究，我就是想确认下。


Question: 负数如何转换为N进制？

引用 3 楼 zhao4zhong1 的回复:先按位取反，再末位加一。 这个貌似不是对所有进制有效，自己琢磨了一天，写了两个方法，实现了itoa和atoi进制转换的功能 不知道有没有BUG，赵老师帮忙测试一下   #include <stdio.h> #include <string.h>  char   *iton(int value, char *string, int radix, const char *range); int     ntoi(const char *string, int radix, const char *range);  int main(void) { 	char string[100]; 	 	printf("%s\n", iton(-123, string, 10, ""));	 	printf("%d\n", ntoi("-123", 10, ""));	 	printf("%s\n", iton(-1, string, 2, ""));	 	printf("%d\n", ntoi("11111111111111111111111111111111", 2, ""));	 	printf("%s\n", iton(-8, string, 7, ""));	 	printf("%d\n", ntoi("211301422343", 7, ""));		 	return 0; /**************************************** 输出结果： -123 -123 11111111111111111111111111111111 -1 211301422343 -8 *****************************************/	 }   /* 十进制整数转N进制 */  char *iton(int value, char *string, int radix, const char *range) { 	int    		   i = 0, m, flag; 	unsigned int   uValue; 	char   		   tmp; 	 	if (strlen(range) == 0) range = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 	if (radix > strlen(range)) exit(1); 	/* 10进制负数特殊处理，其它情况将value的值转换为unsigned */ 	/* 转换为无符号数后利用辗转相除法，取余倒序得到相应的结果 */ 	flag = (radix == 10 && value < 0) ? 1 : 0; 	uValue = (radix == 10 && value < 0) ? (unsigned int) -value : (unsigned int) value; 	 	while (uValue > 0) { 		string[i++] = range[uValue % radix]; 		uValue = (radix == 1) ? --uValue : uValue / radix; 	} 	if (flag) string[i++] = '-'; 	string[i] = '\0';  	m = strlen(string) - 1; 	for (i = 0; i < m - i; i++) { 		tmp = string[i]; 		string[i] = string[m - i]; 		string[m - i] = tmp; 	} 	return string; }  /* N进制整数转十进制 */ int ntoi(const char *string, int radix, const char *range) { 	int   		   m = 0, i, j, flag, k, p; 	unsigned int   n = 0; 	 	if (strlen(range) == 0) range = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 	if (radix > strlen(range)) exit(1); 	flag = (radix == 10 && string[0] == '-') ? 1 : 0; 	while (string[m] != '\0') 		m++;  	/* 按位展开，结果相加，保存在一个无符号数中 */ 	/* 将最终的结果转换为有符号整数 */	 	for (i = flag; i < m; i++) { 		for (j = 0; j < strlen(range); j++)  			if (string[i] == range[j]) 				break;	 		for (k = 0, p = 1; k < m - 1 - i; k++)  			p *= radix; 		n += j * p; 	} 	return flag ? -1 * (int) n : (int) n; }

先按位取反，再末位加一。

char string[100]; printf("%s\n", itoa(-123, string, 7)); 用itoa方法，输出211301422120  不清楚是如何实现的，大神指点！

好问题  但是7进制 9进制 你用几个bit表示一位7进制数？3个？


Question: 关于指针常量和常量指针发现编译的一个问题，实在无法解释。求大神指教。。

对了最后那个程序少了，一行，应该是这样。虽然不写也没什么。只是为了证明第二种情况的发生和它取了变量的地址无关，做个对照。 #include<stdio.h> void main() {char a[5]; char *p; p=a; p="abcd"; *p='t'; printf("%c",*p); }

#include <stdio.h> void main() { 	char  *p="abcde"; 	*p='t';	//Turbo C 下就能正常运行并且修改成功,得看编译器的实现 	printf("%c",*p); }  下面是除了Turbo C那种OK的情况  #include <stdio.h> void main() { 	char a[5]="abcd"; //"abcd"的内存分配在栈区,可修改 	char  *p; 	p=a; 	*p='t'; 	printf("%c",*p); }   #include<stdio.h> void main() { 	char a[5]; 	char  *p; 	p="abcd";//"abcd"的内存分配在常量区,不可修改 	*p='t'; 	printf("%c",*p); }  上面的你都理解了const的问题也就明白了

引用 6 楼 max_min_ 的回复:楼主，好好体会下！  char  *p="abcde";// 这句的意思：把"abcde"这个字符串常量地址的值赋值给char *p                 //也就是p指向了"abcde"这块内存地址，而“abcde”是存放在静态区，      //不可修改，只可读，所以当你通过地址试图修改它的内容的时候，内存报错，只是可读    char p[] = "abcde"; //这句的意思：把"abcde"这的字符串的值赋初始化给 p[]这个栈区间上                     //而且这个只是在初始化时才能作的操作，其实的时候                     //则用strcpy,memcpy!  和上面的意思完全不一样！  +1

你必须明白“左值”和“右值”明白了就解决了。  如；n=n+1；  （n+1）这个是右值。右值是不允许修改，如果可以修改计算是不可能的。 想想，n+1,n/1,n*1,n-1;,n是多少呢，n是不变的，如果可以改变，计算是不确定的和无效的。  （n=）这个是左值。他必须是可修改的，如果不可修改计算将不可执行。  *p 在解引用时，你可以得到三个值中的一个，左值，右值和对象值（也就是地址。如果，他是一个指向指针的指针）。  char a[5]; char *p; p=a; *p //这时，你得到的是左值，即可修改的对象。  p="abcd"; *p;//这时解引用得到的是右值，即不可修改的值。  不知道，你理解了没有。

第一种char *p和const char *p是一样的，但char *p="abcde";是分配在文字常量区的不能被修改。保持等价跟C语言的历史有关，C++建议用const char *p="abcde";而不是用char *p="abcde";可以避免看错而范不必要的错误。  第二种char a[5]="abcd"，这个是数组，分配在栈上。然后char *p=a，使指针指向这个数组的地址。这个和第一种是完全不同的。

char  *p="abcde";将指针p指向数据区的"abcde" 从语法上，p是可以修改其指向的内存的（语言标准怎么规定这种情况的我不记得了） 从实现上，"abcde"不能修改，不管你是通过指针p还是别的什么方式 在编译选项里可以设置"abcde"可修改，这样就可以通过p修改数据区的数据了，但不推荐这种行为 推荐的方式还是const char * p = "abcde";

已经结贴了。。。。重开了一帖，是别的问题，关于结构体成员能不能做形参。。

引用 10 楼 u010412073 的回复:谢谢大家，已经明白了。学些了好多东西。 左上角，左下角有结贴按钮！按时结贴是个好习惯哦！

谢谢大家，已经明白了。学些了好多东西。

那个是不是默认char *p 是const？  还是说默认的是auto？需要特殊情况指定const？  可不可以这样理解，当p赋给一个字符串常量，则无法修改它的值，如果赋的是一个定义好的数组名，那么它可以修改这个数组的内容？    小白，表示不太熟悉。

#include<stdio.h> void main() {char a[5]="abcd";//a数据存在栈中(Main)连续5个字节,不是在数据区，其和p的地位相同，可以随意修改 char  *p; p=a; *p='t'; printf("%c",*p); }   #include<stdio.h> void main() {char a[5]; char *p; p=a; p="abcd";//p指向a后，又马上转到程序数据区（"abcd";和a没有关系，是一个字符串指针，数据在程序数据区） *p='t'; printf("%c",*p); }


Question: c语言内存值

引用 16 楼 zhao4zhong1 的回复:#include <stdio.h> float f=0.1f; double d=0.1; int i; int main() {     printf("float  %g in memory:",f);for (i=0;i<sizeof(float );i++) printf(" %02X",((unsigned char *)&f)[i]);printf("\n");     printf("double %g in memory:",f);for (i=0;i<sizeof(double);i++) printf(" %02X",((unsigned char *)&d)[i]);printf("\n");     return 0; } //float  0.1 in memory: CD CC CC 3D //double 0.1 in memory: 9A 99 99 99 99 99 B9 3F // 谢谢，我想是打印出内存，如果直接打印输出大整数，我还得转换成二进制，这样就方便多了，学习了！！！

内存中的值是二进制的，任何转换都是有误差的。  FPU 中的浮点数寄存器的位数可能超过 64位，在数据的传输过程中也有误差 深入理解计算机系统  有讲  理解：整型数据最精确

a、b的值就存储在它们两个变量中，至于地址，取地址即可，比如&a ... 内存中的数据是二进制，当然不存在类型，你想要什么类型，就转换成什么类型即可。

引用 1 楼 caozhy 的回复:float a = 0.1; byte * pbyte = (byte *)&a; for (int i = 0; i < sizeof(a); i++) {     cout << (int)*pbyte << endl;     pbyte++; }  引用 6 楼 angel_su 的回复:cout << (int)*pbyte << endl;貌似结果不是给人看的，不如直接2进制模式存入文件，非要文本模式就每byte转成2位的hex数字较妥...  引用 5 楼 junlinfushi 的回复:[quote=引用 1 楼 caozhy 的回复:] float a = 0.1; byte * pbyte = (byte *)&a; for (int i = 0; i < sizeof(a); i++) {     cout << (int)*pbyte << endl;     pbyte++; }+1[/quote] 可能我的问题还没说清楚，我现在的问题是，如下图， 我随便写个小程序右侧，左侧是我跟踪的到地址和内存中的值（类型转换输出的），这个程序执行完需要好几万的指令，地址是指令地址，太多了，我想要找到存储a,b的地址和a、b？的值。这需要学习哪些知识，而且内存中的值都是二进制，无法断定是数据类型！！？？各位大大有啥建议码

引用 4 楼 asdwt123 的回复:引用 2 楼 king1076 的回复:调试的时候 看内存！调试的时候看了，因为内存中的值对以后有用，所以想输出在文档中二进制。 数据在底层存储 都是二进制的形式！调试的时候 选择内存查看 你会看到一些16进制的表示。 float 是四个字节，那就这样子 float a;char ch[4];memcpy(ch,&a,4); 这样子 你就把float转换成底层存储的形式，然后写入文件 fwrite（ch,4,1,file)

引用 1 楼 caozhy 的回复:float a = 0.1; byte * pbyte = (byte *)&a; for (int i = 0; i < sizeof(a); i++) {     cout << (int)*pbyte << endl;     pbyte++; }+1

引用 1 楼 caozhy 的回复:float a = 0.1; byte * pbyte = (byte *)&a; for (int i = 0; i < sizeof(a); i++) {     cout << (int)*pbyte << endl;     pbyte++; }这个byte怎么定义的。。。很菜，不明白

调试的时候 看内存！

引用 9 楼 lgbxyz 的回复: #include <stdio.h>  int IsBigEndian(void) { 	union _un_st 	{ 		unsigned int a; 		unsigned char b; 	}un_st;  	un_st.a = 0x01020304; 	if (un_st.b = 0x01) 	{ 		return 1; 	}  	return 0; }  int main(void) {     int i = 0;     char *p = NULL;     float f = 0.1f;      p = (char*)&f;  	if (IsBigEndian()) 	{ 		for (i = sizeof(f) - 1; i >= 0; i--) 		{ 			printf("f[%d]Byte = %#x\n", 3 - i, *(unsigned char *)(p+i)); 		} 	} 	else 	{ 		for (i = 0; i < sizeof(f); i++) 		{ 			printf("f[%d]Byte = %#x\n", i, *(unsigned char *)(p+i)); 		} 	}      return 0; }  想看一个内存值，需要这么麻烦？直接打开调试器就可以了

引用 10 楼 asdwt123 的回复:[quote=引用 9 楼 lgbxyz 的回复:]  #include <stdio.h>  int IsBigEndian(void) { 	union _un_st 	{ 		unsigned int a; 		unsigned char b; 	}un_st;  	un_st.a = 0x01020304; 	if (un_st.b = 0x01) 	{ 		return 1; 	}  	return 0; }  int main(void) {     int i = 0;     char *p = NULL;     float f = 0.1f;      p = (char*)&f;  	if (IsBigEndian()) 	{ 		for (i = sizeof(f) - 1; i >= 0; i--) 		{ 			printf("f[%d]Byte = %#x\n", 3 - i, *(unsigned char *)(p+i)); 		} 	} 	else 	{ 		for (i = 0; i < sizeof(f); i++) 		{ 			printf("f[%d]Byte = %#x\n", i, *(unsigned char *)(p+i)); 		} 	}      return 0; } 验证这个，确实将0.1所在的内存值打印输出出来了，谢谢，不过如果很多行程序，怎么找到想要的程序行，将其对应的内存打印输出[/quote]  printf("%p");打印出去来地址，把每一个字节的地址都循环打印出来，对比就知道了阿！

计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

把对应的代码的行号打印出来不就行了吗

引用 9 楼 lgbxyz 的回复: #include <stdio.h>  int IsBigEndian(void) { 	union _un_st 	{ 		unsigned int a; 		unsigned char b; 	}un_st;  	un_st.a = 0x01020304; 	if (un_st.b = 0x01) 	{ 		return 1; 	}  	return 0; }  int main(void) {     int i = 0;     char *p = NULL;     float f = 0.1f;      p = (char*)&f;  	if (IsBigEndian()) 	{ 		for (i = sizeof(f) - 1; i >= 0; i--) 		{ 			printf("f[%d]Byte = %#x\n", 3 - i, *(unsigned char *)(p+i)); 		} 	} 	else 	{ 		for (i = 0; i < sizeof(f); i++) 		{ 			printf("f[%d]Byte = %#x\n", i, *(unsigned char *)(p+i)); 		} 	}      return 0; } 验证这个，确实将0.1所在的内存值打印输出出来了，谢谢，不过如果很多行程序，怎么找到想要的程序行，将其对应的内存打印输出


Question: linux里怎么查看宏定义

有个简单方法，楼主试试是否奏效： 1、找到使用这个宏的某个文件； 2、找到这个文件使用的头文件； 3、逐个过滤头文件，查找包含关系； 4、定位到最终宏定义；

写个文件，编译一下， gcc -E -dD ，然后你能看到所有的宏定义。  （-E -dD 的含义请参考 man gcc ）

群主，解决了吗？我也想知道这个问题怎么破

eclipse 还可以直接看宏展开的结果“ctrl+=”

VS是IDE啊，你那个右键是IDE的功能，跟linux有什么关系  你要查看定义看你用什么工具咯，eclipse、codeblocks、vim？不同的工具，不同的插件咯。  vim下记得是ctag，man是帮助文档，查的是系统里提供的定义和你的要求应该无关。 eclipse、codeblocks应该有内置这类插件的吧，我不太清楚你自己去用用看。

引用 8 楼 u011779875 的回复:[quote=引用 7 楼 max_min_ 的回复:] [quote=引用 5 楼 liyoubaidu 的回复:] [quote=引用 2 楼 u011779875 的回复:] 这个 得需要安装一个辅助工具   在vi中用 那个工具叫什么来着 我用过 但是忘记名字了 可以实现多文件函数跳转的 对叫 Ctag 你试试 能实现我说的查看宏定义的功能？[/quote]  man 2 open  里面有参数详细的说明！没有想vs那么直接而已！ 可以 /O_RDWR 搜索到具体看看！[/quote]版主 每天都在 不用工作 也不玩游戏 看来是个踏实的人啊[/quote]  现在在上班啊！闲的时候过来看下，游戏啊，过了玩的年纪了

引用 7 楼 max_min_ 的回复:[quote=引用 5 楼 liyoubaidu 的回复:] [quote=引用 2 楼 u011779875 的回复:] 这个 得需要安装一个辅助工具   在vi中用 那个工具叫什么来着 我用过 但是忘记名字了 可以实现多文件函数跳转的 对叫 Ctag 你试试 能实现我说的查看宏定义的功能？[/quote]  man 2 open  里面有参数详细的说明！没有想vs那么直接而已！ 可以 /O_RDWR 搜索到具体看看！[/quote]版主 每天都在 不用工作 也不玩游戏 看来是个踏实的人啊

引用 5 楼 liyoubaidu 的回复:[quote=引用 2 楼 u011779875 的回复:] 这个 得需要安装一个辅助工具   在vi中用 那个工具叫什么来着 我用过 但是忘记名字了 可以实现多文件函数跳转的 对叫 Ctag 你试试 能实现我说的查看宏定义的功能？[/quote]  man 2 open  里面有参数详细的说明！没有想vs那么直接而已！ 可以 /O_RDWR 搜索到具体看看！

O_RDWR 先看看 你是哪个函数调用的返回值啊 这个可能是create函数吧 man 2 create 我很久不写了  首先光标要移动到你要查看的东西上 然后shift和k一块按动

引用 2 楼 u011779875 的回复:这个 得需要安装一个辅助工具   在vi中用 那个工具叫什么来着 我用过 但是忘记名字了 可以实现多文件函数跳转的 对叫 Ctag 你试试 能实现我说的查看宏定义的功能？

引用 3 楼 liyoubaidu 的回复:[quote=引用 1 楼 u011779875 的回复:] O_RDWR man 2 open man 3 fopen 查看先关函数英文文档 有相应的返回值说明 ？？？ 还是没有看到O_RDWR是怎么define的[/quote] shift + K

引用 1 楼 u011779875 的回复:O_RDWR man 2 open man 3 fopen 查看先关函数英文文档 有相应的返回值说明 ？？？ 还是没有看到O_RDWR是怎么define的

引用 11 楼 lgbxyz 的回复:下个源码包，用SourceInSight建个工程，用时搜一下 具体要怎么做呢？

ctags用这很舒服。 ctags -R * 用vim想跳转的话就CTRL + ]

下个源码包，用SourceInSight建个工程，用时搜一下


Question: 数组定义问题！！！

真是太感谢你了

先定义一个足够大的数组,然后根据人数n让前n个元素取值1-3,统计1-3出现的次数


Question: gtk新手   哈希表 求助

引用 2 楼 zaley 的回复:那怎么使用 g_int_hash 的 哈希表 ? 传递key的时候应该传递整形的指针（当然要保证该指针指向有效地址）。  下面的代码参考一下： #include <glib.h>  int main(int arg, char **argv) { 	GHashTable* hash = g_hash_table_new(g_int_hash, g_int_equal); 	gint* key = g_new(gint, 1); 	gint value = 5; 	*key = 1; 	g_hash_table_insert(hash, key, (gpointer)value); 	 	return 0; }  取值value(gint value = 5)的时候再强制转回整形就可以了。

那怎么使用 g_int_hash 的 哈希表 ?

函数taphash_insert()在调用g_hash_table_insert()的时候，将 将guint32转换为gpointer(void *)，如果frame_num为0，g_hash_table_insert()是要读取gpointer的位置的，那么此时会读取地址0位置，程序理所当然的崩溃（虚拟地址0位置不是程序可以访问的位置）。

那么怎么 lookup 呢？


Question: 这个程序你们运行有错么

引用 2 楼 max_min_ 的回复: //%p打印地址！printf格式化输出函数！  printf("%p",p);  +1  不过楼主的代码有其他问题，next数组有溢出，导致栈被破坏无法正常退出程序的问题。

//%p打印地址！printf格式化输出函数！  printf("%p",p);  引用 楼主 u011488256 的回复:大家看看你们这个程序运行会出错么#include "stdafx.h"   #include "stdio.h"  void Get_Next(char *T,int *next) { 	int i=1,j=0; 	next[0]=0; 	next[1]=0; 	char *p=T; 	while (*T) 	{ 		//这里的T 在自己加 所以要多一个P  		//因为题目要求不能求子串的长度 		//然后这里的字符串给近来从0开始 但是这里计算的是从1开始 		if(j==0||p[j-1]==p[i-1]) 		{ 			i++; 			j++; 			next[i]=j; 			T++; 		} 		else 			j=next[j]; 		 	} } int main(int argc, char* argv[]) { 	//下面的代码是子串和主串做比较的一部分 	char a[10]="abaabc"; 	char b[40]="abaaabaabcababaabc"; 	char *p=b; 	printf("%c",*p); 	printf("%ld",p); 	//printf("%c",*q); 	int next[7]; 	int i=0; 	int count=0; 	Get_Next(a,next); 	printf("%ld",p);//我的问题出在这里，每次运行到这里P就没有值了，但是前面的根本没改变过，函数传参也没用他 ，纳闷几天了 	printf("%c",*p); 	return 0; }       我用的编译环境是VC 60 控制台     高分求大神赐教！

打印地址用%p  int main(int argc, char* argv[]) {     //下面的代码是子串和主串做比较的一部分     char a[10]="abaabc";     char b[40]="abaaabaabcababaabc";     char *p=b;     printf("%c\n",*p);     printf("%p\n",p);     //printf("%c",*q);     int next[7];     int i=0;     int count=0;     Get_Next(a,next);     printf("%p\n",p);//我的问题出在这里，每次运行到这里P就没有值了，但是前面的根本没改变过，函数传参也没用他 ，纳闷几天了     printf("%c\n",*p);     return 0; }   我这里的输出是：  a 0xbfc4056a 0xbfc4056a a  引用 楼主 u011488256 的回复:大家看看你们这个程序运行会出错么#include "stdafx.h"   #include "stdio.h"  void Get_Next(char *T,int *next) { 	int i=1,j=0; 	next[0]=0; 	next[1]=0; 	char *p=T; 	while (*T) 	{ 		//这里的T 在自己加 所以要多一个P  		//因为题目要求不能求子串的长度 		//然后这里的字符串给近来从0开始 但是这里计算的是从1开始 		if(j==0||p[j-1]==p[i-1]) 		{ 			i++; 			j++; 			next[i]=j; 			T++; 		} 		else 			j=next[j]; 		 	} } int main(int argc, char* argv[]) { 	//下面的代码是子串和主串做比较的一部分 	char a[10]="abaabc"; 	char b[40]="abaaabaabcababaabc"; 	char *p=b; 	printf("%c",*p); 	printf("%ld",p); 	//printf("%c",*q); 	int next[7]; 	int i=0; 	int count=0; 	Get_Next(a,next); 	printf("%ld",p);//我的问题出在这里，每次运行到这里P就没有值了，但是前面的根本没改变过，函数传参也没用他 ，纳闷几天了 	printf("%c",*p); 	return 0; }       我用的编译环境是VC 60 控制台     高分求大神赐教！


Question: 关于C++的一个获取i键盘按键的疑问

//The _getch function reads a single character from the console without echoing. //Function can not be used to read CTRL+Break. //When reading a function key or an arrow key, //_getch must be called twice; the first call returns 0 or 0xE0, //and the second call returns the actual key code. #include <conio.h> #include <windows.h> void main() {     unsigned short k;      while (1) {         Sleep(100);         k=getch();         if (27==k) break;//按Esc键退出         if (0==k||0xe0==k) k|=getch()<<8;//非字符键         cprintf("%04x pressed.\r\n",k);     } }


Question: 都看看吧   是超界了吗

#include <stdio.h>  int main(void) {     int   s;     int   m, n;     int   i, j, cnt, sum;          scanf("%d", &s);      while (s--) {         scanf("%d%d", &n, &m);  		// 没必要实际求出n的阶乘，肯定会越界 		// 只需要把 1 * 2 * 3 * ... * m * ... * n 中每个数分解质因数，然后把和加起来          for (i = m, sum = 0; i <= n; i++) {             j = i;             cnt = 0;             while (j >= m) {             	if (j % m == 0) { 	            	cnt++; 	            	j /= m; 	            } else {             		break;             	}             }             sum += cnt;         }         printf("%d\n", sum);     }      return 0; }  输出结果： 3 10 3 4 10 5 2 10 7 1

必须越界，n稍微大一点，n的阶乘就越界了


Question: c语言疑问

引用 14 楼 AnYidan 的回复:[quote=引用 12 楼 baijiaheizhiganmao 的回复:] [quote=引用 11 楼 AnYidan 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] F11、F10、Shift+F11 F9、F5  什么东东，给个图片标出好吗？[/quote] 本三大叔说了：反正情况就是这么个情况.2万块钱你要留就留下,不留你就拿走.你要愿意吃,2万大餐你都端走,我一块没动.你看咋样. 请回复：你太有才了！[/quote]  赵老师很有孔圣人的遗风，膜拜！  [/quote] 您就不能配合一下？！

引用 12 楼 baijiaheizhiganmao 的回复:[quote=引用 11 楼 AnYidan 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] F11、F10、Shift+F11 F9、F5  什么东东，给个图片标出好吗？[/quote] 本三大叔说了：反正情况就是这么个情况.2万块钱你要留就留下,不留你就拿走.你要愿意吃,2万大餐你都端走,我一块没动.你看咋样. 请回复：你太有才了！[/quote]  赵老师很有孔圣人的遗风，膜拜！

引用 11 楼 AnYidan 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] F11、F10、Shift+F11 F9、F5  什么东东，给个图片标出好吗？[/quote] 本三大叔说了：反正情况就是这么个情况.2万块钱你要留就留下,不留你就拿走.你要愿意吃,2万大餐你都端走,我一块没动.你看咋样. 请回复：你太有才了！

Debug|DebugStepOver                   |F10                   |Steps over the next statement Debug|DebugStepInto                   |F11                   |Steps into the next statement Debug|DebugGo                         |F5                    |Starts or continues the program Debug|DebugToggleBreakpoint           |F9                    |Inserts or removes a breakpoint Debug|DebugStepOut                    |Shift+F11             |Steps out of the current function  Visual Studio 6开发环境下的所有热键一览表 http://download.csdn.net/detail/zhao4zhong1/2196516

程序别写的很大才去调试。 架子搭起来（不必写太细节的代码），就可以调试了。  每个局部代码写出来，都先调试一下。 这样，程序大了，也好调试。

引用 8 楼 zhao4zhong1 的回复:F11、F10、Shift+F11 F9、F5  什么东东，给个图片标出好吗？

引用 4 楼 baichi4141 的回复:单步调试就是按一下执行一行，在程序中下断点可以省的从头开始 我真不明白怎样才能把单步调试说的更复杂一些+1

引用 2 楼 u010165006 的回复:人为插入一些printf语句输出，看能执行到哪里，或者输出变量的值。 ++ 可以采用这种方法，不过，如果会用gdb，那么采用gdb的方法还是挺快的。

引用 2 楼 u010165006 的回复:人为插入一些printf语句输出，看能执行到哪里，或者输出变量的值。 引用 7 楼 xiaoliang1201 的回复:能单步执行的话就单步执行咯，不然的话，就多添加一些printf函数看看哪里出了问题+1

F11、F10、Shift+F11 F9、F5

可以编译了！生成的执行文件执行试试呗！断点调试呗

人为插入一些printf语句输出，看能执行到哪里，或者输出变量的值。

语法无错误，那就是逻辑有错误


Question: 冒泡排序法的改进

引用 4 楼 baichi4141 的回复:比较之前不知道该不该比较。 比较之后才知道不该比较——有用么？  要真的利用大小的传递关系来优化，那就不是冒泡了，直接快排吧 ++ 快排就是冒泡的一种改进，但是这已经不是冒泡了！ 要维持冒泡,那么可改进的地方，不是很大.

加个布尔量，判断一下需不需要交换，。

冒泡的可改进处，也就是已经有序，就不再排序了，这么一点可以优化之处。  方法是一轮排序下来，看交换几次，如果完全，没有交换； 自然不要继续排序，就可以结束了。  更好的办法，不知有没有。  原理上是，无逆序，不需要排序！

1楼给了个思路，可以简单再改良一下用swapped去记录第一次发生交换的地方。内层循环下轮从swapped前一个位置开始。数据量小，部分有序的情况下可能有点效果，数据量大的话还是用其他算法...

能给我介绍一下鸡尾酒排序吗？

加个flag。。。 还有改良版的 鸡尾酒排序

冒泡就是这样的。比较后，可能不会执行换位。

能做到比较但不交换，但做不到不比较。

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

你不遍历怎么知道不需要比较。  只能说比较了，不需要交换。

怎么看到冒泡有点问题了

#include <stdio.h>  int main(void) {     int arr[9];     int temp, i, j;     int swapped = 1;  	// 初始化      for (i = 0; i <= 9; i++)         arr[i] = 9 - i;  	// 排序前      printf("Before Sort: ");     for (i = 0; i <= 9; i++)         printf("%d ", arr[i]);  	// 冒泡排序      for (i = 0; swapped; i++) {         swapped = 0;         for (j = 0; j < 9 - i; j++) {             if (arr[j] > arr[j + 1]) {                 temp = arr[j];                 arr[j] = arr[j + 1];                 arr[j + 1] = temp;                 swapped = 1;             }         }     }  	// 排序后      printf("\n After Sort: ");     for (i = 0; i <= 9; i++)         printf("%d ", arr[i]);     printf("\n");          return 0; }  Before Sort: 9 8 7 6 5 4 3 2 1 0  After Sort: 0 1 2 3 4 5 6 7 8 9


Question: C语言

引用 2 楼 missheaven2011 的回复:当你if(x==0)错写为if(x=0)时，编译器不会报错，问题难以发现 当你if(0==x)错写为if(0=x)时，编译器能及时报错，易于发现问题  原因是常量不能作左值

ox让人想到牛，觉得你的代码很牛； xo让人想到酒，不喝就醉了

没有区别，不过第一种写法是防止手误写成了if (x = 0)而造成逻辑上的错误。

就是这么回事的 引用 2 楼 missheaven2011 的回复:当你if(x==0)错写为if(x=0)时，编译器不会报错，问题难以发现 当你if(0==x)错写为if(0=x)时，编译器能及时报错，易于发现问题

都可以的！ if(0 == x)只是为了避免出现赋值操作这样编译器会报错而已！一个写法而已！

用惯if(x==0)就好了。养成习惯，这两个没有区别

都可以  用0 == x可以避免将==误写作= 一般大神都用x == 0，原因是习惯了


Question: 小白一枚，求高手。

标题改成“忙着打网游的学生一枚，求代写作业”比较好

这些代码，网上很多啊

亲，百度下！转换的原理！然后自己画画！ 网上狠得多源码的！

赞同二楼，

百度一下，一大票的程序


Question: 课程作业要求写网页爬虫，但是内存分配好像出了问题，谁帮我看看

诶，自己找到了，正则表达式。。。咳咳 感谢一楼帮顶

看着好高端的问题，请大神解答……