Question: C语言怎么循环创建数组

若不能确定数组的个数和长度，建议使用动态申请空间的方式malloc/free。

#include <stdio.h> #include <stdlib.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=new int *[rows];     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=new int[cols];         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         delete[] p[i];     }     delete[] p; } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //  #include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //

C语言中动态创建:malloc,释放：free C++中：new,delete

引用 4 楼 NonArrendertiMai的回复:[quote=引用 3 楼 paschen 的回复:] [quote=引用 2 楼 NonArrendertiMai的回复:][quote=引用 1 楼 paschen 的回复:] 1、每次循环数组大小不同可以每次循环中动态创建数组(malloc)  2、循环次数未知可以在循环中进行判断，在满足条件时再break跳出循环 额，每次的数组长度是一样的，长度已知，但是数组名每次要不一样，比如a1,a2,a3,an，这该如何实现呢[/quote] 循环不会根据变量名字去区分，如果数组长度一样，建议定义成二维数组  循环时分别对应 a[0][N]  a[1][N].......[/quote]  但是循环变量不能用来定义数组呐，长度需要常量啊。。。。[/quote] 动态申请二维数组，长度可以在运行时确定

C语言变量名不接受参数形式，也就是说，你要声明一个变量，就要在编程的时候写出来，而不能用程序自动生成变量名， 所以楼主说的这种动态定义变量，要求每个变量名都不一样，我觉得不可能办得到。 我的做法是声明一个存放指针的数组，比如： char *s[100]; 每次需要用到一个字符数组时，动态申请空间， s[i]=malloc(n*sizeof(char)); 相当于把这个字符数组的首地址放到s中去了， 这样一来，其实s[i]和你要求的不同名变量是等效的。

vector<vector<int> > vecs; for( ..... ) {     vector<int> tmp;    tmp.push_back(1);   ....    vecs.push_back(tmp); }

引用 3 楼 paschen 的回复:[quote=引用 2 楼 NonArrendertiMai的回复:][quote=引用 1 楼 paschen 的回复:] 1、每次循环数组大小不同可以每次循环中动态创建数组(malloc)  2、循环次数未知可以在循环中进行判断，在满足条件时再break跳出循环 额，每次的数组长度是一样的，长度已知，但是数组名每次要不一样，比如a1,a2,a3,an，这该如何实现呢[/quote] 循环不会根据变量名字去区分，如果数组长度一样，建议定义成二维数组  循环时分别对应 a[0][N]  a[1][N].......[/quote]  但是循环变量不能用来定义数组呐，长度需要常量啊。。。。

引用 2 楼 NonArrendertiMai的回复:[quote=引用 1 楼 paschen 的回复:] 1、每次循环数组大小不同可以每次循环中动态创建数组(malloc)  2、循环次数未知可以在循环中进行判断，在满足条件时再break跳出循环 额，每次的数组长度是一样的，长度已知，但是数组名每次要不一样，比如a1,a2,a3,an，这该如何实现呢[/quote] 循环不会根据变量名字去区分，如果数组长度一样，建议定义成二维数组  循环时分别对应 a[0][N]  a[1][N].......

引用 1 楼 paschen 的回复:1、每次循环数组大小不同可以每次循环中动态创建数组(malloc)  2、循环次数未知可以在循环中进行判断，在满足条件时再break跳出循环 额，每次的数组长度是一样的，长度已知，但是数组名每次要不一样，比如a1,a2,a3,an，这该如何实现呢


Question: 运行c语言程序时，单补调试出现unhandle exception in exe，程序出现不明原因的错误。

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

#include<stdio.h> #include<stdlib.h>  void ReadByte(FILE *fp, unsigned char *data, int len); void AllocateByte(unsigned char **ptr, int len); void ExtractPhase(void *in_data,int xsize, int ysize);  //void main() int main() {     int   xsize=512,ysize=512;     unsigned  int            len=xsize*ysize;     FILE           *fp;     void           *in_data=NULL;     //if(fp = fopen("D:\\UserData\\ifsar.512x512.phase","r")==NULL)     if((fp = fopen("D:\\UserData\\ifsar.512x512.phase","r"))==NULL)     {         printf("未找到文件");         exit(1);     }     AllocateByte((unsigned char **)(&in_data), len);     ReadByte(fp, (unsigned char *)in_data, len);     ExtractPhase( in_data,  xsize, ysize);     free(in_data);     //fclose(fp);    /*重复关闭*/ } void AllocateByte(unsigned char **ptr, int len) {     int i;     *ptr = (unsigned char *)  malloc (len*sizeof(unsigned char));     if ((*ptr)==NULL)     {         //printf("打开文件错误");         printf("申请空间错误");         exit(1);     }     else         printf("ok");     for (i=0; i<len; i++)         ptr[i] = 0; } void ReadByte(FILE *fp, unsigned char *data, int len) {     int i;     if (len!= fread(data, sizeof(unsigned char), len, fp))         printf("shibai");     else         printf("读取文件zhenfque");     fclose(fp); } void ExtractPhase(void *in_data,int xsize, int ysize) {     unsigned char  *quantized_phase = in_data;     //float  phase[10000000];     //float  phase[10000000];   /*局部变量申请的空间太大，可能会导致栈溢出*/     float scale;     int j;     scale = 1.0/256.0;     for (j=0; j<xsize*ysize; j++)     {         phase[j] = quantized_phase[j]*scale;     }  }  问题挺多，建议对比查看一下。


Question: 新手小白求助，帮分析下哪里有问题

一次性得到1--N之间的所有质数 可以用埃氏筛法   复杂度O(sqrt(N)loglogN) 代码: # include <stdio.h> # include <math.h> # define N 10000 char A[N]; int main() {     int i,j,Q;     for(A[0]=A[1]=1,Q=sqrt(N)+1,i=2;i<Q;i++) 		if(!A[i])for(j=i*i;j<N;j+=i) 			A[j]=1;//经过筛法后 如果i是质数则S[i]=0 否则为1 		printf("[2,%d)的质数:\n",N);     for(i=0;i<N;i++)     if(!A[i])printf("%d ",i);     return 0; }  希望能帮到你

哦，我是个智障，我绝对是个瓜皮，谢谢各位，已经解决了，判断没写双等号

问题是出在循环内，大部分都可以求出来，不知道为什么有一些不行

大部分奇数都可以，还有一些就不行了，像99和11199就不行了，不知道为什么


理解和讨论之前请先学会如何观察！  http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组  //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]

引用 11 楼 lizh1009的回复:[quote=引用 9 楼 paschen 的回复:] a+b本身是右值，不管b是多少（包括是0），再取&相当于是对一个中间临时变量取地址 不好意思，10楼的回复说错了。 1.(*(a+1)+0)的值是一个内存中存在的地址，请问能详细解释下为何(*(a+1)+0)是右值而*(a+1)是左值吗？还是不太理解。还是说只需要死记硬背*运算符得到的结果就是左值？ 2.c语言是不是规定&运算符的对象必须是左值？这个知识点书上没说，我用man命令也找不到，请问linux系统能不能像查询函数那样用man手册查询到一些运算符的说明？ 谢谢。 [/quote] http://zh.cppreference.com/w/c/language/operator_member_access http://zh.cppreference.com/w/c/language/value_category

引用 9 楼 paschen 的回复:a+b本身是右值，不管b是多少（包括是0），再取&相当于是对一个中间临时变量取地址 不好意思，10楼的回复说错了。 1.(*(a+1)+0)的值是一个内存中存在的地址，请问能详细解释下为何(*(a+1)+0)是右值而*(a+1)是左值吗？还是不太理解。还是说只需要死记硬背*运算符得到的结果就是左值？ 2.c语言是不是规定&运算符的对象必须是左值？这个知识点书上没说，我用man命令也找不到，请问linux系统能不能像查询函数那样用man手册查询到一些运算符的说明？ 谢谢。

引用 9 楼 paschen 的回复:a+b本身是右值，不管b是多少（包括是0），再取&相当于是对一个中间临时变量取地址 1.(*(a+1)+0)的值是一个内存中存在的地址，请问能详细解释下为何(*(a+1)+0)是左值而*(a+1)是右值吗？还是不太理解。还是说只需要死记硬背*运算符得到的结果就是左值？ 2.c语言是不是规定&运算符的对象必须是左值？这个知识点书上没说，我用man命令也找不到，请问linux系统能不能像查询函数那样用man手册查询到一些运算符的说明？ 谢谢。

解引用表达式*p得到的是左值，&(*p)一定是正确的，因为*p得到的是p指向的实体

引用 5 楼 paschen 的回复:[quote=引用 4 楼 lizh1009的回复:][quote=引用 2 楼 paschen 的回复:] 别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的 但是*(a+1)也是右值啊，为什么能对*(a+1)取址？[/quote] 别把&和*搞混了，前者才是取址，后者是解引[/quote] 还是不太明白，(*(a + 1) + 0)是右值，*(a+1)为什么不是右值？

引用 4 楼 lizh1009的回复:[quote=引用 2 楼 paschen 的回复:] 别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的 但是*(a+1)也是右值啊，为什么能对*(a+1)取址？[/quote] 不好意思，理解错你意思了，*(a+1)是左值，不是右值

引用 4 楼 lizh1009的回复:[quote=引用 2 楼 paschen 的回复:] 别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的 但是*(a+1)也是右值啊，为什么能对*(a+1)取址？[/quote] 别把&和*搞混了，前者才是取址，后者是解引

引用 2 楼 paschen 的回复:别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的 但是*(a+1)也是右值啊，为什么能对*(a+1)取址？

引用 1 楼 user-3的回复:#include<stdio.h> int main() {     int a[2][3];     printf("%p\n",(*(a+1)+0));     printf("%p\n",(*(a+1))); //  printf("a=%p\n",a); //  printf("&a+1=%p\n",&a+1); //  printf("a=%p\n",a+1); //  printf("&(a[1]=%p\n",&a[1]);      return 0; }  %p可以认为是默认带了& 所以 不用加& %p输出的是指针指向的地址，并不是指针变量自身的地址，加&得到的是自身的地址，不可混为一谈


Question: C语言对指针常量中的字符进行冒泡排序

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

引用 7 楼 wanggui2015 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！   赵老师的回答总是另辟蹊径呀。。[/quote]

字符串常量是不能修改的，只能读。冒泡排序就会涉及到交换两个字符，交换字符就会涉及到内存的写操作。所以若冒泡就可能出现段错误。

引用 6 楼 zhao4zhong1 的回复:#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！   赵老师的回答总是另辟蹊径呀。。

{*temp=*(p+j);*(p+j)=*(p+j+1);*(p+j+1)=*temp;} /*冒泡交换*/  ↑改用这个试一下吧   下面是完整的代码 #include <stdio.h>  int main()  {  int n,i,j,*temp,*p,num;  printf( "input sum of the numbers\n ");  scanf( "%d ",&n);  num=n;  printf( "input numbers n <%d ",num);  printf( "\n ");  for (i=0;i <n;i++) scanf( "%d ",p+i);  getchar();  for (i=0;i <n;i++)  for (j=0;j <n-i;j++)  if (*(p+j+1) <*(p+j))  {*temp=*(p+j);*(p+j)=*(p+j+1);*(p+j+1)=*temp;} /*冒泡交换*/  printf( "the sort:\n ");  for (i=0;i <n;i++) printf( " %d ",*(p+i));  printf( "\n ");  getchar(); return 0; }

改掉还是用数组吧， char str[]="sgfdsagreqw" char *p = &str;

常量改动会core dump的

字符串常量不能更改吧


Question: 输出结果9这类平方数都是素数

问题： 1.使用到平方根的函数时要用包含math.h的头文件。 2.flag定义时没有赋初值，会导致错误。 3.判断n能否被2到根号n的数整除时，break语句应该放在if的复合语句中，否则执行一次循环便跳出了循环。 正确的代码如下：

另外 有个一次性求出1--N之间所有的数的埃氏筛法 复杂度O(sqrt(N)*log(logN)) 代码: # include <stdio.h>   # include <math.h>   # define N 10000   char A[N];    int main()   {       int i,j,Q;       for(A[0]=A[1]=1,Q=sqrt(N)+1,i=2;i<Q;i++) 		if(!A[i])for(j=i*i;j<N;j+=i) 			A[j]=1;//经过筛法后 如果i是质数则S[i]=0 否则为1   		printf("[2,%d)的质数:\n",N);     for(i=0;i<N;i++)       if(!A[i])printf("%d ",i);       return 0;   }

#include"stdio.h" # include <math.h> int main() {     int i,n,flag,j;     //printf("please enter a number:\n");    // scanf("%d",&n);     for(j=100,n=2;n<j;n++)     {     for(i=2,flag=0; i<=sqrt(n); i++)     {         if(n%i==0)         {             flag=1;           break;         }     }    if(flag)         printf("%d不是素数\n",n);     else         printf("%d是素数\n",n);     }     return 0; }

flag 应初始化为 0


Question: 关于char如何设置最大值

建议将问题描述的更清晰一些，你是想设定char数组的长度还是char类型数据的长度？ 如果要设定char类型数组的长度，可以考虑使用malloc/realloc，根据需要动态改变数组的大小。 如果是要设定char类型数据的长度，可以直接用char类型的返回来约束。

/STACK   (Stack Allocations) Home |  Overview |  How Do I |  Linker Options  The Stack Allocations (/STACK:reserve[,commit]) option sets the size of the stack in bytes.   To find this option in the development environment, click Settings on the Project menu. Then click the Link tab, and click Output in the Category box. The Reserve text box (or in the reserve argument on the command line) specifies the total stack allocation in virtual memory. The default stack size is 1 MB. The linker rounds up the specified value to the nearest 4 bytes.  The optional value specified in the Commit text box (or in the commit argument on the command line) is subject to interpretation by the operating system. In Windows NT, it specifies the amount of physical memory to allocate at a time. Committed virtual memory causes space to be reserved in the paging file. A higher commit value saves time when the application needs more stack space, but increases the memory requirements and possibly the startup time.  Specify the reserve and commit values in decimal or C-language notation.  Another way to set the size of the stack is with the STACKSIZE statement in a module-definition (.DEF) file. STACKSIZE overrides the Stack Allocations (/STACK) option if both are specified. You can change the stack after the .EXE file is built by using the EDITBIN tool.

不知道这样的目的意欲何为

# include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题 # include <conio.h> # define N 10  //如果要录入X个字节则 N=X int user_password(char *A,int min,int max,int F);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度 int main() {     char A[N+1],B[2*N+1];     printf("用户名:");     user_password(A,2,N,0);     printf("密  码:");     user_password(B,6,2*N,1);     printf("用户名:");     puts(A);     printf("密  码:");     puts(B);     return 0; } int user_password(char *A,int min,int max,int F)//F=0录入密码 否则 录入 用户名 {     int B,C,D;     char S[][7]={"用户名","密码"};     do     {         B=max+printf("[");for(C=1; C<B; C++)printf(" ");printf("]");         while(B--)printf("\b");         B=0;         while((C=getch())!='\r')         if(C>='0'&&C<='9'||C>='a'&&C<='z'||C>='A'&&C<='Z'||C=='_'||C==8)             {             if(C!=8&&B<max)             {                 if(F)printf("*");//密码                 else printf("%c",C);//用户名                 A[B++]=C;             }             else if(C==8&&B>0)             {                 printf("\b \b");                 B--;             }             else if(B>=max)             {                 D=printf("]%s长度:[%d,%d]!",S[F],min,max);                 for(C=0; C<60000000; C++);                 while(D-->1)printf("\b \b");                 printf("\b");             }         }         A[B]=0;         if(B<min)         {             for(C=B; C<max; C++)printf(" ");             D=max+printf("]%s长度:[%d,%d]!",S[F],min,max);             for(C=0; C<60000000; C++);             while(D--)printf("\b \b");             printf("\b");         }     }while(B<min);     printf("\n");     return B; }  这一个你也试试看，写的有些粗糙。。。

。。。这样不是很浪费内存吗？ 设置为最大的目的 是防止 用户输入字符串输入的过多吗？ 如果是这样，你看看这个gainchar函数能不能帮到你，你想让用户输入多少字符 用户就输入多少字符。 这个输入字符串的代码可以防止用户输入过多的字符导致数组超界：  # include <stdio.h> # include <time.h> # include <stdlib.h> # define N 10  //如果要录入X个字节则 N=X int gainchar(char A[],int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度 int main(){     char A[N+1];//最后一位存'\0'     int L,min,max;     srand(time(NULL));     do{     min=rand()%N;     max=min+rand()%(N-min);     printf("请输入字符串[%d,%d]:",min,max);     gainchar(A,min,max);     printf("字符串：%s\n",A);     }while(1);     return 0; } int gainchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度 {     int B,C;  do{         A[max]=B=C=0;         while((A[B++]=getchar())!='\n'&&B<max);         if(A[B-1]!='\n')while(getchar()!='\n'&&++C);         else A[--B]=0;     if(C||B&&B<min)        printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);     }while(C||B<min);     return B; }  上面用了随机数 是做测试用的 。

忘了这里是C语言。那你就只好用malloc和free了。

你这样定义必须设置固定的值。要想不固定，换用new char[变量]或者vector<char>


Question: [C语言]新手跪求帮忙分析代码

引用 10 楼 cheese143 的回复:[quote=引用 8 楼 wanggui2015 的回复:] 啊，不好意思，忘了你是C哈。  stack *m = (stack*)malloc(sizeof(stack));  这样。 谢谢！我想问一下为什么要这样分配空间呢？ 为什么不能直接stack *m[/quote] 因为stack* m;只是一个stack结构体的指针，没有实际的对象实例，上面那句话就是给stack分配对象空间。还有你malloc的内存最后不用了要free掉额。 你也可以stack m;直接定义对象实例，然后initstack(&m);传对象的地址进去初始化，这样也可以的。

引用 8 楼 wanggui2015 的回复:啊，不好意思，忘了你是C哈。  stack *m = (stack*)malloc(sizeof(stack));  这样。 谢谢！我想问一下为什么要这样分配空间呢？ 为什么不能直接stack *m

引用 4 楼 cheese143的回复:[quote=引用 1 楼 user-2 的回复:] initstack函数参数是按值传递的，也就是你函数形参只是实参的一个复制品，你在函数中赋值malloc得到的值不会影响到主函数中的m，主函数中的m仍然是没有初始的 不太懂，传入的参数不是指针形式的吗，为什么没有改变呢 如果initstack函数有问题那是不是push函数也不对呀 pop函数我发现问题在哪里了  还有就是改变这三个之后，仍旧没办法输出  不好意思我真滴很菜[/quote] 函数参数类型要改，如果你要修改指针，你需要传入指针的指针  因为指针本身是复制的，虽然他们都指向同一块内存，你如果改指针指向的内存，那没问题，如果改指针本身，那你的改动只针对复制品的指针  pop函数第二个参数也要换成指针的形式  你自己再体会一下，改了如果还是不行，把你改的代码发出来

引用 6 楼 wanggui2015 的回复:[quote=引用 5 楼 cheese143 的回复:] [quote=引用 3 楼 wanggui2015 的回复:] 28行： void pop(stack *l,char* e){          改成传指针，char* e 32行： *e=l->base[l->top]; 37行：stack *m=new stack;   要分配空间 52行： pop(m,&ch); 传指针 37行分配空间不是已经在下面39行的initstack函数中做了吗 pop函数错误感谢指正[/quote] 你的initstack函数里面只是给结构体里面的base分配空间，你没有给你的整个结构体分配空间啊。[/quote]  C里面貌似不可以这样做呀，我试了一下提示出错。

引用 5 楼 cheese143 的回复:[quote=引用 3 楼 wanggui2015 的回复:] 28行： void pop(stack *l,char* e){          改成传指针，char* e 32行： *e=l->base[l->top]; 37行：stack *m=new stack;   要分配空间 52行： pop(m,&ch); 传指针 37行分配空间不是已经在下面39行的initstack函数中做了吗 pop函数错误感谢指正[/quote] 你的initstack函数里面只是给结构体里面的base分配空间，你没有给你的整个结构体分配空间啊。

引用 3 楼 wanggui2015 的回复:28行： void pop(stack *l,char* e){          改成传指针，char* e 32行： *e=l->base[l->top]; 37行：stack *m=new stack;   要分配空间 52行： pop(m,&ch); 传指针 37行分配空间不是已经在下面39行的initstack函数中做了吗 pop函数错误感谢指正

引用 1 楼 user-2 的回复:initstack函数参数是按值传递的，也就是你函数形参只是实参的一个复制品，你在函数中赋值malloc得到的值不会影响到主函数中的m，主函数中的m仍然是没有初始的 不太懂，传入的参数不是指针形式的吗，为什么没有改变呢 如果initstack函数有问题那是不是push函数也不对呀 pop函数我发现问题在哪里了  还有就是改变这三个之后，仍旧没办法输出  不好意思我真滴很菜

同理，pop的第二个参数也是这样


Question: 大神求解！写的这个输入整数逆向输出程序，能实现10位以内的数字逆序输出，但是输出10位以上数字输出结果就乱八七糟，谁能解释下原因啊？？

输入的数值已经超出了int类型的表示范围。建议查一下int，unsigned int， unsigned long long类型数据表示的数值范围。

在现实世界中，除时间和空间可能是无限的以外，其它任何事物都是有限的。  不然你逆向一个16TB长的整数试试？！

int和long范围是一样的，换成long long

各种类型的变量放到内存里面都是二进制，int类型一般为16位或32位，由编译器决定，通常都为32位，而int类型是默认带符号的，就是可以表示负数，所以最高位的二进制位是符号位，所以32位的有符号int型所能表示的范围就是 -2^31 ~ 2^31-1，即 -2147483648 ~ +2147483647 。 long类型也是32位，表示范围跟int一样。 long long类型是64位，可表示范围就是 -2^63 ~ 2^63-1，即 -9223372036854775808 ~ +9223372036854775807。

引用 4 楼 ZhnagJ1an的回复:引用 3 楼 zhagoodwell 的回复:换成long long 的话也只是范围大了点，大约18--19位的样子，如果真要逆输出～用字符串呗～那原因到底是什么呢？不是范围的原因？楼上那个大哥说超过整形所能表示的大小，我不怎么明白。我初学，目的也不是想实现逆输出，就是想弄清楚其中的原因。 拿10进制为例 一个64位的10进制数最多能表示的数的位数就是64位10进制数 在计算机里每个二进制位不是0就是1 而一个字节有8位，一个int占4个字节所以共32位 因此unsigned int最多就能表示32位的2进制数～如果化为我们平时熟悉的10进制数，位数将会更少。 而long long是8个字节，共64位二进制数，只是表示的数的范围大了点

引用 5 楼 zhagoodwell的回复:引用 4 楼 ZhnagJ1an的回复:[quote=引用 3 楼 zhagoodwell 的回复:] 换成long long 的话也只是范围大了点，大约18--19位的样子，如果真要逆输出～用字符串呗～那原因到底是什么呢？不是范围的原因？楼上那个大哥说超过整形所能表示的大小，我不怎么明白。我初学，目的也不是想实现逆输出，就是想弄清楚其中的原因。 拿10进制为例 一个64位的10进制数最多能表示的数的位数就是64位10进制数 在计算机里每个二进制位不是0就是1 而一个字节有8位，一个int占4个字节所以共32位 因此unsigned int最多就能表示32位的2进制数～如果化为我们平时熟悉的10进制数，位数将会更少。 而long long是8个字节，共64位二进制数，只是表示的数的范围大了点[/quote] 多谢！

超过整形所能表示大小了

引用 1 楼 真相重于对错的回复:超过整形所能表示大小了 能具体点吗？整型的所能表示的不能超过10位吗？我换成long int也不行呀？


Question: 求助，看看我这道C语言题目哪儿错了

其实你只是scanf后面少了一个&，下次记得要细心点，希望对你有帮助

scanf("%d",a[i]);，使用scanf()函数时，缺少取地址运算符&，&是地址运算符，分别获得这变量的内存地址。 正确代码应该是#include<stdio.h> void sort(int a[],int n) { int i,j, t; for(j=0;j<n-1;j++) { for(i=0;i<n-j-1;i++) { if(a[i]>a[i+1]) { t=a[i]; a[i]=a[i+1]; a[i+1]=t; } } } } void main() { int i; int s[8]; for(i=0;i<8;i++){ scanf("%d",&s[i]); } sort(s,8); printf("The sort is:\n"); for(i=0;i<8;i++) printf("%d\n",s[i]); }  希望对您有帮助，麻烦给个赞

1楼正解 &a[i]

正如1楼所说，scanf的第二个参数必须是地址，a[i]并不是地址，&a[i]才是地址。 请参考《scanf()、gets()和getline()读取输入》https://blog.csdn.net/hou09tian/article/details/70045040 希望能够帮到你

引用 1 楼 自信男孩的回复:for(i=0;i<=9;i++) scanf("%d", &a[i]); scanf中缺少& 或者这样写也可以 for(i=0;i<=9;i++) scanf("%d",a + i); 总之，第二个参数是地址，而非数值。 大叔可以留个联系方式吗？


Question: 动态内存冒泡排序问题。

引用 6 楼 cfjtaishan 的回复:排序逻辑还有点问题，比如你是想从小到大排序，那么你输入时，可以考虑一种最坏的情况即输入的数是从大到小依次输入。这样看一下你的排序逻辑是否可行。 以下是冒泡排序逻辑供参考。虽然是动态申请的空间，你可以完全可以看成数组。 for (i = 0; i < n; i++)     {         for (j = 0; j < n - i - 1; j++)         {             if (*(p + j) > *(p + j + 1))//p[j] p[j+1]             {                 m = *(p + j);                 *(p + j) = *(p + j + 1);                 *(p + j + 1) = m;             }         }     } for (i = 0; i < n; i++)     {         for (j = 0; j < n - i - 1; j++)         {             if (p[j] > p[j+1])//p[j] p[j+1]             {                 m = p[j];                 p[j] = p[j+1];                 p[j+1] = m;             }         }     } 参考一下

引用 4 楼 qq_30519247 的回复:[quote=引用 1 楼 jianwen0529 的回复:] 可以，但是麻烦了一些，需要解决以下问题： 1：判断输入数据结束，比如用一个数作为结束标志或者一行（即读取一行字符串）或发生流错误等方法 2：动态数组不是很适用，因为个数未知，那么就不知道应该分配多大的内存（虽然有办法解决）。更好的方法是用链表实现 晓得了，感觉能解决也很麻烦。。[/quote] 这个也不是很麻烦，判断scanf_s的返回值，这是第一步，然后在scanf_s返回正确时，在判断n的值，若输入的n大于你设定的值，可以让用户继续输入。 通过判断scanf_s的返回值，可以判定输入的数是正确的，还是非数字，比如字符串等等

引用 7 楼 cfjtaishan 的回复:[quote=引用 4 楼 qq_30519247 的回复:] [quote=引用 1 楼 jianwen0529 的回复:] 可以，但是麻烦了一些，需要解决以下问题： 1：判断输入数据结束，比如用一个数作为结束标志或者一行（即读取一行字符串）或发生流错误等方法 2：动态数组不是很适用，因为个数未知，那么就不知道应该分配多大的内存（虽然有办法解决）。更好的方法是用链表实现 晓得了，感觉能解决也很麻烦。。[/quote] 这个也不是很麻烦，判断scanf_s的返回值，这是第一步，然后在scanf_s返回正确时，在判断n的值，若输入的n大于你设定的值，可以让用户继续输入。 通过判断scanf_s的返回值，可以判定输入的数是正确的，还是非数字，比如字符串等等[/quote] 还是不怎么懂、、、、、

引用 1 楼 jianwen0529 的回复:可以，但是麻烦了一些，需要解决以下问题： 1：判断输入数据结束，比如用一个数作为结束标志或者一行（即读取一行字符串）或发生流错误等方法 2：动态数组不是很适用，因为个数未知，那么就不知道应该分配多大的内存（虽然有办法解决）。更好的方法是用链表实现 晓得了，感觉能解决也很麻烦。。

引用 2 楼 cfjtaishan 的回复:p = (int *)malloc(n);     if (p == 0)     {         printf("内存分配失败！\n");         exit(1);//失败的时候终止程序     } 这部分有问题呢。 p是int类型指针，malloc后面跟的申请的字节数，根据你的代码逻辑，申请的n应该是n个int类型的数，而不是n个字节。注意n个字节和n个int类型的空间是有差距的，相差（n-1） * sizeof(int)个字节呢 所以，这部分要改一下，如下： p = (int *)malloc(n *sizeof(int));     if (p == (void *)0)   //直接用NULL     {         printf("内存分配失败！\n");         exit(1);//失败的时候终止程序     } 搜嘎 感谢感谢

p = (int *)malloc(n*sizeof(int)); 就行了  表示分配n个int大小的空间


Question: 字符串提取数据并转换

如果是每两个非空格字符当做一个数，那么你用getchar写个函数～当录入连续两个非空格字符就存入下一个字符数组，如果是空格直接跳过

引用 6 楼 HelegeHeHeha的回复:[quote=引用 4 楼 zhagoodwell 的回复:] [quote=引用 2 楼 HelegeHeHeha的回复:][quote=引用 1 楼 zhagoodwell 的回复:] 字符串查找 空格键 得到每个空格的下标 我有个函数： int BF(char a[],char b[],int c[])//a为主串 b为次串 c[]存储匹配的下标 函数返回 匹配的个数    {                              int i=0,j=0,k=0;          do{             if (b[j]&&a[i++]==b[j])++j;             else             {                 b[j]?(i-=j):(c[k++]=i-j);                  j=0;                         }         }while(a[i-1]);           return k;     }     函数调用：BF("AB 57 79 73 "," ",C); 空格和字符之间有对应关系 然后 你需要第几个就找到第几个空格的下标 接下来 替换高低位 并进行进制转换即可 我这组数据是随机的也能用吗[/quote] 只要你是这种 16进制与空格相间的 比如你这个是 01 84 04 00 00 00 9c 27 6D 51 只要调用 BF(" 01 84 04 00 00 00 9c 27 6D 51"," ",C)即可[/quote] 我刚看了一下，我得到的数据是0184040000009c276D51这种字符串，这个怎么提呢，而且数据是随机的，[/quote] 你把 0184040000009c276D51 解释成一个数还是多个数？

引用 3 楼 cfjtaishan 的回复:应该是第7字节吧，不是第7位。位和字节不是一个概念。 如果确定将第7个字节和第8个字节取出来，然后组成一个新的数据。 可以考虑  unsigned int num = buf[7]; num = (num << 8) + buf[6]; 在内存中只有2进制表示，没有十进制，十六进制之分。 如果以%d输出是十进制形式，如果是以%x或%X输出是16进制形式。 buf[6]和buf[7]是被认为是字符串呀，能直接计算然后输出吗

引用 7 楼 HelegeHeHeha 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] 应该是第7字节吧，不是第7位。位和字节不是一个概念。 如果确定将第7个字节和第8个字节取出来，然后组成一个新的数据。 可以考虑  unsigned int num = buf[7]; num = (num << 8) + buf[6]; 在内存中只有2进制表示，没有十进制，十六进制之分。 如果以%d输出是十进制形式，如果是以%x或%X输出是16进制形式。 buf[6]和buf[7]是被认为是字符串呀，能直接计算然后输出吗 [/quote] 这有什么不可? 字符串中的每个字符也是有自己数值的，不论是啥，在内存里只有一种表示：2进制形式。 既然都是数，为啥不可以计算呢？

引用 2 楼 HelegeHeHeha的回复:[quote=引用 1 楼 zhagoodwell 的回复:] 字符串查找 空格键 得到每个空格的下标 我有个函数： int BF(char a[],char b[],int c[])//a为主串 b为次串 c[]存储匹配的下标 函数返回 匹配的个数    {                              int i=0,j=0,k=0;          do{             if (b[j]&&a[i++]==b[j])++j;             else             {                 b[j]?(i-=j):(c[k++]=i-j);                  j=0;                         }         }while(a[i-1]);           return k;     }     函数调用：BF("AB 57 79 73 "," ",C); 空格和字符之间有对应关系 然后 你需要第几个就找到第几个空格的下标 接下来 替换高低位 并进行进制转换即可 我这组数据是随机的也能用吗[/quote] 只要你是这种 16进制与空格相间的 比如你这个是 01 84 04 00 00 00 9c 27 6D 51 只要调用 BF(" 01 84 04 00 00 00 9c 27 6D 51"," ",C)即可

引用 4 楼 zhagoodwell 的回复:[quote=引用 2 楼 HelegeHeHeha的回复:][quote=引用 1 楼 zhagoodwell 的回复:] 字符串查找 空格键 得到每个空格的下标 我有个函数： int BF(char a[],char b[],int c[])//a为主串 b为次串 c[]存储匹配的下标 函数返回 匹配的个数    {                              int i=0,j=0,k=0;          do{             if (b[j]&&a[i++]==b[j])++j;             else             {                 b[j]?(i-=j):(c[k++]=i-j);                  j=0;                         }         }while(a[i-1]);           return k;     }     函数调用：BF("AB 57 79 73 "," ",C); 空格和字符之间有对应关系 然后 你需要第几个就找到第几个空格的下标 接下来 替换高低位 并进行进制转换即可 我这组数据是随机的也能用吗[/quote] 只要你是这种 16进制与空格相间的 比如你这个是 01 84 04 00 00 00 9c 27 6D 51 只要调用 BF(" 01 84 04 00 00 00 9c 27 6D 51"," ",C)即可[/quote] 我刚看了一下，我得到的数据是0184040000009c276D51这种字符串，这个怎么提呢，而且数据是随机的，

也可以用sscnf函数 然后是%x格式 sscanf具体用法可以去网上找

引用 1 楼 zhagoodwell 的回复:字符串查找 空格键 得到每个空格的下标 我有个函数： int BF(char a[],char b[],int c[])//a为主串 b为次串 c[]存储匹配的下标 函数返回 匹配的个数    {                              int i=0,j=0,k=0;          do{             if (b[j]&&a[i++]==b[j])++j;             else             {                 b[j]?(i-=j):(c[k++]=i-j);                  j=0;                         }         }while(a[i-1]);           return k;     }     函数调用：BF("AB 57 79 73 "," ",C); 空格和字符之间有对应关系 然后 你需要第几个就找到第几个空格的下标 接下来 替换高低位 并进行进制转换即可 我这组数据是随机的也能用吗


Question: 提问C prime plus 第6版第3章问题

输入的夸克数的值的执行在总共水分子的表达示之后，输入的值无法代入表达式中进行计算。 把计算总共水分子表达式写在输入语句的下面。

# include <stdio.h>  int main(void) {     long double m_H2O = 3.156E-23;                  //给出每克水的分子数     float number_H2O_quart;                               //声明所要输入的夸脱数     long double number_H2O_total;                     //声明总共水的分子数     number_H2O_total = 950*number_H2O_quart/m_H2O;                      //总共水的分子数的表达式     //printf("%f\n",950/m_H2O);     printf("There are %Le H2O molecule in 2 quart water\n",950*2.0/m_H2O);                       //若共有2夸脱水，则所拥有的水分子数     printf("Please enter quart of water: ");     scanf("%f",&number_H2O_quart);                    //提示用户输入水的夸脱数（2夸脱)     //printf("%le",number_H2O_total);     number_H2O_total = 950 * number_H2O_quart / m_H2O;     printf("\nThe number of total H2O molecule  is %Le",number_H2O_total/*950*number_H2O_quart/m_H2O*/);     return 0; } 参考一下吧  在输出总的水分子数之前，并没有计算即缺少这句： number_H2O_total = 950 * number_H2O_quart / m_H2O;

float number_H2O_quart;                               //声明所要输入的夸脱数 long double number_H2O_total;                     //声明总共水的分子数 number_H2O_total = 950*number_H2O_quart/m_H2O;                      //总共水的分子数的表达式  1：没初始化，2：又没赋值。谁知道计算出来是什么数


function退出后 temp_name 被破坏，指向他的 names[stu_name]指针也无意义了

内容已经被覆盖了

你的temp_name 每次都来新的。。。那个 names[stu_name]=temp_name  只是指向了 temp_name 并没有存上 你下一次再选择1 temp_name的内容就被覆盖掉了 。。。。 直接定义 names[][]为二维字符数组 ，录入的时候 也不用 temp_name 了 直接 scanf("%s",names[stu_name]); 另外 代码 可以直接贴上  如果是图片  也不好看出问题。。。 ，如果用一维字符指针数组

char * names[100] 改为 char names[100][32] 试试看


Question: usb通信接口报错

引用 1 楼 user-1 的回复:1784 的解释是：The supplied user buffer is not valid for the requested operation.  https://msdn.microsoft.com/en-us/library/ms681386(v=vs.85).aspx  The size of the DeviceInterfaceDetailData buffer. The buffer must be at least (offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA, DevicePath) + sizeof(TCHAR)) bytes, to contain the fixed part of the structure and a single NULL to terminate an empty MULTI_SZ string.  https://msdn.microsoft.com/zh-cn/ff551120  devDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(length); memset(devDetail, 0, length); devDetail->cbSize = sizeof(PSP_DEVICE_INTERFACE_DETAIL_DATA); 已经设置大小了


Question: 报错..不知道是什么原因

检查q_strGameBack[g_arrSnake[i][0]][g_arrSnake[i][1]]的类型，类型应该是char，建议用&q_strGameBack[g_arrSnake[i][0]][g_arrSnake[i][1]]； 或者其他方式，保证strncpy的第一个参数是char *类型。

1：strncpy类型需要char* 2：关闭安全开发生命周期 参考：https://blog.csdn.net/duke56/article/details/52403458

引用 1 楼 phenix2009 的回复:改成这样：  void DrawSnake() { 	int i = 0; 	for (i = 0; g_arrSnake[i][0] != 0; i++) 	{ 		strncpy(q_strGameBack[g_arrSnake[i][0]], "*", 2); 	} }  这样写画不出来东西。。。。


Question: 咨询libmodbus相关问题

学会使用find、whereis命令。

我之前linux开发时候，头文件什么的都放一块儿的，库放在lib目录下，是linux工程师设置好的位置，没出过问题。

头文件和.c文件放一个目录试试


Question: 求大佬看看为什么结果是wrong answer

引用 1 楼 user-1的回复:leap=(year%4==0&&year%100!=0||year%4==0); 这边的逻辑判断并不是很清晰， 不妨改成leap=(year%400==0||(year%100!=0&&year%4==0)) 谢谢谢谢大神


Question: 关于goto

可以用，但不要滥用

可以往下跳,统一函数出口,集中释放资源,goto还是有替代不了的地方 避免往上跳,往上跳就是循环,即使没写错也不容易阅读

引用 24 楼 lin5161678 的回复:[quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 11 楼 lin5161678 的回复:] [quote=引用 9 楼 cfjtaishan 的回复:] 用在循环里的goto是不可取，代码可读性会大大降低。建议系统开发尽量不要用 那么 怎么处理从多层循环里面跳出来? 举个例子 不多就三层循环 你怎么处理从最内层跳到最外面[/quote] break，return或者通过其他方式，比如修改逻辑。 如果你的逻辑不能跳出循环，而只能通过goto语句，那么你可以重新梳理一下你的逻辑了。[/quote] break 只能跳出最内层循环 不满足 return 会结束函数 如果我循环后面还有需要执行的代码怎么办? 或者其他方式是什么?  PS 我没说只能通过goto 我说的是 通过goto会很方便 可读性也比其他奇淫技巧优秀[/quote] 没说不能用，而是尽量少用。

引用 12 楼 cfjtaishan 的回复:[quote=引用 11 楼 lin5161678 的回复:] [quote=引用 9 楼 cfjtaishan 的回复:] 用在循环里的goto是不可取，代码可读性会大大降低。建议系统开发尽量不要用 那么 怎么处理从多层循环里面跳出来? 举个例子 不多就三层循环 你怎么处理从最内层跳到最外面[/quote] break，return或者通过其他方式，比如修改逻辑。 如果你的逻辑不能跳出循环，而只能通过goto语句，那么你可以重新梳理一下你的逻辑了。[/quote] break 只能跳出最内层循环 不满足 return 会结束函数 如果我循环后面还有需要执行的代码怎么办? 或者其他方式是什么?  PS 我没说只能通过goto 我说的是 通过goto会很方便 可读性也比其他奇淫技巧优秀

慎用goto，恰到好处！

goto慎用，用不好这代码只有上帝看得懂。

双刃剑嘛，用的合理就不用担心，比如很多层嵌套循环，要跳出最外层，没有比goto可读性更好的写法

现实生活中，很多特权人物经常goto

只能说这东西新手很难用好，一旦开放使用权限，代码往往会写成可读性极低的东西，所以一般不推荐新人使用。

你説的對，雖然我不愛用，但其實能妙用就可以了。

引用 1 楼 wang0635 的回复:有些时候用goto反而可读性更强，比如从很深的嵌套循环中退到外层。人们反对的只是滥用 你说得对，但goto不只是用于循环

goto确实很好用，目前项目中很多错误以后得处理都是goto。但是还是尽量少用吧。

引用 18 楼 zhao4zhong1 的回复:#16楼代码实现了“跳出三界外，不在五行中。” 我也不是什么IT上的特权人物，我只是个初中生。。。。。。。

#16楼代码实现了“跳出三界外，不在五行中。”

引用 15 楼 phenix2009 的回复:[quote=引用 14 楼 zyx6680599 的回复:] [quote=引用 10 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 DelphiGuy 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 现实生活中，很多特权人物经常goto  所以他们经常教育民众goto是有害的...  [/quote] [/quote] 用goto代替调用一些自定义函数也增加代码速度[/quote] 他们是在内涵啦，走捷径什么的[/quote] 可见走捷径是富二代、官二代和各种特权阶层、特权人物、……当然也包括你我这种人的再正常不过的实际需求。

仅供参考：#include <stdio.h> #include <setjmp.h> jmp_buf mark; int i=0; void c() {     printf( "c in\n");     if (1==i%2) longjmp( mark, i );     printf( "c out\n"); } void b() {     printf( "b in\n");     c();     printf( "b out\n"); } void a() {     printf( "a in\n");     b();     printf( "a out\n"); } void main( void ) {    int jmpret;    jmpret = setjmp( mark );    printf( "Start %d\n",jmpret);    if( jmpret == 0 ) {        printf( "First\n");        a();        i++;        a();    } else {        printf( "Second\n");    } } //Start 0 //First //a in //b in //c in //c out //b out //a out //a in //b in //c in //Start 1 //Second //  #include <iostream> using namespace std; struct MyStruct {     int Nodedata;     MyStruct *pLeft;     MyStruct *pRight; } s1,s2,s3,s4,s5,s6,s7,s8; void ashow(MyStruct * p) {     if (p != nullptr) {         ashow(p->pLeft);         ashow(p->pRight);         cout << p->Nodedata << endl;         if (p->Nodedata == 4) {             throw 1;//退出递归.直接返回.         }     } } int main() {     MyStruct *pRoot;//根      pRoot = &s1;     s1.Nodedata = 1;     s2.Nodedata = 2;     s3.Nodedata = 3;     s4.Nodedata = 4;     s5.Nodedata = 5;     s6.Nodedata = 6;     s7.Nodedata = 7;     s8.Nodedata = 8;      s1.pLeft = &s2;     s1.pRight = &s3;      s2.pLeft = &s4;     s2.pRight = &s5;      s3.pLeft = &s6;     s3.pRight = &s7;     try {         ashow(pRoot);     } catch (int err) {         cout<<"catch err "<<err<<endl;     }     return 0; } //4 //catch err 1 //

引用 14 楼 zyx6680599 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 DelphiGuy 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 现实生活中，很多特权人物经常goto  所以他们经常教育民众goto是有害的...  [/quote] [/quote] 用goto代替调用一些自定义函数也增加代码速度[/quote] 他们是在内涵啦，走捷径什么的

引用 10 楼 zhao4zhong1 的回复:[quote=引用 7 楼 DelphiGuy 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 现实生活中，很多特权人物经常goto  所以他们经常教育民众goto是有害的...  [/quote] [/quote] 用goto代替调用一些自定义函数也增加代码速度

引用 12 楼 cfjtaishan 的回复:[quote=引用 11 楼 lin5161678 的回复:] [quote=引用 9 楼 cfjtaishan 的回复:] 用在循环里的goto是不可取，代码可读性会大大降低。建议系统开发尽量不要用 那么 怎么处理从多层循环里面跳出来? 举个例子 不多就三层循环 你怎么处理从最内层跳到最外面[/quote] break，return或者通过其他方式，比如修改逻辑。 如果你的逻辑不能跳出循环，而只能通过goto语句，那么你可以重新梳理一下你的逻辑了。[/quote] 用goto代替调用一些自定义函数也增加代码速度


Question: vs2015为什么我打不开我自己建的头文件？

#include "head.h" 一般是<>里存放的是系统头文件或库的头文件。自定义的头文件，建议使用""。 另外，""头文件要使用真确的路径。

你要搞清楚#include <>和#include ""的含义

#include "head.h"  用双引号


Question: 入门之问

cfree吧，操作简单

我开始用的cfree很简单，如果准备长期用简易vs

其实编译软件的话Dev c++会比较简单用，一下就会了。学C语言可以用老九学堂的视频

《彻底解决兼容问题 Windows 7 安装 Visual C++ 6.0 (VC6) 全程图解》 《Windows 7下VC6打开文件报错导致其崩溃的解决办法 》 其实个人觉得VC++6.0还是挺不错的，用起来也方便。而且现在网上的很多代码都是基于VC++6.0的

还是别用 vc 吧很多后来更新的标准都不支持

建议你使用dev c++，这个非常适合新手使用，在这里下载https://pc.qq.com/detail/16/detail_163136.html

C语言快速入门 http://cs.glimix.com

使用VS可以，但是建议文件定义为.c文件，直接创建的是cpp

新手的话强烈推荐用dev c++，VC6.0已经是非常老了，不兼容新版Windows

C语言的话推荐看看这个教程： https://cloud.tencent.com/developer/doc/1023

引用 2 楼 cfjtaishan 的回复:建议使用更高版本的开发环境，比如vs 引用 4 楼 zhao4zhong1 的回复:VC6EN http://pan.baidu.com/s/1jImOtAe Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt 用啊哈C 推荐新手

感觉新手可以用dev c++，不用创建工程，用着也简单，等到熟悉了后可以用vs这些。

还是下载一个vs吧，百度搜一堆，找绿色版本的，不用配置什么乱七八糟的东东，都不用下一步安装，直接使用

推荐看看 cs.glimix.com上的教程

个人觉得菜鸟入门就用devcpp吧，几十个mb，点开就能写代码，新手哪懂什么文件什么配置的，那是以后的事了

http://www.xdowns.com/soft/38/121/2008/Soft_44195.html 下个绿色版就行了，不用安装的

建议使用更高版本的开发环境，比如vs


Question: fgets（）读取字符串数组问题

static char bufs[80] int n; int nn[402]; double fs[402],fe[402]; FILE *rfp; rfp=fopen("d:\\mydir\\mydata.txt","r"); if (rfp) {     for (n=0;n<402;n++) {         if (NULL==fgets(bufs, 80, rfp)) break;         if (3==sscanf(bufs, "%d%lf%lf", &nn[n], &fs[n], &fe[n])) {             printf("%d %d %lg %lg\n",n,nn[n],fs[n],fe[n]);         } else {             break;         }     }     fclose(rfp); } else {     printf("Can not open file [%s]!\n","d:\\mydir\\mydata.txt"); }

static char bufs[402][80] int n,nn; double fs,fe; FILE *rfp; rfp=fopen("d:\\mydir\\mydata.txt","r"); if (rfp) {     for (n=0;n<402;n++) {         if (NULL==fgets(bufs[n], 80, rfp)) break;         if (3==sscanf(bufs[n], "%d%lf%lf", &nn, &fs, &fe)) {             printf("%d %d %lg %lg\n",n,nn,fs,fe);         } else {             break;         }     }     fclose(rfp); } else {     printf("Can not open file [%s]!\n","d:\\mydir\\mydata.txt"); }

char *bufs[256] int n,nn,fs,fe;   for (n=0;n<402;n++){ fgets(bufs[n], 80, rfp); 第一个问题：bufs的长度是256,n的循环是从0~401，这样会有数组越界的问题。 第二个问题：bufs是指针数组，每个指针都是一个野指针，所以要使用之前需要将其指向可以读写的内存位置。可以考虑使用malloc/free方式动态申请内存空间；

fgets表示从文件里面读数据，你的文件打开在哪里？以下是一个fget的调用示例：  FILE * fp = fopen(argv[1],"r"); char buf[200]; while (fgets(buf,200,fp) != NULL) {    /* 每行的字符不能超过199才能正常工作 */       printf("%s",buf); }

fgets的第三个参数是一个FILE*指针


Question: 请问DEV C++可以引用excel表格吗？

引用 9 楼 dlutlh 的回复:问题已经解决，谢谢各位 解决了你到是结贴啊

问题已经解决，谢谢各位

那楼主就把excel另存为csv格式文件，再用记事本打开就知道，它的格式用逗号进行分割。 程序里就直接打开csv文件，处理字符串吧。代码就不献丑了

楼上已经说了。你把自己的Excel文件打开 ，别存为，格式 选 CSV. 其實就是逗號分隔的文本文件 然後用C++讀取CSV文件， 每讀一行getline（），用split()函數 以逗號分隔出CSV一行的數據 每一個分隔出來的數據，添加到你定義的Vector里去。 建議把數組換成Vector

引用 1 楼 donjin9的回复:可以把excel另存为csv文件读取，不然就得使用MSO.dll EXCEL.exe等处理。 您好，非常感谢回复，我是学水利水电的，对这个学的不怎么深，基本上还是小白，您能列举一段程序吗？我对照着看看怎么弄

引用 6 楼 user-4的回复:https://www.codeproject.com/Articles/13852/BasicExcel-A-Class-to-Read-and-Write-to-Microsoft有源码有例子 看懂这个还是很困难啊，我能发给你我的一段代码，和需要输入的Excel，帮我看看怎么写输入的那段代码可以吗？

引用 4 楼 user-4的回复:basic excel 求教，

basic excel


Question: printf输出double类型的问题

确实C99才支持，C89下是未定义行为，但编译器可能不完全支持C99

只能说这一处标准还没有实现。不过，C99标准中只是说了一句 %lf conversion specifier allowed in printf，也没有看见更多的解释和示例

感谢各位老师告知。

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！


Question: C语言关于逻辑“或”运算符在if语句中的应用问题

基础！基——础！

你的代码思想和你的实现要求差距很远呢。

'A'||'E'||'I'||'L'||'N'||'O'||'R'||'S'||'T'||'U' 这些得到的是1，根据||截断的思想，即'A' || 'E'若为真，那么后面的就不会再比较。由于真 || 真则结果是为真。 ch == 真(1)比较得到的结果应该是假，除非输入的是1. 同理下面的比较，都是ch == 真(1)。

这样用或的用法是不是不对？还是应该分开来写吧

if (strchr("AEILNORSTU", ch)){   sum=sum+1; }

if (ch=='A'|| ch=='E')    是这样写吧

if ( ch==('D'||'G') ) 能编译成功?   另建议把+1的处理用else放在最后.

else if(ch==('J'||'X')){ sum=sum+8; } else{ sum=sum+10; } } printf("Scrabble value: %d",sum); return 0; }修改为  else if(ch==('J'||'X')){ sum=sum+8; } else if(ch==('Q'||'Z')){ sum=sum+10; } else{ sum=sum+1; } } printf("Scrabble value: %d",sum); return 0; }


Question: 求大神指点，PAT-B.1008，用了数组和指针两种做法，为什么一用指针就段错误？

for(i=0;i<N;i++)          scanf("%d",&(*(p+i))); 你确定这句话没问题？

b是野指针，可能指向不可读写的内存位置。*b = y;其实是将y地址写到b指向的内存单元，但是b若是指向不可写的内存单元，此操作就会导致段错误；解决办法是：  b = (int *)malloc(sizeof(int)); if (!b)     exit(0); *b = y;

第一个代码是因为p是野指针，并没有让p指向一个可以读写的内容空间。因此会出现段错误（这个段错误不一定每次都会出现）；解决办法是通过malloc/free（释放时使用）为p申请空间，让其指向堆上的内存空间；  p = (int *)malloc(sizeof(int) * N); if (!p)     exit(0);

b没有初始化，所以给*b赋值错误。

指针数组‘中每一个指针都要先指向 你所变换的数组中的不同元素

用指针，就要注意初始化


Question: 求大佬看看，为什么后面else if语句不能表达

定义x是为单精度，输入时用的是lf,表示双精度，而应该用l 正确的代码如下：

int main() { 	float x = 0, y = 0; 	scanf("%f", &x); 	if (x<0) { y = 0; printf("%.2f\n", y); } 	else if (x >= 0 && x <= 15) { y = 4 * x / 3; printf("%.2f\n", y); } 	else if (x>15) { y = 2.5*x - 10.5; printf("%.2f\n", y); } 	else printf("error!\n"); 	return 0; }

要学会下断点查bug 1楼正解，输入的数据类型要和scanf设定的格式匹配

逻辑上来说，就是没有满足if else 的条件，我这里复制不了你的代码

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。

scanf("%f",&x);


Question: 两个程序之间通过文件通讯

进程之间的通信包括剪切板，管道，油槽，共享内存等。 =============== 还有就是通过socket

可以搜一下“命名管道”

引用 7 楼 cfjtaishan 的回复:需要加锁用于解决互斥问题。 #4代码没加锁，为什么没有问题？

需要加锁用于解决互斥问题。

这个就是多进程交互问题了，如果两个进程都是你做的开发，那么还好处理，具体进程通信方法无非那么几种ls都说的很清楚了

进程之间的通信包括剪切板，管道，油槽，共享内存等。

感觉还是通过管道同步靠谱些

管道呢，可以实现这样的需求

这个肯定要加锁的吧。 用内存映射文件进行通讯也很方便的。

不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，再将b.txt改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？ 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话，文本文件的格式问题可参考json或xml  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！ //test.c 本程序演示两个进程之间通过临时文本文件交换数据实现间接调用 //A将请求数据写到文件a.txt，写完后改名为aa.txt //B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，再将b.txt改名为bb.txt //A发现bb.txt存在时，读取其内容，读完后删除bb.txt #include <io.h> #include <stdio.h> #include <windows.h> int main(int argc,char **argv) {     int d,r;     FILE *f;     char cmdstr[512];      if (argc<2) {         sprintf(cmdstr,"cmd /c \"%s\" B",argv[0]);         WinExec(cmdstr,SW_HIDE);         for (d=1;d<=5;d++) {//共使用1..5调用B 5次             //A将请求数据写到文件a.txt，写完后改名为aa.txt             f=fopen("a.txt","w");             fprintf(f,"%d\n",d);             fclose(f);             rename("a.txt","aa.txt");             printf("call with %d\n",d);             //A发现bb.txt存在时，读取其内容，读完后删除bb.txt             while (1) {                 Sleep(100);                 if (_access("bb.txt",0)!=-1) {                     f=fopen("bb.txt","r");                     fscanf(f,"%d",&r);                     fclose(f);                     remove("bb.txt");                     break;                 }             }             printf("result:%d\n",r);         }         return 0;     }     if (argv[1][0]=='a'||argv[1][0]=='A') {//A         for (d=1;d<=5;d++) {//共使用1..5调用B 5次             //A将请求数据写到文件a.txt，写完后改名为aa.txt             f=fopen("a.txt","w");             fprintf(f,"%d\n",d);             fclose(f);             rename("a.txt","aa.txt");             printf("call with %d\n",d);             //A发现bb.txt存在时，读取其内容，读完后删除bb.txt             while (1) {                 Sleep(100);                 if (_access("bb.txt",0)!=-1) {                     f=fopen("bb.txt","r");                     fscanf(f,"%d",&r);                     fclose(f);                     remove("bb.txt");                     break;                 }             }             printf("result:%d\n",r);         }     } else {//B         while (1) {             //B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，再将b.txt改名为bb.txt             while (1) {                 Sleep(100);                 if (_access("aa.txt",0)!=-1) {                     f=fopen("aa.txt","r");                     fscanf(f,"%d",&r);                     fclose(f);                     r=r*10;                     f=fopen("b.txt","w");                     fprintf(f,"%d\n",r);                     fclose(f);                     remove("aa.txt");                     rename("b.txt","bb.txt");                     break;                 }             }             if (r==50) break;         }     }     return 0; } //C:\tmp\test>test //call with 1 //result:10 //call with 2 //result:20 //call with 3 //result:30 //call with 4 //result:40 //call with 5 //result:50 // //C:\tmp\test>start /B test B // //C:\tmp\test>test A //call with 1 //result:10 //call with 2 //result:20 //call with 3 //result:30 //call with 4 //result:40 //call with 5 //result:50 // //C:\tmp\test>

可以参考tail命令实现，如果你是用a模式打开文件应该不用担心


Question: 初学c语言，求大神指点

刚入门C语言可以看看这个：https://cloud.tencent.com/developer/doc/1023

#include <stdio.h>   #include<math.h>   using namespace std;    bool judge(int x);   int main()     {         int m,n;       scanf("%d %d",&n,&m);       if(n%2==0)  n++;         for(int i=n;i<=m;i+=2)       {           if(judge(i)&&judge(i+2)&&i+2<=m)  printf("(%d,%d)",i,i+2);       }          return 0;     }         bool judge(int n)   {        if(n<=1)  return false;       int m=floor(sqrt(n)+0.5);       for(int i=2;i<=m;i++)           if(n%i==0)  return false;       return true;   }     这个是我敲的。 你敲的有太多的问题：1.  if(i%j==0) { flag=0; break;  } ，这有两种可能break 跳出if语句，执行for循环，那就没有意义，或者break跳出for循环，那就肯定出错。 2.     if(flag==1)   { a[m++]=i;printf("%d",i);   }，就算前面的能判断出i为素数，printf里的也应该是a[m++]不是i(即使两者输出结果一样)。


引用 29 楼 czxinc 的回复:[quote=引用 27 楼 zhao4zhong1 的回复:] 建议先弄清楚啥叫字符。 对于字符我是一知半解的状态。[/quote] 如果你以前没见过#21楼的字符的话。

引用 27 楼 zhao4zhong1 的回复:建议先弄清楚啥叫字符。 对于字符我是一知半解的状态。

引用 19 楼 user-4 的回复:# include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题 # include <conio.h> # define Limit 40000000 # define N 10  //如果要录入X个字节则 N=X int  get_GBK(char *A,int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度 int main() {     char A[N+1];     while(1)     {         printf("输入:");         get_GBK(A,2,N);         puts(A);     }     return 0; } int  get_GBK(char *A,int min,int max) {     int B,C,D;     do             {                 for(B=max+printf("["),C=1; C<B; C++)printf(" ");                 printf("]\b");                 while(--B)printf("\b");                 while((C=getch())!='\r')if(C>127||C==8)                     {                         if(C!=8&&B<max&&printf("%c",C))A[B++]=C;                         else if(C==8&&B>0)                         {                            printf("\b \b");                             if(B&1)                             {                                 B--;                                 if(B)printf("\b \b");                                 else printf("[ ");                             }                             else  B-=2;                             printf("\b");                         }                         else if(B>=max)                         {                             D=printf("]  长度:[%d,%d]!",min,max);                             for(C=0; C<Limit; C++);                             while(--D)printf("\b \b");                             printf("\b");                         }                     }                 A[B]=0;                 if(B<min)                 {                     for(C=B; C<max; C++)printf(" ");                     D=max+printf("]  长度:[%d,%d]!",min,max);                     for(C=0; C<Limit; C++);                     while(D--)printf("\b \b");                     printf("\b");                 }             }while(B<min);     printf("\n");     return B; }  这个不行吗？ 这个可以，但是在win10下有点儿问题，我试试看能不能解决。

建议先弄清楚啥叫字符。

输入校验永远做不到完美； 所以程序员永远不会失业。

水很深！  参考下面：#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

禁止输入和输入后截短，没什么本质区别。

引用 24 楼 zyx6680599 的回复:[quote=引用 22 楼 zhao4zhong1 的回复:] 输入校验永远做不到完美； 所以程序员永远不会失业。 引用 17 楼 czxinc 的回复:[quote=引用 6 楼 user-4 的回复:] https://blog.csdn.net/user-4/article/details/77422530 我的这个博客里的第一个代码片中的Getchar函数～和你想过一样的问题～希望能帮到你这个函数改了一年～ 我复制了你的代码尝试了一下，发现了一个问题。 我其实是想用户在屏幕上输入指定数量的字符，如果超过则禁止输入。但是你的这两个例子都是判断输入过多后裁剪字符的呢。[/quote] 其实用uchar.h后用getch()就可以了[/quote] vc++6.0没有uchar.h呢

getch()能输入运行#21楼代码显示的那个字吗？

引用 22 楼 zhao4zhong1 的回复:输入校验永远做不到完美； 所以程序员永远不会失业。 引用 17 楼 czxinc 的回复:[quote=引用 6 楼 user-4 的回复:] https://blog.csdn.net/user-4/article/details/77422530 我的这个博客里的第一个代码片中的Getchar函数～和你想过一样的问题～希望能帮到你这个函数改了一年～ 我复制了你的代码尝试了一下，发现了一个问题。 我其实是想用户在屏幕上输入指定数量的字符，如果超过则禁止输入。但是你的这两个例子都是判断输入过多后裁剪字符的呢。[/quote] 其实用uchar.h后用getch()就可以了

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

引用 2 楼 zhao4zhong1 的回复:wchar_t *fgetws( wchar_t *string, int n, FILE *stream );  wchar_t buf[4]; fgetws(buf,4,stdin); 就算这样，还是达不到要求“用户在屏幕上输入指定数量的字符，如果超过则禁止输入”。

引用 6 楼 user-4 的回复:https://blog.csdn.net/user-4/article/details/77422530 我的这个博客里的第一个代码片中的Getchar函数～和你想过一样的问题～希望能帮到你这个函数改了一年～ 我复制了你的代码尝试了一下，发现了一个问题。 我其实是想用户在屏幕上输入指定数量的字符，如果超过则禁止输入。但是你的这两个例子都是判断输入过多后裁剪字符的呢。

引用 15 楼 zyx6680599 的回复:[quote=引用 11 楼 czxinc 的回复:] [quote=引用 8 楼 zyx6680599 的回复:] [quote=引用 7 楼 user-4 的回复:] # include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题 # define N 10  //如果要录入X个字节则 N=X int Getchar(char A[],int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度 int gainint(int *p,int a,int b); int main(){ 	char A[N+1];//最后一位存'\0' 	int B; 	printf("输入字符串:1--1字节");     Getchar(A,1,1);      printf("输入字符串:0--%d字节",N);     Getchar(A,0,N);//因为min=0  这个时候直接输入回车 结束录入 字符串为空字符串 	 printf("输入字符串:1--%d字节",N);     Getchar(A,1,N);//因为min=1  这个时候直接输入回车 是不会结束录入的 	printf("输入B 1----100："); 	gainint(&B,1,100);     printf("输入B 2----4："); 	gainint(&B,2,4);     return 0; } int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束，并返回*p的位数       {            do{               *p=a-1;    //此处是为了减少意外情况的发生 虽然那种意外情况不常见         scanf("%d",p);               while(getchar()!='\n');               if(*p>b||*p<a)                   printf("输入有误,请重新输入(%d--%d):\n",a,b);           }while(*p>b||*p<a);           return *p;       }       int Getchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度     {         int B,C;//B保存A的长度 C记录缓冲区的字符串         do{             B=-1;  C=0; //每次用户输入错误而循环时 都要初始化             fgets(A,max+1,stdin);//从键盘录入字符             while(A[++B]);  //求A的字符串长度             if(A[B-1]!='\n') while(getchar()!='\n') C++;    //如果缓冲区里读入的不是\n则记录字符串数量             else  A[--B]='\0'; //☆  去掉\n 并且字符串长度-1             if(C||B&&B<min) //如果缓冲区有字符串或者长度不够 则提示错误   但如果用户只输入回车而且min!=0则不提示错误 但还要输入当前字符串               printf("您输入的字符串长度:%d字节\n请重新输入!\n注:只输入(%d--%d)个字节!\n",B+C,min,max);         }while(C||B<min);         return B;//返回B 即:A字符串的长度     }       # include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题   # define N 10  //如果要录入X个字节则 N=X   int Getchar(char A[],int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度   int gainint(int *p,int a,int b);   int main(){       char A[N+1];//最后一位存'\0'       int L,min,max;       do{     printf("请输入字符串的长度的最小值[0,%d]：",N);     gainint(&min,0,N);     printf("请输入字符串的长度的最大值[%d,%d]：",min,N);     gainint(&max,min,N);     printf("请输入字符串[%d,%d]:",min,max);     Getchar(A,min,max);     printf("字符串：%s\n",A);     }while(1);     return 0;   }   int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束，并返回*p的位数         {              do{                 *p=a-1;    //此处是为了减少意外情况的发生 虽然那种意外情况不常见           scanf("%d",p);                 while(getchar()!='\n');                 if(*p>b||*p<a)                     printf("输入有误,请重新输入[%d--%d]:",a,b);             }while(*p>b||*p<a);             return *p;         } int Getchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度       {           int B,C;      do{               A[max]=B=C=0;           while((A[B++]=getchar())!='\n'&&B<max);           if(A[B-1]!='\n')while(getchar()!='\n'&&++C);               else A[--B]=0;        if(C||B&&B<min)          printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);           }while(C||B<min);           return B;     }  这两个Getchar 你看哪好点你用哪个 希望能帮到你 其实用几个getch()输入不同的变量，用一个数组存储就行了虚假生conio.h[/quote] 抱歉前几天比较忙没有仔细看。 我复制了你的代码尝试了一下，发现了一个问题。 我其实是想用户在屏幕上输入指定数量的字符，如果超过则禁止输入。但是你的这两个例子都是判断输入过多后裁剪字符的呢。[/quote] getch()只能一次键入一个变量，你是不是看我上面的代码了，最底下的是我的，上面的是@赵四老师的[/quote] 十分抱歉，本来是想回复#6\#7的user-4 网友的，不小心回复错了。 getch()只能接受ascii码。而我是想要可以同时输入汉字和英文的函数，getch()就无法接收汉字的unicode码。

引用 11 楼 czxinc 的回复:[quote=引用 8 楼 zyx6680599 的回复:] [quote=引用 7 楼 user-4 的回复:] # include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题 # define N 10  //如果要录入X个字节则 N=X int Getchar(char A[],int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度 int gainint(int *p,int a,int b); int main(){ 	char A[N+1];//最后一位存'\0' 	int B; 	printf("输入字符串:1--1字节");     Getchar(A,1,1);      printf("输入字符串:0--%d字节",N);     Getchar(A,0,N);//因为min=0  这个时候直接输入回车 结束录入 字符串为空字符串 	 printf("输入字符串:1--%d字节",N);     Getchar(A,1,N);//因为min=1  这个时候直接输入回车 是不会结束录入的 	printf("输入B 1----100："); 	gainint(&B,1,100);     printf("输入B 2----4："); 	gainint(&B,2,4);     return 0; } int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束，并返回*p的位数       {            do{               *p=a-1;    //此处是为了减少意外情况的发生 虽然那种意外情况不常见         scanf("%d",p);               while(getchar()!='\n');               if(*p>b||*p<a)                   printf("输入有误,请重新输入(%d--%d):\n",a,b);           }while(*p>b||*p<a);           return *p;       }       int Getchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度     {         int B,C;//B保存A的长度 C记录缓冲区的字符串         do{             B=-1;  C=0; //每次用户输入错误而循环时 都要初始化             fgets(A,max+1,stdin);//从键盘录入字符             while(A[++B]);  //求A的字符串长度             if(A[B-1]!='\n') while(getchar()!='\n') C++;    //如果缓冲区里读入的不是\n则记录字符串数量             else  A[--B]='\0'; //☆  去掉\n 并且字符串长度-1             if(C||B&&B<min) //如果缓冲区有字符串或者长度不够 则提示错误   但如果用户只输入回车而且min!=0则不提示错误 但还要输入当前字符串               printf("您输入的字符串长度:%d字节\n请重新输入!\n注:只输入(%d--%d)个字节!\n",B+C,min,max);         }while(C||B<min);         return B;//返回B 即:A字符串的长度     }       # include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题   # define N 10  //如果要录入X个字节则 N=X   int Getchar(char A[],int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度   int gainint(int *p,int a,int b);   int main(){       char A[N+1];//最后一位存'\0'       int L,min,max;       do{     printf("请输入字符串的长度的最小值[0,%d]：",N);     gainint(&min,0,N);     printf("请输入字符串的长度的最大值[%d,%d]：",min,N);     gainint(&max,min,N);     printf("请输入字符串[%d,%d]:",min,max);     Getchar(A,min,max);     printf("字符串：%s\n",A);     }while(1);     return 0;   }   int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束，并返回*p的位数         {              do{                 *p=a-1;    //此处是为了减少意外情况的发生 虽然那种意外情况不常见           scanf("%d",p);                 while(getchar()!='\n');                 if(*p>b||*p<a)                     printf("输入有误,请重新输入[%d--%d]:",a,b);             }while(*p>b||*p<a);             return *p;         } int Getchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度       {           int B,C;      do{               A[max]=B=C=0;           while((A[B++]=getchar())!='\n'&&B<max);           if(A[B-1]!='\n')while(getchar()!='\n'&&++C);               else A[--B]=0;        if(C||B&&B<min)          printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);           }while(C||B<min);           return B;     }  这两个Getchar 你看哪好点你用哪个 希望能帮到你 其实用几个getch()输入不同的变量，用一个数组存储就行了虚假生conio.h[/quote] 抱歉前几天比较忙没有仔细看。 我复制了你的代码尝试了一下，发现了一个问题。 我其实是想用户在屏幕上输入指定数量的字符，如果超过则禁止输入。但是你的这两个例子都是判断输入过多后裁剪字符的呢。[/quote] getch()只能一次键入一个变量，你是不是看我上面的代码了，最底下的是我的，上面的是@赵四老师的

# include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题 # include <conio.h> # define Limit 40000000 # define N 10  //如果要录入X个字节则 N=X int  get_GBK(char *A,int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度 int main() {     char A[N+1];     while(1)     {         printf("输入:");         get_GBK(A,2,N);         puts(A);     }     return 0; } int  get_GBK(char *A,int min,int max) {     int B,C,D;     do             {                 for(B=max+printf("["),C=1; C<B; C++)printf(" ");                 printf("]\b");                 while(--B)printf("\b");                 while((C=getch())!='\r')if(C>127||C==8)                     {                         if(C!=8&&B<max&&printf("%c",C))A[B++]=C;                         else if(C==8&&B>0)                         {                            printf("\b \b");                             if(B&1)                             {                                 B--;                                 if(B)printf("\b \b");                                 else printf("[ ");                             }                             else  B-=2;                             printf("\b");                         }                         else if(B>=max)                         {                             D=printf("]  长度:[%d,%d]!",min,max);                             for(C=0; C<Limit; C++);                             while(--D)printf("\b \b");                             printf("\b");                         }                     }                 A[B]=0;                 if(B<min)                 {                     for(C=B; C<max; C++)printf(" ");                     D=max+printf("]  长度:[%d,%d]!",min,max);                     for(C=0; C<Limit; C++);                     while(D--)printf("\b \b");                     printf("\b");                 }             }while(B<min);     printf("\n");     return B; }  对不起 看了你的要求是 输入汉字  你看看这个可以不

# include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题 # include <conio.h> # define N 10  //如果要录入X个字节则 N=X int user_password(char *A,int min,int max,int F);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度 int main() {     char A[N+1],B[2*N+1];     printf("用户名:");     user_password(A,2,N,0);     printf("密  码:");     user_password(B,6,2*N,1);     printf("用户名:");     puts(A);     printf("密  码:");     puts(B);     return 0; } int user_password(char *A,int min,int max,int F)//F=0录入密码 否则 录入 用户名 {     int B,C,D;     char S[][7]={"用户名","密码"};     do     {         B=max+printf("[");for(C=1; C<B; C++)printf(" ");printf("]");         while(B--)printf("\b");         B=0;         while((C=getch())!='\r')         if(C>='0'&&C<='9'||C>='a'&&C<='z'||C>='A'&&C<='Z'||C=='_'||C==8)             {             if(C!=8&&B<max)             {                 if(F)printf("*");//密码                 else printf("%c",C);//用户名                 A[B++]=C;             }             else if(C==8&&B>0)             {                 printf("\b \b");                 B--;             }             else if(B>=max)             {                 D=printf("]%s长度:[%d,%d]!",S[F],min,max);                 for(C=0; C<60000000; C++);                 while(D-->1)printf("\b \b");                 printf("\b");             }         }         A[B]=0;         if(B<min)         {             for(C=B; C<max; C++)printf(" ");             D=max+printf("]%s长度:[%d,%d]!",S[F],min,max);             for(C=0; C<60000000; C++);             while(D--)printf("\b \b");             printf("\b");         }     }while(B<min);     printf("\n");     return B; }  这个行不？

引用 8 楼 zyx6680599 的回复:[quote=引用 7 楼 user-4 的回复:] # include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题 # define N 10  //如果要录入X个字节则 N=X int Getchar(char A[],int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度 int gainint(int *p,int a,int b); int main(){ 	char A[N+1];//最后一位存'\0' 	int B; 	printf("输入字符串:1--1字节");     Getchar(A,1,1);      printf("输入字符串:0--%d字节",N);     Getchar(A,0,N);//因为min=0  这个时候直接输入回车 结束录入 字符串为空字符串 	 printf("输入字符串:1--%d字节",N);     Getchar(A,1,N);//因为min=1  这个时候直接输入回车 是不会结束录入的 	printf("输入B 1----100："); 	gainint(&B,1,100);     printf("输入B 2----4："); 	gainint(&B,2,4);     return 0; } int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束，并返回*p的位数       {            do{               *p=a-1;    //此处是为了减少意外情况的发生 虽然那种意外情况不常见         scanf("%d",p);               while(getchar()!='\n');               if(*p>b||*p<a)                   printf("输入有误,请重新输入(%d--%d):\n",a,b);           }while(*p>b||*p<a);           return *p;       }       int Getchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度     {         int B,C;//B保存A的长度 C记录缓冲区的字符串         do{             B=-1;  C=0; //每次用户输入错误而循环时 都要初始化             fgets(A,max+1,stdin);//从键盘录入字符             while(A[++B]);  //求A的字符串长度             if(A[B-1]!='\n') while(getchar()!='\n') C++;    //如果缓冲区里读入的不是\n则记录字符串数量             else  A[--B]='\0'; //☆  去掉\n 并且字符串长度-1             if(C||B&&B<min) //如果缓冲区有字符串或者长度不够 则提示错误   但如果用户只输入回车而且min!=0则不提示错误 但还要输入当前字符串               printf("您输入的字符串长度:%d字节\n请重新输入!\n注:只输入(%d--%d)个字节!\n",B+C,min,max);         }while(C||B<min);         return B;//返回B 即:A字符串的长度     }       # include <stdio.h>//int char 输入容易出问题 下面的代码可以解决这个问题   # define N 10  //如果要录入X个字节则 N=X   int Getchar(char A[],int min,int max);//直到用户输入的字符串长度在[min,max]之间时 函数结束 返回字符串A的长度   int gainint(int *p,int a,int b);   int main(){       char A[N+1];//最后一位存'\0'       int L,min,max;       do{     printf("请输入字符串的长度的最小值[0,%d]：",N);     gainint(&min,0,N);     printf("请输入字符串的长度的最大值[%d,%d]：",min,N);     gainint(&max,min,N);     printf("请输入字符串[%d,%d]:",min,max);     Getchar(A,min,max);     printf("字符串：%s\n",A);     }while(1);     return 0;   }   int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束，并返回*p的位数         {              do{                 *p=a-1;    //此处是为了减少意外情况的发生 虽然那种意外情况不常见           scanf("%d",p);                 while(getchar()!='\n');                 if(*p>b||*p<a)                     printf("输入有误,请重新输入[%d--%d]:",a,b);             }while(*p>b||*p<a);             return *p;         } int Getchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度       {           int B,C;      do{               A[max]=B=C=0;           while((A[B++]=getchar())!='\n'&&B<max);           if(A[B-1]!='\n')while(getchar()!='\n'&&++C);               else A[--B]=0;        if(C||B&&B<min)          printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);           }while(C||B<min);           return B;     }  这两个Getchar 你看哪好点你用哪个 希望能帮到你 其实用几个getch()输入不同的变量，用一个数组存储就行了虚假生conio.h[/quote] 抱歉前几天比较忙没有仔细看。 我复制了你的代码尝试了一下，发现了一个问题。 我其实是想用户在屏幕上输入指定数量的字符，如果超过则禁止输入。但是你的这两个例子都是判断输入过多后裁剪字符的呢。


Question: 数组倒置我这个for循环写错了么？为什么不倒置、

因 i->6 j->0 等于换了2遍，负负得正 又换回来了

for (i = 0; i < j; i++)   for (i = 0; i < 7; i++)不行，又换回原顺序了


Question: matlab Sfcn

引用 1 楼 zhao4zhong1 的回复:偶遇到类似问题都是用 “每次注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。 首先谢谢老师回答，之前是犯了中文符号的问题，结果专注于错误提示，找语法方向的问题，浪费了不少时间。


Question: 写了个24bitBMP转RGB565的程序，读出来的数据有问题

帮结贴+蹭分

还是自己解决了，跳过补0语句出了点错，已经解决


Question: C语言初学者不懂的地方

输出c2 = B肯定不对,  重新编译一下( rebuid all) c2 = b; 编译时应该会有警告的. 养成好习惯, 使用 c2 = (char)b ;

重新编译 rebuid all

重建所有

我也觉得奇怪，%d应该输出十进制的数，你的怎么能输出B（十六进制的）

我这里都输出 66 的说

你确定不是输出66？

你那个编译器很神奇 按%d 输出 ，竟然能输出字符？？？

char字符占8 bit的空间，表达范围为0~255，你的322已经超出。322%256=66，66在ascii中就是B


Question: 为什么结构体排序调试会出现断点？

统一回复，谢谢大家的解答，非常感谢。

引用 7 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }  又出来扯淡

int main() {           int n = 0;     STU *s, *v;     printf("请输入学生人数：\n");     scanf("%d",&n);     s = (STU*)malloc(n*sizeof(STU));     if (!s)         exit(0);     v = input(s,n);     printf("原始列表：\n");     print(v, n);     sort(v,0,n);     printf("排序列表：\n");     print(v,n);     //free(s);     system("pause");     return 0; } 这段里面sort(v,0,n)改成sort(v,0,n-1)； 这个错误很致命； STU *input(STU *s,int n) {     int i;     for ( i = 0; i < n; i++)     {         printf("请分别输入学号、姓名、科目1分数、科目2分数、科目3分数(用空格隔开！)\n");         scanf("%ld%s%d%d%d",&s[i].num,&s[i].name,             &s[i].exam.km1,&s[i].exam.km2,&s[i].exam.km3);         s[i].exam.aver = (s[i].exam.km1 + s[i].exam.km2 + s[i].exam.km3) / 3;     }     return s; } 这段格式字符之间要加空格，因为你自己要求输入之间要加空格，而且&s[i].name这个是什么东东，这是要把name数组的首地址给改了？ 都是细节。

引用 8 楼 phenix2009 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }  又出来扯淡[/quote] 充分证明你根本不会使用数据断点来定位越界访问。

越界了，调用排序时候改一下参数即可：  	int n = 0; 	STU *s, *v; 	printf("请输入学生人数：\n"); 	scanf("%d", &n); 	s = (STU*)malloc(n*sizeof(STU)); 	if (!s) 		exit(0); 	v = input(s, n); 	printf("原始列表：\n"); 	print(v, n); 	sort(v, 0, n - 1); 	printf("排序列表：\n"); 	print(v, n); 	free(s); 	system("pause"); 	return 0;

看了评论很受益

请帮我看下快排哪里有问题，谢谢。 引用 1 楼 cfjtaishan 的回复:排序没问题，而是input函数有问题。input的第一个参数，s申请的是一个结构体的空间，但是却被用于于n个结构体空间，所以越界导致程序异常。 改成如下：       printf("请输入学生人数：\n");     scanf("%d",&n);     s = (STU*)malloc(sizeof(STU) * n);     if (!s)          exit(0);     v = input(s,n);

两位再帮我看下这个快速排序哪里出了问题？ 会出现断点，而且输出乱码。  #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h>  struct MyStruct2 { 	int km1, km2, km3; 	float aver; };  struct MyStruct1 { 	long num; 	char name[20]; 	struct MyStruct2 exam; }; typedef struct MyStruct1 STU; STU *input(STU *, int); void print(STU *,int); void sort(STU *,int,int); int main() { 	 	int n = 0; 	STU *s, *v; 	printf("请输入学生人数：\n"); 	scanf("%d",&n); 	s = (STU*)malloc(n*sizeof(STU)); 	if (!s) 		exit(0); 	v = input(s,n); 	printf("原始列表：\n"); 	print(v, n); 	sort(v,0,n); 	printf("排序列表：\n"); 	print(v,n); 	//free(s); 	system("pause"); 	return 0; } STU *input(STU *s,int n) { 	int i; 	for ( i = 0; i < n; i++) 	{ 		printf("请分别输入学号、姓名、科目1分数、科目2分数、科目3分数(用空格隔开！)\n"); 		scanf("%ld%s%d%d%d",&s[i].num,&s[i].name, 			&s[i].exam.km1,&s[i].exam.km2,&s[i].exam.km3); 		s[i].exam.aver = (s[i].exam.km1 + s[i].exam.km2 + s[i].exam.km3) / 3; 	} 	return s; } //结构体排序  /* void sort(STU *s, int n)  { 	STU temp; 	int i,j; 	for ( i = 0; i <n ; i++) 	{ 		for ( j = 0; j < n-1-i; j++) 		{ 			if (s[j].exam.aver < s[j+1].exam.aver) 			{ 				temp = s[j + 1]; 				s[j + 1] = s[j]; 				s[j] = temp; 			} 		} 	} } */ void sort(STU *s, int l,int r) { 	if (l < r) 	{ 		//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1   		int i = l, j = r; 		STU x = s[l]; 		while (i < j) 		{ 			while (i < j && s[j].exam.aver >= x.exam.aver) // 从右向左找第一个小于x的数   				j--; 			if (i < j) 				s[i++] = s[j];  			while (i < j && s[i].exam.aver < x.exam.aver) // 从左向右找第一个大于等于x的数   				i++; 			if (i < j) 				s[j--] = s[i]; 		} 		s[i] = x; 		sort(s, l, i - 1); // 递归调用    		sort(s, i + 1, r); 	} }   void print(STU *s, int n) { 	int i;  	printf("%学号\t姓名\t科目1\t科目2\t科目3\t平均分\n"); 	for ( i = 0; i < n; i++) 	{ 		printf("%ld\t%s\t%d\t%d\t%d\t%.2f\n",s[i].num, s[i].name,s[i].exam.km1, s[i].exam.km2, s[i].exam.km3,s[i].exam.aver); 	} }

因为分配时候，没有根据学生数量进行分配，已经改好了：  	int n = 0; 	STU *s, *v; 	 	 	printf("请输入学生人数：\n"); 	scanf("%d", &n); 	s = (STU*)malloc(sizeof(STU) * n); 	v = input(s, n); 	printf("原始列表：\n"); 	print(v, n); 	sort(v, n); 	printf("排序列表：\n"); 	print(v, n); 	free(s); 	system("pause");


Question: 请教一个在pthread线程函数中使用回调函数的问题

线程对应的函数的格式必须是这样：void *xxoo(void *arg)  a.把“void *sayhello(void *arg)”改成“void sayhello(void *arg)”会报错如下：  root@book-desktop:/opt/pc_test/multithreading/1# make  gcc -o main main.c -lpthread  main.c: In function ‘main’:  main.c:14: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type  /usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but argument is of type ‘void (*)(void *)’  b.把“void *sayhello(void *arg)”改成“void *sayhello(void)”会报错如下：  root@book-desktop:/opt/pc_test/multithreading/1# make  gcc -o main main.c -lpthread  main.c: In function ‘main’:  main.c:14: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type  /usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(void)’

引用 2 楼 cfjtaishan 的回复:pthread_create第三个参数是void *类型，但是void (*func)()函数的返回值是void类型，与void *冲突。 下面的修改，参考一下吧  #include <stdio.h> #include <unistd.h> #include <pthread.h>  struct param {     void (*func)(const char *); };  //回调函数 void OutputSth(const char *str) {     printf("%s\n", str);      //return NULL; }  //线程函数 void *ThreadRun(void *arg) {     const char str[20] = "hello callback.";     struct param *p = (struct param *)arg;     int i = 0;     for(; i < 10; ++i)     {         p->func(str);         sleep(1);     }      return NULL; }  int main(void) {     pthread_t thd;     struct param arg;     arg.func = OutputSth;     pthread_create(&thd, NULL, ThreadRun, (void *)&arg);     pthread_join(thd, NULL);      return 0; } 十分感谢，学习了

void *ThreadRun(void (*func)())  这个函数的参数类型应该是void*  也就是说是：void *ThreadRun(void * func) 这样的形式


Question: gdb调试时输出不能正确输出中文

export LANG=zh_CN.UTF-8

有安装汉字库吗

查看文字的格式。

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

你可以考虑在编写的是，将编码更换为ANSI 编码

确认一下你的code中文的编码格式，是utf-8格式的吗？ 在Linux下中文一般是utf-8格式的才能正常显示，否则可能会以乱码形式出现


Question: 求不同类型（运算or访存）的程序源代码

引用 2 楼 zhao4zhong1 的回复:http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素正在看你推荐的这个视频，感谢指教！

引用 1 楼 zhao4zhong1 的回复:无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！其实也没有需要这么深入，是在做毕业设计，导师说需要来分析不同类型的程序，好让论文有得写，但是自己理解的不够不知道怎样来写这些不同类型的程序，所以才会提出这个问题


Question: win32 串口通信接收数据异常

仅供调用：void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

加个断点调试下

引用 9 楼 hou09tian 的回复:我觉得可以换个串口助手试试，以前遇到过这种情况。  能否推荐一个？谢谢

我觉得可以换个串口助手试试，以前遇到过这种情况。

引用 7 楼 phenix2009 的回复:不能看后面那个，前面的才是收到的数据吧  我发送的数据为：70 15 03 00 00 00 00 02 00 00 70 FA 0A  收到的为：  倒数第二个字节也不对啊，FA应该是250，收到的为什么是122呢

引用 12 楼 phenix2009 的回复:最高位没接收到，0xFA变成了0x7A，以目前状况来看，我比较怀疑你初始化时候，串口的几个参数与调试工具是否一致； 波特率，校验位，数据位，停止位，这里要跟你的串口助手一致，请查看一下； 你之前帖子里说你波特率调的9600，但你截图工具用的115200，请一定确认一下串口参数，如果参数对不上，数据传输是会出现问题的。  果然是因为这个导致的，谢谢大神指点。

不能看后面那个，前面的才是收到的数据吧

收到的是17 17 17 17 34 34 34 34 51 51 51 68 请全部转换成16进制，不就是0x11 0x11 0x11 0x11 0x22 0x22 0x22 0x22 0x33 0x33 0x33 0x44

引用 4 楼 phenix2009 的回复:请问接收数据错乱是指什么，我看接收的数据的确是你发送的，是不是你把16进制和10进制看混了？ 还是说下面那俩0是多发了？ 我发送的是16进制：11 11 11 11 22 22 22 22 33 33 33 44 收到的是 \x11 \x11 \x11 \x11 \‘’  \" \" \" 3 3 3 3 收到的也对不上啊？

引用 1 楼 zhao4zhong1 的回复:波特率设置低一点，串口线短一点。 波特率9600，没有串口线，用的串口调试工具，虚拟的串口

波特率设置低一点，串口线短一点。

想办法换实际的串口。


Question: C语言串口调用

之前刚好做过linux下的串口，分享给你看看，可以配合找找问题。 首先是打开串口，我们设备的串口是固定一个，名字是ttyPS1：  	m_hCom = ::open("/dev/ttyPS1", O_RDWR | O_NOCTTY | O_NONBLOCK);  	if(m_hCom==-1) return false; 	 	struct termios options; 	tcgetattr(m_hCom, &options); 	struct termios newtio; 	switch (m_nBaudRate)//设置数据传输率 	{ 	case 4800: 		cfsetispeed(&newtio, B4800); 		cfsetospeed(&newtio, B4800); 		break; 	case 9600: 		cfsetispeed(&newtio, B9600); 		cfsetospeed(&newtio, B9600); 		break; 	case 19200: 		cfsetispeed(&newtio, B19200); 		cfsetospeed(&newtio, B19200); 		break; 	case 38400: 		cfsetispeed(&newtio, B38400); 		cfsetospeed(&newtio, B38400); 		break; 	case 115200: 		cfsetispeed(&newtio, B115200); 		cfsetospeed(&newtio, B115200); 		break; 	default: 		cfsetispeed(&newtio, B9600); 		cfsetospeed(&newtio, B9600); 		break; 	} 	//修改控制模式，保证程序不会占用串口    	newtio.c_cflag |= CLOCAL; 	//修改控制模式，使得能够从串口读取输入数据    	newtio.c_cflag |= CREAD; 	newtio.c_cflag &= ~CRTSCTS; 	switch (m_DataBits)//设置数据位 	{ 	case 5: 		newtio.c_cflag |= CS5; 		break; 	case 6: 		newtio.c_cflag |= CS6; 		break; 	case 7: 		newtio.c_cflag |= CS7; 		break; 	case 8: 		newtio.c_cflag |= CS8; 		break; 	}  	switch (m_nParityIndex)//设置奇偶效验位 	{ 	case 0: 		newtio.c_cflag &= ~PARENB; 		break; 	case 1: 		//newtio.c_iflag |= (INPCK | ISTRIP); 		newtio.c_cflag |= PARENB; 		newtio.c_cflag &= ~PARODD; 		break; 	case 2: 		newtio.c_cflag |= PARENB; 		newtio.c_cflag |= PARODD; 		//newtio.c_iflag |= (INPCK | ISTRIP); 		break; 	}  	switch (m_nStopBitsIndex) 	{ 	case 1: 		newtio.c_cflag |= CSTOPB; 		break; 	default: 		newtio.c_cflag &= ~CSTOPB; 		break; 	}  	//修改输出模式，原始数据输出    	newtio.c_oflag *= ~OPOST;  	newtio.c_cc[VTIME] = 1; 	newtio.c_cc[VMIN] = 1; 	tcflush(m_hCom, TCIFLUSH);  	if ((tcsetattr(m_hCom, TCSANOW, &newtio)) != 0) 	{//激活新配置 		::close(m_hCom); 		m_hCom = -1; 		return false; 	}   然后是发送部分，buff是char数组，nlen是发送长度：  		nRet = write(hComm, buff, nLen); 		if (nRet < 0) 		{ 			return KSJVB_RET_FAIL; 		}

百度搜“Linux操作系统下串口编程入门教程”

引用 7 楼 leetow2006 的回复:原来ttyPS1是串口设备名称，学习了 这个可不一定的，不过很多设备都会叫这个罢了，具体还要看设备，不像Windows下面，定好了就叫com1 com2

原来ttyPS1是串口设备名称，学习了

引用 2 楼 zhao4zhong1 的回复:百度搜相关关键字。 已经搜了两天了，程序改了好多遍，都不行啊

引用 1 楼 hzy_76 的回复:調試過沒有，能按預期執行到哪一步？ 用USB转串口的线连接到PC上，在串口调试工具里面都看不到返回数据，估计是都没写进去

百度搜相关关键字。

調試過沒有，能按預期執行到哪一步？


Question: 二维指针数组，int* a[2][2]，怎么理解 &(a[0])和&(a[0][0])相等，但a[0]和a[0][0]不等？

a[0]是二维数组的第0行第0列的列地址，对其取地址就相当于上升一个维度，就从列地址变为行地址，&a[0]就是第0行的行地址，a[0][0]为第0行第0列元素的值，对其取址操作就是取a[0][0]元素的地址，&a[0][0]即0行0列的地址，就是刚才说的a[0]，因为a[0][0]中的第二个0代表在行上没有偏移，所以a[0]代表的0行0列列地址等于0行的行地址。所以&a[0]和&a[0][0]相等。 a[0][0]为第0行第0列元素的值，不是地址，所以a[0]和a[0][0]不等。

步长了解一下

int a = {{1,2}, {3, 4}}; 可以将a看成一个数组，这个数组中有2个元素，每个元素又是一个包含2个int的数组。所以&a[0]是第一个数组{1，2}的起始地址；a[0][0]是第一个元素即1的地址，所以两个值相同。而a[0]是第一个数组{1，2}的起始地址，a[0][0]是第一个元素的值即1，所以两者不同。  至于a[0]和&a[0]的区别，请查看《C++中对数组名的运算》https://blog.csdn.net/hou09tian/article/details/80136819 希望能够帮到你

理解和讨论之前请先学会如何观察！  //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]  http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

把int* 看成int，你再理解试试。也许你会恍然大悟

&a[0]， &a[0][0],   都是地址，前者是第0行地址再取地址，后者取a[0][0]这个数的地址，两者都是相同的地址值，但是含义不同，执行++操作结果也不同 a[0]，a[0][0] 类型不同，前者是一个地址，表示第0行首个数字所在的地址，而a[0][0]是数组中的第一个数，两者是不同的东西

在C语言中，a[0]代表的是一维数组的第一列，而a[0][0]是二维数组的第一行第一列，所以表示的内容是不相同的 而当加上取地址符&后，&a[0]和&a[0][0]都表示选取数组中的第一个地址，所以表示的内容是相同的。

&a[0],       &a[0][0],   代表是取地址 a[0] a[0][0] 一个是代表数组的第一行 ，一个是代表数组第一行，第一列，类型不同


Question: malloc与free问题

引用 7楼TWG8 的回复:1.首先，你使用指针p申请内存，但是你并没有使用这块内存，那我不知道你申请内存的意义在哪，直接定义一个指针就行。 2.p=&a[i] 改变指针的指向，指向了数组元素，所以最后free(p),p指向a[0] 等于释放了a[0] 。 但是a[0]是栈变量，函数执行完，程序自动释放，然而你又free，等于释放了2次。所以编译器 报错 double free 3.至于你第二种为什么可以，我也不清楚，但是理论上是和第一种是同一种情况。感谢。我是初学，这部分不清楚，您说的 我现在明白了

p运行到最后已经不指向开始时申请的内存了，如果调用free释放就会出错，第二种方式也是不对的，只是还没有报错而已吧

free Deallocates or frees a memory block.  void free( void *memblock );  Function Required Header Compatibility  free <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  None  Parameter  memblock  Previously allocated memory block to be freed  Remarks  The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc). If memblock is NULL, the pointer is ignored and free immediately returns. Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors.  After a memory block has been freed, _heapmin minimizes the amount of free memory on the heap by coalescing the unused regions and releasing them back to the operating system. Freed memory that is not released to the operating system is restored to the free pool and is available for allocation again.  When the application is linked with a debug version of the C run-time libraries, free resolves to _free_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.  Example  /* MALLOC.C: This program allocates memory with  * malloc, then frees the memory with free.  */  #include <stdlib.h>         /* For _MAX_PATH definition */ #include <stdio.h> #include <malloc.h>  void main( void ) {    char *string;     /* Allocate space for a path name */    string = malloc( _MAX_PATH );    if( string == NULL )       printf( "Insufficient memory available\n" );    else    {       printf( "Memory space allocated for path name\n" );       free( string );       printf( "Memory freed\n" );    } }   Output  Memory space allocated for path name Memory freed   Memory Allocation Routines  See Also   _alloca, calloc, malloc, realloc, _free_dbg, _heapmin

第二个也有问题，只不过潜伏着呢

感觉没区别啊，你指向你分配内存的那个指针指到别的地方了，然后你去释放一块根本不是malloc得来的空间，是有问题的啊 。

正如7楼所说的，你根本就没用申请的内存，何来释放之说

那个都不行。两个都会导致内存泄露。free释放的并不是malloc的空间。不能说运行没问题，就是程序没问题，这个是随机性的。  若用malloc的空间，就不能再将p指向a数组的某个元素或者a数组。 本身这个程序就可以不用malloc/free

free释放的是malloc分配的地址，不是数组的地址


Question: C语言形参char*可以传""进去吗？会不会有乱码生产？

没问题，""是空串，strcpy后你函数中的字符数组也是空，只要函数中不修改参数字符串就没问题，而且也不会有乱码

""代表的是空串，空串的长度为０．因此strlen(a), strlen(b), strlen(c)都为０． strcpy拷贝空串到a1, b1, c1，那么每个字符数组得到也都是空串，唯一的一个字符是'\0'。因为空串也是字符串的一种，所以也是以'\0'结束。 #include <stdio.h> #include <string.h>   int fund(char* a, char* b, char* c) {     char a1[10];     char b1[10];     char c1[10];       printf("a=%s\n",a);     printf("b=%s\n",b);     printf("c=%s\n",c);       //memset(a1,0x00,sizeof(a1));     //memset(b1,0x00,sizeof(b1));     //memset(c1,0x00,sizeof(c1));     strcpy(a1,a);     strcpy(b1,b);     strcpy(c1,c);       if( strlen(a1)> 0 )     {         printf("a1=%s\n",a1);     }       if( strlen(b1)> 0 )     {         printf("b1=%s\n",b1);     }       if( strlen(c1)> 0 )     {         printf("c1=%s\n",c1);     }       return 0; }   int main(void) {     fund("","","");       return 0; } 参考一下吧 memset可以不需要，因为strcpy会将'\0'加到目标串的末尾，目标串即strcpy的第一个参数。

""就是一个字符'\0'呀，你的代码很谨慎，没有任何问题。

可以, c,c++中是以\n结尾，所以"" 后面跟了一个\0, 长度是0，没有信息. 没有错，你不能修改。  char  *p="123456"; //123456/0在常量区，p在栈上.

引用 楼主 baidu_28726667 的回复:     if( strlen(a1)> 0 )     {         printf("b1=%s\n",b1);     }      if( strlen(a1)> 0 )     {         printf("c1=%s\n",c1);     }   这部分应该是以下吧：      if( strlen(b1)> 0 )     {         printf("b1=%s\n",b1);     }      if( strlen(c1)> 0 )     {         printf("c1=%s\n",c1);     }   如楼主所说，这样做是没有问题的，char*实际上是可以看成是字符串的。楼主程序运行后应该没有输出

下断点调试可以看出 char a1[10]; 此时a1的地址为  再查看该地址的数据  使用memset()填零之后的内存数据为 memset(a1, 0x00, sizeof(a1));  使用strcpy()拷贝字符串之后的数据为 strcpy(a1, a);  从以上分析可以看出，字符串""实际上就是包含了“\0”，不会出现你担心的乱码

你当前的程序没有问题，但是需要注意在函数fund中不能修改变量a,b,c的值，为了防止这种情况出现，可以修改下函数定义  int fund(const char* a, const char* b, const char* c)


Question: 一个小小的歌手系统 但是我有一个功能实现不完全 求大神帮忙

引用 7 楼 qq_41951726 的回复:感谢各位大佬提的问题，看到最后我发现确实是初始的变量的问题，我把它放在了某个函数外面了 下次小心吧，顺便把帖子结一下吧

ass里面的变量用来记录10个评委的分数，ass【i】数组是记录歌手人数的

没看懂你的代码，所有输入数值全都赋值给  数值  ass【j】， 没想明白

我不太懂这里用switch   case,并且建议加花括号，避免在case中定义对象产生的一些问题。

如果没进case 1就没有总分啊

好像没看到有错误哈，你看下你sum数组有没有初始化


Question: 想删除特定元素，可是运行时打印了一行，什么原因，求解释

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

#include <stdio.h>  //#define MAX 100000 #define MAX 100  typedef int DataType; typedef struct {     DataType list[MAX];     int size; }SeqList;  void ListInitiate(SeqList* L) {     L->size = 0; }  int ListInsert(SeqList* L,int i,DataType x) {     int j;     if(L->size >= MAX|| i < 0 || i > L->size)         return 0;       for(j = L->size+1;j >= i;j--)         L->list[j+1] = L->list[j];     L->list[i] = x;     L->size++;     return 1;//代表数据插入成功。  } int ListDelete(SeqList* L,int i) {     int j;     if(L->size>MAX||i<0||i>L->size-1)         return 0;      for(j=i;j<L->size-1;j++)         L->list[j]=L->list[j+1];     L->size--; } void ListDeleteByValue(SeqList *L, DataType x) {     int i;     for (i = 0; i<L->size+1; i++)     {         if(L -> list[i]==x)         {             //ListDelete(L,x);//这儿有点蒙             ListDelete(L, i);//这儿有点蒙         }     } } int ListLength(SeqList* L) {     return L->size; } int ListGet(SeqList* L,int i,DataType *x) {     int j;     //判定i是否有效     if(L->size<=0||i<0||i>L->size-1)         return 0;     //如果i有效     *x=L->list[i];     return 1;  } void PrintList(SeqList* L) {     int i,x;     for(i=0;i<L->size;i++)     {          printf("%5d",L->list[i]);     }     printf("\n"); }  int main(int argc, char *argv[]) {     SeqList my;     int i;     DataType x;     ListInitiate(&my);     while(scanf("%d",&x)!=EOF)     {         ListInsert(&my,0,x);     }     PrintList(&my);     ListDeleteByValue(&my,123);     PrintList(&my);     return 0; } 参考下吧  首先，不建议将局部数组定义那么大，因为局部数组是在栈上申请的，栈上的空间是有限的。如果自己使用不了100000，建议定义大小为100，或者更小； 删除操作时，第二个参数应该传递的是位置值而不是要删除的数值

Listdelete你判断的是i数组下标，可是你传递的却是一个值

ListDelete(L,x);//这儿有点蒙     改成ListDelete(L,i);


Question: 关于用Dev-C++运行后的问题

引用 2 楼 qq_42076842 的回复:也不算是运行失败，他是输入两个数据求面积，输完两个数据后，在按回车时就不在了 环境和程序。 如果结果不能停留，建议在程序末尾，确切的说是main末尾使用system("pause");或 getchar();等让结果停留

也不算是运行失败，他是输入两个数据求面积，输完两个数据后，在按回车时就不在了

建议详细描述一下你的问题，比如运行失败的信息，运行.exe的环境等等


Question: 请教一个__LINE__ 的问题,vs报错

引用 6 楼 jianwen0529 的回复:编译器警告级别的问题？ 这个我也调过了，但是不管用，比较尴尬

引用 5 楼 zilaishuichina 的回复:引用 3 楼 yangxiangzhan 的回复:vs2017实测没有报错， 输出 case 8说的不错，就是这样的，但是我这边报错了，让我十分困惑。不知道是要设置预定义还是怎么做  那编译器具体的报错信息是啥啊[/quote]报错代码C2051，case 表达式不是常量.

引用 10 楼 wanggui2015 的回复:https://stackoverflow.com/questions/11461915/visual-studio-9-0-error-c2051-case-expression-not-constant  In particular, if you are getting `case expression not constant' errors when building with MS Visual Studio, this is because MS's Edit and Continue debugging feature causes their compiler to violate ANSI C. To disable Edit and Continue debugging:  - right-click ssh.c in the FileView - click Settings - select the C/C++ tab and the General category - under `Debug info:', select anything _other_ than `Program Database for Edit and Continue'.    如文中描述，把这一项换成只要不是 “Program Database for Edit and Continue” 就行。 膜拜！我找了好久不知道在哪改这个！跪谢！

编译器警告级别的问题？

引用 3 楼 yangxiangzhan 的回复:vs2017实测没有报错， 输出 case 8说的不错，就是这样的，但是我这边报错了，让我十分困惑。不知道是要设置预定义还是怎么做[/quote]  那编译器具体的报错信息是啥啊

引用 2 楼 zhao4zhong1 的回复: 婴儿出生时是不能case没投胎在大富大贵之家，就重新投胎的！这位老师，这个 protothread 的写法我在其他平台运作的很好，只是挪到vs这就报错了

引用 1 楼 zilaishuichina 的回复:你如果说的是类似如下的代码：  #include "stdafx.h"  int main(int argc, char* argv[]) { 	int a = 8; 	switch (a) 	{ 		case __LINE__: 		printf("case %d", a); 		break; 		default: 		printf("default %d", a); 		break; 	} 	return 0; }  vs2017实测没有报错， 输出 case 8 引用 1 楼 zilaishuichina 的回复:你如果说的是类似如下的代码：  #include "stdafx.h"  int main(int argc, char* argv[]) { 	int a = 8; 	switch (a) 	{ 		case __LINE__: 		printf("case %d", a); 		break; 		default: 		printf("default %d", a); 		break; 	} 	return 0; }  vs2017实测没有报错， 输出 case 8说的不错，就是这样的，但是我这边报错了，让我十分困惑。不知道是要设置预定义还是怎么做

婴儿出生时是不能case没投胎在大富大贵之家，就重新投胎的！


Question: 出圈

仅供参考：//假设有n个人团团围做，从第1个人开始数数，数到第m个人时候，第m个人出列， //然后继续从1开始数数，数到第m个人退出 #include <stdio.h> #include <conio.h> int i,k,t; int n,m; static char f[1001];//0该座位未出圈,1该座位已出圈 void main() {     while (1) {         printf("Input n m(1000>=n>=m>=1):");         fflush(stdout);         rewind(stdin);         if (2==scanf("%d%d",&n,&m)) {             if (1000>=n && n>=m && m>=1) break;         }     }     t=0;//已出圈总人数     i=1;//座位编号     k=1;//当前要数的数     while (1) {         if (0==f[i]) {             if (m==k) {                 t++;                 f[i]=1;                 printf("%3d ",i);                 if (0==t%10) printf("\n");                 if (t>=n) break;             }             k++;if (k>m) k=1;         }         i++;if (i>n) i=1;     }     cprintf("Press any key ...");     getch(); }  看来“仅供参考”这四个字我应该去注册专利了。

这不是用数组模拟约瑟夫环吗？！ #include <stdio.h> #include <stdlib.h>  #define OUT_FLAG 7  /*初始化数组*/ int *init_arr(int *a, int len) { 	int i = 0;  	for(; i < len; i++) 		printf("%d ", a[i] = i+1); 	printf("\n");  	return a; }  /*约瑟夫环1*/ void print_out_order(int *a, int len) { 	/*      * num:队列中非0数字的个数      * mark:出列的标记数      * ret:最终剩下的数      * row:换行打印标记      */ 	int num = 0, row = 1, mark = 0, ret; 	int j;  	while(num != 1){ 		num = 0; 		for(j = 0; j < len; j++){ 			if(a[j] != 0){ 				num++; 				mark++; 				ret = a[j]; 			} 			if(mark == OUT_FLAG){ 				printf("%2d%c", a[j], !(row % 10) ? '\n' : ' '); 				a[j] = 0; 				mark = 0; 				row++; 			} 		} 	} 	printf("\n\n--------\"%d\" is the last one!\n", ret); }  /*约瑟夫环2*/ void print_out_order2(int *a, int len) { 	int i, count = 0, rem = len;  	for(i = 0; rem > 1; i++){ 		if(i > (len-1)) 			i = 0; 		if(a[i]){ 			count++; 			if(OUT_FLAG == count){ 				count = 0; 				printf("%d ", a[i]); 				a[i] = 0; 				rem--; 			} 		} 	} 	putchar('\n'); }  int main(void) { 	int len; 	printf("How many people in the queue?\n"); 	scanf("%d", &len);  	int *arr = (int *)malloc(sizeof(int) *len);     if (!arr) {         fprintf(stderr, "malloc error!\n");         return -1;     } 	init_arr(arr, len);  	printf("\nThe order of people quit queue is:\n"); 	print_out_order(arr, len); 	printf("---------proc 2-------------\n");  	int arr2[len]; 	init_arr(arr2, len);  	print_out_order2(arr2, len);      free(arr); 	return 0; } 仅供参考


Question: C语言读取文件的问题

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

找到问题在哪了，但是如果把这句话注释掉的话就只能输出txt文件中的最后一行。

引用 6 楼 cfjtaishan 的回复:建议直接贴代码，不建议用图片显示代码  //wenjian    void filec(TotalNode *head) 	{     int i; 	TotalNode *end; 	TotalNode *pTeacher;     FILE *fp;     fp=fopen("course.txt","r"); //以只读方式打开当前目录下.txt          if(fp==NULL)     {         printf("无法打开文件");         exit(0);        }     head=(TotalNode *)malloc(sizeof(TotalNode));     end=head;     end->next=NULL;          while(!feof(fp)) //------!feof(fp)值为0，不在执行循环语句  ------      	{         pTeacher=(TotalNode *)malloc(sizeof(TotalNode));         fscanf(fp,"%s%s%s\n",&pTeacher->CourseNum,&pTeacher->CourseName,&pTeacher->CourseTeacher);         pTeacher->next=NULL;         end->next=pTeacher;         end=pTeacher;      	}     fclose(fp);                // 选课学生的计数   	 for(i=0;i<20;i++)     {         pTeacher->stuNo[i][0]='\0';     }         }   /* 教师信息的输出-链表 */ void OutTeacherNode(TotalNode *head) {    TotalNode *p;     int num=0;     int i;    p=pTeacher;    	     if(pTeacher==NULL)     { 		puts("\t\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=");         puts("\t\t\t          没有数据!");        	puts("\t\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=");         return;     }    while(p!=NULL)      { 		puts("\t\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=");         printf("\t\t\t课程代码:%s\t\n",p->CourseNum);         printf("\t\t\t课程名称:%s\t\n",p->CourseName);         printf("\t\t\t课程老师:%s\t\n",p->CourseTeacher);          for(i=0;i<20;i++)         {             if(pTeacher->stuNo[i][0]!='\0')             {                 num++;             }         }         printf("\t\t\t选课学生:%d\t\n",num); 	    puts("\t\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=");         num=0;  //  清0操作         putchar('\n');         p=p->next;     }         putchar('\n');   }   pTeacher是全局的

建议直接贴代码，不建议用图片显示代码

引用 4 楼 weixin_40642114 的回复:第二张图跟第三张图顺序反了 p是不是应该指向head； 另外pTeacher是什么指针，全局的？

引用 1 楼 qq_42067537 的回复: 且你的链表似乎只有一个结点  你是不是没有增加链表结点  谢谢~ 这个问题我也发现了，现在已经改完了。又出现了新的问题，能不能帮忙看一下。  这个是我改完的文件读取，我试验过没有问题。 下边这个是输出的函数，怎么调程序都是输出没有数据。不知道哪里出的问题。

第二张图跟第三张图顺序反了

且你的链表似乎只有一个结点  你是不是没有增加链表结点


Question: 求助，不知道下面的程序哪里出了问题

老赵这是代码复用的典范...

程序太乱，完全没法看，这功能应该可以很简单实现。

DDDD拿分呀，不然没得下载.

边界条件 输入输出格式 ……

代码是自己的，调试一下


Question: 关于arm-c的语法温蒂

同上，编译后观察这个文件的变化，例如内容、修改时间等

搜“代码生成技术”


Question: 代码哪里错了？找不出来啊

在调试模式下运行程序，出错了点中断，通过调用堆栈定位到相关位置，分析原因

dir不是exe,是cmd.exe内部实现的命令。

不要空想，学会调试，崩溃时断下来，观察和谈量的值，看是遍历到哪个文件崩溃，看是什么原因崩溃，把这个文件单独复制出来看会不会崩溃，只是想你解决不了问题

引用 11 楼 wqte45 的回复:[quote=引用 10 楼 cfjtaishan 的回复:] [quote=引用 9 楼 wqte45 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 wqte45 的回复:] [quote=引用 4 楼 cfjtaishan 的回复:] strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 建议判断内部的strcat的返回值，然后确认一下FindFileData.cFileNmae的值，这些变量或返回值建议打印出来。  感觉这句话是没问题的  分散写代码里都没问题  ，而且我用sprintf来连接路径和文件名， 放在代码二的位置替换这句话  还是运行到一半就崩溃[/quote] 你需要确认strcat的参数，因此需要将他们都打印出来[/quote]   都打印出来了啊  编译运行 都出来了 代码写的很简单啊  打印的就是 最后用strcat连接到Dir数组里的信息啊  strcat返回值就是 连接后的指针啊 FindFileData.cFileNmae 就是每次获取的文件名啊  我是跟路径连接在一起了   如果发现目录没文件 就不会循环也不会输出啊  我的i盘有十万多文件  枚举出6万多的时候 崩溃了  代码一则不会崩溃  我就是问 代码二有啥写的不对吗 为什么代码一就没问题[/quote] 是不是越界了，每次执行这条语句： strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 你有没有对Dir清空，不清空，strcat就会按照上次的末尾('\0')继续追加，如果文件这么多肯定会导致越界呢。 建议每次得到一个文件路径后，就要把Dir清空一下，memset一下（清空为０） [/quote]  拜托你专心点好吗？我猜你就随便看看吧 肯定都没运行，  第一，这个代码大部分时候是可以用的 只是小概率的遇到一些文件会崩溃， 第二，Dir用得着清空吗？请仔细看strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName);   strcpy每次都会把pFilePath复制到Dir数组里，即每次都是从头覆盖，然后才连接\\和获取到的文件名啊 请认真点 ok？ 看仔细了 最里面的是 strcpy [/quote] 抱歉我的系统是Ubuntu 那我问一下，楼上各位给你提出的建议你又有没有使用一下呢？ 建议将两个strcat分两步做，不用strcat调用strcat，并且对返回值做一下判断。 别人给你的建议，建议你也试试，不要有抵触和让别人一步到位给你解决问题。我看别人帮你，你却这个态度，还怎么继续帮你？！

刚才又试了下换成了微软的lstcat  lstrcpy  lstrcat(lstrcat(lstrcpy(Dir, pFilePath), "\\"), FindFileData.cFileName);  这样就能解决 之前枚举文件中崩溃的问题了，但实际上虽然稳定了 但获取的文件数量 少了5个  而实际文件确实有那几个  用strcat就不会少 但有时候会崩溃。。。

引用 10 楼 cfjtaishan 的回复:[quote=引用 9 楼 wqte45 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 wqte45 的回复:] [quote=引用 4 楼 cfjtaishan 的回复:] strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 建议判断内部的strcat的返回值，然后确认一下FindFileData.cFileNmae的值，这些变量或返回值建议打印出来。  感觉这句话是没问题的  分散写代码里都没问题  ，而且我用sprintf来连接路径和文件名， 放在代码二的位置替换这句话  还是运行到一半就崩溃[/quote] 你需要确认strcat的参数，因此需要将他们都打印出来[/quote]   都打印出来了啊  编译运行 都出来了 代码写的很简单啊  打印的就是 最后用strcat连接到Dir数组里的信息啊  strcat返回值就是 连接后的指针啊 FindFileData.cFileNmae 就是每次获取的文件名啊  我是跟路径连接在一起了   如果发现目录没文件 就不会循环也不会输出啊  我的i盘有十万多文件  枚举出6万多的时候 崩溃了  代码一则不会崩溃  我就是问 代码二有啥写的不对吗 为什么代码一就没问题[/quote] 是不是越界了，每次执行这条语句： strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 你有没有对Dir清空，不清空，strcat就会按照上次的末尾('\0')继续追加，如果文件这么多肯定会导致越界呢。 建议每次得到一个文件路径后，就要把Dir清空一下，memset一下（清空为０） [/quote]  拜托你专心点好吗？我猜你就随便看看吧 肯定都没运行，  第一，这个代码大部分时候是可以用的 只是小概率的遇到一些文件会崩溃， 第二，Dir用得着清空吗？请仔细看strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName);   strcpy每次都会把pFilePath复制到Dir数组里，即每次都是从头覆盖，然后才连接\\和获取到的文件名啊 请认真点 ok？ 看仔细了 最里面的是 strcpy

引用 9 楼 wqte45 的回复:[quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 wqte45 的回复:] [quote=引用 4 楼 cfjtaishan 的回复:] strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 建议判断内部的strcat的返回值，然后确认一下FindFileData.cFileNmae的值，这些变量或返回值建议打印出来。  感觉这句话是没问题的  分散写代码里都没问题  ，而且我用sprintf来连接路径和文件名， 放在代码二的位置替换这句话  还是运行到一半就崩溃[/quote] 你需要确认strcat的参数，因此需要将他们都打印出来[/quote]   都打印出来了啊  编译运行 都出来了 代码写的很简单啊  打印的就是 最后用strcat连接到Dir数组里的信息啊  strcat返回值就是 连接后的指针啊 FindFileData.cFileNmae 就是每次获取的文件名啊  我是跟路径连接在一起了   如果发现目录没文件 就不会循环也不会输出啊  我的i盘有十万多文件  枚举出6万多的时候 崩溃了  代码一则不会崩溃  我就是问 代码二有啥写的不对吗 为什么代码一就没问题[/quote] 是不是越界了，每次执行这条语句： strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 你有没有对Dir清空，不清空，strcat就会按照上次的末尾('\0')继续追加，如果文件这么多肯定会导致越界呢。 建议每次得到一个文件路径后，就要把Dir清空一下，memset一下（清空为０）

引用 8 楼 cfjtaishan 的回复:[quote=引用 6 楼 wqte45 的回复:] [quote=引用 4 楼 cfjtaishan 的回复:] strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 建议判断内部的strcat的返回值，然后确认一下FindFileData.cFileNmae的值，这些变量或返回值建议打印出来。  感觉这句话是没问题的  分散写代码里都没问题  ，而且我用sprintf来连接路径和文件名， 放在代码二的位置替换这句话  还是运行到一半就崩溃[/quote] 你需要确认strcat的参数，因此需要将他们都打印出来[/quote]   都打印出来了啊  编译运行 都出来了 代码写的很简单啊  打印的就是 最后用strcat连接到Dir数组里的信息啊  strcat返回值就是 连接后的指针啊 FindFileData.cFileNmae 就是每次获取的文件名啊  我是跟路径连接在一起了   如果发现目录没文件 就不会循环也不会输出啊  我的i盘有十万多文件  枚举出6万多的时候 崩溃了  代码一则不会崩溃  我就是问 代码二有啥写的不对吗 为什么代码一就没问题

引用 6 楼 wqte45 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 建议判断内部的strcat的返回值，然后确认一下FindFileData.cFileNmae的值，这些变量或返回值建议打印出来。  感觉这句话是没问题的  分散写代码里都没问题  ，而且我用sprintf来连接路径和文件名， 放在代码二的位置替换这句话  还是运行到一半就崩溃[/quote] 你需要确认strcat的参数，因此需要将他们都打印出来

引用 2 楼 那年那人的回复:[quote=引用 1 楼 paschen 的回复:] 在调试模式下运行程序，出错了点中断，通过调用堆栈定位到相关位置，分析原因  看不懂啊  [/quote] 不是给出了，是执行strcat时崩的  检查strcpy返回的指针是否有效，检查字符是否越界，检查拷贝的字符串是否以\0结尾

引用 4 楼 cfjtaishan 的回复:strcat(strcat(strcpy(Dir, pFilePath), "\\"), FindFileData.cFileName); 建议判断内部的strcat的返回值，然后确认一下FindFileData.cFileNmae的值，这些变量或返回值建议打印出来。  感觉这句话是没问题的  分散写代码里都没问题  ，而且我用sprintf来连接路径和文件名， 放在代码二的位置替换这句话  还是运行到一半就崩溃

引用 3 楼 zhao4zhong1 的回复:system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。 如果嫌system黑窗口一闪，将system("...")替换为WinExec("cmd /c ...",SW_HIDE);  在一台被精简了的系统 没有dir.exe程序的情况下 咋弄呢？

引用 1 楼 paschen 的回复:在调试模式下运行程序，出错了点中断，通过调用堆栈定位到相关位置，分析原因  看不懂啊


Question: 请问访问指针范围之外的空间，为什么程序没有崩溃？

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

C语言本身就支持直接访问内存的，内存分配函数只是告诉编译器说申请的内存我程序要用，不要用来做其他事，并不是说没有申请的空间程序就不能访问。 通常内存越界引起程序崩溃是因为你访问的内存空间编译器已经用在其他地方了，结果你修改了内容导致程序运行数据异常，所以才会崩溃 这个属于内存管理的，具体细节说起来就复杂了... 从你的程序来说，你申请了10个字节的内存空间，编译器会保证这10个字节空间不会用在其他地方；但是因为你的程序比较简单，所以这10个字节空间之后的空间也处于空闲状态未被使用，所以你的访问并没有引起程序的异常

崩溃是一种保护行为。如果系统检测到你越界，则会系统崩溃，以免影响其他程序用错误的数据，发生更加莫名其妙的行为。到时不是所有的越界系统都能检查的。

未定义行为并不代表一定要崩溃，崩溃验明不了什么，最多只能说你运气好

越界访问是未定义的行为，若越界的内存空间未被使用，且是可读可写的，那么使用写或者读是没问题。但是越界这部分空间，可能会被其他程序使用，可能会导致其他程序想这段区域写数据，会导致数据出错。 另外，calloc申请空间不一定是根据我们申请的字节数来的，比如我们申请１０个字节的空间，那么内存管理会按照内存管理给予相应的比１０字节要多的内存空间。因此也可能是这种原因导致的不异常。  但是这样的操作还是很有风险的，越界操作不一定每次都没问题，当然也可能出问题。所以，还是申请多少就用多少比较保险。


Question: C语言冒泡法，改了好久还是不知道错在哪

越界问题： for(k=0;k<N;k++)     {         for(i=0;i<N-k-1;i++)         {             if(a[i]<a[i+1])             {t=a[i];a[i]=a[i+1];a[i+1]=t;}         }     }

第一个程序你参照第二个就好

第二个算法修改：  #include<stdio.h> #define N 10 void main() { 	int i, t, k, a[N]; 	printf("Bubble sort\n"); 	printf("old numbers:"); 	for (i = 0; i < N; i++) 		scanf("%d", &a[i]); 	for (k = 0; k < N; k++) 	{ 		for (i = 0; i < N - k - 1; i++) 		{ 			if (a[i] < a[i + 1]) 			{ 				t = a[i]; a[i] = a[i + 1]; a[i + 1] = t; 			} 		} 	} 	printf("new numbers:"); 	for (i = 0; i < N; i++) 		printf("%4d", a[i]); 	printf("\n"); 	system("pause"); }

数组已经越界了，修改一下

数据越界了，超出范围

明显越界了 啊

调试的时候少用几个数据、排序3-5个数就行了。哪里有问题很容易看出来。

第二个code的冒泡算法一样，也是会出现越界。

for(k=0;k<N;k++)     {         for(i=0;i<N-k-1;i++)         {             if(a[i]<a[i+1])             {t=a[i];a[i]=a[i+1];a[i+1]=t;}         }     } 数组越界，当k＝＝０时，i < N;那么i+1就会是N，下表只能是从０～Ｎ－１;因此会会越界；

if(a[i]<a[i+1])  a[i+1]) 数组越界了      for(k=0;k<N-1;k++)     {         for(i=0;i<N-k-1;i++)


Question: 新手求问问题出在哪？

输入数字的前面还应该加英文逗号

应该是输入的格式不对。 正确的输入格式是需要加,逗号的。注意是英文的逗号；  scanf("%d,%d,%d",&a,&b,&c); printf("a = %d, b = %d, c = %d\n", a, b, c);  再输入后加一条打印信息，若输出等于输入的，则格式正确，否则输入的格式不对