Question: 迷宫问题

请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？

#include<stdio.h> #include<stdlib.h>   typedef struct { 	int x,y,r; 	/*line、list、dir分别为数组元素的行坐标、列坐标、choice数组的下标值即对应方向*/ } DataType;  struct SeqStack { 	int MAXNUM; 	int t; 	DataType *s; }; typedef struct SeqStack *PSeqStack;  PSeqStack create_EmptySeqStack(int n) { 	PSeqStack p=(PSeqStack)malloc(sizeof(struct SeqStack));     if(p!=NULL)     {     	p->s=(DataType*)malloc(sizeof(DataType)*n); 	    if(p->s) 	    { 		    p->MAXNUM=n; 		    p->t=-1; 		    return p; 	    }         else free(p);     }     printf("Out of Space!\n"); 	return NULL; }  int createmaze(int a[20][20],int m,int n) { 	int x,y; 	printf("请输入内部迷宫组织，可走通的路径点为0，走不通为1.\n"); 	for(x=0;x<m;x++) 	{ 		for(y=0;y<n;y++) 		{ 			scanf("%d",&a[x][y]); 		} 	} 	     }  int is_EmptyStack(PSeqStack p) { 	return(p->t==-1); }  void pop(PSeqStack p) { 	if(p->t==-1) printf("Underflow!\n"); 	else p->t=p->t-1; }  DataType top(PSeqStack p) { 	if(p->t!=-1) return(p->s[p->t]); }  void push(PSeqStack p,DataType x) { 	if(p->t>=(p->MAXNUM)-1) printf("Overflow!\n"); 	else 	{ 		p->t=p->t+1; 		p->s[p->t]=x; 	} }  void mazepath(int (*maze)[20],int (*direction)[2],int x1,int y1,int x2,int y2,int M,int N) { 	int i,j,k; 	int g,h; 	PSeqStack st; 	DataType element; 	st=create_EmptySeqStack(M*N); 	maze[x1][y1]=2; 	element.x=x1; 	element.y=y1; 	element.r=-1; 	push(st,element); 	while(!is_EmptyStack(st)) 	{ 		element=top(st); 		pop(st); 		i=element.x; 		j=element.y; 		k=element.r+1; 		while(k<=3) 		{ 		    g=i+direction[k][0]; 		    h=j+direction[k][1]; 		    if(g==x2&&h==y2&&maze[g][h]==0) 		    { 			    printf("The reverse path is:\n"); 			    while(!is_EmptyStack(st)); 			    { 				    element=top(st); 				    pop(st); 				    printf("the node is:%d%d\n",element.x,element.y); 			    } 			    return; 		    } 		    if(maze[g][h]==0) 		    {  		    	maze[g][h]=2; 		    	element.x=i; 			    element.y=j; 			    element.r=k; 			    push(st,element); 			    i=g; 			    j=h; 			    k=-1; 		    } 		k=k+1; 		} 	} 	printf("The path has not been found.\n"); }  int main() { 	int a,b,c,d,i,j; 	int s=0; 	int sta1,sta2,end1,end2; 	int maze[20][20]; 	printf("确定迷宫大小：请输入迷宫长、宽分别为(长宽均不大于100)：\n"); 	scanf("%d %d",&a,&b); 	createmaze(maze,a,b); 	printf("请输入入口、出口坐标为：\n"); 	scanf("%d %d %d %d",&sta1,&sta2,&end1,&end2);     maze[end1][end2]=0;                                                     	int choice[4][2]={0,1,1,0,0,-1,-1,0};     mazepath(maze,choice,sta1,sta2,end1,end2,a,b);     return 0; }   谢谢  结果总是出不来 top函数也不知道改得对不对

那可能是你代码的问题，你现在代码是什么，怎么输入，我帮你看下

引用 6 楼 user-3 的回复:[quote=引用 5 楼 may_Xia 的回复:] [quote=引用 4 楼 user-3 的回复:] [quote=引用 3 楼 may_Xia 的回复:] [quote=引用 2 楼 user-3 的回复:] top函数不是每种情况都有返回值  for(x=1,y=1;x<m-1,y<n-1;x++,y++)  应该是这样吧：  for(x=1,y=1;x<m-1&&y<n-1;x++,y++)     如果改成这样 int createmaze(int a[100][100],int m,int n) { 	int x,y; 	printf("请输入内部迷宫组织，可走通的路径点为0，走不通为1.\n"); 	for(x=0,y=0;x<m&&y<n;x++,y++) 	    scanf("%d",&a[x][y]); } 就算输入长宽分别为9,也只能只输入9个数就跳到下一步了,为啥呢??[/quote]  你应该把循环写成骨嵌套的等式，外层对x，内层对y循环[/quote]      改了...然后无论怎么输入都是overflow[/quote]  是栈溢出吗，你的int maze[100][100];数组比较大  把项目属性中栈大小设置大一点：        打开此项目的“属性页”对话框。有关详细信息，请参见设置 Visual C++ 项目属性。      单击“链接器”文件夹。      单击“系统”属性页。      修改下列任一属性：          堆栈提交大小          堆栈保留大小[/quote]  引用 6 楼 user-3 的回复:[quote=引用 5 楼 may_Xia 的回复:] [quote=引用 4 楼 user-3 的回复:] [quote=引用 3 楼 may_Xia 的回复:] [quote=引用 2 楼 user-3 的回复:] top函数不是每种情况都有返回值  for(x=1,y=1;x<m-1,y<n-1;x++,y++)  应该是这样吧：  for(x=1,y=1;x<m-1&&y<n-1;x++,y++)     如果改成这样 int createmaze(int a[100][100],int m,int n) { 	int x,y; 	printf("请输入内部迷宫组织，可走通的路径点为0，走不通为1.\n"); 	for(x=0,y=0;x<m&&y<n;x++,y++) 	    scanf("%d",&a[x][y]); } 就算输入长宽分别为9,也只能只输入9个数就跳到下一步了,为啥呢??[/quote]  你应该把循环写成骨嵌套的等式，外层对x，内层对y循环[/quote]      改了...然后无论怎么输入都是overflow[/quote]  是栈溢出吗，你的int maze[100][100];数组比较大  把项目属性中栈大小设置大一点：        打开此项目的“属性页”对话框。有关详细信息，请参见设置 Visual C++ 项目属性。      单击“链接器”文件夹。      单击“系统”属性页。      修改下列任一属性：          堆栈提交大小          堆栈保留大小[/quote]   我直接把数组改成了20X20？ 然后输入迷宫大小是3X3 迷宫点都可走通都为0 入口1 1 出口3 3 他也显示全是overflow

引用 4 楼 user-3 的回复:[quote=引用 3 楼 may_Xia 的回复:] [quote=引用 2 楼 user-3 的回复:] top函数不是每种情况都有返回值  for(x=1,y=1;x<m-1,y<n-1;x++,y++)  应该是这样吧：  for(x=1,y=1;x<m-1&&y<n-1;x++,y++)     如果改成这样 int createmaze(int a[100][100],int m,int n) { 	int x,y; 	printf("请输入内部迷宫组织，可走通的路径点为0，走不通为1.\n"); 	for(x=0,y=0;x<m&&y<n;x++,y++) 	    scanf("%d",&a[x][y]); } 就算输入长宽分别为9,也只能只输入9个数就跳到下一步了,为啥呢??[/quote]  你应该把循环写成骨嵌套的等式，外层对x，内层对y循环[/quote]     是因为没有定义MAXNUM吗？如果直接用宏定义它也显示错误

引用 5 楼 may_Xia 的回复:[quote=引用 4 楼 user-3 的回复:] [quote=引用 3 楼 may_Xia 的回复:] [quote=引用 2 楼 user-3 的回复:] top函数不是每种情况都有返回值  for(x=1,y=1;x<m-1,y<n-1;x++,y++)  应该是这样吧：  for(x=1,y=1;x<m-1&&y<n-1;x++,y++)     如果改成这样 int createmaze(int a[100][100],int m,int n) { 	int x,y; 	printf("请输入内部迷宫组织，可走通的路径点为0，走不通为1.\n"); 	for(x=0,y=0;x<m&&y<n;x++,y++) 	    scanf("%d",&a[x][y]); } 就算输入长宽分别为9,也只能只输入9个数就跳到下一步了,为啥呢??[/quote]  你应该把循环写成骨嵌套的等式，外层对x，内层对y循环[/quote]      改了...然后无论怎么输入都是overflow[/quote]  是栈溢出吗，你的int maze[100][100];数组比较大  把项目属性中栈大小设置大一点：        打开此项目的“属性页”对话框。有关详细信息，请参见设置 Visual C++ 项目属性。      单击“链接器”文件夹。      单击“系统”属性页。      修改下列任一属性：          堆栈提交大小          堆栈保留大小

引用 4 楼 user-3 的回复:[quote=引用 3 楼 may_Xia 的回复:] [quote=引用 2 楼 user-3 的回复:] top函数不是每种情况都有返回值  for(x=1,y=1;x<m-1,y<n-1;x++,y++)  应该是这样吧：  for(x=1,y=1;x<m-1&&y<n-1;x++,y++)     如果改成这样 int createmaze(int a[100][100],int m,int n) { 	int x,y; 	printf("请输入内部迷宫组织，可走通的路径点为0，走不通为1.\n"); 	for(x=0,y=0;x<m&&y<n;x++,y++) 	    scanf("%d",&a[x][y]); } 就算输入长宽分别为9,也只能只输入9个数就跳到下一步了,为啥呢??[/quote]  你应该把循环写成骨嵌套的等式，外层对x，内层对y循环[/quote]      改了...然后无论怎么输入都是overflow

引用 3 楼 may_Xia 的回复:[quote=引用 2 楼 user-3 的回复:] top函数不是每种情况都有返回值  for(x=1,y=1;x<m-1,y<n-1;x++,y++)  应该是这样吧：  for(x=1,y=1;x<m-1&&y<n-1;x++,y++)     如果改成这样 int createmaze(int a[100][100],int m,int n) { 	int x,y; 	printf("请输入内部迷宫组织，可走通的路径点为0，走不通为1.\n"); 	for(x=0,y=0;x<m&&y<n;x++,y++) 	    scanf("%d",&a[x][y]); } 就算输入长宽分别为9,也只能只输入9个数就跳到下一步了,为啥呢??[/quote]  你应该把循环写成骨嵌套的等式，外层对x，内层对y循环

引用 2 楼 user-3 的回复:top函数不是每种情况都有返回值  for(x=1,y=1;x<m-1,y<n-1;x++,y++)  应该是这样吧：  for(x=1,y=1;x<m-1&&y<n-1;x++,y++)     如果改成这样 int createmaze(int a[100][100],int m,int n) { 	int x,y; 	printf("请输入内部迷宫组织，可走通的路径点为0，走不通为1.\n"); 	for(x=0,y=0;x<m&&y<n;x++,y++) 	    scanf("%d",&a[x][y]); } 就算输入长宽分别为9,也只能只输入9个数就跳到下一步了,为啥呢??

void mazepath(int *maze[],int *direction[],int x1,int y1,int x2,int y2,int M,int N)  改成；  void mazepath(int (*maze)[100],int (*direction)[2],int x1,int y1,int x2,int y2,int M,int N)


Question: core文件分析

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令  搜出错代码对应地址附近的若干条汇编指令对应的opcode 使用IDA Pro带pcode反汇编 应该比较容易找到对应源代码位置。

就是不知道怎么去定位到底哪行代码出了问题。。。


Question: 为什么free函数的形参是void*类型，传入的是其他类型 指针不报警告？

你的代码在vs 2015下也没错，我设想是这样改，无法验证    #include <malloc.h>  void myfree(void **ppuff) { 	if (NULL != ( int *)(*ppuff ) ) 	{ 		free( ( int * )(*ppuff) ); 		*ppuff = NULL; 	} }   int main(int argc, char* argv[]) { 	void *x; 	myfree(&x);  	printf("Hello World!\n"); 	return 0; }

你强转成unsigned char *试试，我在vc6下没问题，无linux环境。

void **buf的 *buf，是取他的值，你类型是void *的，不知道取什么址。

引用 6 楼 liangchaoxi 的回复:[quote=引用 2 楼 fefe82 的回复:] [quote=引用 楼主 liangchaoxi 的回复:] linux编译器GCC下  为什么free函数的形参是void*类型，传入的是其他类型 指针如 int8*，int32*，不报警告？  比如 int8 *puff = NULL；  free（puff）； 编译器不报类型不符的警告。  而我自己定义的函数  void myfree（void **ppuff) {   if(NULL !=*ppuff) {  free(*ppuff); *ppuff = NULL; }  }  myfree(&puff); 编译器就告警：void** 和 **int8 类型不符。为什么？  如何才能针对这个自己定义的函数去掉这个告警 不能。  指针可以转化为 void * 。  但是 void** 不是 void* 。[/quote]  我知道void*不是void**，所以你看我传入的参数是取了地址的，也就是传入的参数是**类型的，我的意思是为什么库函数可以忽略void* 与 int8* 的类型不同警告，却对用户自定义的void**与int32** 报告警[/quote]  指针可以转换成 void * 。与库函数无关。  关键在与转换的目标。

有可能编译器优化了？判断是指针类型后就强制转换了一把？

引用 4 楼 qq_36409192 的回复:[quote=引用 3 楼 paschen 的回复:] 其他类型指针可以隐式转换为void*  但void*不能隐式转换为其他类型的指针  void* 不等于 void** C++语言在对于void* 类型的使用很特别，因为void* 可以间接引用任何其他数据类型的指针，比如int*、float*甚至抽象数据类型的指针，而且可以从void* 强制转换为任何其他数据类型的指针，所以使用起来有时候会比较危险。[/quote] 我知道void*不是void**，所以你看我传入的参数是取了地址的，也就是传入的参数是**类型的，我的意思是为什么库函数可以忽略void* 与 int8* 的类型不同警告，却对用户自定义的void**与int32** 报告警。其实我就算是定义成myfree(void *p);当我传入一个int8* 的指针时也会告警，为什么为什么库函数不告警？

引用 楼主 liangchaoxi 的回复:linux编译器GCC下  为什么free函数的形参是void*类型，传入的是其他类型 指针如 int8*，int32*，不报警告？  比如 int8 *puff = NULL；  free（puff）； 编译器不报类型不符的警告。  而我自己定义的函数  void myfree（void **ppuff) {   if(NULL !=*ppuff) {  free(*ppuff); *ppuff = NULL; }  }  myfree(&puff); 编译器就告警：void** 和 **int8 类型不符。为什么？  如何才能针对这个自己定义的函数去掉这个告警 不能。  指针可以转化为 void * 。  但是 void** 不是 void* 。

引用 7 楼 liangchaoxi 的回复:[quote=引用 3 楼 paschen 的回复:] 其他类型指针可以隐式转换为void*  但void*不能隐式转换为其他类型的指针  void* 不等于 void**我知道void*不是void**，所以你看我传入的参数是取了地址的，也就是传入的参数是**类型的，我的意思是为什么库函数可以忽略void* 与 int8* 的类型不同警告，却对用户自定义的void**与int32** 报告警[/quote]  上面不是说了吗，并不是忽略警告，而是 int8*（包括其他类型指针） 转 void*是允许的，但其他不同类型之间的直接转换是会有警告

void*和void**能一回事么

引用 3 楼 paschen 的回复:其他类型指针可以隐式转换为void*  但void*不能隐式转换为其他类型的指针  void* 不等于 void**我知道void*不是void**，所以你看我传入的参数是取了地址的，也就是传入的参数是**类型的，我的意思是为什么库函数可以忽略void* 与 int8* 的类型不同警告，却对用户自定义的void**与int32** 报告警

引用 2 楼 fefe82 的回复:[quote=引用 楼主 liangchaoxi 的回复:] linux编译器GCC下  为什么free函数的形参是void*类型，传入的是其他类型 指针如 int8*，int32*，不报警告？  比如 int8 *puff = NULL；  free（puff）； 编译器不报类型不符的警告。  而我自己定义的函数  void myfree（void **ppuff) {   if(NULL !=*ppuff) {  free(*ppuff); *ppuff = NULL; }  }  myfree(&puff); 编译器就告警：void** 和 **int8 类型不符。为什么？  如何才能针对这个自己定义的函数去掉这个告警 不能。  指针可以转化为 void * 。  但是 void** 不是 void* 。[/quote]  我知道void*不是void**，所以你看我传入的参数是取了地址的，也就是传入的参数是**类型的，我的意思是为什么库函数可以忽略void* 与 int8* 的类型不同警告，却对用户自定义的void**与int32** 报告警

引用 1 楼 FancyMouse 的回复:void*和void**能一回事么  你们没有认真看我的题目， 当然知道不一样，所以你看我传入的参数是取了地址的，也就是传入的参数是**类型的

引用 3 楼 paschen 的回复:其他类型指针可以隐式转换为void*  但void*不能隐式转换为其他类型的指针  void* 不等于 void** C++语言在对于void* 类型的使用很特别，因为void* 可以间接引用任何其他数据类型的指针，比如int*、float*甚至抽象数据类型的指针，而且可以从void* 强制转换为任何其他数据类型的指针，所以使用起来有时候会比较危险。


Question: c语言里true是1？-1？别的？

。。。更正下自己的说法。只要是非0的数，转成bool都是true，不要求整数

你这个放到编译器里试下就知道了， 这么说吧，true转成int的值确实是1； 但是所有非0的整数，转成bool都是true； 	bool a=999;//a=true 	int b=true;//b=1

引用 11 楼 dreambyday 的回复:[quote=引用 10 楼 paschen 的回复:] TRUE是int型，通常是被定义为1 true是bool型，转换后的整型结果也是1   如果要判断是否为真时，不应该判断是否等于1，而应判断是否非零 计算机考试时问 小写的true的值为______填1？我看网上有人说-1的，，，确定是1？[/quote]  true转换成整数后的值是1

引用 10 楼 paschen 的回复:TRUE是int型，通常是被定义为1 true是bool型，转换后的整型结果也是1   如果要判断是否为真时，不应该判断是否等于1，而应判断是否非零 计算机考试时问 小写的true的值为______填1？我看网上有人说-1的，，，确定是1？

非0为真，0为假

我们自定义的写成这样...typedef enum{false = 0,true =!false} bool;

引用 2 楼 meixu568 的回复:哪里的-1？ 抱歉写错了，教科书上说true是-1

引用 1 楼 jyxuan94 的回复: 你不是说了吗，宏定义TRUE是1教科书也是，自己输出也是。。。不懂你为什么懵 还有TRUE和true还是有区别的 小写的true的值是1还是-1？

啊，教科书上说是-1

非0

哪里的-1？


Question: 最后一句调用出错，为什么？

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

SeqList *initSL() 函数中，L没有初始化就使用了，你L只是个指针，还没分配内存你就访问自然会出错

现在又要学习10年前学的东西，忘的也差不多了，今天找了一本C书看了看，谢谢各位。

SeqList *initSL(SeqList )  {  int i;  SeqList * L =new   SeqList ;    // 这    L->last=3;  for(i=0;i<=L->last;i++)  scanf("%d",L->elem[i]);  printf("your array has been initialized:\n");  return(L);  }  main()  {   SeqList * L;   L=initSL(); delete L;    //  这  }

SeqList * L 中定义的L是在在栈中的，众所周知，栈中的变量都是临时的，当前函数执行完成后，这些临时变量和参数都会被清除，所以不能将指向这些临时变量的指针返回给调用者，这样的指针指向的变量都是随机的，所以程序会出现意想不到的的错误。


Question: linux上的.c文件和windows上的.c文件语法规则不同？

编译器不同很正常，用memset就可能了

随时定义变量是 C99 才加的,  M$ 不支持 C99 ..

vs 支持的 c 语言版本比较旧，= {0} 这个可能是新语法吧。用 memset 清零就行了。

有如下几种可能： 1 代码运行的平台硬件不同。 不同的CPU，如嵌入式CPU，intel CPU，以及IBM的CPU，在硬件最底层就是不同的，而C语言是一门和底层相关性极大的语言，在不同的硬件上运行出不同结果是很正常的。  2 代码运行的系统不同。 相同CPU在不同操作系统上跑相同代码时，一样会出现不同的结果。这是由于系统底层的实现不同造成的。比如Linux和Windows，在底层处理上就有一定的差异。  3 编译器不同，同时代码中使用了C规范未定义规则的语句。 C语言规范并没有对C语言的所有行为做定义，所以相同语句，不同编译器的运行效果可能有所不同。比如同样的sizeof(int)，在16位编译器上结果为2，而32位编译器上就会是4。  4 代码获取到的外部数据不同。 比如运行代码时获取到的其它输入不同，包括程序中获取的环境变量，实时信息，以及各种外部输入等，均有可能出现不同。 比如在做随机数时，如果以当前时间设定随机数种子，由于每次的时间是不同的，同一个程序每次运行的结果都是不同的。

编译器支持的 C 语言版本不一样。


Question: 怎么减少代码时间超限问题

引用 11 楼 hijack00 的回复:[quote=引用 10 楼 zuoside__lord 的回复:] [quote=引用 9 楼 hijack00 的回复:] [quote=引用 8 楼 zuoside__lord 的回复:] [quote=引用 5 楼 hijack00 的回复:] log运算相较于乘除法更慢，由于多个log相加等价先相乘再取一次log，在n不是很大的时候，可以先计算连乘积，再取一次log就是最终结果。 请问怎么写，，，，不好意思我不太会，，，，[/quote]  #include <stdio.h> #include <math.h> int main(int argc, const char * argv[]) {     int i,n;     double sum, mul;     while(scanf("%d",&n)!=EOF)     {         mul = 1.0;         for(i=2; i<=n; i++)         {             mul *= i;         }         sum = log10(mul);         printf("%f\n", sum);     }     return 0; } [/quote] 你的代码错了，输入5应该输出3，但是输出的是2[/quote]  我的代码只是给你提供一个思路，让你照着改的。 你原来的代码里面有个ceil函数，我把它去掉了。你加上这个就是3而不是2了[/quote] 好滴，谢谢

引用 10 楼 zuoside__lord 的回复:[quote=引用 9 楼 hijack00 的回复:] [quote=引用 8 楼 zuoside__lord 的回复:] [quote=引用 5 楼 hijack00 的回复:] log运算相较于乘除法更慢，由于多个log相加等价先相乘再取一次log，在n不是很大的时候，可以先计算连乘积，再取一次log就是最终结果。 请问怎么写，，，，不好意思我不太会，，，，[/quote]  #include <stdio.h> #include <math.h> int main(int argc, const char * argv[]) {     int i,n;     double sum, mul;     while(scanf("%d",&n)!=EOF)     {         mul = 1.0;         for(i=2; i<=n; i++)         {             mul *= i;         }         sum = log10(mul);         printf("%f\n", sum);     }     return 0; } [/quote] 你的代码错了，输入5应该输出3，但是输出的是2[/quote]  我的代码只是给你提供一个思路，让你照着改的。 你原来的代码里面有个ceil函数，我把它去掉了。你加上这个就是3而不是2了

引用 9 楼 hijack00 的回复:[quote=引用 8 楼 zuoside__lord 的回复:] [quote=引用 5 楼 hijack00 的回复:] log运算相较于乘除法更慢，由于多个log相加等价先相乘再取一次log，在n不是很大的时候，可以先计算连乘积，再取一次log就是最终结果。 请问怎么写，，，，不好意思我不太会，，，，[/quote]  #include <stdio.h> #include <math.h> int main(int argc, const char * argv[]) {     int i,n;     double sum, mul;     while(scanf("%d",&n)!=EOF)     {         mul = 1.0;         for(i=2; i<=n; i++)         {             mul *= i;         }         sum = log10(mul);         printf("%f\n", sum);     }     return 0; } [/quote] 你的代码错了，输入5应该输出3，但是输出的是2

引用 8 楼 zuoside__lord 的回复:[quote=引用 5 楼 hijack00 的回复:] log运算相较于乘除法更慢，由于多个log相加等价先相乘再取一次log，在n不是很大的时候，可以先计算连乘积，再取一次log就是最终结果。 请问怎么写，，，，不好意思我不太会，，，，[/quote]  #include <stdio.h> #include <math.h> int main(int argc, const char * argv[]) {     int i,n;     double sum, mul;     while(scanf("%d",&n)!=EOF)     {         mul = 1.0;         for(i=2; i<=n; i++)         {             mul *= i;         }         sum = log10(mul);         printf("%f\n", sum);     }     return 0; }

引用 5 楼 hijack00 的回复:log运算相较于乘除法更慢，由于多个log相加等价先相乘再取一次log，在n不是很大的时候，可以先计算连乘积，再取一次log就是最终结果。 请问怎么写，，，，不好意思我不太会，，，，

引用 2 楼 FancyMouse 的回复:至少用stirling公式啊，一个个log算多慢。数据不强stirling直接能过的 不会，，，，这个是百度上找了好久，

引用 3 楼 jianwen0529 的回复:输入数据改为读文本？  看起来你程序慢，是因为控制台输入和打印这块 请问怎么修改，别人让我存起来再一次性输出，我不太会

输入数据改为读文本？  看起来你程序慢，是因为控制台输入和打印这块

有大神可以教我改下么，我不太会修改，

一般超时都是算法问题吧。


Question: 二进制位取反的问题

destination指针琐有分配内存就使用了

用了destination=(char*)malloc(sizeof(char)*strlen(argv[1]));分配内存，还是不能运行。

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

#include <stdio.h> #include <string.h> #include <stdlib.h> char *destination; void reverse(const char * source); int main(int argc,char * argv[]) {     char * p; 	p=(char*)malloc(sizeof(char)*strlen(argv[1])); 	destination=p; 	reverse(argv[1]); 	printf("%s",p); 	free(p); 	return 0; } void reverse(const char * source) { 	strcpy(destination,source); 	while(*destination!='\0') 	{ 		if(*destination=='0') *destination='1'; 		else  		    *destination='0'; 		destination++; 	} 	return; }

if (argc > 1)         {             destination = new char[strlen(argv[1]) + 1];             reverse(argv[1]);             printf("%s", destination);             delete destination;         }

参考2楼


Question: 求大神帮忙分析下这个递归 通俗易懂最好有图

单步跟踪程序运行，观察程序运行流程，比别人给你讲要容易懂

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


Question: scanf读取数据的问题

引用 12 楼 imhuay 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] FOR(i, 0, n) 以前没见过  这是一个宏啦  #define FOR(i,f_start,f_end) for(int i=(f_start);i<(f_end);++i)[/quote] 宏是语法糖。  语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。

引用 3 楼 qq_36409192 的回复:只要你输入的格式没问题，并且代码也都是英文的，就可以这样进行输入  我贴一下代码，麻烦帮我看下哪里出问题了 n=3 (1,1)  (5,3)  (8,1)   void rd() { 	scanf("n=%d", &n); 	FOR(i, 0, n) 		scanf("(%d,%d)", &vs[i].first, &vs[i].second); }

引用 8 楼 zhao4zhong1 的回复:FOR(i, 0, n) 以前没见过  伪代码看不懂么，赵老四

只要你输入的格式没问题，并且代码也都是英文的，就可以这样进行输入

FOR(i, 0, n) 以前没见过

引用 1 楼 user-4 的回复:不会啊检查你括号、逗号是否都是英文的  我试过好几遍了，也复制试过了，还是读不出啊

不会啊检查你括号、逗号是否都是英文的

引用 6 楼 imhuay的回复:[quote=引用 5 楼 qq_36409192 的回复:] [quote=引用 4 楼 imhuay 的回复:] [quote=引用 3 楼 qq_36409192 的回复:] 只要你输入的格式没问题，并且代码也都是英文的，就可以这样进行输入  我贴一下代码，麻烦帮我看下哪里出问题了 n=3 (1,1)  (5,3)  (8,1)   void rd() { 	scanf("n=%d", &n); 	FOR(i, 0, n) 		scanf("(%d,%d)", &vs[i].first, &vs[i].second); } [/quote] [/quote]  这样一行读确实没问题，但是但是像我给出的数据，要循环读的时候就读不进了[/quote] 循环的话，该怎么输入就怎么输入啊！你输入一次回车一次(前提是你代码没出错)

引用 5 楼 qq_36409192 的回复:[quote=引用 4 楼 imhuay 的回复:] [quote=引用 3 楼 qq_36409192 的回复:] 只要你输入的格式没问题，并且代码也都是英文的，就可以这样进行输入  我贴一下代码，麻烦帮我看下哪里出问题了 n=3 (1,1)  (5,3)  (8,1)   void rd() { 	scanf("n=%d", &n); 	FOR(i, 0, n) 		scanf("(%d,%d)", &vs[i].first, &vs[i].second); } [/quote] [/quote]  这样一行读确实没问题，但是但是像我给出的数据，要循环读的时候就读不进了

引用 8 楼 zhao4zhong1 的回复:FOR(i, 0, n) 以前没见过  这是一个宏啦  #define FOR(i,f_start,f_end) for(int i=(f_start);i<(f_end);++i)

伪代码终究不是代码。

引用 9 楼 zhu339111520 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] FOR(i, 0, n) 以前没见过  伪代码看不懂么，赵老四[/quote] 赵老四比较专业

引用 4 楼 imhuay 的回复:[quote=引用 3 楼 qq_36409192 的回复:] 只要你输入的格式没问题，并且代码也都是英文的，就可以这样进行输入  我贴一下代码，麻烦帮我看下哪里出问题了 n=3 (1,1)  (5,3)  (8,1)   void rd() { 	scanf("n=%d", &n); 	FOR(i, 0, n) 		scanf("(%d,%d)", &vs[i].first, &vs[i].second); } [/quote]


Question: 信息管理系统出错了，求指教

不知道是我的运行环境有问题，还是啥，还是不能运行

#include<stdio.h> #include <stdlib.h> #include <string.h>    #define  MAX_STR_LEN    16 #define  MAX_NAME_LEN   32 #define  MAX_YEAR_LEN   32 #define  MAX_AUTHOR_LEN 32 #define  MAX_SINGER_LEN 32 #define  MAX_SNG_LEN    50   void input(); void del(); void liulan(); void searchname();  void menu();  struct song{     char name[MAX_NAME_LEN];     char year[MAX_YEAR_LEN];     char author[MAX_AUTHOR_LEN];     char singer[MAX_SINGER_LEN]; }song[MAX_SNG_LEN];  int main() {      //menu();      return 0; }  void input() {     FILE *fp;     int ch, record_cnt;     int i;      if(!(fp = fopen("song.txt","a"))) {         printf("can't open file song.txt");         return;         //exit(0);     }     printf("Please input a record:");     scanf ("%d", &record_cnt);     for (i = 0; i <= MAX_SNG_LEN && i < record_cnt; i++) {         printf("\nrecord%d:\n歌名:", i + 1);         fgets(song[i].name, MAX_NAME_LEN, stdin);         printf("\n时间:");         fgets(song[i].year, MAX_YEAR_LEN, stdin);         printf("\n作者:");         fgets(song[i].author, MAX_AUTHOR_LEN, stdin);         printf("\n歌手:");         fgets(song[i].singer, MAX_SINGER_LEN, stdin);          printf("继续输入吗?\n");         ch = getchar();         getchar();         if(ch == 'n') {             break;         }         fwrite(song, sizeof(song[0]), i, fp);         fclose(fp);     } }  /*If you write in one way, please read it use the same way. fwrite/fread, fscanf/fprintf. */ void del() {     int n, i, opt, flag = 0;     long a;     char namekey[8];     FILE* fp;      printf("\n请输入您要删除的歌曲名:");     scanf("%s", namekey);    /* addresss, array name is an address*/     if (!(fp=fopen("song.txt","r+"))) {         printf("\n不能打开该文件!");         return;   /* If open error then exit this function. */         //exit(0);     }     i = 0;     while(!feof(fp))     {         a = ftell(fp);         fscanf(fp,"%6s %5s %5s %10s\n",               song[i].name, song[i].year,               song[i].author, song[i].singer               );         i++;         if(strcmp(namekey,song[i].name) == 0) {             flag = 1;             break;         }     }     if(flag == 1) {         printf("\n已查到,记录为");         printf("\n%6s %5s %5s %10s\n",song[i].name, song[i].year, song[i].author, song[i].singer);         printf("\n确认删除,按1;不删除,按0:");         scanf("%d",&opt);         if(opt == 1)         {             fseek(fp, a, 0);             fprintf(fp,"%6s %5s %5s %10s\n"," "," "," "," ");         }     } else {         printf("\n对不起,查无此人");     }     fclose(fp); }  void liulan() {     FILE *fp;     int n = 0;      if(!(fp = fopen("song.txt","rb")))     {         printf("can't open the file song.txt");         return;         //exit(0);     }     printf("歌名\n作者\n歌手\n时间\n");     while(fread(&song[n],sizeof(song[0]),1,fp)==1)     {         printf("%6s %5s %10s %5s\n",song[n].name,song[n].year,song[n].author,song[n].singer);         n++;     }     fclose(fp); }  void searchname() {     FILE *fp;     int num;     char ch;     int i;     char numstr[MAX_STR_LEN];      if((fp=fopen("song.txt","rb"))==NULL)     {         printf("can not open the file.\n");         // exit(0);     }     while (fread(&song[i],sizeof(song[i]), 1, fp) == 1) {         i++;     }     num = i;     printf("用什么方式查询?\n");     printf("1.歌名 2.时间 3.歌手\n");     ch = getchar();     getchar();      switch(ch) {         case '1':             printf("输入你想要查的歌名:\n");             fgets(numstr, MAX_STR_LEN, stdin);             for (i = 0; i < num;) {                 if(!strcmp(numstr,song[i].name))                     break;                 i++;             }             break;         case'2':             printf("输入你想要查询的歌曲发行时间\n");             fgets(numstr, MAX_STR_LEN, stdin);             for(i = 0; i < num;)             {                 //if(atol(*numstr)==song[n].year)                 if(strcmp(song[i].year, numstr) == 0)                     break;                 i++;             }             break;         case'3':             printf("输入你要查的歌手\n");             fgets(numstr, MAX_STR_LEN, stdin);             for(i = 0; i < num;)             {                 if(!strcmp(numstr,song[i].singer))                     break;                 i++;             }             break;     }     printf("歌名 作者 歌手 时间\n");     printf("%6s %5s %5s %10s\n", song[i].name, song[i].year,song[i].author,song[i].singer);     fclose(fp);  }   问题不止一点点,我将你的程序里的warning和error都去掉了,不过有一个错误是没有定义menu. 对楼主一些建议,编程的提高不是写多少行代码,而是实实在在解决了多少问题,总结了多少方法.你写了这个程序大约近200行代码,你感觉自己从代码里学到什么东西了吗?除了敲这些代码带来手和少部分脑力的辛苦.总得来说编程能力不是有代码行数决定的. 楼主你这个程序实现了多个功能,为什么不能没实现一个函数,哪怕只是一个小小的功能,把它编译通过,并能运行出你想要的结果,然后在去实现下一个功能,一下子把所有功能都实现出来,等你编译之后出来这么多error和警告,自己头都大了吧与其这样,不如一步一步的去实现.前一步的正确作为后一步基础. 这个程序有问题再跟我发私信吧

if(atol(*numstr)==song[n].year)  改成；  if(atol(numstr)==atol(song[n].year))    你在语句前加句 printf("numstr = %d , song = %d , atol song = %d .\n ",atol(numstr) , song[n].year , atol(song[n].year)); 看看结果是否你要的if条件就明白了


Question: 农夫过河问题 求教！

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

return(0!=location&0x08);  改成：  return(0!=(location&0x08));   同理后面的几处


Question: opengl es1.1如何实现遮罩效果

搜网络教程“学OpenGL编3D游戏”？


Question: 文件输入输出 C语言

引用 4 楼 njxs1357 的回复:[quote=引用 3 楼 paschen 的回复:] [quote=引用 2 楼 njxs1357 的回复:] [quote=引用 1 楼 paschen 的回复:]  FILE* pf = fopen("word", "w");  ~~老师你好~除了这种方法 还有没有其他方法呀？比如说我现在即时创建一个名为word的文件可以吗？可以的话我应该把这个文件创建在哪里呢？？？[/quote]  上面那个就即时创建啊，你想创建在哪就哪啦，比如在C盘：  FILE* pf = fopen("c:\\word", "w");[/quote]反正程序自己找的到嘛，那我之前在D盘里面有一个word文件，就直接用就是了不用考虑是吗~~？？[/quote]  嗯

引用 6 楼 qq423399099 的回复:fopen 打开模式总结  r 只读  读模式--打开文件，从文件头开始读。  r+  只读    读写模式--打开文件，从文件头开始读写。  w   只写    写模式--打开文件，从文件头开始读。如果该文件已经存在，将删除所有文件已有内容。如果该文              件不存在，函数将创建这个文件。  w+  只写    写模式--打开文件，从文件头开始读写。如果该文件已经存在，将删除所有文件已有内容。如果该              文件不存在，函数将创建这个文件。  x   谨慎写  写模式打开文件，从文件头开始写。如果文件已经存在，该文件将不会被打开，fopen()函数将返              回false，而且PHP将产生一个警告。  x+  谨慎写  读/写模式打开文件，从文件头开始写。如果文件已经存在，该文件将不会被打开，fopen()函数将              返回false，而且PHP将产生一个警告。  a   追加    追加模式--打开文件，如果该文件已有内容，将从文件末尾开始追加(写)，如果该文件不存在，函              数将创建这个文件。  a+  追加    追加模式--打开文件，如果该文件已有内容，将从文件末尾开始追加(写)或者读，如果该文件不存              在，函数将创建这个文件。  b   二进制  二进制模式--用于与其他模式进行连接。如果文件系统能够区分二进制文件和文本文件，你可能会              使用它。Windows系统可以区分，而UNIX则不区分。推荐一直使用这个选项，以便获得最大程度的              可移植性。二进制模式是默认的模式。  t   文本    用于与其他模式的结合。这个模式只是Windows系统下一个选项。它不是推荐选项，除非你曾经在              代码中使用了b选项。 谢谢了~麻烦了~

引用 3 楼 paschen 的回复:[quote=引用 2 楼 njxs1357 的回复:] [quote=引用 1 楼 paschen 的回复:]  FILE* pf = fopen("word", "w");  ~~老师你好~除了这种方法 还有没有其他方法呀？比如说我现在即时创建一个名为word的文件可以吗？可以的话我应该把这个文件创建在哪里呢？？？[/quote]  上面那个就即时创建啊，你想创建在哪就哪啦，比如在C盘：  FILE* pf = fopen("c:\\word", "w");[/quote]反正程序自己找的到嘛，那我之前在D盘里面有一个word文件，就直接用就是了不用考虑是吗~~？？  引用 5 楼 paschen 的回复:[quote=引用 4 楼 njxs1357 的回复:] [quote=引用 3 楼 paschen 的回复:] [quote=引用 2 楼 njxs1357 的回复:] [quote=引用 1 楼 paschen 的回复:]  FILE* pf = fopen("word", "w");  ~~老师你好~除了这种方法 还有没有其他方法呀？比如说我现在即时创建一个名为word的文件可以吗？可以的话我应该把这个文件创建在哪里呢？？？[/quote]  上面那个就即时创建啊，你想创建在哪就哪啦，比如在C盘：  FILE* pf = fopen("c:\\word", "w");[/quote]反正程序自己找的到嘛，那我之前在D盘里面有一个word文件，就直接用就是了不用考虑是吗~~？？[/quote]  嗯[/quote] 谢谢老师了~~~

引用 2 楼 njxs1357 的回复:[quote=引用 1 楼 paschen 的回复:]  FILE* pf = fopen("word", "w");  ~~老师你好~除了这种方法 还有没有其他方法呀？比如说我现在即时创建一个名为word的文件可以吗？可以的话我应该把这个文件创建在哪里呢？？？[/quote]  上面那个就即时创建啊，你想创建在哪就哪啦，比如在C盘：  FILE* pf = fopen("c:\\word", "w");

引用 1 楼 paschen 的回复: FILE* pf = fopen("word", "w");  ~~老师你好~除了这种方法 还有没有其他方法呀？比如说我现在即时创建一个名为word的文件可以吗？可以的话我应该把这个文件创建在哪里呢？？？

FILE* pf = fopen("word", "w");


Question: invalid use of array with unspecified bounds

请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？

两维数组参数传递只能省去第一维数，因为如果全省去的话将无法确认其中是如何分配的

void print(int (*p)[],int i,int j)  改成：  void print(int (*p)[3],int i,int j)

void print(int (*p)[3],int i,int j)


Question: C语言模块化设计之菱形依赖问题

引用 5 楼 JiLuoXingRen 的回复:钻石依赖在C++中使用虚基类来避免D重复的问题。因为B，C各自依赖D，产生D的两个副本，到A时D就会出现两份，会产生冲突，这是虚基类语法出现的原因。当B、C、D都不能修改时，就只能拓展语言来弥补了。  你是用C语言写的，你的”依赖“是怎么做的？A创建并保持B、C的指针；B、C各自创建并保持D的指针？ C语言中一般会是模块，每个模块有init函数，模块间有调用关系，初始化有顺序要求的

引用 3 楼 maguiwa 的回复:D的初始化也可以放在A里。初始化后传给BC这是个好办法，谢了！

D的初始化也可以放在A里。初始化后传给BC

谢了，C语言单例，有点难

像这种需要init的模块最好看成单例对象 如果只是数据对象，最好还是不要这样设计，否则还得考虑线程安全问题


Question: 编译组建没问题 运行有问题

#include <stdio.h> #include <stdlib.h>  int main(void) {     FILE *fp = NULL;     int i,j;     float a[5][4] = {{0.0}}, ave = 0.0, b;      if((fp = fopen("E:\\自己编写代码\\第三次作业\\10_3_26\\grades.bin","w+")) == NULL)     {         printf("File failed!\n");         exit(0);     }     for(i = 0; i < 3; i++)     {         for(j = 0; j < 2; j++)         {             scanf("%f", &a[i][j]);             fprintf(fp, "%f\n", a[i][j]);    /*一个数据占一行,以利于后面正确读写,或者每次写一个数据后加一个空格或\t,这样写到文件里的数据都能够很好的分割*/         }     }     rewind(fp);     for(i = 0; i < 5; i++)     {         for(j = 0; j < 4; j++)         {             fscanf(fp,"%f\n",&b);    /*上面怎么写入的,这儿就以相同格式读出.*/             ave+=b;         }         ave/=4.0;         printf("第%d行的平均值：%.2f\n",i+1,ave);     }     fclose(fp);     return 0; }  有一个错误,就是判断文件打开判断,另外,你的程序写入文件的数据和读出的数据不一致.我使用回车符(也可以使用空格或\t)将输入的数据分割开,这样保证读出的也写入的一致.

if((fp = fopen("E:\\自己编写代码\\第三次作业\\10_3_26\\grades.bin","w+")) = NULL)  改成：  if((fp = fopen("E:\\自己编写代码\\第三次作业\\10_3_26\\grades.bin","w+")) == NULL)


Question: 字符基础问题

养成好习惯，做if判断时，将常量一律写在==的左边，这样即使有时少写一个=，也能及时发现。如if('a' == a)

a = 'a'是怎么验证的？

用数据类型来看，0是int型，‘0’是char型，所以不一样； 从内存占用空间来看，0占16位，可以看成是一个16位的二进制数；‘0’占8位，可以看成是一个8位的二进制数、

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

a != 'a' true 0 != '0' true a = 'a' .... 好吧，也是true.

字符：信息的通用载体，由“字”和“符”组成，其概念类似数学上的“符号”。但计算机中只能表达0和1，故将多个0和1组合在一起，与字符形成了一个对应关系，形成了最初的ASCII表，最后ASCII扩展了一些，形成了扩展ASCII表，扩展ASCII表再扩展，形成了其它各种各样的符号编码（中国常见的如GBK、UTF-8/16/32、ISO系列）。  如果你懂原始的信息传递机制，可以做一个类比：  1.原始人嚎叫：长嚎一声，表示安全；急促短叫，表示危险；  2.电报的编码：通过间隔时间长短不一的电磁波通断，形成一组信号，然后再通过事先约定好的方法，将信号转为我们能识别的信息；  3.收音机信息：通过电磁波的幅度或者频率的变化，形成一组信号，然后在接收端对这种变化进行解析，还原成声音（即我们能识别的信号）。  以上都是相通的。看不明白就当我没发过帖。

哈哈, 看到当年的自己....

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

引用 4 楼 sdghchj 的回复:楼主一定是发现if(a='a')为真了，欣喜若狂

楼主一定是发现if(a='a')为真了，欣喜若狂

a怎么验证和'a'一样呢,字符0,'0'ascii值是0x30,0是数字0, '\0'是字符串结束标识,其值为0；

a = 'a'不知道楼主是怎么验证出来的

a = 'a' 这是在赋值，而不是在比较  ‘0’ 是字符0，‘\0'表示字符串的终止，他们有不同的ascii码，是完全不同的字符


Question: 请帮忙分析一下

for(i=0,j=0;i<6,j<6;i++,j++)  要写成：  for(i=0,j=0;i<6&&j<6;i++,j++)

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

还是不行啊，能解释一下为什么是int吗

int ch;


Question: 这是一道填空题，请问空缺怎么填？

void reverse( int * p_b , int * p_e ) { 	if ( p_b < p_e ) // p_b所指元素在p_e所指元素之前 	{ 		swap(*p_b, *p_e);//交换p_b与p_e所指向数据的值 		reverse(++p_b, --p_e) ;//对p_b所指元素之后，p_e所指元素之前的元素做同样处理 	} }

引用 2 楼 zhao4zhong1 的回复:[quote=引用 1 楼 sdghchj 的回复:] *p_b ^= *p_e;  *p_e = *p_b ^ *p_e;  *p_b ^= *p_e; -- p_b, -- p_e 感觉咋那么象一串表情呢？(^_^)[/quote] 赵老师知道的。呃，第二行我打错了。 ++ p_b, -- p_e

引用 1 楼 sdghchj 的回复:*p_b ^= *p_e;  *p_e = *p_b ^ *p_e;  *p_b ^= *p_e; -- p_b, -- p_e 感觉咋那么象一串表情呢？(^_^)


Question: 第一次尝试编写一个小程序，结果出问题了，求指导。

建议：必要时把各个小部分分割成函数

printf("已经%d天啦，厉害！", sum); 这句有可能显示了没有初始过的sum

if (yr = 0)//28天  改成：  if (yr == 0)//28天  同理改：else if (yr = 1)//29天  后面还有好几个地方都这种，我就不列了

#include <stdio.h>   int months_list[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  int is_leapyear(int year); int count_days(int year, int month, int days);  int main(int argc, const char *argv[]) {     int born_year, born_month, born_day;     int now_year, now_month, now_day;     int sum_days = 0, i;      printf("请注意：1.我相信您在公元元年后出生\n");     printf("2.我相信您不来自公元后10000年\n");     printf("3.请用‘/’隔开年月日\n");     printf("4.如果你在17世纪前出生，实际天数可能与历史不相符\n\n\n");      printf("Please enter the date you born：");     scanf("%d/%d/%d", &born_year,&born_month,&born_day);     printf("What's the date today:");     scanf("%d/%d/%d", &now_year, &now_month, &now_day);      if (now_year < born_year)         printf("Input error!");      /* Deal with the year. */     for (i = born_year; i < now_year; i++) {         if (is_leapyear(i)) {             sum_days += 366;         } else {             sum_days += 365;         }     }     //printf("born days = %d\n", count_days(born_year, born_month, born_day));     //printf("now days = %d\n", count_days(now_year, now_month, now_day));     sum_days += count_days(now_year, now_month, now_day);     sum_days -= count_days(born_year, born_month, born_day);      printf("已经%d天啦，厉害！\n", sum_days);     return 0; }  int count_days(int year, int month, int days) {     int total_days = 0, i;      for (i = 0; i < month-1; i++)         total_days += months_list[i];     if (is_leapyear(year) && month > 2)         total_days += 1;     total_days += days;      return total_days; }   int is_leapyear(int year) {     if ((year % 4 == 0 && year % 100 != 0)             || (year % 400 == 0))         return 1;     else         return 0; }  作为一个参考吧

判断yr的地方都出现错误.

你yr的比较有好多地方都少了一个等号 比如48行，if (yr = 0)应该是if (yr == 0) 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

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


Question: 关于While的问题

引用 2 楼 qq423399099 的回复:因为你输入字母的话，scanf读取失败，输入缓冲区里的字母并不会被读走，然后下一次循环的时候scanf又会尝试读取输入缓冲区里的数据，又失败。。。。 你fflush(stdin);清空输入缓冲区一下才行。  #include<stdio.h> int main(void) { 	float a; 	while (!scanf("%f", &a)) 	{ 		printf("\nIt is'n a number!"); 		printf("\nPlease enter a number ,such as 2.5,-1.78E8,or 3:"); 		fflush(stdin); 	} 	return 0; }  fflush(stdin)是未定义行为，参考

仅供参考：#include <stdio.h> #include <string.h> char s[80]; double d; char c; int main() {     while (1) {         printf("Input a double:");fflush(stdout);         rewind(stdin);         fgets(s,80,stdin);         if (strlen(s)>20) {             printf("Input too long(>20)!\n");             continue;         }         if (2==sscanf(s,"%lf%c",&d,&c)) {             if ('\n'==c) {                 printf("%lg is a double.\n",d);                 break;             }         }         if ('\n'==s[strlen(s)-1]) s[strlen(s)-1]=0;         printf("\"%s\" is NOT a double!\n",s);     }     return 0; }

引用 1 楼 ipqtjmqj 的回复:改成波浪号~ 更正，应该是用gets吃掉无效的字符串   #include<stdio.h> int main (void) {     float a; 	 char tmp[1024]; 	 while (!scanf("%f", &a))      {             printf("\nIt is'n a number!");          printf("\nPlease enter a number ,such as 2.5,-1.78E8,or 3:"); 			gets(tmp);     } 	       return 0; }

改成波浪号~


Question: printf("01 %d\n", "01"); 将一个字符串整型输出 输出内容的意义是啥,想不出来,查了半天资料也没见介绍 好奇~~~

用十进制显示的这个字符串的地址

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

%d输出的是十进制的字符串的首地址 %p 是以16进制的形式输出内存地址 （楼主也顺便%p输出一下地址就明白了）

对于32位程序，地址为32位4字节，输出的是"12"这个字符串的地址。 对于64位程序，地址为64位8字节，输出的是"12"这个字符串的地址的低32位

输出的是地址


Question: 怎么给数据排序按大小分等级，并跟据输入等级数，输出相应等级的数值，，

其实我想问的是几组从键盘输入的数组，排序，然后各组从高到底依次排序，在输入的各个数组后输入数字a，跟据这个数字输出第a大的数，我写不出来，数组溢出，程序停止运行，，了，能帮帮忙再写一下吗？

随便写了个，你可以参考一下： #include <stdio.h> #include <string.h> #include <stdlib.h>   char *grade(int n,char a[]) { 	if(n > 80) 		strcpy(a,"you"); 	else if(n > 70) 		strcpy(a,"liang"); 	else if(n > 60) 		strcpy(a,"zhong"); 	else strcpy(a,"cha"); 	return a; }  int main () { 	char **a; 	int *b; 	int i,n; 	scanf("%d",&n); 	b=(int *)malloc(n*sizeof(int)); 	a=(char **)malloc(n*sizeof(char *)); 	for(i=0;i<n;i++) 		a[i]=(char *)malloc(10*sizeof(char)); 	 	for(i=0;i<n;i++) 	{ 		scanf("%d",&b[i]); 		a[i]=grade(b[i],a[i]); 	} 	for(i=0;i<n;i++) 	{ 		printf("第%d个成绩的等级：",i);  		printf("%s\n",a[i]); 	} 	return 0; }


Question: 问问题~我想对搜索  很多个结构体数组中的   其中的一个元素，显示元素所在结构体的索引号，求问怎么实现。

参考：  struct Name {     const int Base_Class1;     const int  Sub_Class1;     const int  Interface1;     const char  *Meaning1; } mean[17]={     {0x00,0x00,0x00,"All currently implemented devices"},     {0x00,0x01,0x00,"VGA-compatible device"},     {0x01,0x01,0x80,"IDE controller"},     {0x01,0x80,0x00,"Other mass storage controller"},     {0x02,0x00,0x00,"Ethernet controller"},     {0x02,0x80,0x00,"Other network controller"},     {0x03,0x00,0x00,"VGA-compatible controller"},     {0x03,0x80,0x00,"Other display controller"},     {0x06,0x00,0x00,"Host bridge"},     {0x06,0x01,0x00,"ISA bridge"},     {0x06,0x04,0x00,"PCI-to-PCI bridge"},     {0x06,0x04,0x01,"Subtractive Decode PCI-to-PCI bridge"},     {0x06,0x07,0x00,"CardBus bridge"},     {0x0c,0x00,0x10,"IEEE 1394 OpenHCI"},     {0x0c,0x03,0x00,"USB Universal Host Controller"},     {0x0c,0x03,0x20,"Intel USB2 Enhanced Host Controller"},     {0x0c,0x05,0x00,"SMBus"}, }; int i; for (i=0;i<17;i++)     if (Base_Class == mean[i].Base_Class1      &&  Sub_Class == mean[i]. Sub_Class1      &&  Interface == mean[i]. Interface1) break; if (i<17) puts(mean[i].Meaning1); else printf("%s\t","Unknow Device");

循环遍历结构体数组，循环中检查当前索引的结构体是否满足你的条件，如果满足则找到，可以将当前索引显示出来

循环遍历，与你要找元素进行匹配，如果值是对的，输出结构体对应的索引号。


Question: 学生成绩管理系统

帮你调试了下发现，你应该是count函数有问题 你打开文件失败了，fp = fopen("stud", "rb");这句，应该是stud.txt什么的吧？ PS：注意细节，你save函数里fp = fopen("achievement,txt", "wb");的achievement,txt应该是achievement.txt 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

void zhscore(int n)  /*计算每个学生的综合成绩*/ { 	int i,j,s,zxf,sum; 	for(i=0;i<n;i++) 	{ 		sum=0; 		for(j=0;j<4;j++) 			s=stu[i].score[j]*stu[i].CourseCredit[j]; 		zxf+=stu[i].CourseCredit[j]; 		sum+=s; 		stu[i].zhscore=sum/zxf; 	} }  你的这个函数，第一次执行zxf+=stu[i].CourseCredit[j]; 这句时，zxf还没有初始化就使用了

初始化了咋还是这状况啊


Question: 变步长梯形积分算法求函数定积分C语言

好的，谢谢，我先回去看看，谢谢指导！！

double jifen(double upper, double lower, double esp) {     int nloop = 1;     double area1 = 0, area2 = 0, step = upper - lower;     if (step<=0)     {         printf("Error,the upper must greater than lower\n");         return 0.0;     }      do     {         area1 = area2;         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!         area2 = 0.0;         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!         double x1 = lower, x2 = lower + step;         double y1 = hanshu(x1), y2 = hanshu(x2);         for (int i = 0; i < nloop; i++)         {             area2 += ((y1 + y2)*step / 2.0);             y1 = y2;             x2 += step;             y2 = hanshu(x2);         }         nloop *= 2, step /= 2;     }     while (fabs(area2 - area1) >= esp);     return area2; }

1、在DEBUG下进行程序调试  2、你需要设置断点，然后程序断下之后才可以看到调试窗口


Question: C语言基础问题

scanf中, 第二个参数起, 都要求是指针类型,  所以对于基本数据类型的变量, 都需要加&符号, 才能得到其指针.  但数组是个特例,  对于 int arr[10]来说  arr本身,传入其它函数时, 就会退化为指针,   加一个&也是取这个arr变量的地址. 这个一个编译器的操作, 你不用知道为什么, 只要知道原理, 就是要得到地址就行了.

字符串的输入可加可不加，scanf（“%p”,&n）; 你要获得的是地址

数组名就代表着数组首元素的地址，在scanf中，要修改数组元素，要先取地址，所以直接用数组名即可；同理int也需要取地址，但int类型的变量名不是地址，所以需要用取地址符号“&”取得int变量的地址，再做修改。

引用 5 楼 qq_37120945 的回复:char arr[10] = "hello"; scanf("%p", arr); scanf("%p", &arr); arr表示数组的首地址 &arr表示arr[0]的首地址 地址是同一个地址 但是第一个输入的arr 必须是个地址作为数组的首地址 第二个意思是给arr[0]赋值 第一次回复 我是这么理解的 不对的话还望交流反了 这里的arr 表示的是 指向arr[0]的指针 &arr 表示的是指向 arr的指针

好久没看回复, 感谢各位

arr和&arr代表的数值是一样的，但含义是不同的 参考：http://blog.csdn.net/draw5230/article/details/6699431

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

引用char arr[10] = "hello"; scanf("%p", arr); scanf("%p", &arr); 而这里加或不加取地址符都可以?  因为数组名arr作为参数的时候会退化成指针，是数组首元素的地址 所以正确的写法应该是：scanf("%p", arr); scanf("%p", &arr);之所以可以，是因为数组的地址刚好与指向数组首元素的地址是相同的 但这两种指针的类型是不同的

引用int i; scanf("%p", &i); 为这么这里必须加取地址符?  因为scanf需要的是要修改的地址


Question: 不知道错在哪

%d溢出,可以看一下int类型的取值范围,long,unsigned int等这些基础类型的取值范围

printf中的%d都换成%ld,或者将s,n都换成unsigned int类型,并且%u输出

main函数声明称  int main(int argc, char *argv[])  然后最后添加一个 return 0;  楼主好好整理一下代码格式， 大括号 单独占一行， 同一个逻辑块缩进要相同。   代码风格好点儿也会减少很多错误。

所有的%d改成%ld（最后一个估计也还是溢出了）

main函数没有返回一个值，后面加上return 0;就可以了


Question: 一个C程序双链表通讯录，有些错误，改不出来，求大神指点迷津

引用 1 楼 user-2的回复: 		while(p!=NULL) 		{    			if(!strcmp(p->name,n)) //比较输入名字与通讯录名字 			{                       //输入名字匹配 				flag=1; 				p->prior->next=p->next; 				p->next->prior=p->prior; 				free(p); 				printf("已被被删除\n"); 			} 			p=p->next; 			seat++; 		}   你代码的这一部分，如果你释放了p指向的空间后，紧接着又去访问p=p->next;导致出错 原来如此，知道了，谢谢指点

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


Question: 在printf里做运算的问题

如果对C语言运算符优先级和结合性不熟悉，完全可以通过括号来改变优先级，或者将*p++这样的语句拆分为两句。

1.前++和后++的区别 2.运算符优先级

代码应该写的简洁，而不是让人看不懂

关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775

引用 1 楼 sarras32 的回复:相对的++p就是先++，为什么呢  这就是这前置++和后置++的不同之处，标准就这么规定的，没为什么

*p++是先输出*p，然后p再+1  *++p才是p先+1，再输出p

如果是指针，根据指针的运算规则进行加减，也是一样的。

自增自减问题最主要的就是看++和--的位置，如果是在你变量的前面，则表示你在执行这个语句之前进行自增自减，如果是在变量的后面，则表示在这个语句执行以后，再进行自增自减。  int p=1; printf("%d\n",++p);  //这里的值会是2，因为在输出前就进行了自增 printf("%d",p++);   //这里输出的值也是2，但是p的值在输出以后却自增为3了

相对的++p就是先++，为什么呢


Question: 求大佬帮忙解决完善程序，本人新手，不知道怎么实现。

引用 4 楼 qq_36409192 的回复:掉了个头文件：stdio.h 我知道了，谢谢大佬

掉了个头文件：stdio.h

#include <string.h> #include <math.h> int main () { 	char a[32]; 	int len,sum=0,i=0; 	gets(a); 	len=strlen(a); 	 	for(int i=0;i<len;i++)   		if(a[i]-'0'!=0&&a[i]-'0'!=1) 			return 0;	 	 	i=0; 	for(int j=len-1;j>=0;j--,i++) 		sum+=(a[j]-'0')*pow(2,i); 	 	printf("%d",sum); 	return 0; }

引用 1 楼 user-2 的回复: 	int t = 10; 	int n = 0; 	while (t) 	{ 		t >>= 1; 		++n; 	}   t为你的数 循环之后n为你要的位数 可是数值的每一位数我是直接赋值给数组的，不是int，我的目的就是可以输入任意位数的二进制数，转换为十进制数，求解决


Question: C语言指针，求教。

引用 3 楼 qq_36409192的回复:#include <stdio.h> #include <string.h> #define N 100 char *substr(char a[],int m) { 	int n,i,j=0; 	n=strlen(a); 	for(i=m-1;i<n;i++) 	{ 		a[j]=a[i]; 		j++; 	} 	a[j]='\0'; 	return a; } int main () { 	char a[N],*b; 	int m; 	printf("请输入字符串："); 	scanf("%s",a); 	printf("请输入你的m：");  	scanf("%d",&m);  	b=substr(a,m); 	printf("%s",b); 	return 0; } 已经明白了，题意说复制为另一个字符串我理解错了，就在自定义函数里加了另一个没必要的新字符串，多谢！

引用 1 楼 user-2 的回复:不要返回局部变量的地址，你的char s[N];是一个局部变量，函数结束就销毁了 知道了，多谢，大概是题意不清晰，没理解。


Question: 如何输出字符串的I位呢

引用 4 楼 sarras32的回复:[quote=引用 3 楼 qq_36409192 的回复:]  我改成二进制试了下。。打印没问题啊。。  改成二进制就可以了，10进制不行，为啥呢[/quote] 十进制也可以啊！一样的。。

引用 3 楼 qq_36409192 的回复: 我改成二进制试了下。。打印没问题啊。。  改成二进制就可以了，10进制不行，为啥呢

我改成二进制试了下。。打印没问题啊。。

引用 1 楼 user-2 的回复:sum1[0],改为sum1[j]  改了打不出来，我写0主要是看0能不能打出，改成j也不行


Question: c内嵌汇编不能使用fs寄存器

引用 2 楼 biyaun 的回复:__asm{ 		push offset _except_handler 		push fs : [0] 		mov fs : [0], esp          }  代码在这  push    _except_handler

release与debug下都可以用，到是64位程序就不能这样

SEH异常需要用到fs寄存器，debug可以用，release不能用 有人知道吗


Question: 通讯录管理系统，我编出来的程序有以下的一些问题，请高手指正，谢谢！

1.main函数里你的while(1)放错位置了 2.show函数里的你的这个用法有问题，你int n;以后，根本没有赋过值然后就使用了  #include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> #define N 5 struct person { 	char name[5]; 	char addr[5]; 	char  tel[10]; 	char email[5]; }per[N];  void insert(); void modify(); void cancel(); void show(); void search(); void sort(); void read(); void printf_n(int n);  void menu() { 	int n, w; 	do 	{ 		puts("\t\t******************Here is the menu.********************\n"); 		puts("\t\t\t\t 1.insert\n"); 		puts("\t\t\t\t 2.modify\n"); 		puts("\t\t\t\t 3.cancel\n"); 		puts("\t\t\t\t 4.show\n"); 		puts("\t\t\t\t 5.sort\n"); 		puts("\t\t\t\t 6.search\n"); 		puts("\t\t\t\t 7.name\n"); 		puts("\t\t\t\t 8.addr\n"); 		puts("\t\t\t\t 9.tel\n"); 		puts("\t\t\t\t 10.email\n"); 		puts("\t\t*********Please input the number you need.*************\n\n"); 		scanf("%d", &n); 		if (n<0 || n>7) 		{ 			w = 1; 			getchar(); 		} 		else w = 0; 	} while (w == 1); 	switch (n) 	{ 	case 1:insert(); break; 	case 2:modify(); break; 	case 3:cancel(); break; 	case 4:show(); break; 	case 5:sort(); break; 	case 6:search(); break; 	} }  void main() { 	int n, w; 	do 	{ 		puts("\t\t***************Here is the menu.***************\n"); 		puts("\t\t\t\t 1.insert\n"); 		puts("\t\t\t\t 2.modify\n"); 		puts("\t\t\t\t 3.cancel\n"); 		puts("\t\t\t\t 4.show\n"); 		puts("\t\t\t\t 5.sort\n"); 		puts("\t\t\t\t 6.search\n"); 		puts("\t\t\t\t 7.name\n"); 		puts("\t\t\t\t 8.addr\n"); 		puts("\t\t\t\t 9.tel\n"); 		puts("\t\t\t\t 10.email\n"); 		puts("\t\t*********Please input the number you need.*****\n\n"); 		scanf("%d", &n); 		switch (n) 		{ 		case 1:insert(); break; 		case 2:modify(); break; 		case 3:cancel(); break; 		case 4:show(); break; 		case 5:sort(); break; 		case 6:search(); break; 		} 		 	} while (1); }  void printf_back() { 	int w; 	printf("\n\nSuccessful.^_^\n\n"); 	printf("\t\t****** What do you wan to do? ******\n\nt1).Exit\t2.Back:[ ]\b\b"); 	scanf("%d", &w); 	if (w == 1) exit(0); 	else menu(); }  void show() { 	int n; 	read(); 	printf_n(n); 	printf_back(); }  void read() { 	FILE*fp; 	int i; 	if ((fp = fopen("person.txt", "r")) == NULL) 	{ 		printf("\nCan't open this file.\n"); 		exit(0); 	} 	for (i = 0; !feof(fp); i++) 		fscanf(fp, "%s %s %s %s", per[i].name, per[i].addr, per[i].tel, per[i].email); 	fclose(fp); 	printf_back(); }  void printf_one(int i) { 	printf("%s %s %s %s\n", per[i].name, per[i].addr, per[i].tel, per[i].email); }  void printf_n(int n) { 	int j; 	for (j = 0; j < n; j++) 	{ 		printf_one(j); 	}  }  void insert() { 	int i, n, M; 	printf("Please input the number of person you want to add.\n"); 	scanf("%d", &n); 	M = n + N; 	printf("Please input the detailed information.\n"); 	for (i = 1; i <= n; i++) 	{ 		printf("Name: \n"); 		scanf("%s", per[N - n - 1 - i].name); 		printf("Addr: \n"); 		scanf("%s", &per[N - n - 1 - i].addr); 		printf("Tel: \n"); 		scanf("%d", &per[N - n - 1 - i].tel); 		printf("Email: \n"); 		scanf("%s", &per[N - n - 1 - i].email); 	} 	printf_back(); }  void modify() { 	char m[5], p; 	int q; 	printf("Please input the name you want to modify.\n"); 	scanf("%s", &m); 	for (p = 0; p < N; p++) 	{ 		if (strcmp(m, per[p].name) == 0) 			printf("Please input the word you want to modify.\n"); 		scanf("%d", &q); 	} 	switch (q) 	{ 	case (7) : printf("Please input the new name.\n"); 		scanf("%s", per[p].name); 		printf("The new name is: \n", per[p].name); 		break; 	case (8) : printf("Plesae input the new address.\n"); 		scanf("%s", &per[p].addr); 		printf("The new address is: \n", per[p].addr); 		break; 	case (9) : printf("Plesae input the new tellphone number.\n"); 		scanf("%d", &per[p].tel); 		printf("The new tellphone number is: \n", per[p].tel); 		break; 	case (10) : printf("Plesae input the new email.\n"); 		scanf("%s", &per[p].email); 		printf("The new email is: \n", per[p].email); 		break; 	} 	printf_back(); }  void search() { 	char j[5]; 	int  k; 	printf("Please input the name you want to search.\n"); 	scanf("%s", &j); 	for (k = 0; k < N; k++) 	{ 		if (strcmp(j, per[k].name) == 0) 			printf("%s %s %s %s", per[k].name, per[k].addr, per[k].tel, per[k].email); 		else printf("Can't find it!\n"); 	} 	printf_back(); }  void cancel() { 	int x; 	char k[5]; 	printf("Please input the name you want to remove.\n"); 	scanf("%s", &k); 	for (x = 0; x < N; x++) 	{ 		if (strcmp(k, per[x].name) == 0) 		{ 			per[x] = per[x + 1]; 			printf("Succeed removing!\n"); 		} 		else printf("Can't find it!\n"); 	} 	printf_back(); }  void sort() { 	int i; 	char t[5]; 	for (i = 0; i < N; i++) 	{ 		if (strcmp(per[i].name, per[i + 1].name) < 0) 		{ 			strcpy(t, per[i].name); 			strcpy(per[i].name, per[i + 1].name); 			strcpy(per[i + 1].name, t);  		} 	} 	printf_back(); }

你的main函数中只有一个do， 后面没有while  需要 do...while    void main() {  	int n,w; 	do 	{ 		puts("\t\t***************Here is the menu.***************\n"); 		puts("\t\t\t\t 1.insert\n"); 		puts("\t\t\t\t 2.modify\n"); 		puts("\t\t\t\t 3.cancel\n"); 		puts("\t\t\t\t 4.show\n"); 		puts("\t\t\t\t 5.sort\n"); 		puts("\t\t\t\t 6.search\n"); 		puts("\t\t\t\t 7.name\n"); 		puts("\t\t\t\t 8.addr\n"); 		puts("\t\t\t\t 9.tel\n"); 		puts("\t\t\t\t 10.email\n"); 		puts("\t\t*********Please input the number you need.*****\n\n"); 		scanf("%d",&n); 		switch(n) 		{ 		case 1:insert();break; 		case 2:modify();break; 		case 3:cancel();break; 		case 4:show();break; 		case 5:sort();break; 		case 6:search();break; 		} 		while(1); 	} while(...);  ///////把这里填了 }

我把main函数放在最后之后，只有main函数的最后一个花括号被报错，说是syntax error : '}'，但是我数了一下花括号的个数是对的，不知道哪里出了问题

谢谢，我把remove重新换了一个名字后，仍有两个错误。但是我发现不出哪里有问题，可以再看一下吗 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> #define N 5 struct person  { 	char name[5]; 	char addr[5]; 	char  tel[10]; 	char email[5]; }per[N];  void insert(); void modify(); void cancel(); void show(); void search(); void sort(); void read(); void printf_n(int n);  void menu() { int n,w;  do  {  puts("\t\t******************Here is the menu.********************\n");  puts("\t\t\t\t 1.insert\n");  puts("\t\t\t\t 2.modify\n");  puts("\t\t\t\t 3.cancel\n");  puts("\t\t\t\t 4.show\n");  puts("\t\t\t\t 5.sort\n");  puts("\t\t\t\t 6.search\n");  puts("\t\t\t\t 7.name\n");  puts("\t\t\t\t 8.addr\n");  puts("\t\t\t\t 9.tel\n");  puts("\t\t\t\t 10.email\n");  puts("\t\t*********Please input the number you need.*************\n\n");  scanf("%d",&n);  if(n<0||n>7)  { 	 w=1; 	 getchar();  }  else w=0;  }  while(w==1);  switch(n)  {  case 1:insert();break;  case 2:modify();break;  case 3:cancel();break;  case 4:show();break;  case 5:sort();break;  case 6:search();break;  } }  void main() {	int n,w; 	do 	{ 		puts("\t\t***************Here is the menu.***************\n"); 		puts("\t\t\t\t 1.insert\n"); 		puts("\t\t\t\t 2.modify\n"); 		puts("\t\t\t\t 3.cancel\n"); 		puts("\t\t\t\t 4.show\n"); 		puts("\t\t\t\t 5.sort\n"); 		puts("\t\t\t\t 6.search\n"); 		puts("\t\t\t\t 7.name\n"); 		puts("\t\t\t\t 8.addr\n"); 		puts("\t\t\t\t 9.tel\n"); 		puts("\t\t\t\t 10.email\n"); 		puts("\t\t*********Please input the number you need.*****\n\n"); 		scanf("%d",&n); 		switch(n) 			{ 				case 1:insert();break; 				case 2:modify();break; 				case 3:cancel();break; 				case 4:show();break; 				case 5:sort();break; 				case 6:search();break; 			} 		while(1); 	} }  void printf_back() { 	int w; 	printf("\n\nSuccessful.^_^\n\n"); 	printf("\t\t****** What do you wan to do? ******\n\nt1).Exit\t2.Back:[ ]\b\b"); 	scanf("%d",&w); 	if(w==1) exit(0); 	else menu(); }  void show() {    	int n; 	read();     printf_n(n); 	printf_back(); }  void read() { 	FILE*fp; 	int i; 	if((fp=fopen("person.txt","r"))==NULL) 	{ 		printf("\nCan't open this file.\n"); 		exit (0); 	}     for(i=0;!feof(fp);i++) 		fscanf(fp,"%s %s %s %s",per[i].name,per[i].addr,per[i].tel,per[i].email);     fclose(fp); 	printf_back(); }  void printf_one(int i) { 	printf("%s %s %s %s\n",per[i].name,per[i].addr,per[i].tel,per[i].email); }  void printf_n(int n) { 	int j; 	for(j=0;j<n;j++) 	{ 		printf_one(j); 	}	  }  void insert() {   int i,n,M; 	printf("Please input the number of person you want to add.\n"); 	scanf("%d",&n); 	M=n+N;     printf("Please input the detailed information.\n"); 	for(i=1;i<=n;i++) 	{ 		printf("Name: \n"); 		scanf("%s",per[N-n-1-i].name); 		printf("Addr: \n"); 		scanf("%s",&per[N-n-1-i].addr); 		printf("Tel: \n"); 		scanf("%d",&per[N-n-1-i].tel); 		printf("Email: \n"); 		scanf("%s",&per[N-n-1-i].email); 	} 	printf_back(); }  void modify() { 	char m[5],p; 	int q; 	printf("Please input the name you want to modify.\n"); 	scanf("%s",&m); 	for(p=0;p<N;p++) 	{	 		if(strcmp(m,per[p].name)==0) 		printf("Please input the word you want to modify.\n"); 		scanf("%d",&q); 	} 	switch(q) 	{ 	case (7):printf("Please input the new name.\n"); 		     scanf("%s",per[p].name); 			 printf("The new name is: \n",per[p].name); 			 break; 	case (8):printf("Plesae input the new address.\n"); 		     scanf("%s",&per[p].addr); 		     printf("The new address is: \n",per[p].addr); 			 break; 	case (9):printf("Plesae input the new tellphone number.\n"); 		     scanf("%d",&per[p].tel); 			 printf("The new tellphone number is: \n",per[p].tel); 			 break; 	case (10):printf("Plesae input the new email.\n"); 			  scanf("%s",&per[p].email);               printf("The new email is: \n",per[p].email); 			  break; 	} 	printf_back(); }  void search() { 	char j[5]; 	int  k; 	printf("Please input the name you want to search.\n"); 	scanf("%s",&j); 	for(k=0;k<N;k++) 	{ 		if(strcmp(j,per[k].name)==0) 			printf("%s %s %s %s",per[k].name,per[k].addr,per[k].tel,per[k].email); 		else printf("Can't find it!\n"); 	} 	printf_back(); }  void cancel() { 	 int x; 	 char k[5]; 	 printf("Please input the name you want to remove.\n"); 	 scanf("%s",&k); 	 for(x=0;x<N;x++) 	 { 		 if(strcmp(k,per[x].name)==0)  		 { 		  per[x]=per[x+1]; 		  printf("Succeed removing!\n");          } 		 else printf("Can't find it!\n"); 	 }      printf_back();  }  void sort() {     int i; 	char t[5];     for(i=0;i<N;i++) 	{ 	 if(strcmp(per[i].name,per[i+1].name)<0)  	 { 		 strcpy(t,per[i].name); 		 strcpy(per[i].name,per[i+1].name); 		 strcpy(per[i+1].name,t);  	 } 	} 	printf_back(); }  *****************************************Debug****************************************************** c:\program files (x86)\microsoft visual studio\myprojects\ghjkj\rfghgj.c(88) : error C2059: syntax error : '}' c:\program files (x86)\microsoft visual studio\myprojects\ghjkj\rfghgj.c(105) : warning C4013: 'printf_back' undefined; assuming extern returning int 执行 cl.exe 时出错.

头文件： stdio.h  中也有一个remove()函数，用于删除指定的文件，其原型如下： int remove(char * filename);  你的程序中也有一个同名函数：void remove();


Question: pta cars  on campus

你的N是全局变量，初始为0，char* name[N]; 没这种用法


Question: 为什么会调不到啊， 老师们，高手们都来看下吧

引用 4 楼 u014325402 的回复:引用 3 楼 user-1 的回复:[quote=引用 2 楼 u014325402 的回复:] [quote=引用 1 楼 user-1 的回复:] 运行thread 是异步的，你要么启动thread后sleep几秒，要么set完后发一个信号，在使用之前等到这个信号你好，这个程序设计的是这样的，先执行完set...之后，才回去调用 hw_driv_traini_instr.cpp里的那个接口，进而才会执行到get...的,sleep几秒时间太长了，你说的用发信号怎么用呢？ 简单一点定义一个全局flag变量就可以了，初始为0,设置之后为1,读到那边循环判断flag，为0则sleep一下减小cpu占用。 高级一点有spinlock, mutex, semaphore之类的[/quote] 你好 我用简单的全局变量和互斥锁mutex都用了，现在的现象是：用互斥锁时，程序进入后就一直停在里面get，出不来， 不同互斥锁，用简单的全局变量，每次进入去读，一直判断为0， 尽管我开时时就在调用set后给这个全局变量赋值了，它还是一直读到的是0，程序如下： set_Snapshot（）	 {     ............ 	 if(type == H_PIC_VGA) 	 {       set_pic = H_PIC_VGA; 	 } 	 else if(type == H_PIC_QVGA)    {      printf("#########################################748596\n");       set_pic = H_PIC_QVGA; 	 } 	 else if(type == H_CIF) 	 {       set_pic = 0; 	 } 	 else 	 {        printf("picture size is error!\n"); 	 } 	 get_fag = 1;//这个在构造函数里初始化为0了。 }  get我是这样写的： unsigned int CHw_Driv_Traini_Instr::get_Snapshot(unsigned char * h_size) {  	 //static pthread_mutex_t xml_mutex = PTHREAD_MUTEX_INITIALIZER;	  	// pthread_mutex_lock(&xml_mutex); 	  	 if(get_fag == 0) 	 { 			 printf("GGGGGGGGGGGGGGGGGGGGEEEEEEEEEETTT\n");  			 return -1; 	 } 	  	  printf("--!!!!!!!!!!$$$$$$-%d-h--\n", set_pic);  		     *h_size = set_pic;  	// pthread_mutex_unlock(&xml_mutex); 	  	 return *h_size; } [/quote] 在get里要循环判断flag直到为1 用mutex要定义成全局变量并程序启动时就初始化，你定义成静态变量，怎么在set函数里获取

引用 3 楼 user-1 的回复:引用 2 楼 u014325402 的回复:[quote=引用 1 楼 user-1 的回复:] 运行thread 是异步的，你要么启动thread后sleep几秒，要么set完后发一个信号，在使用之前等到这个信号你好，这个程序设计的是这样的，先执行完set...之后，才回去调用 hw_driv_traini_instr.cpp里的那个接口，进而才会执行到get...的,sleep几秒时间太长了，你说的用发信号怎么用呢？ 简单一点定义一个全局flag变量就可以了，初始为0,设置之后为1,读到那边循环判断flag，为0则sleep一下减小cpu占用。 高级一点有spinlock, mutex, semaphore之类的[/quote] 你好 我用简单的全局变量和互斥锁mutex都用了，现在的现象是：用互斥锁时，程序进入后就一直停在里面get，出不来， 不同互斥锁，用简单的全局变量，每次进入去读，一直判断为0， 尽管我开时时就在调用set后给这个全局变量赋值了，它还是一直读到的是0，程序如下： set_Snapshot（）	 {     ............ 	 if(type == H_PIC_VGA) 	 {       set_pic = H_PIC_VGA; 	 } 	 else if(type == H_PIC_QVGA)    {      printf("#########################################748596\n");       set_pic = H_PIC_QVGA; 	 } 	 else if(type == H_CIF) 	 {       set_pic = 0; 	 } 	 else 	 {        printf("picture size is error!\n"); 	 } 	 get_fag = 1;//这个在构造函数里初始化为0了。 }  get我是这样写的： unsigned int CHw_Driv_Traini_Instr::get_Snapshot(unsigned char * h_size) {  	 //static pthread_mutex_t xml_mutex = PTHREAD_MUTEX_INITIALIZER;	  	// pthread_mutex_lock(&xml_mutex); 	  	 if(get_fag == 0) 	 { 			 printf("GGGGGGGGGGGGGGGGGGGGEEEEEEEEEETTT\n");  			 return -1; 	 } 	  	  printf("--!!!!!!!!!!$$$$$$-%d-h--\n", set_pic);  		     *h_size = set_pic;  	// pthread_mutex_unlock(&xml_mutex); 	  	 return *h_size; }

引用 2 楼 u014325402 的回复:引用 1 楼 user-1 的回复:运行thread 是异步的，你要么启动thread后sleep几秒，要么set完后发一个信号，在使用之前等到这个信号你好，这个程序设计的是这样的，先执行完set...之后，才回去调用 hw_driv_traini_instr.cpp里的那个接口，进而才会执行到get...的,sleep几秒时间太长了，你说的用发信号怎么用呢？ 简单一点定义一个全局flag变量就可以了，初始为0,设置之后为1,读到那边循环判断flag，为0则sleep一下减小cpu占用。 高级一点有spinlock, mutex, semaphore之类的

引用 9 楼 user-1 的回复:你每次都new一个instance，set与get操作的对象压根就不是同一个谢谢啊，已近解决了，正如你所说。

你每次都new一个instance，set与get操作的对象压根就不是同一个

引用 7 楼 user-1 的回复:[quote=引用 6 楼 u014325402 的回复:] 我把它设置为全局变还是不行，循环我这个程序不能写， 不能等待的，程序后面还有重要的功能没完成，得不到set设置的，使用默认的。 现在的情况是在自己本文件的接口内可以读到设置的，别的文件接口来读，就会读到0， 在别的文件里使用要加extern[/quote]可我是用instance来调用接口的呀

引用 6 楼 u014325402 的回复:我把它设置为全局变还是不行，循环我这个程序不能写， 不能等待的，程序后面还有重要的功能没完成，得不到set设置的，使用默认的。 现在的情况是在自己本文件的接口内可以读到设置的，别的文件接口来读，就会读到0， 在别的文件里使用要加extern

引用 5 楼 user-1 的回复:引用 4 楼 u014325402 的回复:[quote=引用 3 楼 user-1 的回复:] [quote=引用 2 楼 u014325402 的回复:] [quote=引用 1 楼 user-1 的回复:] 运行thread 是异步的，你要么启动thread后sleep几秒，要么set完后发一个信号，在使用之前等到这个信号你好，这个程序设计的是这样的，先执行完set...之后，才回去调用 hw_driv_traini_instr.cpp里的那个接口，进而才会执行到get...的,sleep几秒时间太长了，你说的用发信号怎么用呢？ 简单一点定义一个全局flag变量就可以了，初始为0,设置之后为1,读到那边循环判断flag，为0则sleep一下减小cpu占用。 高级一点有spinlock, mutex, semaphore之类的[/quote] 你好 我用简单的全局变量和互斥锁mutex都用了，现在的现象是：用互斥锁时，程序进入后就一直停在里面get，出不来， 不同互斥锁，用简单的全局变量，每次进入去读，一直判断为0， 尽管我开时时就在调用set后给这个全局变量赋值了，它还是一直读到的是0，程序如下： set_Snapshot（）	 {     ............ 	 if(type == H_PIC_VGA) 	 {       set_pic = H_PIC_VGA; 	 } 	 else if(type == H_PIC_QVGA)    {      printf("#########################################748596\n");       set_pic = H_PIC_QVGA; 	 } 	 else if(type == H_CIF) 	 {       set_pic = 0; 	 } 	 else 	 {        printf("picture size is error!\n"); 	 } 	 get_fag = 1;//这个在构造函数里初始化为0了。 }  get我是这样写的： unsigned int CHw_Driv_Traini_Instr::get_Snapshot(unsigned char * h_size) {  	 //static pthread_mutex_t xml_mutex = PTHREAD_MUTEX_INITIALIZER;	  	// pthread_mutex_lock(&xml_mutex); 	  	 if(get_fag == 0) 	 { 			 printf("GGGGGGGGGGGGGGGGGGGGEEEEEEEEEETTT\n");  			 return -1; 	 } 	  	  printf("--!!!!!!!!!!$$$$$$-%d-h--\n", set_pic);  		     *h_size = set_pic;  	// pthread_mutex_unlock(&xml_mutex); 	  	 return *h_size; } [/quote] 在get里要循环判断flag直到为1 用mutex要定义成全局变量并程序启动时就初始化，你定义成静态变量，怎么在set函数里获取[/quote]，我把它设置为全局变还是不行，循环我这个程序不能写， 不能等待的，程序后面还有重要的功能没完成，得不到set设置的，使用默认的。 现在的情况是在自己本文件的接口内可以读到设置的，别的文件接口来读，就会读到0，


Question: 对于c语言数组的理解问题

二维数组实际是一维数组的一维数组，所以二维数组时，a[0]表示的是内层的那个一维数组

仅供参考：//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

自己写个小程序练练就知道了，不巧我正好有一个，就给你玩玩吧。   #include <iostream>   int main() {     int **x ;   //创建一个指向指针x[row]的指针x     const int row = 5 ;     const int col = 10 ;          x = new int *[row] ;   //创建一个行指针，没错，在内存中连续分配的数组就是个指针     for(int j = 0 ; j < row ; j++)     {         x[j] = new int [col] ; //在第row行指针x[j]里再次创建col个int型变量     }     for(int i = 0 ; i < row ; i++)     {         for(int j = 0 ; j < col ; j++)         {             x[i][j] = i * j ;    //x是指针，x[i]也是指针，x[i][j]终于不是了，如果你创建三维数组，那么x,x[i],x[i][j]都是指针，x[i][j][k]才不是哦。             std::cout << "x[" << i << "][" << j << "]="<< x[i][j] << std::endl;         }     }     //std::cout << "address of x : " << x << std::endl ;      //std::cout << "value of x : " << *x << std::endl ;      for(int i = 0 ; i < row ; i++)     {         //std::cout << "address of x[" << i << "] = "<< x[i] << std::endl ;          std::cout << "value of x[" << i << "] = "<< *x[i] << std::endl ;          delete [] x[i] ;   //使用完了后记得要delete啊，不然就是内存泄漏。先delete 后创建的     }     delete [] x ;  //再delete先创建的。               }

http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组

楼主多去了解下指针就明白了


Question: free问题求解

没出错不代表你是对的，可能你程序之后将这片内存分配给其他变量，你就修改了不属于你的内存

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  提醒：Linux下的malloc和free都是开源的。

或者说，i在堆上，p在栈上，但是打印出来地址都是一样的。0x1004002d0 不太明白。

引用 5 楼 u010637941 的回复:谢谢各位的回复，那请教一下，free(i)，这个时候p可以正常的，p,i不是指向同一个地址吗？操作系统这一块暂时还没有了解学习呢。 实际上malloc、free的过程与操作系统无关，这是C环境的逻辑，你的程序一开始，便会向操作系统申请一大块堆空间，之后对于小内存的malloc、free都是这一大块堆空间的操作。 你调用free释放，仅仅是对于C环境内存管理而言。实际上对于操作系统来说这块内存已经是你的了，你当然可以使用！ free仅仅只是C环境将此内存标记为可用，以便下次你再malloc，这块内存可以再次被用到。

当free一块内存后，free(即运行库)会将这块内存标记为未使用，并不会清零或者说不能继续访问。 你继续使用free后的内存是个未定义行为，一旦这块内存被别的变量使用就会出错


Question: 为什么转义字符里面需要存在十六进制和八进制

发表下个人见解: 第一. 一般说的字符是指英文ASCII码字符 ASCII字符的本质是整数 例如:字符'A'在内存中存在的形式其对应的ASCII码的二进制的补码 第二 在大多数编程语言中,整数的表示方式有三种 1.十进制 2.八进制 3.十六进制

举两个例子吧

引用 1 楼 qq_35061930 的回复:思考了一下，我觉得其存在还是有必要的，因为在输出字符串中如果要添加响铃或者别的功能的话就需要用到转义字符 例如  printf（“HELLO\007”）时 括号内就一定要用转义字符 此时如果写数字的话就只能显示数字了  不知道我说的对不对


Question: C语言调用网页录入功能

使用WebBrowser控件，可以操作网页中的元素、控件，调用网页的JS方法。 可以使用MFC集成WebBrowser。  QT中，有与WebBrowser类似的QWebEngineView控件。

引用 1楼yes-hyh 的回复:分析页面的输入字段，然后c++程序自己构造POST包，POST到服务器就可以了撒！能具体说一下吗

引用 3 楼 heyuhang112 的回复:网页录入信息的本质是，你再填写了信息之后，浏览器根据你的输入，将数据通过HTTP的POST方式发送到服务器。你若是不想手动录入，便按照既定的格式，自己用程序构造HTTP的POST请求，然后将其发送到服务器即可。 这里我肯定只能给出思路，具体的实现如果楼主还不清楚的话，建议楼主自己去学习一下web的工作方式、HTTP相关知识。 清楚了HTTP之后，c的网络相关直接用socket。若嫌麻烦便找个HTTP客户端库吧，建议使用curl。  楼上说得对。 但是，不够全面，你先下载个Wireshark学会分析包再说吧。最后要使用管道执行Curl命令。 事先要有心理准备，以前对网络解析包等没了解，那没个一周摸索学习是玩不来的。 我弄过。


Question: 统计数字出现的次数

while((c=getchar())!=EOF);  去掉后面的分号

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

#include<stdio.h>  #define  DIGIT_NUM  10  int main(int argc, const char *argv[]) {     int c, i = 0;     int quantity[DIGIT_NUM];      for(; i < DIGIT_NUM; i++)         quantity[i] = 0;      while((c = getchar()) != EOF)         if('0' <= c && c <= '9')             ++quantity[c-'0'];      for(i = 0; i < DIGIT_NUM; i++)         printf(" %d", quantity[i]);      putchar('\n');      return 0; }  建议你注意下代码风格

#include<stdio.h>  int main() {     int c, i=0;     int quantity[10];      for(; i < 10; i++)         quantity[i] = 0;      while((c=getchar())!=EOF)         if('0'<=c&&c<='9')             ++quantity[c-'0'];     for(i = 0; i < 10; i++)         printf(" %d", quantity[i]);     putchar(10);      return 0; }  多一个分号;对比一下找到多了哪个分号

1、while后面有封号，int c为整形只能保存一个整数，所以无论输入多少次，只判断一次 2、getchar读取换行符赋给int c，所以if语句判断的一直是换行符，不符合条件，所以输出都是0


Question: 怎么把int和int*不兼容的问题解决下啊

ShellSort第一个参数需要的是int *的指针类型，你传一个int有什么用

ShellSort(&x, 10000);


Question: 菜鸟求问，struct类型的初始化和传参

用结构体数组

引用 2 楼 erxiaoqing5536 的回复:传参的话是怎样？AAA* aaa[ ] ??  aaa[0].a = 1; aaa[0].b = 'a';  //..........

struct AAA { int a; char b; double c; };  void Foo(AAA* pAAAs, int count) { 。。。 }  void main() {    AAA *aaa = new AAA[10];   Foo(aaa, 10);    AAA aaa2[20];   Foo(aaa2, 20); }

传参的话是怎样？AAA* aaa[ ] ??

多个就：AAA *aaa = new AAA[10];


Question: 关于函数指针的一个小问题。

可以直接使用函数指针调用函数  你也可以写成：(*pf)(5);


Question: 编译无错可一运行就出问题是什么原因？

估计你文件没有打开成功，fopen后先检查文件是否打开成功

void Appe()    /*追加模块*/   { 	int n,i;    	printf("       *******************\n"); 	printf("         请输入要追加的条数   n= ?      \n");   	printf("       *******************\n");   	scanf("%d",&n);   	printf(" *************************\n");  	printf("   请输入所追加的学生信息 \n");  	printf(" *************************\n");    	printf("*********************************************************************\n");    	printf("     学号     名字     英语     数学      计算机      物理     总分\n");    	printf("**********************************************************************\n");    	for(i=0;i<n;i++)   	{ 		scanf("%d%s%lf%lf%lf%lf%lf", 			&s[N].xh,s[N].name,&s[N].yy,&s[N].mat,&s[N].jsj,&s[N].wl,&s[N].zf);   		N++;   	}  }    void Modi()   /*修改模块*/   { 	int x,m,n,k=0,i,j;  	char st[20];    	printf("=======================================\n");   	printf("==           1.学号                ==\n");   	printf("==           2.名字                ==\n");    	printf("=====================================\n");  	scanf("%d",&m);   	if(m==1)    	{ 		printf("=====================================\n");  		printf("        请输入 学号                   \n");  		printf("=======================================");  		scanf("%d",&n);   		for(i=0;i<N;i++)  			if(n==s[i].xh) 			{  				k=1;j=i; 			}   	}    	else if(m==2)  	{ 		printf("=====================================\n"); 		printf("         请输入 名字                  \n");   		printf("======================================\n");   		scanf("%s",st);     		for(i=0;i<N;i++)  			if(!strcmp(s[i].name,st))    			{ 				k=1;j=i; 			}   	}    	if(k==1)  	{ 		printf("*********************************************************************\n");   		printf("  请问要修改哪项？    1:英语     2:数学      3:计算机      4:物理           \n");     		printf("**********************************************************************\n");    		scanf("%d",&x);  		switch(x)  		{  		case 1:scanf("%lf",&s[j].yy); break;     		case 2:scanf("%lf",&s[j].mat); break;     		case 3:scanf("%lf",&s[j].jsj); break;    		case 4:scanf("%lf",&s[j].wl); break;   		}   	}   	else   	{   		printf("===========================\n");  		printf("         出现错误        *\n");   		printf("============================\n");  	}  }   void Dele()   /*删除模块*/   { 	int m,n,k=0,j,i;   	char str[20];    	printf("       ===============================\n");   	printf("       =       1.按学号删            =\n");   	printf("       =       2.按姓名删            =\n");    	printf("       ===============================\n");   	scanf("%d",&m);  if(m==1)   	{  		printf("       ===============================\n");   		printf("        =       请输入学号!           =\n");       		printf("       ===============================\n");   		scanf("%d",&n);   		for(i=0;i<N;i++)    			if(n==s[i].xh)    			{  				k=1;j=i; 			}   	}    	else if(m==2) 	{  		printf("       ===============================\n");  		printf("        ==         请输入名字!      ===\n");   		printf("        ===============================\n");  		scanf("%s",str);   		for(i=0;i<N;i++)     			if(!strcmp(s[i].name,str))     			{ 				k=1;j=i; 			}   	}      	if(k==1)   	{ 		for(i=j;i<N-1;i++)     			s[i]=s[i+1];   		N--;     	}      	else  	{   		printf("=============================\n");            		printf("   没有要删除的此人      *\n");         		printf("============================\n");     	}  }    void Query()   /*查询模块*/   { 	int n,num,i,k,j;   	char xm[10];    	printf("1、按学号查询   2、按姓名查询\t");  printf("\n请输入你的选择:\t");  	scanf("%d",&n);  	if(n==1)  	{    		printf("\n请输入学号:");   		scanf("%d",&num);   		for(i=0;i<N;i++)     			if(num==s[i].xh)     			{     				k=1; 				j=i;  			}   	}    	else if(n==2)  	{    		printf("请输入姓名:");    		scanf("%s",xm);    		for(i=0;i<N;i++)     			if(strcmp(s[i].name,xm)==0)   			{      				k=1;      				j=i;      			}   	}    	if (k==1)  	{    		printf("学号    姓名       英语        数学         计算机        物理       总分\n");     		printf("===============================================================================\n");    		printf("%d   %s    %f    %f    %f    %f    %f\n", 			s[j].xh ,s[j].name ,s[j].yy ,s[j].mat ,s[j].jsj ,s[j].wl, s[j].zf);     		printf("===============================================================================\n");   	}    	else printf("没有所查询的人");  getchar();  }     void Quit()    /*退出*/     {   	printf("                     ******  Thank you  bye  ****** \n");  	printf("\t***************************************************************\n"); 	printf("\n");   	printf("\t*                     谢谢使用学生成绩管理系统                *\n");  	printf("\n");  	printf("\t*                                                             *\n");  	printf("\n");   	printf("\t*                      钟一文（制作）                         *\n");  	printf("\n");   	printf("\t*                    学号：201101040232                      *\n");  	printf("\n");   	printf("\t_________________    如有疑问，请致电13047237362    ___________\n");  	printf("\t***************************************************************\n");  	printf("\n");   	printf("\t                                                 2012年06月26日\n");    }    void main()  {  	int sele;    	Re_file();    	sele=1;   	while(sele)   	{  		printf("\n\n");   		printf("    ***欢迎使用学生成绩管理系统***\n");   		printf("     ****************************\n");      		printf("     *                          *\n");    		printf("     *   1:显示        2:追加   *\n");   		printf("     *                          *\n");    		printf("     *   3:修改        4:删除   *\n");  		printf("     *                          *\n");     		printf("     *   5:查询        6:排序   *\n");     		printf("     *                          *\n");    		printf("     *   7:统计        8.退出   *\n");    		printf("     *                          *\n");   		printf("     ****************************\n");     		printf("\n\n请输入你的选择: ");     		scanf("%d",&sele);    		switch(sele)      		{        		case 1:Disp();break;        		case 2:Appe();Disp();break;       		case 3:Modi();Disp();break;       		case 4:Dele();Disp();break;      		case 5:Query();break;      		case 6:Sort();Disp(); break;   		case 7:Total(); break;        		case 8:Quit(); sele=0;break;     		}    		printf("\n\nPress any key to continue\n");   		getchar();    	}     	Wr_file();    }


Question: 求助关于计算数字和

引用 3 楼 qq423399099 的回复:试试itoa?  #include <stdio.h> #include <stdbool.h> #include <string.h> #include <stdlib.h> int main(void) { 	int i, sum = 0; 	char k[100]; 	char str[100] = ""; 	scanf("%s", k); 	for (i = 0; i<strlen(k); i++){ 		sum += (int)k[i] - '0'; 	} 	printf("%d", sum);  //计算数字和  	char sum2[32] = { 0 }; 	_itoa(sum, sum2, 10); 	printf("%s", sum2);    		return 0; }   itoa确实可以，但是为什么不能强制转换呢。。奇怪

引用 4 楼 paschen 的回复:最后那里改成：   		char sum2 = sum + '0'; 		printf("%c",sum2);   这样打印是空的啊

#include <stdio.h> #include <stdbool.h> #include <string.h>  #define MAX_STRING_LEN  64  int my_itoa(int num, char *str);  int main(void) {     int i, sum = 0;     char str[MAX_STRING_LEN];     char sum_str[MAX_STRING_LEN] = "";      printf("Please input a string of numbers: ");     scanf("%s", str);      for(i = 0; i < strlen(str); i++)         sum += str[i] - '0';      printf("sum num = %d\n", sum);  //计算数字和      my_itoa(sum, sum_str);     printf("sum string = %s\n", sum_str);      return 0; }   int my_itoa(int num, char *str) {     int i, j;      for (i = 0; num; i++) {         str[i] = num % 10 + '0';         num = num / 10;     }     str[i] = 0;      for (j = 0; j < i/2; j++) {         int tmp = str[j];         str[j] = str[i-j-1];         str[i-j-1] = tmp;     }      return 0; }     做一个求和的反操作

有人吗。。。求回答


Question: 为什么函数的地址不会变？

引用 6 楼 zkr33928 的回复:[quote=引用 4 楼 paschen 的回复:] [quote=引用 2 楼 zkr33928 的回复:] [quote=引用 1 楼 akirya 的回复:] 这个本来就是是不确定事情。 试了很多遍，都只改变前四位，虽然地址不确定，但是这个改变的规律应该确定吧？[/quote]  因为函数与函数之间也会进行对齐[/quote] 不明白，这个对齐是什么意思[/quote]  网上搜索“内存对齐”

引用 5 楼 zkr33928 的回复:[quote=引用 3 楼 ipqtjmqj 的回复:] 空行编译时就忽略掉了，操作系统不变，编译器不变，编译配置不变，结果就不变 后4位地址没变，你还是一个函数，编译配置相同，当然地址不变了。  你输出的地址是操作系统分配的虚拟地址，并不是物理地址。 一个程序的地址空间分为几个段，text段放函数，data段放全局变量,bss段是未初始化的全局变量  不仅是空行！定义100个变量他也不会变。[/quote]  变量是定义在栈上，而不是代码区，不会影响到函数的地址

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构

一年管理成富翁，三年市场路路通，十年技术一场空。 ======================================== 孟子曰：劳心者治人，劳力者治于人。

因为爱情  管他为啥呢，windows封装这么多层，一层套一层的，为的就是让我们摆脱这种乱七八糟没意义的探索，用得着的都会在编译器窗口里显示出来。  如果实在是闲的难受想研究下，通读下《数字逻辑》->《计算机组成原理》->《操作系统》->《编译原理》,  读完之后顺便怀疑下人生，然后大彻大悟发现自己不适合干程序员，从此转行卖烧饼，年入百万，赢取白富美，走向人生巅峰。  正印了那句老话：一年管理成富翁，三年市场路路通，十年技术一场空。

引用 4 楼 paschen 的回复:[quote=引用 2 楼 zkr33928 的回复:] [quote=引用 1 楼 akirya 的回复:] 这个本来就是是不确定事情。 试了很多遍，都只改变前四位，虽然地址不确定，但是这个改变的规律应该确定吧？[/quote]  因为函数与函数之间也会进行对齐[/quote] 不明白，这个对齐是什么意思

引用 3 楼 ipqtjmqj 的回复:空行编译时就忽略掉了，操作系统不变，编译器不变，编译配置不变，结果就不变 后4位地址没变，你还是一个函数，编译配置相同，当然地址不变了。  你输出的地址是操作系统分配的虚拟地址，并不是物理地址。 一个程序的地址空间分为几个段，text段放函数，data段放全局变量,bss段是未初始化的全局变量  不仅是空行！定义100个变量他也不会变。

引用 2 楼 zkr33928 的回复:[quote=引用 1 楼 akirya 的回复:] 这个本来就是是不确定事情。 试了很多遍，都只改变前四位，虽然地址不确定，但是这个改变的规律应该确定吧？[/quote]  因为函数与函数之间也会进行对齐

引用 1 楼 akirya 的回复:这个本来就是是不确定事情。 试了很多遍，都只改变前四位，虽然地址不确定，但是这个改变的规律应该确定吧？

这个本来就是是不确定事情。


Question: 小白，求解！

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

#include<stdio.h>  #define MAX_LEN     8 int main (void) {     double n[MAX_LEN];     double h[MAX_LEN];     int i;      printf("Enter eight number(double):");     for( i = 0; i < MAX_LEN; i++)         scanf("%lf", &n[i]);      h[0] = n[0];     for(i = 0; i < MAX_LEN-1; i++)         h[i+1] = h[i] + n[i+1];      for(i = 0; i < MAX_LEN; i++)         printf("%5.2lf %5.2lf\n", n[i], h[i]);     return 0; }

因为你的代码：h[0]=n[0];  你自己让h[0]的值等于n[0]  后面的循环 h[q+1]=h[q]+n[q+1]; 是从h[1] ~ h[8]的赋值，而且越界了


Question: 命令行 文件压缩程序问题

引用 12 楼 bigwatercar 的回复:老赵的回答很正确。

老赵的回答很正确。

谢谢你啊 代码我看的懂啊，只是书上就只是简单的写道“ 命令如下：reducto eddy”    我不知道在哪里去输入这个命令。。。谢谢你了 我按你的方法去试一下

引用 2 楼 njxs1357 的回复:书上的代码啊  应该没错吧。。看了几遍 那也是抄的，而且你没懂。  Windows命令行使用方法：在你的工程目录中，找到你编译的可执行(exe)程序所在目录, 然后按住shift鼠标右击，选择“在此处打开命令行”， 然后敲你的程序名字(按tab可自动补全), 再敲空格，再是参数，如有更多参数则都是空格分隔。 然后回车参数传入程序，程序启动

还是不懂呀，有没有人能帮帮我

VC6：  工程、设置、Debug、U程序变量：填写命令行参数。 VS20XX：  项目、属性、配置属性、调试、命令参数：填写命令行参数。

书上的代码啊  应该没错吧。。看了几遍

你代码网上抄来的吧。 从命令行与从stdin你搞混了

没看出是文件压缩程序，就是简单的读写。 如果是要实现压缩文件功能，可以直接调用Windows 自带 WinRAR ！

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

引用 8 楼 zhao4zhong1 的回复:现在的码农竟然99%都不会在cmd窗口中输入cd命令设置当前目录为程序所在目录，输入程序名运行程序了！呀呀 老师我不是码农啊   我只是一个初学者，学基础呀


Question: 求把下面的代码转换成用指针完成

A[B] *(A+B) *(B+A) B[A] //以上四行等价  "abc"[1] *("abc"+1) *(1+"abc") 1["abc"] //以上四行等价  A[0] *(A) 0[A] //以上三行等价

#include<stdio.h>  #define     MAX_NUM  10 #define USE_POINTER static void print_num(int *num, int len); void get_max_min_num(int *num, int len);  int main() {     int num[MAX_NUM]={2,1,5,4,8,7,9,7,2,6};  #ifndef USE_POINTER     int i,max=0,min=0,m,n;      m=num[9];     n=num[0];     for(i=0;i<MAX_NUM;i++)     {         if(num[i]>num[max])         {             max=i;             num[9]=num[max];             continue;         }         else if(num[i]<num[min])         {             min=i;             num[0]=num[min];             continue;         }     }     num[max]=m;     num[min]=n;     for(i=0;i<MAX_NUM;i++)         printf("%d ",num[i]);     putchar('\n'); #else     get_max_min_num(num, MAX_NUM);     print_num(num, MAX_NUM); #endif     return 0; }  static void print_num(int *num, int len) {     int i;      for(i = 0; i < len; i++)         printf("%d ", num[i]);      putchar('\n'); }  void get_max_min_num(int *num, int len) {     int m, n, i;     int max = 0, min = 0;      m = num[len-1];     n = num[0];     for(i = 0; i < len; i++)     {         if(num[i] > num[max])         {             max = i;             num[len-1] = num[max];             continue;         }         else if(num[i] < num[min])         {             min = i;             num[0] = num[min];             continue;         }     }     num[max] = m;     num[min] = n; }  在得到最大和最小值的处理中,代码有点"硬",我做了修改,就是把9改成了len-1

用一个指针指向数组？

楼主可以看看这个 http://blog.csdn.net/peiyao456/article/details/51291785?locationNum=3&fps=1

arr[i] 等价于 *(arr+i)


Question: 删除字符

引用 2 楼 ldsh304的回复:#include <stdio.h> #include <string.h>  /* 	删除字符串dest中的字符ch 	返回值：删除个数 */ int delchar (char *dest,const char ch) { 	int count = 0;     char *p = dest;     int i = 0;     for (; i < strlen(dest); )     {     	if (dest[i] == ch)     	{ 			strcpy(dest+i, dest+i+1); 			count++;     	}     	else     	{     		i++;     	}     }     return count; }  int main () {     char s[80];     char ch;     int count;          printf("pls input ch:\n");     ch=getchar();     printf("pls input s:\n");     scanf("%s",s);     count = delchar(s,ch);     if (count == 0)     	printf("删除失败，没有元素%c\n", count, ch); 	else printf("已成功删除%d个元素！\n", count);     printf("%s",s);     return 0; }  为什么dest+i不能写成dest[i]

//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

引用 3 楼 u012924019 的回复:好简单粗暴的提问方式，直接拍照。 打字都懒得打了。自己的分析呢？ 哎。。。。现在的学生啊。。。。 很多时候，使用的工具越先进，人越笨；得到得越轻松，人越懒。

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

#include <stdio.h> #include <stdlib.h> #include <string.h>   char * delchar(char a[],char ch) { 	char *b; 	int len , i , j = 0; 	len = strlen (a); 	b = (char *)malloc(len * sizeof(char)); 	for(i = 0 ; i < len ; i++) 		if(a[i] != ch) 		{ 			b[j] = a[i]; 			j++; 		} 	b[j] = '\0'; 	return b; }  int main () { 	char a[100] , *b , ch; 	int len; 	printf ("请输入字符串：");  	gets(a); 	printf ("请输入字符：");  	scanf("%c",&ch); 	len = strlen (a); 	b = (char *)malloc (len * sizeof (char)); 	b = delchar(a,ch); 	printf("%s\n",b); 	return 0; }


Question: tsp问题求解

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

程序贴上去了希望有大佬能给解决一下。

#include "stdafx.h" # include<time.h>  # include<math.h>  # include<stdio.h>  # include<stdlib.h> # define Max 11   int cn, tt, start;                          // 要经过的城市个数,,起点 double arry1[Max][Max];                   // 邻接矩阵，存放两两城市间的距离 double fn = 0, gn = 0, hn = 0;                    // 启发函数 double f1 = 0, g1 = 0, h1 = 0; int arry3[Max];                           // 存放已历经的城市名 int arry4[Max];                           // 标志位数组，cn个城市中已历经的置，未历经的置  // 定义顶点数据类型 struct Vertex { 	int x; 	int y; }City[Max];  /////////////////////////////////////////////////////////////////////////////////////////// // 主函数 void main() { 	void RandNum(int); 	void CityCoordinate(); 	double CityCost(int, int); 	void TSP(); 	double MaxLengh();  	int i, j;  	CityCoordinate();          // 随机生成并显示个城市及其坐标  	printf("\n"); 	printf("\n");  	for (i = 1; i<Max; i++)                 // 随机生成并显示表示两城市间距离的邻接矩阵 	{ 		tt = 0; 		for (j = i; j<Max; j++, tt++) 		{ 			if (i == j)   arry1[i][j] = 0; 			else   arry1[i][j] = CityCost(i, j); 		} 	}  	TSP();                               // 用最小生成树查找最短路径  	printf("\n从%d出发的最佳路径为：%d→", start, start); 	for (i = 2; i <= cn; i++) printf("%d→", arry3[i]); 	printf("%d\n", arry3[cn + 1]);  	printf("总路径长度为:%f\n", fn); }  ///////////////////////////////////////////////////////////////////////////////////////////  // 随机数产生器 int RandNum(int max) { 	int m; 	m = rand() % (max - 1) + 1;                   // 产生一个~20的随机数 	return m; }  // 生成并显示城市坐标 void CityCoordinate() { 	int i, j, hh = 0;  	srand((unsigned)time(NULL));   // 使用当前时间作为种子 	City[1].x = RandNum(Max);        // 生成并显示第个城市的坐标 	City[1].y = RandNum(Max); 	printf("City[1]的坐标: (%d,%d);     ", City[1].x, City[1].y);   	for (i = 2; i<Max; i++)            // 生成第~10个城市的坐标 	{ 		City[i].x = RandNum(Max); 		City[i].y = RandNum(Max);  		for (j = 1; j<i; j++)            // 检查重合坐标,有重合时重新生成 		if (City[i].x == City[j].x&& City[i].y == City[j].y) 			i = i - 1;  		hh++;                             // 换行 		if (0 != i % 2)  hh = 0; 		if (0 == hh)   printf("\n");  		printf("City[%d]的坐标: (%d,%d);   ", i, City[i].x, City[i].y);// 显示第i个城市的坐标 	} }  // 计算并显示城市间的欧式距离 double CityCost(int i, int j) { 	int x1, x2, y1, y2, hh = 0; 	double Distance, t;  	x1 = City[i].x; 	x2 = City[j].x; 	y1 = City[i].y; 	y2 = City[j].y; 	t = (x1 - x2)* (x1 - x2) + (y1 - y2)* (y1 - y2); 	Distance = sqrt(t); 	arry1[i][j] = Distance;  	hh++; 	if (0 != tt % 2)  hh = 0;            // 换行  	if (0 == hh)   printf("\n");  	printf("%d与%d的距离：%3.2f      ", i, j, Distance); 	return arry1[i][j]; }  // 用最邻近法找最短路径 void TSP(){ 	int Mnode;                                         // 起点，当前搜索层的父节点 	int h, i, k, l, m,  j; 	double min; 	int x, y = 0; 	int arry2[Max] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };;// 标志位数组，已历经的置0，未历经的置1 	double temp1 = 100, temp2 = 100; 	printf("\n请输入要经过的城市个数："); 	scanf_s("%d", &cn); 	printf("\n");  	printf("请输入要历经的城市：\n"); 	for (h = 1; h <= cn; h++)                  // 输入历经节点 	{ 		scanf_s("%d", &x); 		if (0 == arry2[x]) arry2[x] = 1;   // 避免重复 		else if (1 == arry2[x]) h = h - 1; 	}  	printf("\n"); 	for (i = 1; i<Max; i++)                  // 显示历经节点 	if (1 == arry2[i]) 		printf("%d ", i); 	printf("\n");  	printf("请输入出发城市：");         // 输入出发点 	scanf_s("%d", &start); 	printf("\n");  	arry2[start] = 0;                         // 初始化 	arry3[1] = start; 	arry3[cn + 1] = start;                   //首尾端点一致 	Mnode = arry3[1]; 	      ////////////////////////////////////////寻找最近的点  	for (k = 1, l = 1; k < Max&&arry2[k] == 1; k = m){ 		for (j = 1; j < Max; j++){ 			if (arry2[j] == 1 && j != k) { 				min = arry1[k][j]; 				if (arry1[k][j] <= min){ 					min = arry1[k][j]; 					m = j; 					arry3[++l] = j; 				} 			} 		} 		fn += min; 	}  }


Question: 求助：帮忙看看老师所要求的这道重要节点组的挖掘该怎么做

百度搜相关关键字。

卧槽，这都被你发现了

哥们，电子科大英才陈端兵老师的吧~hhhhhhhh同病相怜啊哈哈哈哈哈哈哈哈哈哈哈哈哈


Question: C语言point跟Bool问题

uint32_t battery;    //无符号? Bool read_battery(int *data); //有符号 ret = read_battery(&info.battery);   // 有无符号匹配么？？  另外，常用C++。 在c中，ret是保留关键字么？

需要传递一个参数,不然编译器回报错或者警告吧,尤其是在这个函数里使用到这个参数,那么就不会得到想要的结果.还是传一个实参进去吧

是整数: Bool read_battery(int *data){...}  另外请教, int main() {     int BattValue;     BattValue = read_adc();     } read_adc后面似乎要带一个参数吧? 才能够将Bool read_battery(int *data){...}内的资料带回main

struct system_info {   uint8_t   mcu[12];   uint32_t battery;   uint8_t   firmware_version[12]; }  int main() {    struct system_info info;    bool                        ret;   //error      ret = read_battery(&info.battery);   //error      if (ret == false)         return error message; }  Bool read_battery(int *data){      ADC_Handle    adc;      ADC_Params  params;     bool	              ret;      ADC_Params_init(¶ms);     adc = ADC_open(Board_ADC0, ¶ms);       if ( adc == NULL )       return FALSE;         ret = read_adc(adc,0,data,sizeof(uint32_t));       ADC_close(adc);      return ret; }

我就是不知道要传递啥数据型态才PO上去求救  int main(){    int	      BattValue;    int       battery;    BattValue = read_battery(&battery);  }  Bool read_battery(int *data){ 	ADC_Handle  adc; 	ADC_Params  params; 	bool		ret;  	ADC_Params_init(¶ms); 	adc = ADC_open(Board_ADC0, ¶ms);    	if ( adc == NULL ) 			return FALSE; 	ret = read_adc(adc,0,data,sizeof(uint32_t)); 	ADC_close(adc); 	return ret; }  这样也出错

int read_adc(*data)  没有指定参数类型

1.我也知道没调用参数 2.写错了,应该是:    int read_battery(int *data){...} 3. Bool read_adc(void *handle, uint8_t address, void *data, size_t size) { 	uint16_t value;  	if (ADC_convert((ADC_Handle)handle, &value)  == ADC_STATUS_SUCCESS) { 		*(uint32_t *)data = ADC_convertRawToMicroVolts((ADC_Handle)handle, value); 		return TRUE; 	} else { 		return FALSE; 	} }

在main函数中调用read_abc时没有写参数，下面出现四个参数同一楼一样看不懂

看不懂你这个read_adc函数 1.main函数里调用是不传参数的，BattValue = read_adc();  2.函数实现的时候是有一个参数的，类型也没有写而且，int read_adc(*data) 3.这次调用，又是4个参数的？？？battery = read_adc(adc, 0, µVolts, sizeof(int));


Question: scanf) 函数 当输入a到z的字母时，都显示为1

int select; 	printf("                    请选择：（1/2/3/4/0）"); 	if (scanf("%d",&select) != 1) 		select = 1; 	printf("\n%s%d%s","---",select,"---"); 	printf("\n"); 	system("pause");

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

仅供参考：#include <stdio.h> #include <string.h> char s[80]; int i; char c; int main() {     while (1) {         printf("Input a integer:");fflush(stdout);         rewind(stdin);         fgets(s,80,stdin); 		if (strlen(s)>10) { 			printf("Input too long(>9)!\n"); 			continue; 		}         if (2==sscanf(s,"%d%c",&i,&c)) {             if ('\n'==c) {                 printf("%d is a integer.\n",i);                 break;             }         }         if ('\n'==s[strlen(s)-1]) s[strlen(s)-1]=0;         printf("\"%s\" is NOT a integer!\n",s);     }     return 0; }


Question: “student *(student *,int)”与“int ()”的间接寻址级别不同

请问博主有没有遇到p1 是 nullptr的问题，该怎么解决。

多谢大神指点，已经成功调试了。。。

1.函数声明不要放在main函数里，放到你的13行的位置（struct student这个结构体后面） 2.你的函数struct student * create_lb(int n);只有函数声明啊？并没有看到你的函数实现

麻烦各位大神帮忙看看。。。 真的调了好久还是错啊！  #include <stdlib.h> #include <stdio.h> #include <malloc.h> struct student { 	int num; 	char name[20];     int age; 	char sex[10]; 	int score; 	struct student *next; }; void print_lb(struct student *head) { 	struct student *p=head;  	printf("学生的信息表为：\n"); 	while(p!=NULL) 	{ 	    printf("%2d%2s%d%s%d",&p->num,p->name,&p->age,p->sex,&p->score); 	} } void count_lb(struct student *head) { 	struct student *p=head; 	int res[6]={0};  	while(p!=NULL) 	{ 	    if(p->score<60) 			res[0]++; 		else res[p->score/10-5]++; 		p=p->next; 	}  	printf("[0 ,59]的人数有:%d\n",res[0]); 	printf("[60,69]的人数有:%d\n",res[1]); 	printf("[70,79]的人数有:%d\n",res[2]); 	printf("[80,89]的人数有:%d\n",res[3]); 	printf("[90,99]的人数有:%d\n",res[4]); 	printf(" 100分 的人数有:%d\n",res[5]); } void edit_node(struct student *head,int num) { 	struct student *p=head;  	p=Cha(head,num);  	if(p==NULL) 		printf("无该生信息!\n"); 	else 	{ 	    printf("该生的原始信息为:学号:%d,名字:%s,年龄:%d,性别:%s,成绩:%d\n", 			p->num,p->name,p->age,p->sex,p->score); 		printf("请输入要修改该生的信息:\n"); 		scanf("%d%s%d%s%d",&p->num,p->name,&p->age,p->sex,&p->score); 		getchar(); 	} } void query_lb(struct student *head,int num)//查询 { 	struct student *p; 	 	p=Cha(head,num);  	if(p==NULL) 		printf("无该生信息!\n"); 	else printf("%d%s",p->num,p->name); } struct student *del_node(struct student *head,int num) { 	struct student *p1=head,*p2=head;  //p1待删点  	while(p1->next!=NULL&&p1->num!=num ) 	{ 		p2=p1; 	    p1=p1->next; 	}  	if(p1->num==num) 	{ 		if(head==p1)  			head=p1->next; 		else  			p2->next=p1->next; 		free(p1); 	} 	else printf("无删除结点！\n");  	return head; }  struct student *insert_node(struct student *head,struct student *stud) { 	struct student *p0,*p1,*p2; 	p1=head; 	p0=stud; 	if(p1==head) 	{ 	    head=p0; 		p0->next=NULL; 	} 	else 	{ 	    while((p0->num>p1->num) && (p1->next!=NULL)) 		{ 		    p2=p1; 			p1=p1->next; 		} 	    if(p0->num>p1->num) 		{ 		    p1=p0; 			p0->next=NULL; 		} 		else if(head==p1) 		{ 		    p0->next=head; 			head=p0; 		} 		else  		{ 		    p2->next=p0; 			p0->next=p1; 		} 	}  	return head; } struct student *create(int n) { 	struct student *head=NULL,*p1,*p2=NULL; 	int i;  	for(i=1;i<n;i++) 	{ 	    if((p1=(struct student *)malloc(sizeof(struct student)))==NULL) 	    { 	        printf("不能成功分配储存块!\n"); 	    	exit(0); 	    } 	 	    p1->next=NULL; 	    printf("请输入第%d个学生的信息(学号，名字，年龄，性别，成绩):\n"); 		scanf("%d%s%d%s%d",&p1->num,p1->name,&p1->age,p1->sex,&p1->score); 		if(i==1) head=p1; 		else p2->next=p1; 		p2=p1; 	}  	return head; } struct student *Cha(struct student *head,int num) { 	while(head!=NULL) 	{ 		if(head->num==num) 			break; 		else head=head->next; 	}  	return head; } void main() { 	int n,num,sel;               //sel菜单选项 	struct student * head=NULL,*p; 	struct student *Cha(struct student *head,int num); 	struct student * create_lb(int n); 	struct student * insert_node(struct student *head,struct student *stud); 	struct student * del_node(struct student *head,int num);     void query_lb(struct student *head,int num); 	void edit_node(struct student *head,int num); 	void count_lb(struct student *head); 	void print_lb(struct student *head);  	while(1) 	{ 	    system("cls"); 		printf("\n");printf("\n");printf("\n");printf("\n");printf("\n"); 		printf("                 ***************学生成绩信息系统***************\n"); 	    printf("                ╭────────张朝中出品─────────╮\n");printf("\n"); 		printf("                │                                            │\n"); 		printf("                │     1.输入学生信息       2.插入学生信息    │\n"); 		printf("                │     3.查询学生信息       4.修改学生信息    │\n"); 		printf("                │     5.删除学生信息       6.成绩统计分析    │\n"); 		printf("                │     7.输出学生信息       0.退出系统        │\n"); 		printf("                │                                            │\n"); 		printf("                ╰──────────────────────╯\n");printf("\n"); 		printf("                 **********************************************\n"); 	    printf("请输入(1-7,0退出):\n"); 	    scanf("%d",&sel); 	    switch(sel) 	    { 	         case 1: 				 printf("输入一批学生人数:\n"); 				 scanf("%d",&n); 				 head=create_lb(n); 				 break; 			 case 2: 				if((p=(struct student *)malloc(sizeof(struct student)))==NULL) 				{ 				    printf("不能成功分配储存块\n"); 					exit(0); 				 } 				 printf("请输入该生的信息: "); 				 scanf("%d%s",&p->num,p->name); 				 p->next=NULL; 				 getchar(); 				 head=insert_node(head,p); 				 break;              case 3: 				 printf("请输入待查的学生学号: "); 				 scanf("%d",&num); 				 getchar(); 				 query_lb(head,num); 				 break; 	         case 4: 				 printf("请输入要修改的学生学号: "); 				 scanf("%d",&num); 				 getchar(); 				 edit_node(head,num); 				 break; 	         case 5: 				 printf("请输入待删除的学生学号: "); 				 scanf("%d",&num); 				 getchar(); 				 del_node(head,num); 				 break; 	         case 6: 				 count_lb(head); 				 break; 	         case 7: 				 print_lb(head); 				 break; 	         case 0: 				 printf("您已经退出学生成绩信息系统"); 				 return; 	         default: 		          printf("输入错误,请重新输入选择: \n"); 		          break; 	    } 	    printf("\n请按任意键继续..."); 	    getchar();     } }

struct student { 	int num; 	char name[20]; 	int age; 	char sex[10]; 	int score; 	struct student *next; }; void main() { 	int n,num,sel;               //sel菜单选项 	struct student * head=NULL,*p;  	struct student * cha(struct student *head,int num);

多贴一点代码，特别是struct student这个结构体

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

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。


Question: C题求解

引用 9 楼 qq_24138885 的回复:[quote=引用 8 楼 qq_24138885 的回复:]  #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h>  void del_char(char a[], char); int main() { 	char s[20] = {0}; 	char ch = 'a'; 	scanf("%s", s); 	getchar(); 	scanf("%c", &ch);  	printf("原始字符串为：%s \n", s); 	printf("要截取的字符串为：%c \n", ch); 	printf("截取后字符串为："); 	del_char(s, ch); 	return 0; } void del_char(char s[], char ch) { 	unsigned int i, n; 	n = strlen(s); 	char tmp[30] = {0};  	for (i = 0; i < n; i++) 	{ 		if (s[i] != '\0')  		{ 			if (ch != s[i]) 			{ 				strncpy(&tmp[i],&s[i],1); 				printf("%c", tmp[i]); 			} 		} 	} 	printf("\n"); }  第8行改为 char ch = {0}；[/quote] 是第九行

引用 8 楼 qq_24138885 的回复: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h>  void del_char(char a[], char); int main() { 	char s[20] = {0}; 	char ch = 'a'; 	scanf("%s", s); 	getchar(); 	scanf("%c", &ch);  	printf("原始字符串为：%s \n", s); 	printf("要截取的字符串为：%c \n", ch); 	printf("截取后字符串为："); 	del_char(s, ch); 	return 0; } void del_char(char s[], char ch) { 	unsigned int i, n; 	n = strlen(s); 	char tmp[30] = {0};  	for (i = 0; i < n; i++) 	{ 		if (s[i] != '\0')  		{ 			if (ch != s[i]) 			{ 				strncpy(&tmp[i],&s[i],1); 				printf("%c", tmp[i]); 			} 		} 	} 	printf("\n"); }  第8行改为 char ch = {0}；

学生党  挺多的   我们老师要求我们  进csdn  期末检查论坛积分

strlen()返回的字符串长度和字符数组的下标是不一样的。

1.你的for (j = i; j<n; j++)s[j] = s[j + 1];这个会越界，如果j等于n-1的时候，s[j+1]会越界 2.出于效率考虑，你其实不需要每次都从i前移到n（前移到'\0'的位置就行了）

改成j<n-1就对了

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

void del_char(char a[],char) 声明后少了分号   s[20] 设置大一点，否则字符串长度只有20字符

当j=n-1的时候，那么请问你的j+1又是多少呢？？


Question: 在C语言中

根据2楼所述，没有rw

打开文件的方式，rw表示读写方式打开

ANSI C规定文件打开用函数fopen，关闭为fclose。  1、调用方式通常为:  FILE *fp; fp=fopen(文件名, 打开方式);   2、参数说明: 文件名: 形如"myfile.dat"、"F:\data\myfile.dat"等等; 打开方式: 　　"r"(只读) 为输入打开一个文本文件 　　"w"(只写) 为输出打开一个文本文件 　　"a"(追加) 向文件文件尾添加数据 　　"rb"(只读) 为输入打开一个二进制文件 　　"wb"(只写) 为输出打开一个二进制文件 　　"r+"(读写) 为读写打开一个文本文件 　　"w+"(读写) 为读写建立一个新的文本文件 　　"a+"(读写) 为读写打开一个文本文件 　　"rb+"(读写) 为读写打开一个二进制文件 　　"wb+"(读写) 为读写建立一个新的二进制文件 　　"ab+"(读写) 为读写打开一个二进制文件   3、注意: 　　(1)用"r"方式打开的文件，不能向其输入数据，并且该文件已存在，否则出错； 　　(2)用"w"方式打开的文件，只能向该文件输入数据，如果所打开的文件不存在，则在打开时新建一个以指定的名字命名的文件；如果指定文件存在,则在打开时将该文件删去，然后新建一个新的文件； 　　(3)如果函数fopen打开文件出错，则fopen返回一个空指针值NULL； 　　(4)在程序开始运行时，系统自动打开3个标准文件:标准输入(stdin)，标准输出(stdout)，标准出错输 出(stderr)。如果要使用输入输出终端，则不需要打开，可以直接使用，如fputc(stdout,'a');向屏幕输出字符a。

文件打开模式  参看：http://en.cppreference.com/w/c/io/fopen 中 mode 参数