Question: 请问C语言里面的指针里面的“*”和“&”用法怎么区别一下，各种混乱啊！谢谢！

在声明中和在语句中不一样。

具体看你这个函数是要干什么了！调用时总归会是  int *b; ...; add(&b);  在add函数内 a表示b的地址，只是个形参，调用过程中不会对原本b产生任何影响！ *a表示b的值，对*a的修改直接反馈到b的值上面。 &a表示的是一个二级指针，存放的是a的地址也就是b的地址的地址，类型是int **，你这个函数估计是不会用到的！

int a,int *a都是定义一个局部变量（一个整形，一个指针），它都局部于函数内部。函数结束自动灭亡。 int &a是C++中引用特性，即另一个变量的“别名”。 当外部调用函数，传递参数num(或者&num)时，那么 fun(int a) == a = num; fun(int *a)== a = # fun(int &a)== &a = num;

变量a 本质上代表一个存储单元。CPU通过该存储单元的地址访问该存储单元中的数据。所以a本来代表两个值：存储单元的地址和储单元中的数据。于是就有了二异性。为了消除这种二义性，C语言规定a表示存储单元中的数据，&a表示存储单元的地址。 a存储单元中的数据可以是一个普通数值，也可以是另一个存储单元的地址，比如：a = &b; 语句就是将b的存储单元的地址存入a存储单元中。C语言规定*a代表a中存储的地址对应的存储单元中的数据，也就是访问*a就等于访问b，于是*a提供了通过a访问b中的数据的手段。  a表示a对应的存储单元中的数据。 &a表示a对应的存储单元的地址。 *a表示：首先，要求a对应的存储单元中的数据一定是另一个存储单元的地址。         于是，*a表示另一个存储单元中的数据。 当a声明的类型是int时，a中存储的是一个整数数值，通过a可以访问（读取或修改）这个数值。 当a声明的类型是int*时，a中存储的是一个存储单元的地址，而该存储单元中存储的数据是一个整数数值；通过*a可以访问（读取或修改）这个数值。a == &*a 都是该存储单元的地址。 当a声明的类型是int**时，a中存储的是一个存储单元的地址，而该存储单元中存储的数据是另外一个存储单元的地址，另外这个存储单元中存储的是一个整数数值；通过**a可以访问（读取或修改）这个数值。 ...  最后，在C语言里地址叫指针。

http://download.csdn.net/detail/max_min_/6333711 c和指针   多看看！

找本语法书看看

void Add(int * a)   // a 是一个int型的指针,a指的地址存放的是int型的数据 {   a    // 取指针a的值(即地址)   *a   // 取指针a指向的内容   &a   // 取存放指针a的值的地址 }

a、*a、还是&a  对于声明或定义int * a; a 是一个指针,存放一个地址，a的值就是这个地址。 *a 是指针a，所存放的地址中存放的数据。 &a 指针也是数据的一种，而且它也有个地址，&a就是这个地址。 一切需要存放的数据，都有地址。  一般我们 都只考虑，变量的地址，而不考虑常量的地址；  因为常量，要么没有地址，要么像变量一样，也有一个地址， 这种有地址的常量，当作变量看待就可以了。

*a代表类型指针，a代表某类型的变量，&a代表某类型的变量的引用 *a 是指向某个地址，字节都是4 , a表示复制一个变量的值，字节与要复制的变量的字节一样大，&a表示引用某一个变量字节与类型有关！


Question: C语言中怎么利用API获得操作系统和CPU的信息？(求大神指点)

shell不错 很方便 学习下

批处理啊，Linux Shell都出来了，哈哈。 偶是这么干的：物理内存信息是用GlobalMemoryStatusEx读取的。CPU信息是用汇编cpuid读取的。系统信息直接注册表读取出来的。  系统版本: Windows 7 Ultimate 产品号:  所有者: Microsoft CPU制造商: GenuineIntel CPU型号:        Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz 总共物理内存: 9.86 GB

内联汇编好像可以

操作系统信息，要读取硬盘启动扇区的硬盘分区标志，但是linux,可以运行在，windows 分区，所以一般不是靠程序测试出来的，而是由编译器定义的。 CPU信息，X86及兼容CPU，可以通过内置汇编，CPUID指令得到。

@logiciel    为什么还是有错误 不会改啊。。。

要用C语言。。。

man 5 proc

看不懂 我是新手小白。。。这是程序吗

使用C语言调用系统shell批处理.... 用批处理获取电脑机器码的方法 以下是获取cpu和硬盘序列号的组合ID   @echo off&setlocal ENABLEDELAYEDEXPANSION set sig=0 for /f %%i in ('wmic DISKDRIVE get signature') do ( set /a sig+=1 if !sig!==2 set pcid=%%i ) set sig=0 for /f %%i in ('wmic cpu get ProcessorId') do ( set /a sig+=1 if !sig!==2 set pcid=!pcid!%%i ) echo cpu的id和硬盘序列号的组合为: %pcid% pause

试了一下，有个错误啊 'std' : is not a class or namespace name 怎么改

linux下面就读取/proc/version和/proc/cpuinfo的信息就行了吧。

#include <windows.h> #include <stdio.h> int main() {   SYSTEM_INFO  sysInfo;   OSVERSIONINFOEX osvi;    GetSystemInfo(&sysInfo);    printf("OemId : %u\n", sysInfo.dwOemId);   printf("处理器架构 : %u\n", sysInfo.wProcessorArchitecture);   printf("页面大小 : %u\n", sysInfo.dwPageSize);   printf("应用程序最小地址 : %u\n", sysInfo.lpMinimumApplicationAddress);   printf("应用程序最大地址 : %u\n", sysInfo.lpMaximumApplicationAddress);   printf("处理器掩码 : %u\n", sysInfo.dwActiveProcessorMask);   printf("处理器数量 : %u\n", sysInfo.dwNumberOfProcessors);   printf("处理器类型 : %u\n", sysInfo.dwProcessorType);   printf("虚拟内存分配粒度 : %u\n", sysInfo.dwAllocationGranularity);   printf("处理器级别 : %u\n", sysInfo.wProcessorLevel);   printf("处理器版本 : %u\n", sysInfo.wProcessorRevision);    osvi.dwOSVersionInfoSize=sizeof(osvi);   if (GetVersionEx((LPOSVERSIONINFOW)&osvi))   {     printf("Version     : %u.%u\n", osvi.dwMajorVersion, osvi.dwMinorVersion);     printf("Build       : %u\n", osvi.dwBuildNumber);     printf("Service Pack: %u.%u\n", osvi.wServicePackMajor, osvi.wServicePackMinor);   }   return 0;	 }

cat /proc/version cat /proc/cpuinfo           when /darwin9/       `hwprefs cpu_count`.to_i     when /darwin/       ((`which hwprefs` != '') ? `hwprefs thread_count` : `sysctl -n hw.ncpu`).to_i     when /linux/       `cat /proc/cpuinfo | grep processor | wc -l`.to_i     when /freebsd/       `sysctl -n hw.ncpu`.to_i     when /mswin|mingw/       require 'win32ole'       wmi = WIN32OLE.connect("winmgmts://")       cpu = wmi.ExecQuery("select NumberOfCores from Win32_Processor") # TODO count hyper-threaded in this       cpu.to_enum.first.NumberOfCores


Question: 从文件中读单词并统计个数

啊呀，传错代码了 不好意思啊 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct wstr { char w[50]; int count; struct wstr *next; }WORD;  void main() {     FILE *fp; WORD *h,*p,*q; char word[50]; h=(WORD*)malloc(sizeof(WORD));  h->next=NULL; p=h;//h->next  if((fp=fopen("s.txt","r"))==NULL) { printf("Can't open file");     return; }   while(fscanf(fp,"%s",word)!=EOF) {      q=h->next;	 	while(q!=NULL&&strcmp(q->w,word)) 		q=q->next;  	if(q!=NULL) 		q->count++; 	else 	{ 	q=(WORD*)malloc(sizeof(WORD)); 	strcpy(q->w,word); 	q->count=1; 	q->next=NULL; //新加的 	p->next=q; 	p=p->next;  	} } //新加的 p=h->next;  while(p!=NULL)  {  printf("%s  %d",p->w,p->count);  p=p->next;  } }

楼主，你MALLOC的q并没有添加到h链表中  我帮你改了下#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct wstr { char w[50]; int count; struct wstr *next; }WORD;  void main() {     FILE *fp; WORD *h,*p,*q; char word[50]; h=(WORD*)malloc(sizeof(WORD));  h->next=NULL; p=h;//h->next  if((fp=fopen("s.txt","r"))==NULL) { printf("Can't open file");     return; }   while(fscanf(fp,"%s",word)!=EOF) {      q=h->next;	 	while(q!=NULL&&strcmp(q->w,word)) 		q=q->next;  	if(q!=NULL) 		q->count++; 	else 	{ 	q=(WORD*)malloc(sizeof(WORD)); 	strcpy(q->w,word); 	q->count=1; 	q->next=NULL; //新加的 	p->next=q;  	} } //新加的 p=p->next;  while(p!=NULL)  {  printf("%s  %d",p->w,p->count);  p=p->next;  } }   你看看有没有错误，我随便试了一个能成功

运行不出来是个什么概念呢？ 是运行了后什么都没有？还是运行了，没有得到输出结果 只得到请按任意键结束呢？ 打个断点调试下吧

恩恩，谢谢，你们真是好人

void insert(struct wstr *head, struct wstr *i_new) { 	int n = 0; 	struct wstr *p, *q;  	p = head; 	q = head->next; 	while(q) 	{ 		while(q->w[n] == i_new->w[n])		//跳过前面相等的字符,你也可以使用字符比较函数 		{ 			++n; 		} 		if (q->w[n] > i_new->w[n])		//q字符大于i_new字符，插在i_new之前,返回 		{ 			p->next = i_new; 			i_new->next = q; 			return; 		} 		else							//q字符小于i_new字符，下偏移一个结点，继续			 		{ 			n = 0; 			p = q; 			q = q->next; 		}  	}//循环结束，说明只能插入到尾部 	i_new->next = q; 	p->next = i_new;  } void main() { ... while(fscanf(fp,"%s",word)!=EOF)  {   while(q!=NULL&&strcmp(q->w,word))     q=q->next;   if(q!=NULL)  q->count++;   else{   q=(WORD*)malloc(sizeof(WORD));   strcpy(q->w,word);   q->count=1;   insert(h, q);   }   ... }   临时写的，你自己测试一下

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<malloc.h> typedef struct wstr { 	char w[50]; 	int count; 	struct wstr *next; }WORD;  typedef struct word { 	char words[50]; 	int counts; }NEWWORD;  int cmp(const void *a,const void *b) { 	return ((NEWWORD *)b)->counts-((NEWWORD *)a)->counts; }  void main() {     FILE *fp; 	WORD *h,*p,*q; 	char word[50]; 	int wordcount=0,i=0; 	 	NEWWORD **wordarr, *t; 	 	//h=(WORD*)malloc(sizeof(WORD)); 	//h->next=NULL; 	h=NULL;     //p=h->next; 	if((fp=fopen("s.txt","r"))==NULL) 	{ 		printf("Can't open file"); 		return; 	} 	while(fscanf(fp,"%s",word)!=EOF) 	{  		//q=h->next; 		q=h; 		while(q!=NULL&&strcmp(q->w,word)) 			q=q->next; 		 		 		if(q!=NULL) 			q->count++; 		else{ 			q=(WORD*)malloc(sizeof(WORD)); 			strcpy(q->w,word); 			q->count=1; 			q->next=NULL; 			if(h==NULL)  { 				h=q; 			} else { 				p=h; 				while(p->next!=NULL) 					p=p->next; 				p->next = q; 			} 			wordcount++; 		} 	} 	 	/* p=h; 	while(p!=NULL) 	{ 	printf("%s  %d\n",p->w,p->count); 	p=p->next; } */ 	  	 	 	wordarr=(NEWWORD **)malloc(sizeof(NEWWORD*)*wordcount); 	     p=h;     while(p!=NULL) 	{ 		t = (NEWWORD *)malloc(sizeof(NEWWORD)); 		strcpy(t->words,p->w); 		t->counts=p->count; 		wordarr[i] = t; 		i++; 		p=p->next; 	} 	 	qsort(wordarr,wordcount,sizeof(NEWWORD*),cmp); 	for(i=0;i<wordcount;i++) 		printf("%s %d\n",wordarr[i]->words,wordarr[i]->counts);  } //这个是用qsort按排的，可是不知道怎么好像没用

那你学排序（算法）了吗？

可以帮我写写那个排序的程序么，我好好研究一下，我刚刚学链表，不怎么会用，求大神帮忙

引用 5 楼 my_live_123 的回复:第一个结点没有挂到h->next上，然后随后的结点虽然都挂上了，但是头丢了！  你可以在插入的时候，就直接找到恰当位置插入，也就是说插入新结点就“排序”  引用 4 楼 u012027885 的回复:谢谢啊，我想把这些单词排序后再输出，怎么办？恩，边插入边排序最方便

对于链表的排序，可以选用快速，插入，冒泡等，交换的时候交换结构体内的所有变量就行

谢谢啊，我想把这些单词排序后再输出，怎么办？


Question: 用c编程万年历

localtime();


Question: 您懂这个嘛 “模式匹配”

引用 1 楼 taodm 的回复:刚接触编程的还是放弃吧。这题至少要1年以后再试了。 也不一定，因为作业中没规定时间复杂度。。。

刚接触编程的还是放弃吧。这题至少要1年以后再试了。

不能给你全做，否则起不到锻炼作用，下面代码是两个字符串匹配，供参考，不懂拍我，我可以给你讲解！   int main(void) { 	size_t i = 0, j = 0; 	char str1[128] = {0}; 	char str2[128] = {0}; 	gets(str1); 	gets(str2);  	while(i < strlen(str1) - strlen(str2) + 1) 	{ 		while (j < strlen(str2)) 		{ 			if (str1[i] != str2[j]) 			{ 				i -= j - 1; 				j = 0; 				break; 			} 			++i; 			++j; 		} 		if (j == strlen(str2)) 		{ 			printf("%d\n", i - j); 			break; 		} 	}  	return 0;  }

写了两种方式的c++和c的。  #include<iostream> #include<string> using namespace std;   int main() {    string a,b;    int p[100];    int max,i;    cin>>max;    for(i=0;i!=max;i++)    { 	   cin>>a; 	   cin>>b; 	   size_t l=a.find(b);        p[i]=(l==string::npos)?-1:l;    }    for(i=0;i!=max;i++) 	   cout<<p[i]<<endl;    return 0; }     #include<stdio.h> #define max 100 int judge(char *a,char *b)//b在a中是否出现，返回位置或-1 { 	int temp; 	char *p1=a,*p2=b; 	while(*p1!='\0')			//从p1头开始找 	{ 		temp=0; 		while(*p1!=*p2)			//试图找到p1和p2开头一样的地方 		{ 			if(*p1=='\0')		//如果找到尾部也没发现和p2开一样的地方，则返回-1 				return -1; 			p1++;				//p1一直向后 		} 		temp=p1-a;				//找到p1和p2开头一样地方，记录下位置  		while(*p2!='\0')		//开始进行对比 		{ 			if(*p1=='\0')		//如果找到p1尾还没对比完的话，返回-1	 				return -1;		 			if(*p1!=*p2)		//如果发现不一样的地方，跳出，继续找p1和p2头相同的地方 			{ 				break; 			} 			else  				if(*(p2+1)=='\0')		//如果对比完都一样的话返回位置 					return temp; 			p1++; 			p2++; 		} 		p1=&a[temp+1];			//p1到刚刚记录的temp的位置后面一个 		p2=b;					//p2回到头部 	}   	return -1; }  int main() { 	char a[max],b[max]; 	int p[100]; 	int m,i; 	scanf("%d",&m); 	for(i=0;i!=m;i++) 	{ 		scanf("%s%s",&a,&b); 		p[i]=judge(a,b); 	} 	for(i=0;i!=m;i++) 	{ 		printf("%d\n",p[i]); 	} }

如果匹配的字符串是如同485通讯一样，一个一个字节或者连续几个字节的来，来一次匹配一次的话，那的确是麻烦。 但这里字符串是一次性输入的，这倒简单： #include <stdio.h> #include <string.h> #include <stddef.h>  int AnalysisStr(char const *pStrS, char const  *pStrP) {     char Count = 0;     char const *pStrSTmp = pStrS;     char const *pStrPTmp = pStrP;     if(strlen(pStrS) < strlen(pStrP)) {/*字符串S长度短于P肯定错误*/         return -1;     }     for(Count = 0; Count <= strlen(pStrS) - strlen(pStrP); Count++)     {         pStrSTmp = pStrS + Count;         pStrPTmp = pStrP;         /*对比两字符串中的元素，直到字符串P结束或者不相等*/         while( (*pStrPTmp != '\0') && (*pStrPTmp == *pStrSTmp) ) {             pStrPTmp++;             pStrSTmp++;         }         /* *pStrPTmp == '\0'说明全部相同*/         if(*pStrPTmp == '\0'){             return (int)Count;         }     }     return -1;/*没找到*/ }  #define N 3 typedef struct MatchTag{     char p[128];     char s[128]; } Match_t; void PatternMatch(void) {     Match_t MatchTbl[N];      char count = 0;     printf("样例输入\n");     /*输入三组数组*/     for(count = 0; count < N; count++)     {         scanf("%s", MatchTbl[count].s);         scanf("%s", MatchTbl[count].p);     }     printf("样例输出\n");     for(count = 0; count < N; count++)     {         printf("%d\n", AnalysisStr(MatchTbl[count].s, MatchTbl[count].p));     } }   int main() {     PatternMatch();     getchar(); }  貌似LZ想让大家给他写作业，一条题100块 你看可否~~


Question: scanf循环输入的问题

请问这程序是完成什么事情的？我跑了下，不知道为什么要我一直输入。一直是死循环。

scanf("%d %d", &m, &n); 把两个%d直接加个空格试试~

int main(void) {  int m,n; while(scanf("%d%d",&m,&n)==2) { 	int p1,p2; 	p1=m; 	p2=n; 	while(p1>1&&p2>1) 	{ 		if(p1>p2) 		{ 			p1/=2; 		} 		else if(p1<p2) 		{ 			p2/=2; 		} 		else 		{ 			printf("共同祖先是%d",p1);  			break; 		} 	} 	 	puts("perfect\n");  } return 0;  }  我跑了一下，木事问题噻！就是一个死循环，只能强制退出，其他没啥大病！估计是你的输入有问题，  你可以 12 空格 4 回车 也可以： 12 回车 4 回车

楼主“  1.输入第一个数后输入一个空格，再输入第二个数，再输入回车。这样每输入两个数就按一下回车。 以两个数为一组。  数1 空格 数2 回车 数3 空格 数4 回车 。。。  而且在while循环中刷新一下输入缓冲区。把回车的副作用消除

在你的while循环里加上getchar()会取回车， 然后输出的的时候fflush(stdout)或者printf("\n") 刷新下缓冲区


Question: S3C2440中断的编写问题

我在linux用的gcc，void __irq IRQ_Eint0(void);  void IRQ_Eint0(void) __irq; 都试过了都不行

ADS编译器中 ： void __irq IRQ_Eint0(void);  Keil编译器中 ： void IRQ_Eint0(void) __irq;

能不能详细说下，我是裸板开发，TQ2440的板子。看其他代码都是那样写的难道gcc不支持？

理解compiler,向前找找


Question: 新人求 救  删除字符串中的数字和符号，只留下英文字符，然后输出

如果在原缓冲上难以掌控移动指针出错的话， 可以重新定义一个缓存，判断是字母则就拷贝赋值过来就好！

逐个判断是否是字母就好了啊 int isalpha( int ch ); 功能：如果参数是字母字符，函数返回非零值，否则返回零值。


Question: while(scanf("%d",&a)!=EOP) 求犀利哥 急求 犀利哥

for(i=length-1;i>=0;i--)    {     nus[i]=(a/((int)(pow(10,i))))%10;    }

输出结束是不是想用EOF啊？  //取各个位的数字  int num =13579,tmp =0; while(num != 0) {    tmp = num%10;    num = num/10;    printf("%d \n", tmp); //tmp就是取位的数字，从个位开始  }


Question: strcat函数

其实我的也正常输出了，但是随后 exe终止了，可见还是有问题了。vc6飘过。

引用 6 楼 zpxly 的回复:[quote=引用 5 楼 handoudouhao 的回复:] s[4]是5没有问题，但是没有是s[4]这个元素，换句话说结果是123456\0,前4个元素是使用数组s的存储空间后三个用的是s[3]后面紧挨着的三个存储单元，可是这三个并没有分配给数组s，这是有风险的，c不检查不提示，这是一缺陷，但是使用者必须注意，可能产生未知错误。 这个解释可以接受,这就把问题留给我们自己了[/quote]受用了

引用 2 楼 zpxly 的回复:[quote=引用 1 楼 handoudouhao 的回复:] C是不做越界检查的，所以还是运行，但不是正常运行，有可能出错，因为使用了未分配的内存。另外，你的函数返回值没有意义了，请lz仔细看一下。 是标准c不做越界检查吗?这里是数组越界了也不检查?例如:我putchar(s[4])是5,这也不检查? 返回值只是附带的,没有用它[/quote]  putchar需要一个int型，你给他一个整形，你真好，正好满足我的要求，我可不管你存的啥玩意，也不管是不是你的！我照样输出，无非是个乱码，仅此而已！ 测试代码很简单  int main(void) { 	int s[1] = {0}; 	putchar(s[1]); 	return 0; }

c哲学：程序员为自己的行为负责

C语言数组越界，这是程序员的责任，不是语言本身责任，你也不要转移责任到编译器等等其他身上！ 无数漏洞都发生在越界上，也是黑客攻击最喜欢的方式之一！

引用 7 楼 handoudouhao 的回复:“返回值只是附带的,没有用它 ”这句我不是很明白，返回值没有用可以设置void类型，或者不写也行 我的意思是这个返回值其实应该要,但是我的测试程序没有用它,您是个严谨的人

引用 5 楼 handoudouhao 的回复:s[4]是5没有问题，但是没有是s[4]这个元素，换句话说结果是123456\0,前4个元素是使用数组s的存储空间后三个用的是s[3]后面紧挨着的三个存储单元，可是这三个并没有分配给数组s，这是有风险的，c不检查不提示，这是一缺陷，但是使用者必须注意，可能产生未知错误。 这个解释可以接受,这就把问题留给我们自己了

引用 3 楼 user-5 的回复:我这用vc 6.0最后会内存报错啊  如果我改成分配在堆上就没问题  分配在栈上（楼主）为什么我的就会报错呢。是编译器或电脑原因么。 我用的是gcc,等待大神来指点

我这用vc 6.0最后会内存报错啊  如果我改成分配在堆上就没问题 void main() {     char s[4] = "123"; 	char t[4] = "456"; 	char *s1=(char *)malloc(sizeof(char)); 	char *t1=(char *)malloc(sizeof(char)); 	strcpy(s1,s); 	strcpy(t1,t);          Strcat(s1, t1);      printf("%s\n", s1);   }  分配在栈上（楼主）为什么我的就会报错呢。是编译器或电脑原因么。

引用 1 楼 handoudouhao 的回复:C是不做越界检查的，所以还是运行，但不是正常运行，有可能出错，因为使用了未分配的内存。另外，你的函数返回值没有意义了，请lz仔细看一下。 是标准c不做越界检查吗?这里是数组越界了也不检查?例如:我putchar(s[4])是5,这也不检查? 返回值只是附带的,没有用它


Question: 指向结构体数组元素的指针

引用 1 楼 user-1 的回复: //是这样的吧？ Stu st[4]={{"raul",22,'M'}, 	{"joe",23,'W'}, 	{"philip",21,'M'}, 	{"alan",20,'M'} 	}; 	Stu *p = st;  	while(p < st + 4) 		printf("%s\n",(p++)->name); 	printf("为什么单独一种可以全部输出。" 		"一起就不可以了？\n");  	for(p = st;p < st + 4;p++) 	{ 		printf("%s\t",(p)->name); 		printf("%d\t",(p)->age); 		printf("%c\n",(p)->gender); 		 	}    多谢我懂了！！谢谢！


Question: 为什么在两个文件中分别定义了两个相同的变量，却没有冲突，而有时候却有重复定义的冲突呢？

编译时各文件单独编译，跟其他文件无关，除非你用include把另一个文件的内容复制了过来 C语言规定变量定义时未赋值则为弱定义，如果和其它定义冲突可以视为声明

因为你用了C语言的一个垃圾特性。多用C++编译器来编译C代码吧。

编译的时候不做链接的事情，不知道有两个定义

没有赋初值的被当成变量声明处理了。


Question: 怎么用vc实现生产者和消费者演示程序

引用 5 楼 zhao4zhong1 的回复:参考 Microsoft SDK\samples\winbase\SharedMem\Consumer.Cpp Microsoft SDK\samples\winbase\SharedMem\Makefile Microsoft SDK\samples\winbase\SharedMem\Producer.Cpp Microsoft SDK\samples\winbase\SharedMem\Queue.h Microsoft SDK\samples\winbase\SharedMem\ReadMe.Txt Microsoft SDK\samples\winbase\SharedMem\Common.h 正解！

Windows 一般是，线程调度。 Unix ,linux 进程，线程调度都可以，因为他们是真正的多用户多任务系统。 Windows进程调度，要编写几个程序，在进程之间同步和通讯，不如线程同步好用。 多线程调试也比多进程简单。 多线程，只要编写一个程序，编译通过就可以测试了。

只有多核CPU才有实质上的并行，如果是单核的，那么宏观上是并行，微观上串行，是通过进程或者线程间不断的切换实现的！  创建线程，及其操作控制有相关函数供使用，自己查阅多线程技术文档

线程从创建 调度 到结束 不是一两个函数的事儿 你还是下载份源码参考吧

那用vc实现多线程并行执行需要什么函数呢

都是用线程的 进程并行执行。。。我是没见过的啦


Question: VC++6.0win32控制台程序PlaySound不能播放，跪求高手赐教！！！

19.wav文件是不是放在E:盘根目录？

经验证，是有声音输出。检查下自己电脑是不是 声音输出有问题

有喇叭吗？没静音吧。没音量调为接近0吧。听力正常吧。……

SND_LOOP | SND_FILENAME

引用 4 楼 vrace 的回复:因为你的程序已经退出了，声音自动关闭了 在 return 0; 之前加上 system("pause"); 试试还是不行

引用 2 楼 u010233287 的回复:引用  [quote=引用 1 楼 u011097438 的回复:] SND_LOOP | SND_FILENAME  还是不行[/quote] SND_LOOP 重复播放声音，必须与SND_ASYNC标志一块使用。

引用 引用 1 楼 u011097438 的回复:SND_LOOP | SND_FILENAME  还是不行


Question: c++6.0控制台程序，使用mcisendstring函数播放mp3文件，没有声音

用这个API播放就ok了： PlaySound("c:\\Sound.wav", NULL, SND_FILENAME | SND_ASYNC);

要先open吧。


Question: C + windos socket 什么地方导致程序无法发送 ？？

问题解决了。。我启用了双线程、、一个线程专门接收数据

调试下确认代码哪里开始出错的，socket是否建立成功，监听端口是否有效并处于监听状态

建立通信的Setp  //1、Server : socket()、bind()、listen() //2、Client : socket()、connect() //3、Server : accept()

Windows网络编程


Question: c语言类型长度由什么决定

类型长度的定义也可以说是编译器做的，因为编译器将遵循C标准将我们的程序翻译成汇编语言，然会将汇编翻译成计算机可以直接识别的二进制指令，汇编指令与二进制又是一一对应的，用汇编来分析比较容易理解。 在32位系统中：     至于int是32位，1字，CPU在单位时间能处理的长度；要知道CPU和寄存器打交道最广泛，而我们存储在内存中的数如 int a=5;我们把5这个数存在变量a所在的内存单元，那个CPU要获取这个5数据，则要将a这个内存单元的数据传送(赋值)给数据寄存器，CPU也就得到了这个变量，而这个数据寄存器就是32位的，所以1字也就32位，它能一次性保存这个数。     至于double是64位，CPU将用两个寄存器(32位)来分高低字来存储这个数，对应着汇编中的单位双字。

在汇编中有字节、字、双字。 字节（Byte）：铁定的是8位； 字（WORD）：如8086CPU是16位的，故1字为16位，而像Windows下32位系统1字为32位（即4字节)，同理 64位系统则一字为64位，即8字节； 双字(Double Word)：顾名思义即两个字（WORD），如8086CPU是16位，即1字*2=16(Bit)*2=32(Bit)，即4字节。  int 在C语言规范中定义为有符号的整数（有正负之分），一个整数占用一个字。对于不同的系统而言，一个字的所占的字节数也不同，如32位系统1字=4字节，所以我们说在32位系统中 int占4字节。同理：64位系统，int即占8字节。 （以上属自己结合汇编总结的，不正确的地方希望大家指点！）

编译器不同，或者系统上安装的编译器来确定的吧。

编译器

有标准长度，但一般会因编译器、系统不同而不同。

应该是编译器吧     还有其他的因素

int 一般就是CPU寄存器长度，当然也是由实现时决定。  16 Bits int 2字节 32 Bits int 4字节 64 Bits int 8字节  其他就是个不等式。 由编译器，实现时决定。  通常和操作系统有些关联，但是关系不大。

谢谢，学到不少！感谢大神！

C标准的规定是个“不等式”，个人觉得是为了跨平台。不会规定死类型多大。  The rank oflong long int shall be greater than the rank oflong int , which shall be greater than the rank of int , which shall be greater than the rank of short int , which shall be greater than the rank of signed char

对于数据类型的长度是有规范的，是被预先制定好的。CPU在对存储器进行读写的时候发现特定的数据类型那么就会根据这些预先制定好的规范（数据长度）来读写数据。楼主可以看看计算机组成原理。或者看8086汇编 里面介绍的很详细

可以依赖stdint.h中的可移植类型编程。

根据当时主流平台的架构，并具有前瞻性

类型长度的最小值由标准协会指定，如果硬件遵守标准的话那么实现的类型长度就不能小于规定值。

由类型的取值范围决定

可以多尝试几种语言，总结体会一下。 基本定义主要是基于经验总结。


Question: ACM 滴盐水问题

感觉用整数计算，用循环，比较准确。 效率并不低。

#include<stdio.h> #include<math.h> int main(){     int VUL,D,index,n;      scanf("%d%d",&VUL,&D)          if(VUL%D==0)             index=VUL/D;         else             index=VUL/D+1;          n=(sqrt((double)8*index)-1)/2;           printf("%d\n",index+n);       return 0; }

Output Limit Exceeded不是超时。。 还有，这题VUL和D应该用double吧

没人了吗？.....

scanf写在while里，真奇怪。。。


Question: B树建立代码调试问题

问题自己都知道了！单步调试，一个一个错误的改，慢慢来！ 调试程序也是基本技能！

引用 1 楼 user-1 的回复:问题自己都知道了！单步调试，一个一个错误的改，慢慢来！ 调试程序也是基本技能！  -------------------------------------------------------------------------------------------------- 求教一下遇到这些问题，该如何解决。。 就是VS有的时候定位在这里，错不一定出在这里，一行一行的看，总觉得没什么问题。。


Question: 我做了个游戏辅助以前键盘钩子可以用，现在不能用了求解啊！

这就是外挂与反外挂的对抗.  键盘钩子被禁用, 那是被检查看了撒, 你原理就是检查这个钩子有没有被安装,有没有加载非自己的dll.  你需要做更底层的技术.  如果你对外挂技术, 破解技术很有兴趣, 那么去"看雪" 多学习下吧. 上面也有很多大牛.


Question: 如果一个指针函数没有定义返回值，那么在调用完毕后会返回什么？

引用 4 楼 max_min_ 的回复:显然程序错了啊！create函数接口没有返回，也就是malloc的地址没有返回！ 在接口里堆内存不返回如何使用如何调用释放? 代码有问题！在哪里复制过来的啊？ 真的吗？为什么视频作者在程序中下段，添加监视又可以把二叉树里面的数据都显示出来..视频是郁金香视频，不是很有名

恩，程序有错：  CreateNode(v);  函数体少了个return语句。  返回值一般都是通过通用寄存器eax返回，也就是在退出函数时候，要返回的值会存储到eax中去，然后再赋值给主调函数中的变量。如果不使用，就简单的抛弃。  注意：最多只能返回一个值，因此一个寄存器就够了！如果想多个返回，可以使用传参数引用或者指针方式，或者返回多个值合成的结构体

这个问题问得好，以前还真没想过这个问题

引用 3 楼 a1385341 的回复:[quote=引用 2 楼 caozhy 的回复:] 什么“视频”误人子弟？敢不敢让作者曝光下。 其实代码是这样的： #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdarg.h>  #include <time.h> struct node   //定义一个node结构体 { 	long  data; //存放数据的一个或者多个项  	long count; 	struct node *pLeft;  //左孩子 指向一个二叉树 	struct node *pRight; //右孩子  指向一个二叉树 };  struct node * CreateNode(long value)   //创建根结点的函数 { 	struct node *p=malloc(sizeof(struct node));   //为p分配内存空间 	p->pLeft=p->pRight=NULL;   //将左右孩子都置空 	p->data=value;             //data赋值为传进来的value的值 	p->count=1; } struct node * AddNode(struct node * pNode,long v)   //创建“孩子”的函数 { 	//情况一 pNode==NULL 	if (pNode==NULL) 	{ 		return CreateNode(v); 	} 	// pNode->data=v 	if (pNode->data==v) 	{ 		pNode->count++; 		return pNode; 	} 	//v大于结点数据 	if (v>pNode->data) 	{ 		if (pNode->pRight==NULL) 		{ 			pNode->pRight=CreateNode(v); 			return pNode->pRight; 		}else return AddNode(pNode->pRight,v); //递归调用 	} 	//v小于 结点数据 	if (v<pNode->data) 	{ 		if (pNode->pLeft==NULL) 		{ 			pNode->pLeft=CreateNode(v); 			return pNode->pLeft; 		}else return AddNode(pNode->pLeft,v); //递归调用 	}  	return NULL; } int main(void) {	 	struct node*root; 	long v,i; 	printf("请输入二叉树根结点数值："); 	scanf("%d",&v); 	root=CreateNode(v);   //创建根结点 	for (i=0;i<=10;i++)   	{ 		AddNode(root,i);   //加入10个孩子  	}  	getchar(); 	return 0; } 在倒数第8行的位置不懂，root=CreateNode(v);   //创建根结点 ，不知道是我表达错了，还是程序错了..[/quote]  程序肯定错误了，用VC编译的话会认为没有返回值，错误。使用gcc编译倒是没有问题， 程序可能运行还是能显示值啥的，因为，虽然没有返回值，实际在createnode(v)后，还是有一个值赋给root，但这个值完全是不可知的，可能正确，可能不正确。而视频中的root值可能指向一个可以读写的内存，所以运行看上去似乎是正确的。

引用 2 楼 caozhy 的回复:什么“视频”误人子弟？敢不敢让作者曝光下。 其实代码是这样的： #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdarg.h>  #include <time.h> struct node   //定义一个node结构体 { 	long  data; //存放数据的一个或者多个项  	long count; 	struct node *pLeft;  //左孩子 指向一个二叉树 	struct node *pRight; //右孩子  指向一个二叉树 };  struct node * CreateNode(long value)   //创建根结点的函数 { 	struct node *p=malloc(sizeof(struct node));   //为p分配内存空间 	p->pLeft=p->pRight=NULL;   //将左右孩子都置空 	p->data=value;             //data赋值为传进来的value的值 	p->count=1; } struct node * AddNode(struct node * pNode,long v)   //创建“孩子”的函数 { 	//情况一 pNode==NULL 	if (pNode==NULL) 	{ 		return CreateNode(v); 	} 	// pNode->data=v 	if (pNode->data==v) 	{ 		pNode->count++; 		return pNode; 	} 	//v大于结点数据 	if (v>pNode->data) 	{ 		if (pNode->pRight==NULL) 		{ 			pNode->pRight=CreateNode(v); 			return pNode->pRight; 		}else return AddNode(pNode->pRight,v); //递归调用 	} 	//v小于 结点数据 	if (v<pNode->data) 	{ 		if (pNode->pLeft==NULL) 		{ 			pNode->pLeft=CreateNode(v); 			return pNode->pLeft; 		}else return AddNode(pNode->pLeft,v); //递归调用 	}  	return NULL; } int main(void) {	 	struct node*root; 	long v,i; 	printf("请输入二叉树根结点数值："); 	scanf("%d",&v); 	root=CreateNode(v);   //创建根结点 	for (i=0;i<=10;i++)   	{ 		AddNode(root,i);   //加入10个孩子  	}  	getchar(); 	return 0; } 在倒数第8行的位置不懂，root=CreateNode(v);   //创建根结点 ，不知道是我表达错了，还是程序错了..

什么“视频”误人子弟？敢不敢让作者曝光下。

返回值一般保存在eax寄存器中，所以如果没赋值返回值，也就是没对eax赋值，那么你读取eax即返回的值是不确定的。


Question: 一个小白问题，关于补码

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

补码本身的定义，就是取反（反码）+1 不过负数用补码表示，正数，0用原码表示，称作补码数，有时也简称补码。  带符号整型数据就是补码数。  原码就是2进制表示本身，无符号数就是原码表示的原码数。  反码就是对源码每位取反的结果，原码 |反码 =~0 ,即全1 ~~a =a  反码的反码是原码 C 语言的 ~ 就是求反码，-a 就是 a的补码， 不过对于补码整数，正数和0 就是它本身，即原码。 负数才是补码。 原码是相对反码，和补码来说的。  所以，补码，到底是什么意思，要看上下文的。 如果是编码的概念，补码就是反码加1.  如果是补码数的概念，就是正数，0 原码表示，负数补码表示的补码数。 PS： 这一般不是教材的问题，而是这个词汇本身就有两重含义。 如果只看到其中一个说法，或者问题很含糊，那么补码的的意义，很容易就把人弄糊涂了。

概念很重要

你要理解为什么会创造补码。 操作系统的书上应该有解释的。  网易公开课的 《编程范式》第2课有推导这个问题

引用 3 楼 u011636587 的回复:[quote=引用 2 楼 user-6 的回复:] 正数的补码是自己。 负数的补码是取反+1。  有了上述理论基础，那么正补码的原码还是补码，负补码可以取反+1获得原码。 有点明白了，我被教材坑了，教材给的例子是： （-43）原=1000000000101011 （-43）反=1111111111010100 （-43）补=1111111111010101 害的我还以为所有的补码都是反码+1呢！！！ 刚又看了一下教材，在哪一页最低部发现一句：对于正整数而言，其原码、反码、补码均相同。 原本不理解，现在明白了。 谢了版主。[/quote]  补码只是相对于负数存储来说的，可以google网上多搜点相关理论知识看看，自己再编码练习下 不要太相信教材！当然选一本好的教材也是很重要的！

引用 2 楼 user-6 的回复:正数的补码是自己。 负数的补码是取反+1。  有了上述理论基础，那么正补码的原码还是补码，负补码可以取反+1获得原码。 有点明白了，我被教材坑了，教材给的例子是： （-43）原=1000000000101011 （-43）反=1111111111010100 （-43）补=1111111111010101 害的我还以为所有的补码都是反码+1呢！！！ 刚又看了一下教材，在哪一页最低部发现一句：对于正整数而言，其原码、反码、补码均相同。 原本不理解，现在明白了。 谢了版主。

额，先占个沙发。坐等答案


Question: 【新手求助】c编译的相关问题

明白了，谢谢大家。

编译和运行 两个完全不同的动作！楼主好好理解下！

引用 2 楼 youaretwob 的回复:[quote=引用 1 楼 u012331924 的回复:] 1. 预编译好的那是库文件，不是头文件，头文件不参与编译，只是在被包含的地方展开。 2. 需不需要库那看你的程序了，如果用的是标准库的话一般是不需要的，但是要注意平台是否兼容(32bit和64bit，windows和unix)。如果是用的自己的库或者是特定平台才有的库，那当然要一起打包，但是也要考虑兼容性，或者说是可移植性。 那头文件里用到的函数是库文件的是吗？[/quote]   标准库的头文件里声明的函数的定义在库文件中

引用 1 楼 u012331924 的回复:1. 预编译好的那是库文件，不是头文件，头文件不参与编译，只是在被包含的地方展开。 2. 需不需要库那看你的程序了，如果用的是标准库的话一般是不需要的，但是要注意平台是否兼容(32bit和64bit，windows和unix)。如果是用的自己的库或者是特定平台才有的库，那当然要一起打包，但是也要考虑兼容性，或者说是可移植性。 那头文件里用到的函数是库文件的是吗？


Question: 大神帮帮忙！！！

引用 2 楼 u012339623 的回复:[quote=引用 1 楼 u012331924 的回复:] puchar()打印了一个'a'和一个'\n'，所以后面输出的"212"才显示在下一行，而不是跟在'a'后面。 可结果是212跟在a后面 结果 121 a 212 而不是我想的那样： 121 a  212[/quote]  putchar()不会自动换行

引用 6 楼 u012339623 的回复:[quote=引用 5 楼 u011636587 的回复:] 求，楼主能把各句的含义解释一下嘛。小白一只求各种知识，好多看不懂啊。char c1,c2   c1=getchar();   putchar(c1);  都不明白 getchar（）、putchar（）是单个输入输出函数[/quote] 恩，明白了。谢谢LZ指点

引用 5 楼 u011636587 的回复:求，楼主能把各句的含义解释一下嘛。小白一只求各种知识，好多看不懂啊。char c1,c2   c1=getchar();   putchar(c1);  都不明白 getchar（）、putchar（）是单个输入输出函数

引用 3 楼 user-4 的回复:lz 何不设断点 断点还没学

lz 何不设断点

引用 1 楼 u012331924 的回复:puchar()打印了一个'a'和一个'\n'，所以后面输出的"212"才显示在下一行，而不是跟在'a'后面。 可结果是212跟在a后面 结果 121 a 212 而不是我想的那样： 121 a  212


Question: 多项式乘法的链表实现，求优化。

超时的话，估计有成千上百的项次，每次插入都是从头搜寻位置效率就不行了，既然数据是升序的，第二层循环时指数都是越来愈大，所以pre = head3;这句挪动到第一层循环里，类似归并算法。还有<0,0>的节点就不要了吧，分支代码就精简一些，只要打印的时候判断一下做适当输出即可...

1 = 1 x^0 ==>1,0    x =1x     ==> 1,1  + a x = a x => a,1 - a x = -a x ==> -a,1 x2 = 1x2     ==> 1,2 -x2 =-1 x2   ===> -1,2 解析字符串表示的多项式 这里有几个问题要考虑好 1）无系数只有未知数，系数为1 2）系数的符号      2.1）不带符号为正号    2.2）带+， 为正号，    2.3) 带-，为负号  3）无指数      指数为1 4）无未知数==>常量， 值为常量，指数为 0 其他都很简单。

可以借用多项式乘法电路实现，复杂度会降低一些 其中a，b序列串分别是两个多项式的系数。  你可以在采集两个多项式系数的时候生成对应的系数序列（比如初始化为0000，输入<3,2>即0300）

建议:  1 减小不必要的循环判断(考虑三目运算符)  2 减小嵌套循环(无法避免的话，次数少的嵌套循环次多的)  3 避免循环调用malloc函数，能分配完尽量一次分配完！


Question: 数三退一 报错 请各位指点 不胜感激

引用 5 楼 worldy 的回复:for(index=0;len>=1;index++) 估计是一个死循环，除非在循环体中，能 在for循环里： count++; if(count==3){count=0;a[index]=false;len--;} 这里每逢数到3，len就从最初的500递减一次，最后总会达到len=1的时候 那个。。让len小于1是为什么呢~

传说中的java，楼主还好没有发在C++版，否则被认为砸场地的。  》for(index=0;len>=1;index++)可以么？ 显示不能这样写啊，你这个循环永远不会结束。

for(index=0;len>=1;index++) 估计是一个死循环，除非在循环体中，能让len小于1

嗯 ~是啊 txt复制的 过来我看着也乱，， 下回换个方式复制

引用 2 楼 u012328381 的回复:菜鸟一只 多谢指点啦~其实我也是想多发几个地方能多点交流 嘿嘿  下次贴代码记得用代码格式，这没缩进看着难受。

菜鸟一只 多谢指点啦~其实我也是想多发几个地方能多点交流 嘿嘿


Question: C语言初学者编写一个控制台通讯录程序时关于信息存储的问题

用结构体把姓名，地址，电话放在一起，再用动态指针，想输入信息就向系统申请空间，存储输入进去的信息要用到文本操作，一般要用到“a+”这个格式，可以向你建立的文本中一直存放输入的信息，不会覆盖前面的，，，

同意楼上，对于小数据量的可以考虑Access数据库。

可以考虑用数据库

引用 1 楼 ylbhz 的回复:作业贴。。。 不是的好吧，要是作业我就直接求代码了

作业贴。。。

用sqlite数据库实现吧，了解些基本数据库操作就行了

使用链表吧。首先判断文件是否存在，第一次启动时(文件不存在)创建文件，以后每次启动程序时都从文件中读取数据到链表，退出程序时，把链表中的数据写入(覆盖)到文件中。 具体如何操作请参考这里：(学生信息管理系统)http://www.cnblogs.com/Anker/archive/2013/05/06/3063436.html

同推荐SQLite

学习使用数据库以及数据库编程，可以从sqlite入手，比较适合你的小应用。


Question: Ubuntu下运行该程序出现段错误，求解释

a[i+1][j+1] = a[i][j] + a[i][j+1]; 你这程序都越界了，数组a[11][11];     用的时候要到10的

数组越界了！ a[i+1][j+1]这个循环会越界引起地址非法访问的，也就是段错误的！


Question: 稀疏矩阵的程序求助

引用 5 楼 user-1 的回复:27行 TMatrix *M = NULL; 改成 TMatrix *M = new TMatrix;明白了...是我又脑抽了  没有给分配空间

引用 3 楼 user-1 的回复:意思是，试图取地址0处的数据那我程序应该怎么改才能让他正常运行呢

意思是，试图取地址0处的数据

表示本人菜鸟 不懂汇编  所以那个汇编指令也没有看懂

真心求解...快压垮我的心里防线了


Question: 输入一个含有8个数字的数组,判断有没有可能把这8个数字分别放到正方体的8个顶点上，使得正方体上三组相对的面上的4个顶点的和相等。

晕，是临时变量c，我CSDN不能编辑帖子，我擦

不好意思，上面的check()中的c忘了重置为0 #include <stdafx.h> #include <stdio.h> void swap(int &a, int &b)//交换连个元素 { 	int tem = a; 	a = b; 	b = tem; } int check(int array[]) { 	/* 	对正方体八个顶点编号(0-7)，对应于数组的8个元素 	构成数学模型，我这里为组成的面为 	0 1 2 3 	4 5 6 7 	0 1 4 5 	2 3 6 7 	1 2 4 7 	0 3 5 6 	*/ 	int offset[6][4] =  	{ 		{0, 1, 2, 3}, 		{4, 5, 6, 7}, 		{0, 1, 4, 5}, 		{2, 3, 6, 7}, 		{1, 2, 4, 7}, 		{0, 3, 5, 6} 	}; 	int c = 0, t = 0; 	for(int i = 0;i < 4;i ++) //计算出第一个面的总和作为参考 		c += array[offset[0][i]]; 	for(i = 1;i < 6;i ++) //从第二面开始 	{ 		for(int j = 0;j < 4;j ++) //计算面上顶点上的数的总和 			t += array[offset[i][j]]; 		if(t != c) //有任何的面不等于c都视为失败 			return 0;  		c = 0; 	} 			 	return 1; }  void fullarray(int array[], int first, int length) //全排列选择出所有顶点组合 { 	if(first == length) 	{ 		int point[8] = {0}; //8个顶点 		for(int i = 0; i <= length; i++) 		{ 			printf("%d ", array[i]); 			point[i] = array[i]; 		} 		if(check(point)) 			printf("此组合可以成功。\r\n"); 		else 			printf("\r\n"); 	} 	else 	{ 		for(int i = first; i <= length; i++) 		{ 			swap(array[first], array[i]); 			fullarray(array, first+1, length); 			swap(array[first], array[i]); 		} 	} }  int main(int argc, char* argv[]) {  	int a[] = {2, 3, 7, 9, 11, 0, 2, 6}; //8个顶点上的数字 	fullarray(a, 0, 7); 	return 0; }

#include <stdafx.h> #include <stdio.h> void swap(int &a, int &b)//交换连个元素 { 	int tem = a; 	a = b; 	b = tem; } int check(int array[]) { 	/* 	对正方体八个顶点编号(0-7)，对应于数组的8个元素 	构成数学模型，我这里为组成的面为 	0 1 2 3 	4 5 6 7 	0 1 4 5 	2 3 6 7 	1 2 4 7 	0 3 5 6 	*/ 	int offset[6][4] =  	{ 		{0, 1, 2, 3}, 		{4, 5, 6, 7}, 		{0, 1, 4, 5}, 		{2, 3, 6, 7}, 		{1, 2, 4, 7}, 		{0, 3, 5, 6} 	}; 	int c = 0, t = 0; 	for(int i = 0;i < 4;i ++) //计算出第一个面的总和作为参考 		c += array[offset[0][i]]; 	for(i = 1;i < 6;i ++) //从第二面开始 	{ 		for(int j = 0;j < 4;j ++) //计算面上顶点上的数的总和 			t += array[offset[i][j]]; 		if(t != c) //有任何的面不等于c都视为失败 			return 0;  	} 			 	return 1; }  void fullarray(int array[], int first, int length) //全排列选择出所有顶点组合 { 	if(first == length) 	{ 		int point[8] = {0}; //8个顶点 		for(int i = 0; i <= length; i++) 		{ 			printf("%d ", array[i]); 			point[i] = array[i]; 		} 		if(check(point)) 			printf("此组合可以成功。\r\n"); 		else 			printf("\r\n"); 	} 	else 	{ 		for(int i = first; i <= length; i++) 		{ 			swap(array[first], array[i]); 			fullarray(array, first+1, length); 			swap(array[first], array[i]); 		} 	} }  int main(int argc, char* argv[]) {  	int a[] = {2, 3, 7, 9, 11, 0, 2, 6}; //8个顶点上的数字 	fullarray(a, 0, 7); 	return 0; }  不知道对不对，不过描述的算法应该没问题。楼下轻喷。

帮ylbhz断帖。

上面还少说了一步，要加上初始化每个面上的顶点序号。 1种编号方式如下： 前后两个面的顶点分别是 1 2 3 4 ，5 6 7 8         5          6 1         2      7          8                   3         4

1）给顶点，面编号， 2）求相对面，写成函数 3）枚举三个面，可以得到一种，安排方式的结果。 4）对顶点全排列，再按照上面的方式处理，即可得到所有安排的结果。 5）遍历该排列，即可得到结果。

引用 2 楼 a1232345 的回复:[quote=引用 1 楼 u011636587 的回复:] 沙发，同求，随时关注本帖，学习一切可学习的知识 还以为是回答了。。。[/quote] 别激动，我们两个聊着聊着就有人回答了

引用 1 楼 u011636587 的回复:沙发，同求，随时关注本帖，学习一切可学习的知识 还以为是回答了。。。

沙发，同求，随时关注本帖，学习一切可学习的知识


Question: c-free使用自己安装的mingw 报错

return 0/*或其他任何int类型的表达式*/; 不谢

自己解决了，其实是编译环境没有设置好，主要是还混杂着c-free自己的编译环境。 我是看了http://www.programarts.com/cfree_ch/doc/help/UsingCF/CompilerSupport/MinGW/MinGW2.htm这个文章来的灵感。 我是这样设置的     这个是以前错误的设置，里面夹杂着c-free的编译环境

汗，木有沙发了


Question: 同样的程序在codeblock  cfree5.0编译结果不同，为什么？

引用 3 楼 u012331924 的回复:用的什么编译器？ 你把这两句  typedef    struct   vertexnode    VertexNode; typedef   VertexNode   AdjList[MAXVEX];  放到结构体定义后面试试，前置声明去掉。  嗯，用codeblock 12.11编译一直报错，用cfree5.0编译就没问题，所以问一下！

引用 2 楼 user-2 的回复:文件名  creatadjlist.c 改 creatadjlist.cpp让mingw用g++编译。  或者手工用g++编译。  好的，我试试！

没人来，只能自顶一个了！


Question: while的一点小疑问

有区别。。一个包括等于零，另一个不包括！

有区别，楼上正解！

我如此愚蠢，这是我发的？浪费大家时间，只是有那么一个计算天数的程序，理解了好久，最后转糊涂了，多谢各位

楼上都正解~

楼上都正解~

while(sum>=0)在sum=0的时候也能执行循环体的内容 而前者不能

sum = 0的时候，一个不进入循环，一个进入。。。


Question: 安装 ubuntn10.04版本的32位

我怎么感觉你还是用Ghost XP比较合适

应该是你设置的登陆口令啊

自己的登录密码吧

口令应该是设置的自己账户的密码吧？ 是不是有一个输入，一个确认输入？

应该是自己设置的登陆用户名和密码吧

提醒楼主，这是c语言板块。。。


Question: 使用list_for_each_entry_safe遍历删除结点时出现segmentation default

user_del使用错误吧 我记得应该是这样用的：list_del(&ctrl_user->list);

引用 2 楼 user-4 的回复:内存出错了！ 查查是不是哪里非法访问内存空间，例如 越界，可读不可改这些！ 谢谢您的回答，按照您的思路，我在list_for_each_entry的下一个对ctrl_user判空，发现，它果然为空，存在对空指针的使用，但是我 malloc+memset后，再在同样位置对ctrl_user判空，发现他还是为空，问题依然存在，不过还是谢谢您的回答，总算是知道哪里出了问题。

引用 4 楼 dizuo 的回复:list_for_each_entry_safe((ctrl_user), (n), &index_tbl[i], list) {                user_del(ctrl_user); 这两个函数怎么定义的，目测是函数传参问题哦，list_for_each_entry_safe 函数内容如果申请和初始化ctrl_user指针，应该传二级指针。 谢谢您的回答，list_for_each_entry_safe(pos,n,head,list)是linux内核中，是一个宏，用于遍历链表来删除链表上的某个结点。这里的ctrl_user是用来暂存结点，然后进行删除的。其实，这个segmentation fault在进行单元测试打桩时遇到的，现在还没解决，我想可能是因为head指向了一段未知的内存（由于是单元测试，没有实际数据），所以就出现了段错误，不过先照着您给的建议试试去，谢谢您的回答。

此错误一般由非法读写内存导致，例如：   指针初始化 数组越界

内存出错了！ 查查是不是哪里非法访问内存空间，例如 越界，可读不可改这些！

还没大神来指导指导么？自己顶一个！


Question: 求助：某司的一道笔试题（关于编译时确定哪些变量内存地址）

A，B 存储在，数据区。所以编译链接后，就确定了地址，最多延迟到程序加载的时候。（广义的编译期确定） C 函数局部变量，编译时确定，分配的相对位置，函数调用时，实际分配内存。 D 不确定，因为宏只是会做个替换而已。 E 比较含糊，想坑人还是想蒙人。 大概只有C++ 类(类型)静态变量，才用作用域限定符定义吧！！  函数中带作用域方式声明的变量 ，有谁用过？  感觉还是 A，B

引用 5 楼 zhouchichi203 的回复:引用 3 楼 wangyaninglm 的回复:我猜ab。。。猜的我也是这么猜的，可是到底是什么呢 +1

引用 9 楼 z542858367 的回复:引用 7 楼 zhouchichi203 的回复:引用 6 楼 z542858367 的回复:我会选AB。理由呢AB都是全局变量存放在静态存储区，在程序开始运行时就已经分配了空间，而局部变量在程序运行到声明代码时才分配空间。c选项属于自动变量，存储在动态存储区，D选项：宏，预处理在程序编译之前就不存在了，不占用内存空间，仅仅做一个替换功能。E选项，无论以何种方式申明，只要不是静态局部变量，它就属于动态存储区。

引用 8 楼 shn521 的回复:A.声明时初始化的全局变量 B.声明时未初始化的全局变量 在静态存储区嗯，是的~

A.声明时初始化的全局变量 B.声明时未初始化的全局变量 在静态存储区

引用 6 楼 z542858367 的回复:我会选AB。理由呢

我会选AB。

我猜AB。。。

我猜ab。。。猜的

难道是ADE

ABE吧


Question: 下面的i--着实不懂。。

多谢各位了。。。恩，我懂了，就是多加了一，减去一得到原来值吧。谢谢啦

引用 1 楼 user-3 的回复:a[i++]表示a数组付完值之后i加1，故每次循环一次i作为a数组的角标都会往后移一位，所以最后一次执行循环的时候，a数组的角标是多一位的，也就是数组的最后一位并未赋值，所以要i--吧……说实话程序未看懂……  ++

楼上正解，不过程序很简单啊、。。。


Question: 这程序哪有错？感觉。。。没错啊！

引用 23 楼 hnhnanhai 的回复:我的想法是这样 #include <stdio.h>  //一人的年龄的三次方有四位数，四次方有六位数，且这十位数刚好包括从0-9。二次方有三位数。求年龄  void main() {     int  x,y,age;     int  a[10]; 	bool m = false;  	for (age = 10; age < 22; age++) 	{ 		x = age * age * age; 		for (int i = 0 ; i < 4 ; i++) 		{ 		   a[i] = x % 10; 		   x /= 10; 		} 		y = age * age * age * age; 		for (; i < 10; i++) 		{ 			a[i] = y % 10; 			y /= 10; 		}  		for (i = 0; i < 9; i++) 		{ 			for (int j = i+1; j < 10; j++) 			{ 				if (a[i] != a[j]) 				{ 					m = true; 				} 				else 				{ 					m = false; 					break; 				} 			} 			if (!m) 			{ 				break; 			} 		} 		if (m) 		{ 			printf("%d\n",age); 		} 	}  } 抓住两两不相等，但是你干嘛不ture，要false啊。。。非常人。。

引用 14 楼 my_live_123 的回复:bug1,你的平方条件还没有用噻，问题条件都没有用完  bug2:这个逻辑错误，试想一部分相等，并不成立，你却输出结果了   for(i = 0 ; i <= 9 ; i++)                 {                      if (a[i] == s[i])                    printf("这位同学的年龄是%d\n",age);                    break;                  }            建议：你可以设置a[0]-a[9]值为1，然后算的各位数字为索引i，设置a[i]=0，计算过程中遇到a[j]=0，说明此j数字已经出现，就不必往下继续计算，结束此次循环。否则，计算完毕必定是结果，因为此次循环共产生10个数字，此次循环能执行到底，说明每个数字出现且仅出现一次。跳出循环输出结果结论。此外，未能执行到底的循环，记得把a[0]-a[9]还原到初始1的状态。  这样就不必排序，也能缩短计算时间（因为不满足的，中间就会停止本次循环）而且答案是惟一的，找到即可  其实我有一一种更加投机的想法：把这十个数相加，如果等于 1+2+。。。+9 ，则输出。这样子，岂不是更快？ 代码如下：结果还是18~~  #include<stdio.h> #include<math.h>  int main(void) {     int age = 18;     int age3,age4,result=0,temp = 0;     int  a[10],i,t,j;     int  s[10]={0,1,2,3,4,5,6,7,8,9}; 	do{ 		age3 = pow(age,3); 		for(i = 0 ; i <= 3 ; i++) 		{ 			a[i] = age3 % 10; 			age3 /= 10; 		} 		age4 = pow(age,4); 		 		for(i = 4 ; i <= 9 ; i++) 		{ 			a[i] = age4 % 10; 			age4 /= 10; 		} 		for(int i=0; i <10 ; i++) 		{ 			temp += i ; 			result +=a[i]; 		} 		if(temp == result) 		{ 			printf("这位同学的年龄是%d\n",age);		 		     break ; 		}  		age++; 	}     while(age <= 21);        return 0 ; }

引用 14 楼 my_live_123 的回复:bug1,你的平方条件还没有用噻，问题条件都没有用完  bug2:这个逻辑错误，试想一部分相等，并不成立，你却输出结果了   for(i = 0 ; i <= 9 ; i++)                 {                      if (a[i] == s[i])                    printf("这位同学的年龄是%d\n",age);                    break;                  }            建议：你可以设置a[0]-a[9]值为1，然后算的各位数字为索引i，设置a[i]=0，计算过程中遇到a[j]=0，说明此j数字已经出现，就不必往下继续计算，结束此次循环。否则，计算完毕必定是结果，因为此次循环共产生10个数字，此次循环能执行到底，说明每个数字出现且仅出现一次。跳出循环输出结果结论。此外，未能执行到底的循环，记得把a[0]-a[9]还原到初始1的状态。  这样就不必排序，也能缩短计算时间（因为不满足的，中间就会停止本次循环）而且答案是惟一的，找到即可  在理。估计他只是想使用冒泡算法吧

for(i = 0 ; i <= 9 ; i++) 				{   					if (a[i] != s[i]) 					  break; 					else if (i==9) 					   printf("这位同学的年龄是%d\n",age);                 }              你是if语句没有判断对，你进行了排序，应该是 0-9这10个数字都匹配才能确定结果。  这位同学的年龄是18 Press any key to continue

引用 12 楼 zhouchichi203 的回复:[quote=引用 10 楼 abc594986308 的回复:] [quote=引用 5 楼 zhouchichi203 的回复:] 试试：将   for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i])                   printf("这位同学的年龄是%d\n",age);                   break;                 }              改为： for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i]) 					  ; 				  else                   break;                 }  		 			   if(i==10) 				   printf("这位同学的年龄是%d\n",age); 空语句的引用以及下面if（i == 10）的判断，没明白。注释下，谢谢啦[/quote]//for循环判断a数组中是否含有0-9  for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i])//若相等则什么也不做 					  ; 				  else             //不等则跳出for循环                   break;                 }  //若i==10，则表明上面的for循环运行到最后都没有跳出，说明a数组中含有数字0-9，表明这个age是我们要找的，打印出来 			   if(i==10) 				   printf("这位同学的年龄是%d\n",age);[/quote] 数组默认指向下一位么？定义时是a[10],i==10,就是这个数组指向了下一位了

引用 10 楼 abc594986308 的回复:[quote=引用 5 楼 zhouchichi203 的回复:] 试试：将   for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i])                   printf("这位同学的年龄是%d\n",age);                   break;                 }              改为： for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i]) 					  ; 				  else                   break;                 }  		 			   if(i==10) 				   printf("这位同学的年龄是%d\n",age); 空语句的引用以及下面if（i == 10）的判断，没明白。注释下，谢谢啦[/quote]//for循环判断a数组中是否含有0-9  for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i])//若相等则什么也不做 					  ; 				  else             //不等则跳出for循环                   break;                 }  //若i==10，则表明上面的for循环运行到最后都没有跳出，说明a数组中含有数字0-9，表明这个age是我们要找的，打印出来 			   if(i==10) 				   printf("这位同学的年龄是%d\n",age);

引用 21 楼 lc10915819 的回复:[quote=引用 20 楼 my_live_123 的回复:] [quote=引用 17 楼 lc10915819 的回复:]   [quote=引用 14 楼 my_live_123 的回复:] bug1,你的平方条件还没有用噻，问题条件都没有用完  bug2:这个逻辑错误，试想一部分相等，并不成立，你却输出结果了   for(i = 0 ; i <= 9 ; i++)                 {                      if (a[i] == s[i])                    printf("这位同学的年龄是%d\n",age);                    break;                  }            建议：你可以设置a[0]-a[9]值为1，然后算的各位数字为索引i，设置a[i]=0，计算过程中遇到a[j]=0，说明此j数字已经出现，就不必往下继续计算，结束此次循环。否则，计算完毕必定是结果，因为此次循环共产生10个数字，此次循环能执行到底，说明每个数字出现且仅出现一次。跳出循环输出结果结论。此外，未能执行到底的循环，记得把a[0]-a[9]还原到初始1的状态。  这样就不必排序，也能缩短计算时间（因为不满足的，中间就会停止本次循环）而且答案是惟一的，找到即可  其实我有一一种更加投机的想法：把这十个数相加，如果等于 1+2+。。。+9 ，则输出。这样子，岂不是更快？ 代码如下：结果还是18~~  #include<stdio.h> #include<math.h>  int main(void) {     int age = 18;     int age3,age4,result=0,temp = 0;     int  a[10],i,t,j;     int  s[10]={0,1,2,3,4,5,6,7,8,9}; 	do{ 		age3 = pow(age,3); 		for(i = 0 ; i <= 3 ; i++) 		{ 			a[i] = age3 % 10; 			age3 /= 10; 		} 		age4 = pow(age,4); 		 		for(i = 4 ; i <= 9 ; i++) 		{ 			a[i] = age4 % 10; 			age4 /= 10; 		} 		for(int i=0; i <10 ; i++) 		{ 			temp += i ; 			result +=a[i]; 		} 		if(temp == result) 		{ 			printf("这位同学的年龄是%d\n",age);		 		     break ; 		}  		age++; 	}     while(age <= 21);        return 0 ; } [/quote]  针对本题，你这种方案不可行 18:5832 104976 =45 19：6859 130321 = 38 20：8000 160000 = 32 21：9261 194481 = 45  如果问题拓展一下，也存在潜在的bug 1+...+9=45可以有很多种分解方案，不是嘛?比如1+2+(1+2)+4+...+9=2+2+2+4+...+9=45只要保证是10个数字就行 [/quote]】  其实还在于对待该问题的思路上，我只是突发奇想，想到的。其实，这题多变~谢谢你的批评哦[/quote]  恩，很好噻。有想法要多多交流。批评谈不上，属于讨论的结果！

引用 20 楼 my_live_123 的回复:[quote=引用 17 楼 lc10915819 的回复:]   [quote=引用 14 楼 my_live_123 的回复:] bug1,你的平方条件还没有用噻，问题条件都没有用完  bug2:这个逻辑错误，试想一部分相等，并不成立，你却输出结果了   for(i = 0 ; i <= 9 ; i++)                 {                      if (a[i] == s[i])                    printf("这位同学的年龄是%d\n",age);                    break;                  }            建议：你可以设置a[0]-a[9]值为1，然后算的各位数字为索引i，设置a[i]=0，计算过程中遇到a[j]=0，说明此j数字已经出现，就不必往下继续计算，结束此次循环。否则，计算完毕必定是结果，因为此次循环共产生10个数字，此次循环能执行到底，说明每个数字出现且仅出现一次。跳出循环输出结果结论。此外，未能执行到底的循环，记得把a[0]-a[9]还原到初始1的状态。  这样就不必排序，也能缩短计算时间（因为不满足的，中间就会停止本次循环）而且答案是惟一的，找到即可  其实我有一一种更加投机的想法：把这十个数相加，如果等于 1+2+。。。+9 ，则输出。这样子，岂不是更快？ 代码如下：结果还是18~~  #include<stdio.h> #include<math.h>  int main(void) {     int age = 18;     int age3,age4,result=0,temp = 0;     int  a[10],i,t,j;     int  s[10]={0,1,2,3,4,5,6,7,8,9}; 	do{ 		age3 = pow(age,3); 		for(i = 0 ; i <= 3 ; i++) 		{ 			a[i] = age3 % 10; 			age3 /= 10; 		} 		age4 = pow(age,4); 		 		for(i = 4 ; i <= 9 ; i++) 		{ 			a[i] = age4 % 10; 			age4 /= 10; 		} 		for(int i=0; i <10 ; i++) 		{ 			temp += i ; 			result +=a[i]; 		} 		if(temp == result) 		{ 			printf("这位同学的年龄是%d\n",age);		 		     break ; 		}  		age++; 	}     while(age <= 21);        return 0 ; } [/quote]  针对本题，你这种方案不可行 18:5832 104976 =45 19：6859 130321 = 38 20：8000 160000 = 32 21：9261 194481 = 45  如果问题拓展一下，也存在潜在的bug 1+...+9=45可以有很多种分解方案，不是嘛?比如1+2+(1+2)+4+...+9=2+2+2+4+...+9=45只要保证是10个数字就行 [/quote]】  其实还在于对待该问题的思路上，我只是突发奇想，想到的。其实，这题多变~谢谢你的批评哦

引用 17 楼 lc10915819 的回复:  [quote=引用 14 楼 my_live_123 的回复:] bug1,你的平方条件还没有用噻，问题条件都没有用完  bug2:这个逻辑错误，试想一部分相等，并不成立，你却输出结果了   for(i = 0 ; i <= 9 ; i++)                 {                      if (a[i] == s[i])                    printf("这位同学的年龄是%d\n",age);                    break;                  }            建议：你可以设置a[0]-a[9]值为1，然后算的各位数字为索引i，设置a[i]=0，计算过程中遇到a[j]=0，说明此j数字已经出现，就不必往下继续计算，结束此次循环。否则，计算完毕必定是结果，因为此次循环共产生10个数字，此次循环能执行到底，说明每个数字出现且仅出现一次。跳出循环输出结果结论。此外，未能执行到底的循环，记得把a[0]-a[9]还原到初始1的状态。  这样就不必排序，也能缩短计算时间（因为不满足的，中间就会停止本次循环）而且答案是惟一的，找到即可  其实我有一一种更加投机的想法：把这十个数相加，如果等于 1+2+。。。+9 ，则输出。这样子，岂不是更快？ 代码如下：结果还是18~~  #include<stdio.h> #include<math.h>  int main(void) {     int age = 18;     int age3,age4,result=0,temp = 0;     int  a[10],i,t,j;     int  s[10]={0,1,2,3,4,5,6,7,8,9}; 	do{ 		age3 = pow(age,3); 		for(i = 0 ; i <= 3 ; i++) 		{ 			a[i] = age3 % 10; 			age3 /= 10; 		} 		age4 = pow(age,4); 		 		for(i = 4 ; i <= 9 ; i++) 		{ 			a[i] = age4 % 10; 			age4 /= 10; 		} 		for(int i=0; i <10 ; i++) 		{ 			temp += i ; 			result +=a[i]; 		} 		if(temp == result) 		{ 			printf("这位同学的年龄是%d\n",age);		 		     break ; 		}  		age++; 	}     while(age <= 21);        return 0 ; } [/quote]  针对本题，你这种方案不可行 18:5832 104976 =45 19：6859 130321 = 38 20：8000 160000 = 32 21：9261 194481 = 45  如果问题拓展一下，也存在潜在的bug 1+...+9=45可以有很多种分解方案，不是嘛?比如1+2+(1+2)+4+...+9=2+2+2+4+...+9=45只要保证是10个数字就行

#include<stdio.h> int main(void) {     int  age = 10;     int  age2;     int  age3;     int  age4;     int  a[10]; 	int  i=0, n2=0,n3=0,n4=0;   	do{  		for (i=0;i<10;i++) 		{ 			a[i] = -1; 		} 		printf("%6d  ",age); 		age2 = age * age; 		age3 = age * age *age; 		age4 = age * age *age *age; 		n2 = age2/100; 		n3 = age3/1000; 		n4 = age4/100000; 	  		if (n4 <= 0) 		{ 			printf("age4=%6d is to small!\n",age4); 			age++; 			continue; 		} 		else if (n2>9) 		{ 			printf("age2=%6d is to big!\n",age4); 			break; 		}  		printf("age2 = %6d  age3 = %6d  age4=%6d  ",age2,age3,age4); 		age3 = age * age * age ; 	   		while (age3) 		{ 			int k= age3 % 10; 			age3 /= 10; 			if(a[k] !=-1) 			{ 				n3 = -1; 				break; 			} 			else 			{				 				a[k] = k; 			} 		}   		if(n3 == -1) 		{ 			printf("age3 is reshow!\n"); 			age++; 			continue; 		}     		while (age4) 		{ 			int w = age4%10; 			age4 /= 10; 			if (a[w] != -1) 			{ 				n4 = -1; 				break; 			} 			else 				a[w] = w; 		} 			  		if (n4 == -1) 		{ 			printf("age4 is reshow!\n"); 			age++; 			continue; 		} 		printf("这位同学的年龄是%d\n",age); 		break; 	}     while(1);        return age; }

引用 17 楼 lc10915819 的回复:  [quote=引用 14 楼 my_live_123 的回复:] bug1,你的平方条件还没有用噻，问题条件都没有用完  bug2:这个逻辑错误，试想一部分相等，并不成立，你却输出结果了   for(i = 0 ; i <= 9 ; i++)                 {                      if (a[i] == s[i])                    printf("这位同学的年龄是%d\n",age);                    break;                  }            建议：你可以设置a[0]-a[9]值为1，然后算的各位数字为索引i，设置a[i]=0，计算过程中遇到a[j]=0，说明此j数字已经出现，就不必往下继续计算，结束此次循环。否则，计算完毕必定是结果，因为此次循环共产生10个数字，此次循环能执行到底，说明每个数字出现且仅出现一次。跳出循环输出结果结论。此外，未能执行到底的循环，记得把a[0]-a[9]还原到初始1的状态。  这样就不必排序，也能缩短计算时间（因为不满足的，中间就会停止本次循环）而且答案是惟一的，找到即可  其实我有一一种更加投机的想法：把这十个数相加，如果等于 1+2+。。。+9 ，则输出。这样子，岂不是更快？ 代码如下：结果还是18~~  #include<stdio.h> #include<math.h>  int main(void) {     int age = 18;     int age3,age4,result=0,temp = 0;     int  a[10],i,t,j;     int  s[10]={0,1,2,3,4,5,6,7,8,9}; 	do{ 		age3 = pow(age,3); 		for(i = 0 ; i <= 3 ; i++) 		{ 			a[i] = age3 % 10; 			age3 /= 10; 		} 		age4 = pow(age,4); 		 		for(i = 4 ; i <= 9 ; i++) 		{ 			a[i] = age4 % 10; 			age4 /= 10; 		} 		for(int i=0; i <10 ; i++) 		{ 			temp += i ; 			result +=a[i]; 		} 		if(temp == result) 		{ 			printf("这位同学的年龄是%d\n",age);		 		     break ; 		}  		age++; 	}     while(age <= 21);        return 0 ; } [/quote] 是满足0-9含有这10个数字，不是和相等。如果是两个2，那也等于1+3啊。条件不久不满足了么？

简化一下； for(i=0;i<=9;i++) {   if(a[i]!=i) break; } if(i==10) printf("..............");

引用 5 楼 zhouchichi203 的回复:试试：将   for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i])                   printf("这位同学的年龄是%d\n",age);                   break;                 }              改为： for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i]) 					  ; 				  else                   break;                 }  		 			   if(i==10) 				   printf("这位同学的年龄是%d\n",age); 最后判断应该是这样，if(i==10)                     {                          printf("这位同学的年龄是%d\n",age);                           break;                      } 输出结果后，最后要跳出do-while循环，用break

引用 5 楼 zhouchichi203 的回复:试试：将   for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i])                   printf("这位同学的年龄是%d\n",age);                   break;                 }              改为： for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i]) 					  ; 				  else                   break;                 }  		 			   if(i==10) 				   printf("这位同学的年龄是%d\n",age); 空语句的引用以及下面if（i == 10）的判断，没明白。注释下，谢谢啦

引用 5 楼 zhouchichi203 的回复:试试：将   for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i])                   printf("这位同学的年龄是%d\n",age);                   break;                 }              改为： for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i]) 					  ; 				  else                   break;                 }  		 			   if(i==10) 				   printf("这位同学的年龄是%d\n",age); 求深层次的解释下。谢谢

引用 6 楼 u012259895 的回复:[quote=引用 5 楼 zhouchichi203 的回复:] 试试：将   for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i])                   printf("这位同学的年龄是%d\n",age);                   break;                 }              改为： for(i = 0 ; i <= 9 ; i++)                {                     if (a[i] == s[i]) 					  ; 				  else                   break;                 }  		 			   if(i==10) 				   printf("这位同学的年龄是%d\n",age); 最后判断应该是这样，if(i==10)                     {                          printf("这位同学的年龄是%d\n",age);                           break;                      } 输出结果后，最后要跳出do-while循环，用break[/quote]不用跳出吧，有可能有多解呢？

本题真的有正解吗？


Question: 解方程组

对于这种方程，迭代法是最简单的方法。 运气好指的不是随便猜个初值就正好收敛，而是指能存在一个或多个能收敛的初值。先把方程改写成 xi4= f(xi1,xi2,xi3),根据abcmk的值分析方程是否存在稳定点,如果没有，还需改写成别的形式，然后再选初值。 当然之前还应有一步，把公共部分提出来换元

引用 4 楼 lpcads 的回复:运气好的话，迭代法能解出来  四个未知数的迭代，是不是偶然性太大了呢。

引用 2 楼 user-2 的回复:用数值解法吧，需要知道极值点，和单调区域 需要求导数。  用数值解法里面的哪种算法呢？  其实就是求导数比较麻烦。  所以就想问问说，有没有不求导数可以把方程给解出来的。

运气好的话，迭代法能解出来

用数值解法吧，需要知道极值点，和单调区域 需要求导数。


Question: 我的发问：函数返回局部指针的问题

明白了，就是说该函数的指针变量ret是局部的，被分配在栈内存中， 而其指向的内存地址却非该函数局部的，因为是外面传递过来 O(∩_∩)O谢谢

指针变量定义在栈上，但是指针指向的内存就不一定咯。

引用 楼主 AILOONG 的回复: void * __cdecl memcpy (          void * dst,          const void * src,          size_t count          )  {          void * ret = dst; //ret这个指针变量是局部变量，但是指向的内容不是局部变量。         while (count--) {                  *(char *)dst = *(char *)src;                  dst = (char *)dst + 1;                  src = (char *)src + 1;          }          return(ret);  } 上面是memcpy库函数，一时间找不到其他的，暂且拿来做分析吧 指针ret是函数的局部指针，不是说不鼓励返回函数的局部指针吗？ 为何该库函数这样子写？          void * ret = dst; //ret这个指针变量是局部变量，但是指向的内容不是局部变量。

此函数的目的从src拷贝count字节到des中去，然后返回目的buf首地址。 函数体中直接操作的是局部变量des指针，如果不用局部变量ret事先保留副本，那么执行完毕后（des不断后偏移），返回des就不是首地址了，这就错了。  这里返回地址只是一个外部已经存在的地址，所以不会出现问题。 相反，如果外部不存在，而只在局部与函数内部，那么返回出去，就麻烦大了！这才是返回指针真正要害

你这个返回的可以说不是局部的吧！ void * ret = dst; 是传进来字符串地址的！ 返回的是传进来的参数地址的！

不能返回的是指向栈上的对象的指针，因为该对象的生命周期在返回后结束了。 你这里指向的对象是外部传入的，这样可以把memcpy的结果当参数传给其它函数。


Question: POJ1007 为什么我的有问题 wa

引用 4 楼 FancyMouse 的回复:char只能存到127。长度50的字符串逆序数可以上千。 3Q

char只能存到127。长度50的字符串逆序数可以上千。

要沉.......

看看这个博客，POJ1007的题目！有源代码

顶一记！


Question: 为一个指针分配了空间，然后再赋值为NULL，是不是等同于没有分配空间？

谢谢大家，我知道了。

一楼正解呀，回答的很好

一楼的回答很好  楼主该加强哈自己指针等基础知识

看看指针方面的资料，体会会深些。

是这样呀，谢谢！

>为一个指针分配了空间，然后再赋值为NULL，是不是等同于没有分配空间？  等同于内存泄露。 >如果注释掉p = NULL;，加上free(p)，依然能得到10。 说明那部分内存空间还没有被留作他用，里面暂时还是原来的值。未定义行为不保证正确但也不保证一定出错。


Question: 同一行代码 devC++正常编译运行 c-free报错

自己解决了，其实是编译环境没有设置好，主要是还混杂着c-free自己的编译环境。 我是看了http://www.programarts.com/cfree_ch/doc/help/UsingCF/CompilerSupport/MinGW/MinGW2.htm这个文章来的灵感。 我是这样设置的     这个是以前错误的设置，里面夹杂着c-free的编译环境

引用 9 楼 pcxys 的回复:#include <stdio.h> int main (void)  { 	int dogs; 	 	printf ("how many dogs do you have?\n"); 	scanf ("%d", &dogs); 	printf ("so you have %d dog(s) !\n", dogs); 	 	return 0; }   也是同样的代码，在devC++里面执行编译，没问题。 在c-free里面就不行，还是报错。   我的用cfree5.0可以通过呀！

不会只有报错信息吧，拉动一下滑块，看看整个信息，应该先调用gcc，链接的时候才ld...

#include "stdio.h" #include "conio.h"  int main(void) {     printf("Hello, world\n");     getch(); } 代码修改成这样，貌似还是不可以。

引用 3 楼 max_min_ 的回复:[quote=引用 2 楼 pcxys 的回复:] [quote=引用 1 楼 user-6 的回复:] 楼主能写出这样的main函数，足见用了一本垃圾到家的教材啊。  我买的是经典教材，刚开始学习，教材是C Primer Plus（第五版） 这个代码是从网上当的，为了测试软件是不是可以正常的编译，结果就出来问题了。[/quote]  好点的教材main函数应该是有返回值int类型的！你再看看书，是不是哪里漏掉了的？[/quote] 这个代码是从网上当下来的，不是书里面写的。为了测试软件的。

你上的图里，下方本框有个滑块，表示有很多信息被遮掩，认真看一下里面所有的内容...

引用 4 楼 qq120848369 的回复:建议楼主使用VS。 DEV C++有个对学习来说的大优点：不用建工程~~ 另外VS有点不标准吧，DEV C++倒是可以在编译器选项中选择“支持所有ANSI C标准”，这时候连//都会报错，哈哈 这是在DEV C++ 5.4.2上的，国内下载不知道为什么不更新了~~

建议楼主使用VS。

引用 2 楼 pcxys 的回复:[quote=引用 1 楼 user-6 的回复:] 楼主能写出这样的main函数，足见用了一本垃圾到家的教材啊。  我买的是经典教材，刚开始学习，教材是C Primer Plus（第五版） 这个代码是从网上当的，为了测试软件是不是可以正常的编译，结果就出来问题了。[/quote]  好点的教材main函数应该是有返回值int类型的！你再看看书，是不是哪里漏掉了的？

引用 1 楼 user-6 的回复:楼主能写出这样的main函数，足见用了一本垃圾到家的教材啊。  我买的是经典教材，刚开始学习，教材是C Primer Plus（第五版） 这个代码是从网上当的，为了测试软件是不是可以正常的编译，结果就出来问题了。

楼主能写出这样的main函数，足见用了一本垃圾到家的教材啊。


Question: 新手做题，求点拨。

#include<stdio.h> #include<stdlib.h>  typedef struct person{ 	int id; 	struct person * next; }Person;   int main(){ 	Person * head=NULL,* tail=NULL; 	Person * p; 	int pcount;//队列人数 	int i,j; 	int flag;//入队方向标志 	int rid; 	 	printf("输入人数："); 	scanf("%d",&pcount); 	printf("入队方式：\n"); 	/*读取入队*/ 	for(i=0;i<pcount;i++){ 		scanf("%d",&flag); 		 		p=(Person *)malloc(sizeof(Person));//动态分配 		p->id=i+1; 		p->next=NULL; 		 		if(head==NULL){ 			head=p; 			tail=p; 		}		 		else{ 			switch(flag){ 				 				case 1: 					tail->next=p; 					tail=tail->next; 					break; 				 				case 0: 					p->next=head; 					head=p; 					break; 				default: 					//非法输入处理 					break;			 			} 		}				 	} 	printf("结果\n"); 	/*打印结果*/ 	for(j=1;j<=pcount;j++){ 		//查找id,打印next 		rid=getNextId(head,j); 		printf("%d\n",rid); 	}  }  /*在队列中查找，返回后边人的id*/ int getNextId(Person * head,int id){ 	Person * p; 	p=head; 	do{ 		if(id==p->id){ 			if(p->next==NULL)return -1; 			return p->next->id;  //? 		} 		p=p->next; 	}while(p!=NULL); }

搜“种子填充算法”

跟那个不一样啊

数据结构与算法实验题 简单的走迷宫 实验任务 NC 一天要去走一个迷宫，迷宫是由一个 R*C 的网格表示。迷宫只有一个出口和一个入 口，这个大家都知道。迷宫的出口在第一行，出口在最底行。他想知道走出迷宫的最短时间。 这是一个很简单的问题，至于你信不信，反正我是信了。 数据输入 输入第一行包括四个正整数 R，C，ENT,EXIT（2<=R<=200，2<=C<=200），表示 R 行,C 列,入口在第 ENT 列,出口在 EXIT 列。接下 2*R-1 行，第 2*i 行有 C-1 个数，第 j 个数表示 网格 g[i][j]与 g[i][j+1]之间有墙壁。第 2*i+1 行有 C 个数，第 j 个数表示网格 g[i][j] 和 g[i+1][j]之间有墙壁。‘0＇表示没有墙壁，‘1’表示两个位置之间有墙壁。 数据输出 如有有路径走出，则输出最短的步数，否则输出“No Way”(引号去掉)。 输入示例 输出示例 3 4 2 3 0 0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 5   上一题一完成，能不能帮忙看下这题。

对哦，双向链表好像比较简单。我们现在在教队列，我一直都想着用队列解决。

如果用队列，创建两个队列，如果是1直接入第一个队列，如果是0就把第一个队列读出到第二个队列，然后把数读入第一个队列，再把第二个队列的重新读入第一个。我想到这样，不知这个想法对不对。

双向链表也很方便，表头表尾两个节点，表示头尾指针。

这是双端队列 队头队尾，都可以插入 搞个数组，和头尾两个指针（游标）就可以了

做个for循环，假定是m,代表第m个新生，读取i[m-1]的值。如果是1那么n[m-1]位置放入编号，如果是0那么从n[m-2]开始到n[0]每个数据后退一格，退完后在n[0]位置放入编号m,直到全部完成。 从n[0]开始打印到n[N-1],最后打印下-1；

楼主顺便帮俺看看！ http://bbs.csdn.net/topics/390606094

同为新人帮忙顶！！！大牛们可能去旅游去啦，只有我们这种未来苦逼的程序猿才看数据结构！（楼主别忘了给分^_^）

没人吗，求回复。


Question: devC++想使用自己安装的mingw，报错

引用 1 楼 user-1 的回复:所有目录、程序相关的设置都可能要一个个手工改。 我自己刚才搞了一下，跟你说的一样，感谢你的回复！

我自己解决了，需要把所有的devC++的内置mingw版本的地方都换成自己安装的那个地方的路径。

所有目录、程序相关的设置都可能要一个个手工改。


Question: 关于搜索的问题

#include <iostream> #include <queue> #include <cstdio> #include <string.h> using namespace std; char s[1010][1010]; int map[1010][1010]; //int go[1002][2]; int move[4][2]= {{1,0},{-1,0},{0,-1},{0,1}}; int c,r; int xx,yy,sum; bool inmap(int x,int y) {     if (x>=0 && x<=c && y>=0 && y<=r)         return true;     return false; } void bfs(int x,int y,int step,int c) {     //map[x][y]=c;     if (sum<step)     {         sum=step;         xx=x;         yy=y;     }     for (int i=0; i<4; i++)     {         int x1,y1;         x1=x+move[i][0];         y1=y+move[i][1];         if (inmap(x1,y1) && map[x1][y1]!=c && s[x1][y1]=='.')         {             map[x1][y1]=c;             bfs(x1,y1,step+1,c);             //map[x1][y1]=0;         }     }    return; } int main() {     int t;     scanf("%d",&t);     while (t>0)     {         int f=0;         sum=0;         t--;         scanf("%d%d",&c,&r);         memset(map,0,sizeof(map));         // int k=0;         for (int i=0; i<r; i++)             scanf("%s",s[i]);         for (int i=0; i<r; i++)         {             for (int j=0; j<c; j++)             {                 if (s[i][j]=='.' && map[i][j]==0)                 {                     map[i][j]=1;                     f=1;                     bfs(i,j,0,1);                     i=r+1;                      break;                 }             }         }         if (f){             map[xx][yy]=2;         bfs(xx,yy,0,2);         printf("Maximum rope length is %d.\n",sum);         }         else         printf("Maximum rope length is 0.\n");         //printf("Maximum rope length is %d.\n",ans);     }     return 0; } 我的程序哪里错了，求大神解释。。。。

理解了

引用 4 楼 u012246881 的回复:从任意点开始搜索最长路径不是要把每一个点都搜过嘛，那不是就把最长路径搜出来了吗？ 那样你的复杂度就是平方。每个点都要线性的扫一遍整个棋盘。现在棋盘大小是1k*1k=1m，你觉得平方算法能行？

... .## .##  比如这个例子。你如果从左上角开始搜，你是搜不出长4的路径的。

因为它用了一个结论，你从任意点开始，所达到的最远点，必定可以从那个点开始延伸出一个全局最长路径。 只做一次的话，你从哪个点开始？初始点没选好的话，你只能做出从那个点开始的最长路径，而不是所有路径里的最长。


Question: 我想用C写一个常用的数据结构操作库，有多少人觉得有必要么？

建议帖主先通读STL源代码。

非常有必要啊

有必要，练就一身过硬的好本领！

我自己写过栈 队列  树 之类的 感觉有收获。

如果各方面都能比现在的主流编译器（gcc, clang, vc++）附带的stl强，我保证会有很多人用 这包括稳定性，运行期效率，可复用性及灵活度 稳定性是基本要求，最难的是如何同时兼顾运行期效率 可复用性及灵活度  首先c在resource management上总是需要用到goto 不使用goto程式反而很难维护   stack_int *intStack = generate_stack_int(); //...... freeResource :     release_int_stack(intStack);     //.....   第二个问题，你要用void*还是macro实现你的资料结构？ 用void*先天上执行速度就较慢 而且一直cast来cast去的，这api也太难用了，不是type safe的，不安全也不方便  假设你使用macro产生stack_int, stack_double, stack_long等type 如果有一天我需要的是stack_image, stack_human, stack_bmp呢？ 难道要我自行用你提供的macro产生stack_image,stack_human, stack_bmp吗？ 这样一来的话不是很容易发生name collision,甚至是重复的代码吗？  而且使用macro还有一个问题，就是所有我不需要的api都会被编译成binary codes 这间接加剧了code bloat的问题，你要如何让这些资料结构和stl一样 跟template一样只把我需要用到的api编译成binary codes?  用c实现通用的data structures,问题还远不只是这些 不过最难的问题我想还是出在两个地方 第一 ： 没有destructor == 不支援RAII 第二 ： 没有template == 不支援generic programming 顶多只能用macro辅以一堆人类很难理解的奇技淫巧来模拟template的功能 这点跟c++本来就不支援metaprogramming，结果我们只能用一堆奇技淫巧来实现的道理一样

这个看人的。。。有的人领的工资很高，有的干了那么久工资还是4000上下！

如果是要学习数据数据结构的话，自己写会收获很大的，如果是要在工作中用的话，我觉得有些库还是比较好的。。。

OK，不写了，不是为了练手~

自己的代码库通常只有自己愿意用，别人是没心思看的。  这种开源库你去看glib，或者更多的去oschina里翻一翻外国的C/C++开源项目，它们实现的肯定是很优秀的，很多你不了解的东西。  如果是工作用途或者开源项目，可以考虑C++算法和容器，保证可靠和简单。

对自己很必要：实践出真知  对别人也很重要：能力的提高可以带动一批人提高，东西写得好作用更大。

lz 有想法

C 基本写不了，因为C没有模板，很难做到通用数据结构。 不过你可以每种都实现一个。 写一个实现，然后用宏定义来处理每种类型

对自己很必要，提升技能与加深理解；对别人没有必要，有开源的代码！如果你数据结构学的不好，也是一个很好锻炼！如果已经相当棒了，那就别浪费那个时间了

好像已经有了好的开源算法项目了吧


Question: 写一个小小的学生信息管理系统，帮忙看错在哪里？

在函数Create_List中要增加以下语句：  A.length=n;

#include <stdio.h> #include <malloc.h> #define MaxSize 50   typedef struct {     char No[5];     char name[10];     float score;     int age; } Student; typedef struct {     Student data[MaxSize];     int length; } SqList;   void Create_List(SqList &); int Empty_List(SqList L); int Delete_List(SqList *L,int i); void Print_List(SqList L);   int main() {     SqList L;     Create_List(L);     Print_List(L); 	     return 0; }   void Create_List(SqList &A) {     //L=(SqList *)malloc(sizeof(SqList));         int n=0;     printf("请输入要创建的学生个数：\n");     scanf("%d",&n); 	A.length=n;     printf("请依次输入学生的年龄，姓名，学号，分数:\n");     for(int i=0;i<n;i++)     {         scanf("%d%s%s%f",&A.data[i].age,A.data[i].name,A.data[i].No,&A.data[i].score);     } }   int Insert_List(SqList *L,Student &e,int i) {     Student *p,*q;     if(i<1||i>L->length+1)         return 0;     q=&L->data[i-1];     for(p=&L->data[L->length-1];p>=q;--p)         *(p+1)=*p;     *q=e;     ++L->length;     return 1; }   int Delete_List(SqList *L,int i) {     if(Empty_List(*L)==1)     {         return 0;     }     for(int j=i-1;j<=L->length-2;j++)         L->data[j]=L->data[j+1];     return 1; }   int Empty_List(SqList L) {     if(L.length==0)         return 1;     else         return 0; }   void Print_List(SqList L) {     int j=0;     printf("年龄      姓名    学号    分数\n");     for(j=0;j<=L.length-1;j++)     {         printf("%d  %s  %s  %f\n",L.data[j].age,L.data[j].name,L.data[j].No,L.data[j].score);           }   }

错误描述：当输入学生信息时候。输出函数没有输出学生成绩！


Question: 最小生成树prime算法输出错误，求教！

CreatGraph(Graph  G):      /**< 矩阵初始化 */     for(i=0;i<G->numvertex;i++)     {         for(j=0;j<G->numedge;j++)         {             G->edge[i][j] = INFINITY;         }     }  [/code] void  PrintGraph(Graph  G) {     int  i,j;      for(i=0;i<G->numvertex;i++)     {         for(j=0;j<G->numedge;j++)         {             if(G->edge[i][j] == INFINITY)                 printf("\t**");             else                 printf("\t%d",G->edge[i][j]);         }         printf("\n");     } } [/code] 这是函数CreatGraph、PrintGraph，两者的内循环j的上界有问题吧 应该是顶点个数，即G->numvertex，而你却写成了边数，即G->numedge

引用 6 楼 lelieven 的回复:[quote=引用 5 楼 user-3 的回复:]       /**< 初始化辅助数组 */       for(i=1;i<G->numvertex;i++)       {           lowcost[i] = 0;           adjvertex[i] = 0;       }  你一开始所有的点距离已经是0了，那求出来的距离和当然是0。  原来如此，非常感谢！[/quote] 是的，昨晚回去看了看，辅助数组的初始化有问题

引用 5 楼 user-3 的回复:/**< 初始化辅助数组 */       for(i=1;i<G->numvertex;i++)       {           lowcost[i] = 0;           adjvertex[i] = 0;       }  你一开始所有的点距离已经是0了，那求出来的距离和当然是0。  原来如此，非常感谢！

引用 10 楼 u011636587 的回复:引用 2 楼 lelieven 的回复:[quote=引用 1 楼 u011636587 的回复:] 额，沙发？？？  好孩子呀！ 汗，第一次用错了，谢谢夸奖，额  ，我就一小白，在各个板块混经验，请多多指教[/quote]  我也是小白！

引用 2 楼 lelieven 的回复:引用 1 楼 u011636587 的回复:额，沙发？？？  好孩子呀！ 汗，第一次用错了，谢谢夸奖，额  ，我就一小白，在各个板块混经验，请多多指教

引用 1 楼 u011636587 的回复:额，沙发？？？ 谢谢夸奖，额  ，我就一小白，在各个板块混经验，请多多指教。

引用 3 楼 AILOONG 的回复:main函数中的 G=malloc(sizeof(struct graph)); 最好改成 G=(Graph)malloc(sizeof(struct graph)); malloc返回的是void *类型，而G是struct graph *类型 至于你说的主要问题，稍后答复  好的！谢谢！

引用 1 楼 u011636587 的回复:额，沙发？？？  好孩子呀！

额，沙发？？？


Question: Turbo C下编程设置屏幕分辨率为1024*768,24位模式，BMP图片显示有问题

你是华科自动化的吗？

pokeb(0xa0000000,position%65536L,write); /*写到显存位置*/ 改成pokeb(0xa0000000+(position /65536L) *(2048)* 16*16*16 ,position%65536L,write);

pokeb(0xa0000000,position%65536L,write); /*写到显存位置*/ 这个会不会有问题 当数据超过65536L应该，修改段的位置，不应该换页吧 64k/16 = 2k     每16字节对应一个段偏移 每增加 64k 段地址增加64k/16 = 2k   段地址是 0xa000 + (position /65536L) *(65536L /16)

@lm_whales 谢谢你的回答，还是不可以。我觉得会不会是Dosbox虚拟的DOS环境，显存不够，因为1024*768,24位的需要4M显存。用1024*768,256色的可以成功读出Bmp图。

这个学了有实际意义么。

实际显示


Question: Windows编程InvalidateRect()函数

查了下MSDN的InvalidateRect，重点如下 Remarks The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT message occurs or until the region is validated by using the ValidateRect or ValidateRgn function.  InvalidateRect函数名不会去重画无效区域，只有在下一次收到WM_PAINT消息事后才会重画，所以如果你想现在就更新的话需要::SendMessage( hwnd ,WM_PAINT, 0, 0);

引用 6 楼 hunanzhiying 的回复:@zhao4zhong1 好详细的解释啊 查MSDN是Windows程序员必须掌握的技能之一。  粘贴MSDN是zhao4zhong1经常用来刷CSDN论坛分的办法之一。

@zhao4zhong1 好详细的解释啊

UpdateWindow The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty. The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent.   BOOL UpdateWindow(   HWND hWnd   // handle of window );   Parameters hWnd  Handle to the window to be updated.  Return Values If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.   Windows NT: To get extended error information, callGetLastError.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winuser.h.   Import Library: Use user32.lib.  See Also Painting and Drawing Overview, Painting and Drawing Functions, ExcludeUpdateRgn, GetUpdateRect, GetUpdateRgn, InvalidateRect, InvalidateRgn, WM_PAINT

InvalidateRect The InvalidateRect function adds a rectangle to the specified window's update region. The update region represents the portion of the window's client area that must be redrawn.   BOOL InvalidateRect(   HWND hWnd,  // handle of window with changed update region   CONST RECT *lpRect,               // address of rectangle coordinates   BOOL bErase // erase-background flag );   Parameters hWnd  Handle to the window whose update region has changed. If this parameter is NULL, the system invalidates and redraws all windows, and sends theWM_ERASEBKGND and WM_NCPAINT messages to the window procedure before the function returns.  lpRect  Pointer to a RECT structure that contains the client coordinates of the rectangle to be added to the update region. If this parameter is NULL, the entire client area is added to the update region.  bErase  Specifies whether the background within the update region is to be erased when the update region is processed. If this parameter is TRUE, the background is erased when the BeginPaint function is called. If this parameter is FALSE, the background remains unchanged.  Return Values If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.   Windows NT: To get extended error information, callGetLastError.  Remarks The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT message occurs or until the region is validated by using the ValidateRect or ValidateRgn function.   The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.   If the bErase parameter is TRUE for any part of the update region, the background is erased in the entire region, not just in the given part.   Windows CE: The hWnd parameter cannot be NULL.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winuser.h.   Import Library: Use user32.lib.  See Also Painting and Drawing Overview, Painting and Drawing Functions, BeginPaint, InvalidateRgn, RECT, ValidateRect, ValidateRgn,WM_ERASEBKGND, WM_NCPAINT, WM_PAINT

@gameslq 不是吧，我记得InvalidateRect是可以发送WM_PAINT消息的，但是因为WM_PAINT消息在消息队列中是属于等级较低的消息，所以如果要提前处理WM_PAINT可以用UpdateWindow来让窗口过程直接处理ＷＭ＿ＰＡＩＮＴ而不经消息队列。

InvalidateRect(某窗口句柄，假设为hwnd,NULL,TRUE);         2.UpdateWindow(hwnd); 这两句应该放在 3的最后，一般是绘制完图形然后进行刷新显示。  InvalidateRect函数只是置窗口区域为无效，UpdateWindow才真正发送wm_pain 1,2可用redrawwindow代替，更直接

updatewindow函数理论上会直接调用onpaint，不会经过消息循环。


Question: 求一c语言算法，伪代码也行。

用堆排序吧，建立最大或者最小堆，把每个单词加进去，如果存在的话就直接把他的计数器++，最后排序下就可以先序输出了

可以用二叉排序树

额，好深奥的感觉


Question: vc++出现 必需的文件确实，需要重新安装怎么办...

是不是之前卸载过什么软件,再重新装上,也许就能够解决,之前我就是这样解决了一个类似的问题

把杀毒的等，其他软件关掉。。。

重启重装 都试过了....重转都没用 这是比我重转系统额....

重启试试，不行的话就重装吧！

重装吧,要不换个版本

EECXX.DLL 你重新安装试试吧。


Question: 栈中返回的元素怎么会是问号啊？

我明白了，哈哈哈


Question: linux c下，在终端下画了个文本框，如何控制输入时在碰到边框时自动换行？

引用 7 楼 liuhongwei110 的回复:[quote=引用 5 楼 liuchao35758600 的回复:] 边框的宽度和当前行输入的字符数，这两个是已知的； 那么，判断光标的位置，或者判断当前输入的字符在文本框里的位置，超出边框后换行。 在键盘输入的过程中也能换行？怎么实现？我的意思是一次大量输入，按回车就结束输入了。如果每次少输入一点倒是可以换行，但这样交互性不好。[/quote] 设置终端为无回显无缓冲模式，就能直接响应每个按键，不用等按了回车后才能获取到输入的内容， 由于设置了无回显模式，你按了键后，终端上不会显示相应字符，这样，就不用担心控制终端上显示的内容被打乱。 你可以通过使用转义序列来控制光标位置，程序输出的字符就会从光标处开始打印出来。  或者，和楼上的说的一样，用ncurses函数库来实现。

使用ncurses库

引用 5 楼 liuchao35758600 的回复:边框的宽度和当前行输入的字符数，这两个是已知的； 那么，判断光标的位置，或者判断当前输入的字符在文本框里的位置，超出边框后换行。 在键盘输入的过程中也能换行？怎么实现？我的意思是一次大量输入，按回车就结束输入了。如果每次少输入一点倒是可以换行，但这样交互性不好。

引用 5 楼 liuchao35758600 的回复:边框的宽度和当前行输入的字符数，这两个是已知的； 那么，判断光标的位置，或者判断当前输入的字符在文本框里的位置，超出边框后换行。 ++

你先把代码搞出来，让人看看。。。

学生来学习。

curses库不怎么熟悉，求深入，最好举个例子？

屏幕捕捉 curses库？


Question: 关于Borland c++

google,看看别人如何写

现在还有人要用c、c++做点菜系统？

使用cpp合适吗？

我怎么导入总菜单啊，可以显示汉字么……

简单的，就是一个字符指针数组，或者二维数组 然后如果菜式少，一个选项，如果比较多，分类一下 根据客户选择，显示菜单页面 根据选择，输出选中的菜名，也可以选好后输入确定，显示所有菜名。 复杂点自己在琢磨琢磨即可。  如果采用窗口界面，或者图形界面，Bc ++也有相应的函数。


Question: 熟练掌握C、汇编

引用 3 楼 jingyexiaoyue 的回复:[quote=引用 楼主 return_heiniu 的回复:] 对操作系统算法设计数据结构有一定的理解可以哪方面的工作 当你说这个的时候，我是不是可以理解为你还是不熟练，因为你要是熟练的话，你是不会不知道干什么的！ 要是迷惘就去看看招聘的要求的[/quote]  要是迷惘就去看看招聘的要求的 ++

引用 楼主 return_heiniu 的回复:对操作系统算法设计数据结构有一定的理解可以哪方面的工作 当你说这个的时候，我是不是可以理解为你还是不熟练，因为你要是熟练的话，你是不会不知道干什么的！ 要是迷惘就去看看招聘的要求的

看到底有多“熟练”，“理解”到了什么程度

理论上 啥 工作都可以吧。 要具体到哪个行业，就得看编程语言以外的技术了， 比如图像处理， 网络通信， 或者现在流行的大数据等等。


Question: 在poj做题时 超时了 求大神们看一下怎么可以优化一下

http://poj.org/problem?id=1002 题目 求大神啊

LZ程序超时的主要原因是： （1）判断部分的程序陷入死循环 （2）排序不够快  还有数组不够大。  如下修改AC:  #include <stdio.h> #include <stdlib.h> #include <string.h> int cmp(const void *a, const void *b) {   return strcmp((char *)a,(char *)b); } int main(void) {   int count;   int count2=1;   scanf("%d",&count);   int i;   int j;   int right=0;   char h[9];   void change(char*, char*);//char* change(char*);   char a[50];//char a[100][20];   char (*b)[9] = new char[count][9];//char b[100][9];   for(i=0;i<count;i++)   {     scanf("%s",a);//scanf("%s",a[i]);     change(a, b[i]);//strcpy(b[i],change(a[i]));   }    /*   for(i=0;i<count-1;i++)     for(j=i+1;j<count;j++)     {       if(strcmp(b[i],b[j])>0)       {         strcpy(h,b[i]);         strcpy(b[i],b[j]);         strcpy(b[j],h);       }     }     */   qsort(b, count, sizeof(b[0]), cmp);      for(i=0;i<count;i++)     {       while(i<count-1 && strcmp(b[i],b[i+1])==0)       {         i++;         count2++;       }       if(count2>1)       {         printf("%s %d\n",b[i],count2);         count2=1;         right=1;       }     }     if(right==0)     {       printf("No duplicates.\n");     }      return 0; } void change(char* a, char *b)//char* change(char* a) {   int count=0;   int i=0;   //char b[9];   //char *p=b;   for(;*(a+i)!='\0';i++)   {     if(*(a+i)=='-')     {       continue;     }     else if(count==3)     {       b[3]='-';       i--;       count++;     }     else if(*(a+i)>='0'&&*(a+i)<='9')     {       b[count]=*(a+i);       count++;     }     else if(*(a+i)=='A'||*(a+i)=='B'||*(a+i)=='C')     {       b[count]='2';       count++;     }     else if(*(a+i)=='D'||*(a+i)=='E'||*(a+i)=='F')     {       b[count]='3';       count++;     }     else if(*(a+i)=='G'||*(a+i)=='H'||*(a+i)=='I')     {       b[count]='4';       count++;     }     else if(*(a+i)=='J'||*(a+i)=='K'||*(a+i)=='L')     {       b[count]='5';       count++;     }     else if(*(a+i)=='M'||*(a+i)=='O'||*(a+i)=='N')     {       b[count]='6';       count++;     }     else if(*(a+i)=='R'||*(a+i)=='S'||*(a+i)=='P')     {       b[count]='7';       count++;     }     else if(*(a+i)=='T'||*(a+i)=='U'||*(a+i)=='V')     {       b[count]='8';       count++;     }     else if(*(a+i)=='W'||*(a+i)=='X'||*(a+i)=='Y')     {       b[count]='9';       count++;     }   }   b[count]='\0';   //return p; }


Question: TC中能用的bios.h 里边bioskey（）函数，在VC中有没有类似的函数，能输入按键？

珍惜生命，换本比你自己年轻的教材吧。

有木有人啊啊。。求助


Question: tc 编译 链表 指针那里，一直说我定义确实； ！！！！！！！！

引用 5 楼 alalalalalqp 的回复:我typedef过，notetype不就等于struct notetype了吗17行 你才能说你 typedef过了 可你的错误是出现在 16行  明白了吗

我typedef过，notetype不就等于struct notetype了吗

我typedef 过了，不是应该不用再写struct了么

没有简不简单，要看你学到什么程度，如果是做个设计，MFC的基础知识应该就可以了。

struct NodeType *next

楼上正解 NodeType * next;改成struct NodeType * next;

struct NodeType * next;

引用 6 楼 ylbhz 的回复:请扔掉TC，我用VC6已经觉得太老了，你还在用TC，佩服。    做个课程设计而已，TC图形界面好学，VC 图形界面是不是要学windows API的？简单不？能介绍下经验不

引用 5 楼 alalalalalqp 的回复:我typedef过，notetype不就等于struct notetype了吗 在你定义next的那行，你的typedef语句还没有完结，也就没有生效

请扔掉TC，我用VC6已经觉得太老了，你还在用TC，佩服。


Question: 关于memcpy不考虑内存重叠的问题

memmove会处理重叠的情况，memcpy不会。memcpy主要是性能上的考虑，memmove主要是安全性上的考虑。

单步跑，看看过程

不保证有正确结果  为什么都理解为  保证有不正确的结果   语文问题??

学习一下

lz 自己设个断点，看看str 的变化

char str[200] = "abcdefghijklmnopq";  printf( "%s\n", memcpy( str+4 , str+8, 6 ) ); 看看是什么效果

C库就有说明，如果内存有重叠，函数会考虑拷贝方向，使得重叠处的字节能正确拷贝

编译器会优化吧

必须memmove。

我这几个编译器, 输出 abcd , aaaa 的都有, 还有输出 abcc 的...

对于memcpy来说，overlap属于未定义行为，就是说，编译器的设计者可以不考虑overlap情况，但并非必须不考虑overlap，懂了没？

内存重叠的memcpy是未定义行为, 输出 aaaa , abcd 的都有, 常见的 M$ CRT, 高点版本的 glibc/eglibc 的运行库下, memcpy行为都跟 memmove 一样...


Question: 帮忙看看：这个顺序表怎么传参？

引用 6 楼 zhang5476499 的回复:[quote=引用 4 楼 user-1 的回复:] [quote=引用 3 楼 zhang5476499 的回复:] 这个函数好像不正确吧？void Clear_List(SqList L) {     L.length=0; }  why?  实践是检验真理的唯一标准[/quote]洗耳恭听！请赐教！[/quote]  输入代码，运行看看

引用 4 楼 user-1 的回复:[quote=引用 3 楼 zhang5476499 的回复:] 这个函数好像不正确吧？void Clear_List(SqList L) {     L.length=0; }  why?  实践是检验真理的唯一标准[/quote]洗耳恭听！请赐教！

本人想尽了所有主调函数的调用方式，都不知道怎么清空表。请帮忙写下主调函数。

引用 3 楼 zhang5476499 的回复:这个函数好像不正确吧？void Clear_List(SqList L) {     L.length=0; }  why?  实践是检验真理的唯一标准

结构体可以赋值，copy,当参数时by value

还有就是最让人费解的就是这个清空顺序表的函数： void Clear_List(SqList L) { 	L.length=0; } 在此函数中，L.length=0啦，但是主调函数的L.length也等于0嘛？


Question: 由一种文本文件生成固定格式文件的问题

格式xml，文本，二进制都可以吧，二进制稍微麻烦点，建议写一个读、写脚本。。。

引用 2 楼 qq120848369 的回复:xml, ini啊。 现在就是需要根据不规则的技术文档生成ini文件，能否详述一下步骤？

谢谢大家的回复 我试试吧！

引用 3 楼 u011498034 的回复:[quote=引用 2 楼 qq120848369 的回复:] xml, ini啊。 现在就是需要根据不规则的技术文档生成ini文件，能否详述一下步骤？[/quote]  这么简单的格式你还生成不出来啊？

xml, ini啊。

写一个分析文件，生成文档的程序


Question: ？关于c primer plus 程序7.5中while（scanf（“%lu",&num)==1)

引用 6 楼 FancyMouse 的回复:while(scanf("%lu",&num)==1);//这个输入数字依然等待输入，除非输入非数字才继续  多了个分号 ++ 这个是问题的关键！！！

引用 楼主 longwngtang 的回复:#include<stdbool.h> #include<stdio.h> int main(void) {     unsigned long num;     unsigned long div;     bool isPrime;      printf("Please enter an integer for analysis;");     printf("Enter q to quit .\n");     while(scanf("%lu",&num)==1);//这个输入数字依然等待输入，除非输入非数字才继续     {         for(div=2,isPrime=true;(div*div)<=num;div++)         {             if(num%div==0)             {                 if((div*div)!=num)                 printf("%lu is divisible by %lu and %lu.\n",                       num,div,num/div);                 else                     printf("%lu is divisible by %lu.\n",num,div);                 isPrime=false;             }         }         if(isPrime)            printf("%lu is prime.\n",num);         printf("Please enter anotherinteger for analysis;");         printf("Enter q to quit .\n");     }     printf("Bye.\n");     return 0; } 同时按下"CTRL"键和"Z"键。表示"EOF"输入结束，回车就ok了

引用 3 楼 user-5 的回复:scanf reads from stdin under control of format, and assigns converted values through subsequent arguments, each of which must be a pointer. It returns when format is exhausted. fscanf returns EOF if end of file or an error occurs before any conversion; otherwise it returns the number of input items converted and assigned.      最简单的，这里可以在输完数字后输ctrl+z 再回车

scanf("%lu",&num)的返回值为1时while（）成立，为什么输入数字后这个程序不继续运行也不推出。

新手，codeblocks，


Question: 为什么相同的结构体指针增量操作在不同代码有的编译正常，有的出现错误?

第二程序的 ++操作是错误的！ 数组名怎么++ 数组和指针完全不是一个东西的，指针可以，数组不一定可以的！ 下载这本c和指针看看吧！ http://download.csdn.net/detail/max_min_/6333711

第二个程序中，p->name 是数组名 你认为可以++吗？？  数组名，虽然也能当指针使用，但是这个指针是个指针常量，不可变的； ++需要左值,所以错了。  另外，第一个程序，虽然编译和运行没有错误。 不过这种用法，是有问题的。 不管，这个指针是否左值，这个指针实际意义是，指向一个字符串，这个字符串，是一个名字。  做了++以后，他就不能指向，完整的字符串了。 如果其他地方，也用到这个指针，那么你只能得到这个名字的一部分，  那么程序就出错了。 这个程序就不正确了。  这种程序逻辑错误，最麻烦了。  PS： 如果只是研究一下，这么做没什么。  如果是在项目中，千万不能这么做。

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

楼主第二个程序中的红色语句不合法是可以肯定的，p->name对应的是一个地址常量，不能认为是左值，固然不可以作为++的操作数了。。。


Question: 结构体指针查找报错

if (temp == p1 ->name) 字符串比较大小是需要使用strcmp或者strncmp函数的，不可以直接进行比较哦。

你那个free（p）为什么要加呢？你又没申请内存，释放的是什么啊？这个去掉吧

试了，还是不行。不过，还是谢谢你。

差不多是这样

你好，不是很懂你说的内容，但是我差不多知道问题出在哪里了。应该是给字符数组赋值的时候，方式不对造成的。但是，我又不知道具体该如何写这句话，是strcpy（p1->name，20，temp）这样吗？

while (p1 &&  p1 -> next !=NULL&& strcmp(temp ,p1->name) { ...... }  C 串其实是带结束符的字符数组，串名赋值，只是个对指针赋值， 用 = 赋值，不论是数组，还是指针，都是不对的。  要对数组的每一个元素赋值才行，记住要加结束符. 这可以使用库函数 strcpy。  比较也要比较每个字符， 这可以使用库函数strcmp


Question: 如何用C语言写个程序来采集外界的音频并存在电脑上

这个你做不了，你还是找人做吧


Question: 问个网络竞赛的问题

找到函数main 使用的栈，修改 n 所在位置的数据，使之 ＝0 由于不知道用的编译器，操作系统，和模式，比较麻烦 如果是 DOS tiny 模式，C语言 main函数是第一个被调用的函数直接查找堆栈即可

现在还正在比赛呢！你这样搞有意思么 你说你要是在做的过程中遇到单方面的问题出来问 没什么 你直接把题拿出来问有意思么！！！ 如果大家知道怎么做的话 请在比赛结束后在给出答案 现在还正在比赛呢 此题的地址： https://ctf.xdsec.org/?m=article&id=31 有兴趣的 也可以注册一个号码 去打打酱油

谁来给点思路什么的


Question: 结构体指针中的前置++问题

对于运算符不管怎么变只需要记住2点：1是运算符的左右结合规则，2是运算符的优先级别。这2点直接影响最终结果

引用 2 楼 qq120848369 的回复:(*ptr->name+8), 这是一个左值, 不能应用++操作符. 就像你没办法这样写：++(1+2)是一样的。  说错了，左值 -> 右值

引用 13 楼 lm_whales 的回复:++ 不是和*(ptr->name+8)结合的，而是是和(ptr->name+8)结合的 因为++的优先级高， 所以这个表达式的意思是，先 ++(ptr->name+8) 然后 *(ptr->name+8) (ptr->name+8) 是右值，不是左值； 所以 ++(ptr->name+8) 是个错误的表达式，右值不可以改变自身。 所以 ++ *(ptr->name+8) 也是错误的表达式； 你的说法有误，操作符何时能够越过另外一个操作符进行操作了？ 另外所谓的++优先级比*优先级高的说法,也只是因为他们的结合方向同属自右向左， 所以才会有*p++,等于*(p++)这种情况（++在右边，先结合），但事实上他们的优先级是同样的，同属第二优先级。  但前导的（左边的）++在某些编译器（貌似cosmic就是）里被分配到第一优先级中，这个优先级的结合方向是自左向右。 不过左边的++跟第二优先级的几个操作符结合起来使用的时候，不算出错的情况的话，事实上也和 在第二优先级一样~~  所以++ *(ptr->name+8) 不是错误的表达式。

根本不是楼上说的优先级啊等问题...是这样的，你要知道对一个指针（即地址）进行解引用后，该值是左值，可以理解为一个变量名，可以置于赋值号左边，而楼主说的第二种写法中的(*ptr->name+8)是一个中间结果，不是左值，而是右值，无对应的内存地址，所以不能当做++的左值使用..另外，++就含有赋值操作，所以它需要一个左值！

再看看优先级吧！ ++ 比* 优先级高。 优先级，不知道，加括号！

++(*(ptr->name+8)) 才行吧 ++ 和* 都是单目运算符，都是和(ptr->name+8) 结合，  (ptr->name+8)右值，不带++的；

引用 1 楼 modyaj 的回复:,++(*ptr->name+8)) 都已经解引用了 他已经只是个值而已  相当于 int i = 10;  整个表达式右边的部分 那么数10都不能++  楼主的值当然也不能++  那么++*(ptr->name)也已经解引用了，为什么还可以前++ ？

另外 自增运算符的优先级高于解引用

++*(ptr->name) == ++*ptr->name  关键是不能 +8 ++*(ptr->name+8)是表达式

引用 5 楼 user-10 的回复:++*(ptr->name+8) ++(*ptr->name+8) 两个都是有错误的吧

引用 4 楼 zaixiankaifa 的回复:[quote=引用 1 楼 modyaj 的回复:] ,++(*ptr->name+8)) 都已经解引用了 他已经只是个值而已  相当于 int i = 10;  整个表达式右边的部分 那么数10都不能++  楼主的值当然也不能++  那么++*(ptr->name)也已经解引用了，为什么还可以前++ ？[/quote] 如楼上所说！很好理解吧

引用 4 楼 zaixiankaifa 的回复:[quote=引用 1 楼 modyaj 的回复:] ,++(*ptr->name+8)) 都已经解引用了 他已经只是个值而已  相当于 int i = 10;  整个表达式右边的部分 那么数10都不能++  楼主的值当然也不能++  那么++*(ptr->name)也已经解引用了，为什么还可以前++ ？[/quote] int a = 1; a++; //ok (a + 8)++;//不ok 和解引用没关系

++*(ptr->name+8) ++(*ptr->name+8)


Question: 高分求助：CreatFile()函数读取字符串路径失败，错误代码123(文件名、目录名或卷标语法不正确。)

不知道楼主的问题解决了没有     在下也碰到了同样的问题    如果楼主的问题已解决，希望也能帮我一下     谢谢

就没有人说吗？

引用 4 楼 jerry_dqh 的回复:[quote=引用 3 楼 Auro_L 的回复:] 哪位大虾能给小弟解惑呢，已经调试12个小时了都没解决 这种函数一般还是路径错误了，或者你没有权限写。 路径中的"\",是不是要用双\\[/quote] 路径是没有错的，因为这是字符串数组，所以没必要用\\，而且我也测试过了，还是出错 我读取不是要写，而且我把第二个参数改成GENERIC_READ，还是一样的结果 最后我连函数换成FindFirstFile()还是出错，就是不能解析字符串中的路径

引用 3 楼 Auro_L 的回复:哪位大虾能给小弟解惑呢，已经调试12个小时了都没解决 这种函数一般还是路径错误了，或者你没有权限写。 路径中的"\",是不是要用双\\

哪位大虾能给小弟解惑呢，已经调试12个小时了都没解决

CreateFile  要看是否Unicode ，不匹配会出错  这个函数实际是个宏定义为 CreateFileA，CreateFileW 中的一个。

引用 1 楼 user-5 的回复:在函数刚进入时加断点，检查输入参数pwchar_param_LogFile的内容。 是下面的那个CreatFile()函数，上面的是正常的，下面的第一个参数是字符串数组，数组内容是从文件中读取来的，内容也是路径没有错，可CreatFile()就是报错


Question: goto 语句会不会引起内存错误 c语言

关键是你知不知道自己在干什么……

goto和跳转处之间行数少，还是可以把

引用 1 楼 jerry_dqh 的回复:goto语句本身不会引起内存错误，但是可能你用goto，导致流程有了问题，从而有内存没有释放或者分配，或者有空指针之类的问题。  正解。goto本身不会引起内存错误。

设置标志，goto统一进行处理最后结果

goto还是有其好处的，但不能滥用。 至于能否导致内存泄漏则要具体问 题具体分析，不能一句话定性。不过 在到处都是指针（非智能指针）的情 况下，导致内存泄漏的几率确实很大。

尽量不要使用goto，否则用多了，会让你的程序看起来执行流程很乱，而且容易发生问题。

关键不在于用的多少，而是在于用在什么地方。如楼上说的goto用来处理错误跳转是绝对好用的。而且很多优秀的开源代码都在用goto作为错误处理机制。 但是在其它用途上使用goto我倒是见得不多。所以goto不是能不能用的问题，也不是用的多少的问题，而是用的时候有没有原则的问题。

goto在处理错误跳转时绝对好用，还应该提倡。

引用 22 楼 nadleeh123 的回复:[quote=引用 21 楼 qq523176585 的回复:] [quote=引用 20 楼 nadleeh123 的回复:] [quote=引用 2 楼 qq523176585 的回复:] 尽量不要使用goto语句  呵呵[/quote]  [/quote] 没事去看看内核编程的出错处理吧，用goto是标准模式[/quote]  目前还接触不到，我只是一个菜鸟，还有很多需要学习的地方。我觉得由浅入深的好一点，

任何语句都不会引起内存错误. 只要正确使用. goto少用,但是有的时候使用会使代码更简洁. goto比较经典的使用请参考linux内核.几乎重要的模块都用使用goto的情况.

引用 21 楼 qq523176585 的回复:[quote=引用 20 楼 nadleeh123 的回复:] [quote=引用 2 楼 qq523176585 的回复:] 尽量不要使用goto语句  呵呵[/quote]  [/quote] 没事去看看内核编程的出错处理吧，用goto是标准模式

引用 20 楼 nadleeh123 的回复:[quote=引用 2 楼 qq523176585 的回复:] 尽量不要使用goto语句  呵呵[/quote]

引用 2 楼 qq523176585 的回复:尽量不要使用goto语句  呵呵

用好就行了 。

关键还看goto到什么地方吧。

如果没有分配公共资源的函数调用（例如：打开文件、创建句柄、在堆上分配内存 等）和goto搅在一起，绝对就不会有资源泄露问题，除非编译器有Bug。

你怎么使用的？

用起来很爽,改起来就麻烦了.我没用过,用的好也许能实现一些难以解决的问题.

不会内存错误，倒是存在潜在的内存泄漏！核心代码用goto非常普遍，但是用户程序还是尽量少用吧。

建议用switch case语言来替换goto


Question: 求助浮点数上溢下溢问题

float 型数据在内存中整数部份值通常为1，但如果该数据的绝对值小于2^-127, 整数部份的值可以为0，所以可以表示绝对值最小值是2^-143.

引用 5 楼 lm_whales 的回复:数据比较小时，转换为非规格化表示，可以表示10.0E-37f/100; 10.0E-37f/10000; 没有下溢，也不是其他不可表示数据。 不是0 printf时候，转换为double 但是不影响，表示范围。  float 无穷大，转换为double还是无穷大。而不是可表示的数据。 同样NAN也还是NAN,也就是说float不是在10.0E-37f/100，附近下溢了？thanks。。。书有问题啊。。。

难道在调用printf（）时，float型的数值转换成了double型？

引用 1 楼 qq523176585 的回复:float b = 3.40E+38; 编译时没有提示3.40E+38是一个const double 型的数据？,没有提示啊。。。。

float x=1; 	for(int i=0;i<128+40;i++) 	{ 		TRACE("%e\n",x); 	    x/=2; 	}  1.000000e+000 5.000000e-001 2.500000e-001 1.250000e-001 6.250000e-002 3.125000e-002 1.562500e-002 7.812500e-003 3.906250e-003 1.953125e-003 9.765625e-004 4.882813e-004 2.441406e-004 1.220703e-004 6.103516e-005 3.051758e-005 1.525879e-005 7.629395e-006 3.814697e-006 1.907349e-006 9.536743e-007 4.768372e-007 2.384186e-007 1.192093e-007 5.960464e-008 2.980232e-008 1.490116e-008 7.450581e-009 3.725290e-009 1.862645e-009 9.313226e-010 4.656613e-010 2.328306e-010 1.164153e-010 5.820766e-011 2.910383e-011 1.455192e-011 7.275958e-012 3.637979e-012 1.818989e-012 9.094947e-013 4.547474e-013 2.273737e-013 1.136868e-013 5.684342e-014 2.842171e-014 1.421085e-014 7.105427e-015 3.552714e-015 1.776357e-015 8.881784e-016 4.440892e-016 2.220446e-016 1.110223e-016 5.551115e-017 2.775558e-017 1.387779e-017 6.938894e-018 3.469447e-018 1.734723e-018 8.673617e-019 4.336809e-019 2.168404e-019 1.084202e-019 5.421011e-020 2.710505e-020 1.355253e-020 6.776264e-021 3.388132e-021 1.694066e-021 8.470329e-022 4.235165e-022 2.117582e-022 1.058791e-022 5.293956e-023 2.646978e-023 1.323489e-023 6.617445e-024 3.308722e-024 1.654361e-024 8.271806e-025 4.135903e-025 2.067952e-025 1.033976e-025 5.169879e-026 2.584939e-026 1.292470e-026 6.462349e-027 3.231174e-027 1.615587e-027 8.077936e-028 4.038968e-028 2.019484e-028 1.009742e-028 5.048710e-029 2.524355e-029 1.262177e-029 6.310887e-030 3.155444e-030 1.577722e-030 7.888609e-031 3.944305e-031 1.972152e-031 9.860761e-032 4.930381e-032 2.465190e-032 1.232595e-032 6.162976e-033 3.081488e-033 1.540744e-033 7.703720e-034 3.851860e-034 1.925930e-034 9.629650e-035 4.814825e-035 2.407412e-035 1.203706e-035 6.018531e-036 3.009266e-036 1.504633e-036 7.523164e-037 3.761582e-037 1.880791e-037 9.403955e-038 4.701977e-038 2.350989e-038 1.175494e-038 5.877472e-039 2.938736e-039 1.469368e-039 7.346840e-040 3.673420e-040 1.836710e-040 9.183550e-041 4.591775e-041 2.295887e-041 1.147944e-041 5.739719e-042 2.869859e-042 1.434930e-042 7.174648e-043 3.587324e-043 1.793662e-043 8.968310e-044 4.484155e-044 2.242078e-044 1.121039e-044 5.605194e-045 2.802597e-045 1.401298e-045  //float 最小可表示的数据 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000


Question: 多个线程可以共用一个目的窗口句柄吗

窗口句柄可以跨线程操作，不过如果是新建子窗口，在新线程也必须写上消息循环

既然发送消息给窗口,那共用一个窗体句柄,一个消息,无所谓啦.  PS:头像是你嘛,好漂亮呀

引用 10 楼 lm_whales 的回复:发消息没有区分来自那个串口吧！ 不知道是不是和互斥有关 http://bbs.csdn.net/topics/390606033

引用 11 楼 dahaiI0 的回复:一发命令就死机.问题太抽象 http://bbs.csdn.net/topics/390606033就是这个

引用 3 楼 dahaiI0 的回复:窗口跟串口没什么关系，共用一个自然木问题，不过PostMessage的时候要注意参数的生存期 生存期是什么意思？可以具体解释一下吗？万分感谢

一发命令就死机.问题太抽象

发消息没有区分来自那个串口吧！

引用 2 楼 user-5 的回复:主线程　每次都是从消息队列里面取出消息来处理　并不管他们来自哪里　它视所有属于他的消息都一样　个人觉得　WM_MYMSG　可以共用　　楼主可以小试一下效果啊恩，现在能收到东西，而且似乎也正常，但是老是一发命令就死机，是不是双串口涉及多线程操作导致的呢？

引用 6 楼 dahaiI0 的回复:postmessage是异步的，在消息响应函数里你会把参数取出来使用对吧，有可能这个参数已经无效了。栈上的变量离开作用域时会被销毁，其生存期结束。恩，现在能收到东西，而且似乎也正常，但是老是一发命令就死机，是不是双串口涉及多线程操作导致的呢？


Question: 约瑟夫环 求大神改错

跪求大神改错！

在线等大神！


Question: 请教各位这个宏定义该怎么理解，祝大家国庆快乐！

\是续行符的意思 至于宏里面带；这个，可以把整个宏定义后面的内容用一对{}这个括起来吧

引用 5 楼 qq120848369 的回复:do {} while(0) 正解！

do {} while(0)

c 语言中， 见分号才算一行 define 中用 \ 将两行连接起来

还是不够好，想想下面语句： if (...)     MSE_DEMAND_M9_CFG(...); else     doSomething();  编译都过不了  引用 1 楼 user-6 的回复:斜杠是连接符的意思。这样写比较好： #define  MSE_DEMAND_M9_CFG(pszPath, szData) \{          bufclr(szData); \          DemandInXmlExt((PXMLSTRU)pxmlstru, pszPath, szData, sizeof(szData));}

define的内容当然可以有分号，不然怎么玩复杂的语法糖？


Question: c语言反汇编

这是按照嵌入汇编，显示的反汇编代码 0x80484a0 明显是C格式，不是汇编格式

这个地址应该是全局数据区的地址,在PE中是rdata这个数据节,他存储的是一些编译时需要的常量,比如 char szTemp[] = "abcd",这个"abcd"就是存储在rdata这个数据节中的.至于你说的超出程序地址空间的地址.我猜可能是你看错了!


Question: C语言， vsnprintf 打印方法

这个问题有两个解决方案，第一个难度比较大，就是自己解释格式，自己输出，够24个换行继续输出。 //第二个，把所有数据输出到字符数组中，每次截取lensize个输出 //每行只打印lensize 个字符 int myprintf(const int lensize,const char *fmt,... ) {    char *buff=NULL;      const int termsize =4;      va_list lst;      va_start (fmt,lst);      int n = vscprintf(fmt,lst);      buff =(char *) malloc ((n + termsize )* sizeof(char));      vsnprintf(buff,n,fmt,lst);            char *pcurr =buff,*pterm;      char swaper =0;      pterm =pcurr + linesize;       //每次取出linesize字节输出，最后不足linesize的单独输出，没有处理'\t'字符。           //为了节省复制数据的操作，下面取个巧       //数据分段输出，具体方法是每个linesize个字符，输出一次      //每次输出，在分段处做替换，过程如下        //保存要被替换的字符，字符替换成结束符，输出数据,字符替换回来。      while(pterm < buff+n)      {          swaper =*pterm; //保存，被替换的数据，，          *pterm = '\0';  //替换为结束符          printf("%s\n",pcurr);          *pterm= swaper;   //替换回来          pcurr +=  linesize; //指针位置，增加linesize。          pterm += linesize;  //      }       if(pcurr< pbuf + n )          printf("%s\n",pcurr);      free(pbuff);      va_end(lst);   }   Ps ： printf 替换为 a_debug 就差不多了。

熟悉vsnprintf的返回值，你才能写出正确的程序，兼具效率与灵活性，选一个折衷方案：  #include <stdio.h> #include <stdlib.h> #include <stdarg.h>  typedef void (*line_callback)(const char *line, int bytes);  void printf_callback(const char *line, int bytes) {     printf("%.*s\n", bytes, line); }  int limited_printf(const char *fmt, int chars_per_line, line_callback cb, ...) {     if (!fmt || !cb || chars_per_line <= 0)         return -1;      va_list ap;     va_start(ap, cb);      char minimal[1024];      char *buf = minimal;     int size = sizeof(minimal);          int ret = vsnprintf(buf, size, fmt, ap);     if (ret >= sizeof(minimal))     {         size = ret + 1;         buf = malloc(size);         ret = vsnprintf(buf, size, fmt, ap);     }      int i;     for (i = 0; i < ret; i += chars_per_line)         cb(buf + i, ret - i >= chars_per_line ? chars_per_line : ret - i);      if (size != sizeof(minimal))         free(buf);     return 0; }  int main(int argc, char *argv[]) {     limited_printf("%s", 2, printf_callback, "1234567");     return 0; }

引用 4 楼 missheaven2011 的回复:对debug进行打印啊，24字节打印一下，人为控制下应该就可以了  怎样人为控制呢？？

对debug进行打印啊，24字节打印一下，人为控制下应该就可以了

没有完全明白。 a_debug() 是什么函数？不支持多行输出吗？

引用 1 楼 N_sev7 的回复:int vsnprintf(char *str, size_t size,  const  char  *format,  va_list ap); 参数说明: char *str [out],把生成的格式化的字符串存放在这里. size_t size [in], buffer可接受的最大字节数,防止产生数组越界. const char *format [in], 指定输出格式的字符串，它决定了你需要提供的可变参数的类型、个数和顺序。 va_list  ap [in], va_list变量. va:variable-argument:可变参数 然后呢？


Question: 通过按键来设置时分秒，祝各位大神国庆节快乐！

参考《编译原理》中的词法分析和有限状态自动机。

看着挺复杂的样子哦！~


Question: 如何给结构体成员赋值问题

没有错误吧！ 楼主 clean下，再make试试

vs08全都没有问题（包括注释了的——）

codeblock with mingw-gcc 4.6.2没有问题。

别太在意不同编译器的结果不同，毕竟不是搞编译器的。。。。

struct point { int x; int y; }; The keyword struct introduces a structure declaration, which is a list of declarations enclosed in braces. An optional name called a structure tag may follow the word struct (as with point here). The tag names this kind of structure, and can be used subsequently as a shorthand for the part of the declaration in braces.  那是初始化，不是赋值

学习了！

struct student st={"John",100}; 只能在结构体定义的地方这样初始化； 如果在其他地方，就只能逐个成员初始化了，所以 st={"John",100}是不行的

1.没见过 student st={"John",100},*ptr;的写法。不过在vs2010上可以通过。你说的不能在gcc4.2上通过，肯定是编译器的问题，我没有4.2的gcc所以没试，可以找个4.2的机子再试试，看是否是因为缺少了什么。应该还可以通过gcc网站查看不同的版本有哪些不同。 2.我了解的赋值方式就是你说的struct student st={"John",100};或者:st.name="John";st.score=100;

C语言标准是需要struct student st带struct定义结构体变量的，student st的话并不是所有编译器都支持的，如果一定要用student st的话，那么最好用typedef进行定义： typedef struct student{ 		char name[20]; 		int score; 	}student;  引用 楼主 zaixiankaifa 的回复:#include <stdio.h>  int main() { 	struct student{ 		char name[20]; 		int score; 	};  	struct student st={"John",100},*ptr; 	//	  student st={"John",100},*ptr; 		ptr=&st;  	printf("ptr->name=%s\n",ptr->name);  return 0; }        用gcc 4.2编译器无法编译：//	  student st={"John",100},*ptr;,但是用VS08却可以, 是不是编译器问题？       另外用gcc 4.2也无法这样编译：st={"John",100};是不是只能这样赋值：struct student st={"John",100};或者:st.name="John";st.score=100; ?


Question: 请大家给我个方向

tcpcopy啊, 学习一下.

网络搜索下"FTP" 参考下

引用 6 楼 chen908987082 的回复:谢谢各位的帮助，最近在找工作，但是没什么项目，能不能推荐一些能写在简历上的LINUX网络项目，我打算一周搞定，谢谢各位  不如静下心看：unix网络编程

文件传输FTP靠谱点！ 找FTP的源码学习学习吧！

了解一下socket编程~然后自己定义一下通讯协议!

参考wget源码。  引用 楼主 chen908987082 的回复:有语言基础，想做个小项目：linux下网络文件传输工具（一周时间内），但是不知道如何下手


Question: c++ primer

抱歉，发错地方了  这里解释一下你的问题： 这句话的实质是 1）地址本身是不区分类型的，你可以用同一个地址，存储不同类型（字节数）的数据。 2）某地址中的数据类型，是地址所代表的存储单元，内部存储的数据的类型（数据大小，字节数）。

网上搜到的的一个算法  http://www.ahathinking.com/archives/103.html  你可以看一看。

我们可以用一个地址是指任何几个不同大小的位地址字节集

我们可以使用一个地址来引用任何几个不同大小的字节地址位的集合 大概的意思就是，可以用一个地址给不同类型的变量赋值，不同类型的变量的位的个数是不一样的，例如当你给int赋值时collections of bits是32，char就是8，但是都是字节的的整数倍，下次再贴这样的句子的时候最好能把上下文都贴上，那样别人帮你理解起来也简单些


Question: windows串口api读串口 程序卡死，长时间会蓝屏，求教

要用异步事件，参考http://www.vckbase.com/index.php/wv/1439.html  引用 楼主 TonyShengTan 的回复:想做个qt的串口数据波形显示，但串口读出来的数据有问题，会卡死（单片机不停的发数据） #include <stdio.h> #include<Windows.h> #include<iostream> #define MAXBLOCK 80  int main(){ 	HANDLE hCom;  //全局变量，串口句柄   	hCom=CreateFile("COM3",//COM1口       GENERIC_READ|GENERIC_WRITE, //允许读和写       0, //独占方式       NULL,       OPEN_EXISTING, //打开而不是创建       0, //同步方式       NULL);   	if(hCom==(HANDLE)-1){   		printf("串口无法打开\n"); 	}   	SetupComm(hCom,1024,1024); //输入缓冲区和输出缓冲区的大小都是1024     	COMMTIMEOUTS TimeOuts;   //设定读超时   	TimeOuts.ReadIntervalTimeout=1000;   	TimeOuts.ReadTotalTimeoutMultiplier=500;   	TimeOuts.ReadTotalTimeoutConstant=5000;   //设定写超时   	TimeOuts.WriteTotalTimeoutMultiplier=500;   	TimeOuts.WriteTotalTimeoutConstant=2000;   	SetCommTimeouts(hCom,&TimeOuts); //设置超时     	DCB dcb;   	GetCommState(hCom,&dcb);   	dcb.BaudRate=19200; //波特率为19200   	dcb.ByteSize=8; //每个字节有8位   	dcb.Parity=NOPARITY; //无奇偶校验位   	dcb.StopBits=ONESTOPBIT; //一个停止位   	SetCommState(hCom,&dcb);     	PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);   	unsigned char str[10];  	DWORD wCount;//读取的字节数   	BOOL bReadStat; 	int line=0; 	int total;  	while(1){ 		 		int i=0; 		bReadStat=ReadFile(hCom,str,10,&wCount,NULL);   		total=wCount; 		if(!bReadStat)  {   			printf("读串口失败!\n");        		} else{ 			while(wCount--){ 				printf("%d:%x\n",line++,str[i]); 				i++; 			}  		} 			PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);  		 	} } 奇怪的事情是，如果在运行这个程序之前运行一下串口调试助手，那么这个程序就能无限的读下去

是不是还有没初始化到的地方  启动串口工具的时候 工具也会自己初始化一次  下面仅供参考 楼主好运   BOOL ComXXX::Initialize(CString comName, int nBaudRate) {  	// 初始化变量 	m_rSize = 0; 	memset(m_rBuf, 0, sizeof(m_rBuf));  	// 打开串口 	m_hCom = CreateFile(comName, 						GENERIC_READ | GENERIC_WRITE, 						0,    // Exclusive access  						NULL, // No security attributes  						OPEN_EXISTING, 						0,    // FILE_FLAG_OVERLAPPED 						NULL); 	if (m_hCom == INVALID_HANDLE_VALUE) { 		// 打开失败 		AfxMessageBox("打开失败"); 		return FALSE; 	}  	if(nBaudRate>0) { 		// 设置比特率 		m_nBaudRate = nBaudRate; 	}  	// 取得指定串口的当前状态 	DCB dcb; 	if(!GetCommState(m_hCom,(LPDCB)&dcb)) { 		return FALSE; 	}  	dcb.BaudRate = (DWORD)m_nBaudRate; 	dcb.ByteSize = 8; 	dcb.Parity = NOPARITY; 	dcb.StopBits = ONESTOPBIT; 	dcb.fBinary = 1;  	// 设置指定串口状态 	if(!SetCommState(m_hCom, &dcb)) { 		LPVOID lpMsgBuf; 		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |  					  FORMAT_MESSAGE_FROM_SYSTEM |  					  FORMAT_MESSAGE_IGNORE_INSERTS, 					  NULL, 					  GetLastError(), 					  0,  					  (LPTSTR)&lpMsgBuf, 					  0, 					  NULL); 		MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION); 		LocalFree(lpMsgBuf); 		return FALSE; 	} 	 	// 设置超时 	COMMTIMEOUTS timeouts; 	timeouts.ReadIntervalTimeout			= MAXDWORD; // 读间隔超时 	timeouts.ReadTotalTimeoutMultiplier		= 0; // 读时间系数 	timeouts.ReadTotalTimeoutConstant		= 0; // 读时间常量 	timeouts.WriteTotalTimeoutMultiplier	= 0; // 写时间系数 	timeouts.WriteTotalTimeoutConstant		= 1500; // 写时间常量(1.5秒后写超时)  	if (!SetCommTimeouts(m_hCom, &timeouts)) { 		// 设置超时失败 		return FALSE; 	}  	// 设置串口读缓冲和写缓冲的大小 	SetupComm(m_hCom, 1024*4, 512*4);  	// 清空串口读写缓冲区 	PurgeComm(m_hCom, PURGE_RXCLEAR | PURGE_TXCLEAR);  	// 启动线程 	IsComStateOnFree= false; 	m_comThread = AfxBeginThread(CComIO::RecvHandler, this, THREAD_PRIORITY_HIGHEST); 	m_bExitFlag = FALSE;  	  	return TRUE; }


Question: 关于IOCCC的一道题，兴趣看看

引用 6 楼 zhao4zhong1 的回复:A[B] 等价于 *(A+B) 等价于 *(B+A) 等价于 B[A]  赵老师正解

A[B] 等价于 *(A+B) 等价于 *(B+A) 等价于 B[A]

对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）

除了“加数”可以任意交换外，还有什么？

引用 2 楼 qq523176585 的回复:VC下编译通不过哈。。。。 C专家编程里面有讲这个。。。。   VC上面需要定义一个宏  #define unix 1  其实和这个是差不多的 "abcde"[1] = 1["abcde"] = 'b';"abcde"是一个指向'a'的地址

VC下编译通不过哈。。。。 C专家编程里面有讲这个。。。。

http://www.cnblogs.com/me_hades/archive/2011/08/06/2129726.html 这里面解释了。

仅仅限于有印象而已

在VS中编译不过？ 是要加#define unix 1 吗？ 输出的东西好诡异！


Question: ACM 寻找素数对

用筛法把10000以内的素数筛出来.

方向要反，这样找到第一个就是所求的，如果还不行 为了提高速度，可以先把10000以内的素数先求出来，然后在程序里面查表就可以了


Question: 关于链码表转线段表的问题

我的理解是,所谓“中间点、左端点、右端点”是指端点在线段围成的区域的相对方位，而不是指端点在线段中的方位。请看下例（其中数字代表方向）：

5 6 7 4 X 0            八联通示意图 3 2 1

不知所云，无法回答

自己 顶一下  啊


Question: 请教free函数的作用

引用 6 楼 u012287871 的回复:可是执行后，是正确的结果，并且是唯一的结果啊 [quote=引用 3 楼 lin5161678 的回复:] 这么做是不对的  未定义行为了[/quote]不做保证  你换一个编译 换一下编译参数 结果可能就不对了

free只是释放了指针所指向地址的空间，本质上就是做了一些标记而已，所以指针及空间内容都还是存在的，只不过有隐患罢了。  引用 4 楼 u012287871 的回复:那current->next这个指针本身，不是在current指向的内存块中存储的吗？ [quote=引用 1 楼 turingo 的回复:] free的是current所指向地址的内存，而不是current->next所指向地址的内存。  [quote=引用 楼主 u012287871 的回复:] 我看c primer的书里，有这么个结构 struct film{     char title[TSIZE];     int rating;     struct film * next; } 下面的current, head都是这个结构的指针。 在清理列表的时候 current = head; while(current != NULL) {     free(current);     current = current->next; } 这里我理解的是，free()已经释放了current指向内存，可是，为什么current->next还是可以指向这个指针成员？[/quote][/quote]

引用 11 楼 mingliang1212 的回复:[quote=引用 6 楼 u012287871 的回复:] 可是执行后，是正确的结果，并且是唯一的结果啊 [quote=引用 3 楼 lin5161678 的回复:] 这么做是不对的  未定义行为了[/quote]  看本好书。 你判断正确和错误的标准有问题。 google 未定义行为 [/quote]  好的~感谢提醒~~

引用 6 楼 u012287871 的回复:可是执行后，是正确的结果，并且是唯一的结果啊 [quote=引用 3 楼 lin5161678 的回复:] 这么做是不对的  未定义行为了[/quote]  看本好书。 你判断正确和错误的标准有问题。 google 未定义行为

我明白了！！！感谢大家的耐心回答！！结贴~~~~~~

free(current); //要求在此没有别的线程或进程修改current->next的值 current = current->next;

释放的是当前的地址，它的next地址还是有效的 这是链表删除的基本操作吧！ 分配的内存谁分配谁释放，每分配一次，都必须对应释放一次的！

操作系统肯定要这样做，一个效率高，一个也没必要 不过程序员free后，是应该吧指针设置为NULL的，才是标准的，不然就是野指针了。

可是执行后，是正确的结果，并且是唯一的结果啊 引用 3 楼 lin5161678 的回复:这么做是不对的  未定义行为了

意思是释放的内存块，只是通知内存又可以覆盖别的了，可是他现在的内容其实并没有清空？ 我觉得你这么说好像有点道理啊 引用 2 楼 Idle_Cloud 的回复:这个内存是释放了，操作系统也知道了，但是free不会去做清零的动作，也没必要。

那current->next这个指针本身，不是在current指向的内存块中存储的吗？ 引用 1 楼 turingo 的回复:free的是current所指向地址的内存，而不是current->next所指向地址的内存。  [quote=引用 楼主 u012287871 的回复:] 我看c primer的书里，有这么个结构 struct film{     char title[TSIZE];     int rating;     struct film * next; } 下面的current, head都是这个结构的指针。 在清理列表的时候 current = head; while(current != NULL) {     free(current);     current = current->next; } 这里我理解的是，free()已经释放了current指向内存，可是，为什么current->next还是可以指向这个指针成员？[/quote]

这么做是不对的  未定义行为了

这个内存是释放了，操作系统也知道了，但是free不会去做清零的动作，也没必要。

free的是current所指向地址的内存，而不是current->next所指向地址的内存。  引用 楼主 u012287871 的回复:我看c primer的书里，有这么个结构 struct film{     char title[TSIZE];     int rating;     struct film * next; } 下面的current, head都是这个结构的指针。 在清理列表的时候 current = head; while(current != NULL) {     free(current);     current = current->next; } 这里我理解的是，free()已经释放了current指向内存，可是，为什么current->next还是可以指向这个指针成员？


Question: 求一函数～可以检查出静态分配的地址偏移量没有和其他的冲突！

另外你可以写一个程序，作为编译器的辅助工具； 检查有没有重叠之类的地址冲突，如果编译器自身提供不了类似功能的话。

你可以做个静态链表， 或者B+树来管理文件系统

没看明白楼主的需求 要说重复覆盖的问题，只能是你们设计的问题。 如果有多个文件都申请的话，应该是统一由一个函数去申请（该函数管理一个链表结构，类似内存管理），而不能每个文件自己实现一个申请的函数。

所有地址，写到一个头文件 定义为  宏常量， 或者枚举常量 或者C++常量 使用时调整这些常量即可，不用检查。

判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

lz 是怀疑compiler 有问题？

引用 4 楼 user-8 的回复:别扯啦，根本不可能冲突的啊。 只会是你自己使用过程中数组越界。  我是初学者，可能是我表达的不太清楚，程序用的是文件系统进行数据存储，每个文件都负责管理不同种类的数据，在文件内对应一张存储分配表，表里面的包括数据项的DI和偏移地址。例如：static DBSS_ITEM ms_parms[] =  { //	DI				Offset 	{0x00000000,	0x00000000},  	{0x00000001,	0x00000120}, 	{0x00000002,	0x00000200},         。。。 }; DI代表了一种数据，这个数据的可能是个结构体也可能是个数组也可能是任何复杂的复合类型，但是他的最大长度是确定的，OFFSET是偏移起始地址。如图第一个DI的最大长度是120字节，我给他分配对应的地址范围是0x00000000到0x00000120,第二个DI就是接着DI1后面继续偏移，后面的DI偏移地址也是这样人工自定义的，整个工程可能包含很多个这样的文件，对应的也有很多张这个表，我怎么确保文件之间分配的静态存储空间偏移是别人没有用过的。自己一个一个去检查可能太耗时间，因为整个工程有很多个模块，每个模块有专门的人负责编写，其他人怎么申请静态存储（他申请的是哪一段存储空间等），可能事先都不知道，而且就算不同的人用了重复的空间，最后编译都不会报错，只是在程序运行后存数据的时候会不停的彼此覆盖，这样对于我们来说是最可怕的失误，所以我想做个函数检查一下整个工程里面，有没有重复的申请静态存储空间，可以提前打印调试信息。希望可以帮帮我（有点啰嗦，希望能帮助理解。）。

楼主想干啥？这怎么可能冲突呢？

静态分配，感觉要检查难度很大啊。 为何不考虑初始化的时候动态申请呢？申请的时候记录起始地址和大小，这样由系统来保证内存不重叠

根本就不会有地址重叠，你要把握好指针与数组的关系。注意指向位置，就算是重叠也变成双向的链表了

别扯啦，根本不可能冲突的啊。 只会是你自己使用过程中数组越界。

求关注求关注

求关注！！！求关注


Question: 求使用Ndis抓包的方法

应用程序，我就是想用ndis抓包，能不能指导一下

楼主是驱动编译失败了还是应用程序编译失败了？


Question: 求解：对一组字符数组按照自定义的字母顺序排序应该怎么做

//字母优先级是  d, f, e, c, a .  然后字符数组是str=｛"deec","dac","ceef","fee"｝;输出的是"deec","dac","fee","ceef" #include <stdio.h> #include <string.h> int od(char c) {     char *p;     char order[6]="dfeca";      if (0==c) return -1;     p=strchr(order,c);     if (NULL==p) return -1;     return p-order; } int cmp(char *s1,char *s2) {     int od1,od2;      while (1) {         od1=od(*s1);         od2=od(*s2);         if (od1<od2) return -1;         if (od1>od2) return  1;         if (-1==od1 && -1==od2) return 0;         s1++;         s2++;     } } int main() {     char *str[4]={"deec","dac","ceef","fee"};     char *t;     int i,j;     for (i=0;i<4-1;i++) {         for (j=i+1;j<4;j++) {             if (1==cmp(str[i],str[j])) {                 t=str[i];str[i]=str[j];str[j]=t;             }         }     }      for (i=0;i<4-1;i++) printf("\"%s\",",str[i]);     printf("\"%s\"",str[i]);     return 0; } //"deec","dac","fee","ceef"

给每个字母重新定义权值，类似于： int right[26] = { xx, xx, xx, ... , xx };  对于楼主举的这个例子：d, f, e, c, a  可以这样做：  int right[26] = {1, 0, 2, 5, 3, 4, 0, 0, ...., 0};  一个新的字符串比较的函数：  int mystrcmp( const char *str1, const char *str2) {     while (*str1 && *str2 && *str1++ == *str2++) ;     if ('\0' == *str1 && '\0' == *str2)  return 0;     if ('\0' == *str1 )   return -*str2;     if ('\0' == *str2 )   return *str1;     return right[*str1 - 'a'] - right[*str2 - 'a']; }  我这个写的只是举个例子，希望能起到抛砖引玉的效果

做个表吧  char alphaorder[26]= {......};//自定义顺序

先写个最基础的函数，参数是两个字母，返回bool，通过这个函数确定字母的优先级，然后需要实现字符串排序函数

>>> priority = {'d':0, 'f':1, 'e':2, 'c':3, 'a':4 } >>> def keyfunc(str): 	return priority[str[0]]  >>> slist = {'deec', 'dac', 'ceef', 'fee'} >>> result = sorted(slist, key = keyfunc) >>> result ['dac', 'deec', 'fee', 'ceef']  python写了一个。 priority为字符串到int的映射表，keyfunc返回sorted函数用于比较的主键。 sorted对字符串slist的所有键排序，结果在result中。


Question: 用C语言实现单链表的生成(求解= =\\\\\\\\\)

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


Question: const char * 转 char * 疑问

日经贴

const char *s="hello world";  这样s是一个指针，指向一块只读区域，该区域最开始处是"hello world\0",程序无法修改只读区域的内容；  char s[]="hello world";  这样s是一个数组，或者说数组名，该数组在编译连接后确定为含12个元素（包括结束符'\0'），指针转换后，可以修改数组中元素内容

const char *s="hello world";  这么申明字符串本来就没法修改。 char s[]="hello world";  这么申明才可以修改。


Question: GTK+官方中文文档？

这么窄的范围的文档一般很少有中文的了

看英文的又不会死…… 关键是，你不能期望这东西总有中文文档，特别是新版本的。


Question: ubuntu系统，怎样开发触摸屏桌面应用程序？

GTK＋，MYSQL? 这两个都不是语言啊

这个谁说说呢？


Question: 位运算的小程序求解

引用 2 楼 user-1 的回复:位预算符而已！   z=~0;   //~一元运算符， 0000 0000对数据取反1111 1111 z=(z>>n1)&(z<<(16-n2));  //把z先右移n1位和左移16-n2位的结果取与运算， //(具体的是不是这样得实践下，这里我一般会分开操作) z=value&z; //z和value 与运算 z=z>>(16-n2); //把z右移16-n2位，结果赋值给z  参考下 http://blog.csdn.net/heiniaoyuyouling/article/details/4696586 版主大大 你好！我输入7，接着输入位数14 ，15，最后得出3，能为我分析一下么……谢谢了

n1，n2是要提取的位数，忘了表明了


Question: ACM 简单A+B

什么叫无法调试？ 目测代码无问题啊

引用 1 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我也知道的啦，是这题我纠结了一下午了，实在看不出哪里有问题，后来才发现是软件出BUG了，囧死了、。。。