Question: C语言用fgets读取utf-8编码文本文件出现问题

引用 4 楼 qq423399099 的回复:windows下利用标准库fopen以UTF-8格式打开一个文件,要注意下面几个问题.  1.如果文件编码为UNICODE(UTF-8),有两种情况: 1)没有BOM头,调用fopen必须指定css=UTF-8. 2)有BOM头,调用fopen不要指定css=UTF-8. 2.文件编码为其它格式(如ANSI),调用fopen必须指定css=UTF-8.  fopen打开其它UNICODE(如UTF-16LE,UNICODE)等,与此类似,只是BOM头不相同. 例如 记事本中如果保存编码格式为Unicode big endian，则无法使用 ccs=UNICODE 这个功能 如果用了ccs=UNICODE，则必须使用宽字符格式的相应函数，即便文件本身编码是ANSI格式 虽然没遇到过，但是赞一个

是不是   数组的最后一位不是0啊

fgets是读取文本文件的

引用 10 楼 zcmerlin 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:]  Flag      No BOM (or new file)  BOM: UTF-8  BOM: UTF-16 UNICODE   ANSI                  UTF-8       UTF-16LE      UTF-8     UTF-8                 UTF-8       UTF-16LE      UTF-16LE  UTF-16LE              UTF-8       UTF-16LE         用的就是，fopen（FILE *p_file,  "r,  ccs = utf-8"）; 可是不行。。。编译就没通过，错误提示就是截图里那样[/quote]  #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <wchar.h>   #define MAX_SIZE    64 int main(void) {     FILE *p_source = NULL;     char *fname = "2.txt";     wchar_t buffer[MAX_SIZE] = { 0 };      if((p_source = fopen(fname, "r,ccs=utf-8")))     {         while(!feof(p_source))         {             wchar_t *src = fgetws(buffer, MAX_SIZE, p_source);             if (!src) {                 printf("return NULL\n");                 break;             } else                 printf("%s\n", src);         }         printf("\n");     }      fclose(p_source);      return 0 ; }  需要添加头文件<wchar.h> 如果使用fgets读取，会直接返回NULL，即出错。使用fgetws打开是可以的，同样缓存也要做调整。 对于wchar_t类型的数据如何输出到终端，还需要查一下，使用%s，编译器本身就会提警告。

引用 9 楼 paschen 的回复:应该读取到wchar_t中试了下，貌似并不行，不知道是哪里的问题

引用 6 楼 zhao4zhong1 的回复: Flag      No BOM (or new file)  BOM: UTF-8  BOM: UTF-16 UNICODE   ANSI                  UTF-8       UTF-16LE      UTF-8     UTF-8                 UTF-8       UTF-16LE      UTF-16LE  UTF-16LE              UTF-8       UTF-16LE         用的就是，fopen（FILE *p_file,  "r,  ccs = utf-8"）; 可是不行。。。编译就没通过，错误提示就是截图里那样

引用 7 楼 zcmerlin 的回复:[quote=引用 4 楼 qq423399099 的回复:] windows下利用标准库fopen以UTF-8格式打开一个文件,要注意下面几个问题.  1.如果文件编码为UNICODE(UTF-8),有两种情况: 1)没有BOM头,调用fopen必须指定css=UTF-8. 2)有BOM头,调用fopen不要指定css=UTF-8. 2.文件编码为其它格式(如ANSI),调用fopen必须指定css=UTF-8.  fopen打开其它UNICODE(如UTF-16LE,UNICODE)等,与此类似,只是BOM头不相同. 例如 记事本中如果保存编码格式为Unicode big endian，则无法使用 ccs=UNICODE 这个功能 如果用了ccs=UNICODE，则必须使用宽字符格式的相应函数，即便文件本身编码是ANSI格式  不是很明白，试了下，好像还是不行，代码如下： #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h>  int main(void) { 	FILE *p_source = NULL; 	char *fname = "e:\\source"; 	wchar_t buffer[10] = { 0 };  	if(p_source = fopen(fname, "r, ccs = utf - 8")) 	{ 		while(!feof(p_source)) 		{ 			printf("%s", fgetws(buffer, 10, p_source)); 		} 		printf("\n"); 	}  	fclose(p_source);  	system("pause"); 	return 0 ; }  已改为wchar_t，fgetws，但结果依然是失败，提示如下：    文件打开方式不可用  原问题是这样的：  文本文件为utf-8 无bom编码格式，文本内容包含英文字母和中文标点  C语言编写的程序想计算每行的字符个数，但是英文字母和中文标点在utf-8无bom的编码格式下的字节长度不同  造成的结果是含中文标点的行，计算的字符不准确  所以在想怎么样让程序准确判断每行的字符个数  另，把文本文件改为ansi后，输入了几个汉字，可以识别汉字，是不是说明fopen，fgets这些是以ansi编码格式读取文件的呢？[/quote]  对了，操作环境：windows7，vs2012

引用 4 楼 qq423399099 的回复:windows下利用标准库fopen以UTF-8格式打开一个文件,要注意下面几个问题.  1.如果文件编码为UNICODE(UTF-8),有两种情况: 1)没有BOM头,调用fopen必须指定css=UTF-8. 2)有BOM头,调用fopen不要指定css=UTF-8. 2.文件编码为其它格式(如ANSI),调用fopen必须指定css=UTF-8.  fopen打开其它UNICODE(如UTF-16LE,UNICODE)等,与此类似,只是BOM头不相同. 例如 记事本中如果保存编码格式为Unicode big endian，则无法使用 ccs=UNICODE 这个功能 如果用了ccs=UNICODE，则必须使用宽字符格式的相应函数，即便文件本身编码是ANSI格式  不是很明白，试了下，好像还是不行，代码如下： #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h>  int main(void) { 	FILE *p_source = NULL; 	char *fname = "e:\\source"; 	wchar_t buffer[10] = { 0 };  	if(p_source = fopen(fname, "r, ccs = utf - 8")) 	{ 		while(!feof(p_source)) 		{ 			printf("%s", fgetws(buffer, 10, p_source)); 		} 		printf("\n"); 	}  	fclose(p_source);  	system("pause"); 	return 0 ; }  已改为wchar_t，fgetws，但结果依然是失败，提示如下：    文件打开方式不可用  原问题是这样的：  文本文件为utf-8 无bom编码格式，文本内容包含英文字母和中文标点  C语言编写的程序想计算每行的字符个数，但是英文字母和中文标点在utf-8无bom的编码格式下的字节长度不同  造成的结果是含中文标点的行，计算的字符不准确  所以在想怎么样让程序准确判断每行的字符个数  另，把文本文件改为ansi后，输入了几个汉字，可以识别汉字，是不是说明fopen，fgets这些是以ansi编码格式读取文件的呢？

In Visual C++ 2005, fopen supports Unicode file streams. A flag specifying the desired encoding may be passed to fopen when opening a new file or overwriting an existing file, like this:  fopen("newfile.txt", "rw, ccs=<encoding>");  Allowed values of the encoding include UNICODE, UTF-8, and UTF16-LE. If the file is already in existence and is opened for reading or appending, the Byte Order Mark (BOM) is used to determine the correct encoding. It is not necessary to specify the encoding with a flag. In fact, the flag will be ignored if it conflicts with the type of the file as indicated by the BOM. The flag is only used when no BOM is present or if the file is a new file. The following table summarizes the modes used in for various flags given to fopen and Byte Order Marks used in the file.  Flag      No BOM (or new file)  BOM: UTF-8  BOM: UTF-16 UNICODE   ANSI                  UTF-8       UTF-16LE      UTF-8     UTF-8                 UTF-8       UTF-16LE      UTF-16LE  UTF-16LE              UTF-8       UTF-16LE         If mode is "a, ccs=<encoding>", fopen will first try to open the file with both read and write access. If it succeeds, it will read the BOM to determine the encoding for this file; however, if it fails, it will use the default encoding for the file. In either case, fopen will then re-open the file with write-only access. (This applies to mode a only, not a+.)

引用 1 楼 qq423399099 的回复:你的文件的后缀名呢？  是编码方式的问题吧，fgets以ascii编码读取，但文本是utf-8编码，所以在遇到中文字符时出现乱码，不知道我分析错了没？ 另，如果原因是这样的话，怎样让程序以utf-8读取文件呢

引用 1 楼 qq423399099 的回复:你的文件的后缀名呢？ 并没有

你的文件的后缀名呢？


Question: 用筛法求第N个素数，注意是第N个素数，求帮助  看看哪里出错了

不清楚筛选法 但是你int a[N];最开始没有设置为0吧，后面你判断 == 0基本是错的

两点小问题： 1）数组空间过大，如果仅仅是为了测试和练习用没必要使用那么大的空间，栈上的空间是有限的，不建议你使用这么大的内存； 2）你的求第N个素数的方法不像是筛选法求素数的，另外，栈上的数组不会自动初始化为0的，除非你把a定义为全局的数组（初始化为0）。 以下是我的demo:  #include<stdio.h>  #define MAX_LEN 1001  void print_all_prime(int *array, int len); void print_number_prime(int *prime_list, int len, int idx);  int main(void) {     int i;     int N, count;     int arr[MAX_LEN];    //限制数据量大小为1000      printf("你想求多少以内的素数:");     scanf("%d", &N);      for(i = 1; i <= N; i++) //为方便计，从1起         arr[i] = 1;      count = 2;  //筛选起点为2     while(count <= N/2) //显然：count不会超过N/2,必能使留下的数全为素数。     {         for(i = count+1; i <= N; i++) {             if(arr[i] == 1 && i % count == 0)                 arr[i] = 0;         }         for(i = count+1; i <= N; i++) {             if(arr[i] == 1) {                 count = i;                 break;             }         }     }     print_all_prime(arr, N);     print_number_prime(arr, N, 5);      return 0; }  void print_all_prime(int *array, int len) {     int i, cnt = 0;      printf("%d以内的素数为:\n", len);     for(i = 2; i <= len;i++)         if(array[i]) {             cnt++;             printf("%d ", i);             if(!(cnt % 10)) //增设cnt为输出换行                 printf("\n");         }     printf("\n"); }  void print_number_prime(int *array, int len, int idx) {     int i, cnt = 0;      for (i = 2; i < len; i++) {         if (array[i] == 1) {             cnt++;             if (cnt == idx) {                 printf("NO.%d prime is %d\n", idx, i);                 break;             }         }      }     if (i >= len) {         printf("不存在第%d 素数\n", idx);     } }

另外我想问一下  你们怎么发的代码（我还是复制粘贴，看着好不爽）；

//这是我做的时候遇到的一些问题向大家说明一下 并阐述一下观点    1.数组没有初始化 （全局变量定义后没有给出值的情况下全为0，而局部变量给出的是不确定的值）      2.开辟空间（全局变量与局部变量定义的范围是不同的，区别在与栈区，堆区和静态存储区）详情可以去看//我遇到的一些问题向大家说明一下 并阐述一下观点 //1.数组没有初始化 （全局变量定义后没有给出值的情况下全为0，而局部变量给出的是不确定的值）  //2.开辟空间（全局变量与局部变量定义的范围是不同的，区别在与栈区，堆区和静态存储区）详情可以去看http://blog.csdn.net/ccccdddxxx/article/details/7085165 以下是我根据大家给我指出的错误修改好的代码，有什么建议还请多多指教（本人英语较差，所以定义函数名实在不知道怎么写，也懒得去查，我感觉汉语拼音就挺好，都能看懂） //运用筛法  #include<stdio.h> # define N 1000*1000//很多人可能有异议，为什么要开那么大的空间？原题是求第100001个素数。    int a[N];	//对数组初始化 void shai_fa(int n){  	int i,k; 	// 将所有和数置1  	for(i=2;i<N/2;i++){       		if(a[i]==1) continue;//和数不参加筛法；  			for(k=2;k<=N/i;k++){ 				if(i*k<N) 				a[i*k]=1;  //将i的倍数全置1  			} 	} 	//找出第n个素数      int m=0; 	for(i=2;i<N;i++){ 		if(a[i]==0){ 			m++; 	        if(m==n) 	            printf("%d\n",i); 		}  	} }   int main(){ 	shai_fa(2); 	return 0; }

对于初始化那个问题已经解决了，但是关于数组的开辟空间问题还希望能指点一下，如果我要开辟一个1000*1000*10的空间怎么弄？

int a[N];你在栈上申请那么大的空间？ 栈一般只有1~2M的大小


Question: 结构体的声明在主函数内还是外？为什么有的在内有的在外？

区别就在于作用域不同。声明的位置不同，有效的区间也就不一样。

引用 2 楼 qq_37268797 的回复:内外有什么区别在函数内部声明的结构类型只能在函数内部使用 在函数外部声明的结构类型可以被多个函数使用

引用 2 楼 qq_37268797 的回复:内外有什么区别  可用范围。。

内外有什么区别

都可以，看你的需求了


Question: 求例程：设置计算机RS232串口RTS的电平

引用 楼主 oHanTangDuHeYing1 的回复:看到论坛里有说用EscapeCommFunction（）这个函数设置的，CLRRTS或SETRTS之类的。 我想知道仅仅完成这一个功能，需要对串口进行哪些配置。谢谢。 用C语言或C++实现。 不知道你想实现什么,给你个demo http://download.csdn.net/detail/u010095741/7251843

查了很多，内容太杂没有什么参考价值

百度搜相关关键字。


Question: codeblocks 添加头文件

从你贴出的头文件和其中一个的源文件看不出问题所在，能否继续贴出一些源码。

#include "onPaint.h" void onPaint(HDC hdc) {     Rectangle(hdc,0,0,50,100); } 源文件的代码

#ifndef ONPAINT_H_INCLUDED #define ONPAINT_H_INCLUDED  #include <windows.h> void onPaint(HDC hdc);   #endif // ONPAINT_H_INCLUDED 添加的头文件的代码

||=== Build: Debug in fangkuai (compiler: GNU GCC Compiler) ===| ||error: ld returned 1 exit status| ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===| 图片一直上传不上去

截个图看看


Question: fgets()读取文件问题

引用 1 楼 cfjtaishan 的回复: fgets (sendBuf, strlen(sendBuf), p_source); //改成 fgets (sendBuf, 20, p_source);  fgets第二个参数是指要读取的最大长度；第一次sendBuf中没有数据，那么strlen()得到是0； fgets的功能如下： char *fgets(char *s, int size, FILE *stream); fgets()  reads  in  at  most  one  less than size characters from stream and stores them into the buffer pointed to by s.  Reading stops after an EOF or a newline.  If a newline is read, it is        stored into the buffer.  A terminating null byte ('\0') is stored after the last character in the buffer.  多谢


Question: 贪吃蛇跑不动了，谁来帮看下，就百多行...

这是一个控制台的贪吃蛇，仅供参考

看了你写的贪吃蛇游戏，我在Linux下运行没什么大的问题。主要问题如下： 1）是接收输入的地方需要优化一下； 2）蛇会越界，即越过图的边界，你可以做一下校验，尤其是在蛇运动前对其是否到边界做一个预判； 3）蛇吃到果子后，蛇继续运动发现果子还在原地方； 以下是我写的简单贪吃蛇；你可以在这个基础上做的更复杂，比如动态中延长蛇的身体，延长蛇的身体就要考虑蛇在运行中是否会咬到自己。  #include <string.h> #include <time.h>  #define MAP_ROW     20 #define MAP_COL     20  #define SNAKER_BODY_LEN  2  struct pos {     int pos_x;     int pos_y; };  enum game_status {     EATING_FRUIT = 0,     EATEN_FRUIT,     EATEN_SELF };   /*Init the map */ void draw_map(char (*map)[MAP_COL], struct pos *fruit_pos, struct pos *snaker_pos, int snaker_len) {     int i, j, k;     int is_snaker = 0;      for (i = 0; i < MAP_ROW; i++) {         for (j = 0; j < MAP_COL; j++) {             if (fruit_pos->pos_x == i && fruit_pos->pos_y == j) {                 map[i][j] = 'X';             } else {                 is_snaker = 0;                 for (k = 0; k < snaker_len; k++) {                     if (snaker_pos[k].pos_x == i && snaker_pos[k].pos_y == j) {                         if (k == 0)                             map[i][j] = '*';                         else                             map[i][j] = 'o';                         is_snaker = 1;                     }                 }                 if (!is_snaker) {                     map[i][j] = '.';                 }             }         }     } }  /* show the map */ void show_map(char (*map)[MAP_COL], int row, int col) {     int i, j;      for (i = 0; i < row; i++) {         for (j = 0; j < col; j++)             printf("%c ", map[i][j]);         putchar(10);     } }   void add_fruit(struct pos *fruit_pos, struct pos *snaker_pos, int snaker_len) {     int i;     struct pos tmp;      srand(time(NULL));     while (1) {         tmp.pos_x = rand() % MAP_ROW;         tmp.pos_y = rand() % MAP_COL;          for (i = 0; i < snaker_len; i++) {             if (tmp.pos_x == snaker_pos[i].pos_x                     && tmp.pos_y == snaker_pos[i].pos_y)                 continue;         }         memcpy(fruit_pos, &tmp, sizeof(struct pos));         break;     } }  static void change_snaker_body(struct pos *snaker_pos, int snaker_len) {     struct pos tmp;     int i;      tmp = snaker_pos[0];     for (i = 1; i < snaker_len; i++) {         snaker_pos[i] = tmp;         if (i+1 < snaker_len)             tmp = snaker_pos[i+1];     } }  static int check_snaker_status(struct pos *snaker_pos, int snaker_len, struct pos *fruit_pos) {     struct pos tmp;     int i, is_eaten = EATING_FRUIT;      tmp = snaker_pos[0];     if (snaker_len >= 4) { /* snaker maybe bites itself*/         for (i = 3; i< snaker_len; i++) {             if (tmp.pos_x == snaker_pos[i].pos_x                     && tmp.pos_y == snaker_pos[i].pos_y)                 is_eaten = EATEN_SELF;         }      }     if (is_eaten != EATEN_SELF) {         if (fruit_pos->pos_x == tmp.pos_x                 && fruit_pos->pos_y == tmp.pos_y) {             is_eaten = EATEN_FRUIT;             fruit_pos->pos_x = -1;             fruit_pos->pos_y = -1;         }     }      return is_eaten; }  int move_snaker(int dir, char (*map)[MAP_COL], struct pos *fruit_pos, struct pos *snaker_pos, int snaker_len) {     int is_eaten = EATING_FRUIT;      switch (dir) {         case 'w':         case 'W':             if (snaker_pos[0].pos_x > snaker_pos[1].pos_x)                 break;             if (snaker_pos[0].pos_x <= 0)                 break;             change_snaker_body(snaker_pos, snaker_len);             /*                tmp = snaker_pos[0];                for (i = 1; i < snaker_len; i++) {                snaker_pos[i] = tmp;                if (i+1 < snaker_len)                tmp = snaker_pos[i+1];                }                */             snaker_pos[0].pos_x -= 1;             is_eaten = check_snaker_status(snaker_pos, snaker_len, fruit_pos);             /*             if (fruit_pos->pos_x == snaker_pos[0].pos_x                     && fruit_pos->pos_y == snaker_pos[0].pos_y) {                 is_eaten = 1;                 fruit_pos->pos_x = -1;                 fruit_pos->pos_y = -1;             }             */             break;          case 's':         case 'S':             if (snaker_pos[0].pos_x < snaker_pos[1].pos_x)                 break;             if (snaker_pos[0].pos_x >= MAP_ROW - 1)                 break;             change_snaker_body(snaker_pos, snaker_len);             /*             tmp = snaker_pos[0];             for (i = 1; i < snaker_len; i++) {                 snaker_pos[i] = tmp;                 if (i+1 < snaker_len)                     tmp = snaker_pos[i+1];             }             */             snaker_pos[0].pos_x += 1;             is_eaten = check_snaker_status(snaker_pos, snaker_len, fruit_pos);             /*             if (fruit_pos->pos_x == snaker_pos[0].pos_x                     && fruit_pos->pos_y == snaker_pos[0].pos_y) {                 is_eaten = 1;                 fruit_pos->pos_x = -1;                 fruit_pos->pos_y = -1;             }             */             break;          case 'a':         case 'A':             if (snaker_pos[0].pos_y > snaker_pos[1].pos_y)                 break;             if (snaker_pos[0].pos_y <= 0)                 break;             change_snaker_body(snaker_pos, snaker_len);             /*             tmp = snaker_pos[0];             for (i = 1; i < snaker_len; i++) {                 snaker_pos[i] = tmp;                 if (i+1 < snaker_len)                     tmp = snaker_pos[i+1];             }             */             snaker_pos[0].pos_y -= 1;             is_eaten = check_snaker_status(snaker_pos, snaker_len, fruit_pos);             /*             if (fruit_pos->pos_x == snaker_pos[0].pos_x                     && fruit_pos->pos_y == snaker_pos[0].pos_y) {                 is_eaten = EATEN_FRUIT;                 fruit_pos->pos_x = -1;                 fruit_pos->pos_y = -1;             }             */             break;          case 'd':         case 'D':             if (snaker_pos[0].pos_y < snaker_pos[1].pos_y)                 break;             if (snaker_pos[0].pos_y >= MAP_COL-1)                 break;             change_snaker_body(snaker_pos, snaker_len);             /*             tmp = snaker_pos[0];             for (i = 1; i < snaker_len; i++) {                 snaker_pos[i] = tmp;                 if (i+1 < snaker_len)                     tmp = snaker_pos[i+1];             }             */             snaker_pos[0].pos_y += 1;             is_eaten = check_snaker_status(snaker_pos, snaker_len, fruit_pos);             /*             if (fruit_pos->pos_x == snaker_pos[0].pos_x                     && fruit_pos->pos_y == snaker_pos[0].pos_y) {                 is_eaten = 1;                 fruit_pos->pos_x = -1;                 fruit_pos->pos_y = -1;             }             */             break;          default:             break;     }     system("clear");     draw_map(map, fruit_pos, snaker_pos, snaker_len);     show_map(map, MAP_ROW, MAP_COL);      return is_eaten; }    int main(void) {     char map[MAP_ROW][MAP_COL];     struct pos snaker_pos[SNAKER_BODY_LEN] = {{9, 9}, {8, 9}};     struct pos fruit_pos;     int ret = 0;     char dir;      add_fruit(&fruit_pos, snaker_pos, SNAKER_BODY_LEN);     //printf("fruit pos: x = %d, y = %d\n", fruit_pos.pos_x, fruit_pos.pos_y);     draw_map(map, &fruit_pos, snaker_pos, SNAKER_BODY_LEN);     show_map(map, MAP_ROW, MAP_COL);      while (1) {         printf("w(W)->up, s(S)->down, a(A)->left, d(D)->right:\n");         ret = scanf("%c", &dir);         getchar();         while (ret != 1) {             ret = scanf("%c", &dir);             getchar();         }         ret = move_snaker(dir, map, &fruit_pos, snaker_pos, SNAKER_BODY_LEN);         if (ret) {             if (ret == EATEN_SELF) {                 printf("Game over!\n");                 break;             }             system("clear");             add_fruit(&fruit_pos, snaker_pos, SNAKER_BODY_LEN);             draw_map(map, &fruit_pos, snaker_pos, SNAKER_BODY_LEN);             show_map(map, MAP_ROW, MAP_COL);         }     }     return 0; }  一个简单的贪吃蛇游戏，相互学习～

仅供参考：#include <conio.h> #include <windows.h>  void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); } 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);    } } void GetWH(int *w,int *h) {     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     CONSOLE_SCREEN_BUFFER_INFO csbi;     if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) {         *w=csbi.srWindow.Right;         *h=csbi.srWindow.Bottom;     } else {         *w=80;         *h=25;     } } void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  int main() {     unsigned short k;     int x,y,w,h;     char d;      SetConsoleOutputCP(437);     ClearConsole();     GetWH(&w,&h);     x=w/2;y=h/2;     HideTheCursor();     ConPrintAt(x,y,"O",1);     d='o';     while (1) {         Sleep(50);         if (kbhit()) {             k=getch();             if (27==k) break;//按Esc键退出             if (0==k||0xe0==k) k|=getch()<<8;//非字符键             switch (k) {                 case 0x48e0:case 0x04800://上                     d='u';                     if (y>0) {                         ConPrintAt(x,y," ",1);                         y--;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 0x50e0:case 0x05000://下                     d='d';                     if (y<h) {                         ConPrintAt(x,y," ",1);                         y++;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 0x4be0:case 0x04b00://左                     d='l';                     if (x>0) {                         ConPrintAt(x,y," ",1);                         x--;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 0x4de0:case 0x04d00://右                     d='r';                     if (x<w-1) {                         ConPrintAt(x,y," ",1);                         x++;                         ConPrintAt(x,y,"O",1);                     }                 break;             } //          cprintf("%04x pressed.\r\n",k);         } else {             switch (d) {                 case 'u':                     if (y>0) {                         ConPrintAt(x,y," ",1);                         y--;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 'd':                     if (y<h) {                         ConPrintAt(x,y," ",1);                         y++;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 'l':                     if (x>0) {                         ConPrintAt(x,y," ",1);                         x--;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 'r':                     if (x<w-1) {                         ConPrintAt(x,y," ",1);                         x++;                         ConPrintAt(x,y,"O",1);                     }                 break;             }         }     }     ClearConsole();     ShowTheCursor();     return 0; }

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

画蛇添足了....那个LastKey和 switch可以不要的...   直接改s[0]就行了....... 你看着改吧.....估计你还要加好多功能进去，比如吃水果变长，得分数...然后水果一次 刷几个...碰边刷新对面或者死掉..碰自己死掉..另外屏幕闪得有点不舒服....

我复制你的代码试了一下，然后根据自己知道的说些看法---我也是自学的，很多东西不懂： 首先char s[2]; scanf("%1s", s); 无法得到你想要的 s,直接导致   MoveSnake(s, gm, len, x, y, &fcount, &fx, &fy) 中几个判断都无效果，然后无反应----这个我试了，在 MoveSnake中多加了一个 else 之后 ，就能看出来。  所以我改了下 //打印棋谱  	PrintGameMap(gm, len, x, y, fcount, fx, fy); 	char *s; 	while (1) {        printf("输入W:向上，S:向下，A:向左，D:向右\n"); 		char c;         	c = std::cin.get();                 s = new char[2]; 		s[0] = c; 		s[1] = 0; 	//	scanf_s("%s", c); 		 		//printf(s); 		//移动蛇  		MoveSnake(s, gm, len, x, y, &fcount, &fx, &fy); 		delete[]s;  就是只改最后的一点点，可以按键，敲回车后走动了，但是bug还是很多。因为 std::cin.get();是等待按键的，要敲回车才开始工作..所以wwwww 回车 它会向上爬5格然后等待继续。  所以  你应该有一个计时的东东，直接判断时间到了不管你按没按键，或者按错了键，都要走，然后根据俩个时间段之间的最后按键 判断走向。   然后我就 #include<window.h> 加了一个 判断按键的 bool jiancha(char a){ 	if (GetAsyncKeyState(a) & 0x8000) 	{ 	 return true; 	}  else{ 	 return false;  } 改动了	//打印棋谱      PrintGameMap(gm, len, x, y, fcount, fx, fy); 	int LastTime = GetTickCount();         char *s; 	int Lastkey = 1; 	while (1) { 		 	 		if (jiancha('W')){ 			Lastkey = 1; 		} 		if (jiancha('A')){ 			Lastkey = 2; 		} 		if (jiancha('S')){ 			Lastkey = 3; 		} 		if (jiancha('D')){ 			Lastkey = 4; 		} 		if (GetTickCount() - LastTime >= 1000){ 		LastTime = GetTickCount();  		s = new char[2]; 		switch (Lastkey)  		{ 		case 1: 			s[0] = 'w'; 			break; 		case 2: 			s[0] = 'a'; 			break; 		case 3: 			s[0] = 's'; 			break; 		case 4: 			s[0] = 'd'; 			break; 		default: 			break; 		} 		s[1] = 0; 		MoveSnake(s, gm, len, x, y, &fcount, &fx, &fy); 		printf("输入W:向上，S:向下，A:向左，D:向右\n"); 		delete[]s; 		Sleep(20); }  	} 	return 0;  这样以后会动，会有按键反应，但是还有很多问题，1 靠边就没了，2吃掉水果，蛇离开，水果会刷原地。3：吃掉水果仅仅是吃掉水果....没啥意义。


Question: 为什么了？

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

只能说明运气好，没崩，仅此

未定义行为，如果你越界访问的内存刚好没有被别的变量使用或占用，那么没事。否则就会崩溃

#include<stdio.h> #include<stdlib.h>  #define MAX_SIZE    3 int main() {     int *p, i,t,j;      p = (int*)malloc(sizeof(int)*MAX_SIZE); /* malloc MAX_SIZE * sizeof(int) Bytes*/     if (!p) {         fprintf(stderr, "malloc error!\n");         return -1; /*exit*/     }      for(i = 0; i < MAX_SIZE; i++)         scanf("%d",p+i);      for(i = 0; i < MAX_SIZE; i++)         for(j = 0; j < MAX_SIZE-i-1; j++)             if(*(p+j) > *(p+j+1)) {                 t = *(p+j);                 *(p+j) = *(p+j+1);                 *(p+j+1) = t;             }      for(i = 0; i < MAX_SIZE; i++)         printf("%d ", *(p+i));      return 0; }  malloc申请的字节数不对呢，应该是申请3 * sizeof(int)个字节。而不是3个字节，因为p的类型是int（占4个字节）

访问内存越界了，其行为是未知的，也可能对，也可能崩溃，即使对了，这种写法也是不应该的


Question: c语言结构体变量问题，谢谢。

放到主函数里面去啊，就行了。一起学习交流，关注一下嘛。http://m.blog.csdn.net/article/details?id=55061737

哦哦 明白了谢谢大家

a.x = 1;放到函数里去，函数外只有变量的声明和初始化。不能对其赋值和修改操作。放到函数里去做这些。

a.x=1;这样的赋值语句需要放在函数中执行

要写在函数里，不能写在全局范围内

主函数(main)外只能进行定义或声明，不可以有执行语句。

引用 2 楼 jianwen0529 的回复:不能这么用的 =。= 你得在函数中写赋值语句。  或者在定义的时候初始化 如 coor a = {1, 10};

不能这么用的 =。= 你得在函数中写赋值语句。

自己顶一下，小白一个。


Question: 求助，运行错误，求解

if(fopen("date.dat","wb")==NULL) 修改为 if ((fp = fopen("date.dat", "wb")) == NULL)  你fp没有赋值就使用了（NULL）


Question: 怎么判断一个数是不是0.5的倍数？？？

学习了，谢谢！！！！

0.5是浮点，所以要考虑精度，比如 1.000000000000000000001 算不算0.5的倍数？

把数字都乘上10，

直接数据*10，先判断是否存在小数，然后判断个位是不是0和5， 楼上的各位考虑的好全面哦

输入是字符串的话其实挺简单的，没小数点或者有小数点且小数点后只有1个5就是0.5的倍数

引用 9 楼 GKatHere 的回复:[quote=引用 8 楼 sanredfish 的回复:] [quote=引用 7 楼 GKatHere 的回复:] 呃... 整数部分清0， 再检测是否等于0.5或0， 忘0了  乘以2之后检测小数是否接近0，这样更简单。[/quote] 直接检测 float(double)的尾数部分是否为0，或是与0.5相等（异或是否为0）， 也就是两个位测试而已。 没有比这更简单的了吧[/quote] 浮点数运算可能有误差,直接判断有可能不准确。

乘以2 是整数，需要考虑精度问题

楼主你的问题没说清楚啊   0.5不管是哪个阿拉伯数字都是它倍数啊  是不是想问怎么判断输入一个整数是不是五的整数倍数 #include <stdio.h> int main() { int x; scanf("%d",&x); if(x%5==0) printf("%d是5的整数倍数\n",x); else printf("%d不是5的整数倍数",x)； return 0; }

LZ应该指的是整数倍吧

高精度 任何位数都可以   http://blog.csdn.net/zhagoodwell/article/details/55051301

用字符串，可以避免double的10的-12次方的精度误差，用字符串，用户输入数字，用字符串匹配找到   .   若没有则为整数说明是0.5倍数，若有则判断最后一个字符是否为5不是5就不是0.5的倍数，晚上给你代码

引用 11 楼 zhu339111520 的回复:任何数都是0.5的倍数，这句话有什么毛病 楼主应该是没说清楚问题

引用 9 楼 GKatHere 的回复:[quote=引用 8 楼 sanredfish 的回复:] [quote=引用 7 楼 GKatHere 的回复:] 呃... 整数部分清0， 再检测是否等于0.5或0， 忘0了  乘以2之后检测小数是否接近0，这样更简单。[/quote] 直接检测 float(double)的尾数部分是否为0，或是与0.5相等（异或是否为0）， 也就是两个位测试而已。 没有比这更简单的了吧[/quote] float不建议直接和0比较，在一些条件下可能不成立；比如： 	float a ; 	float b = 1; 	 	a = 1.0/3.0;  	b -= a; 	b -= a; 	b -= a;  	printf("%f,%f\n",a,b); 	if(b !=0) 	{ 		printf("b != 0\n"); 	} 输出是  0.333333,-0.000000 b != 0

任何数都是0.5的倍数，这句话有什么毛病

倍数是啥？

fmod Calculates the floating-point remainder.  double fmod( double x, double y );  Function Required Header Compatibility  fmod <math.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  fmod returns the floating-point remainder of x / y. If the value of y is 0.0, fmod returns a quiet NaN. For information about representation of a quiet NaN by the printf family, see printf.  Parameters  x, y  Floating-point values  Remarks  The fmod function calculates the floating-point remainder f of x / y such that x = i * y + f, where i is an integer, f has the same sign as x, and the absolute value of f is less than the absolute value of y.  Example  /* FMOD.C: This program displays a  * floating-point remainder.  */  #include <math.h> #include <stdio.h>  void main( void ) {    double w = -10.0, x = 3.0, y = 0.0, z;     z = fmod( x, y );    printf( "The remainder of %.2f / %.2f is %f\n", w, x, z );    printf( "The remainder of %.2f / %.2f is %f\n", x, y, z );  }   Output  The remainder of -10.00 / 3.00 is -1.000000   Floating-Point Support Routines  See Also   ceil, fabs, floor

引用 8 楼 sanredfish 的回复:[quote=引用 7 楼 GKatHere 的回复:] 呃... 整数部分清0， 再检测是否等于0.5或0， 忘0了  乘以2之后检测小数是否接近0，这样更简单。[/quote] 直接检测 float(double)的尾数部分是否为0，或是与0.5相等（异或是否为0）， 也就是两个位测试而已。 没有比这更简单的了吧

首先要看数据精度， 其次，如果是0.5的倍数的话，让原始数据向左移1位，去掉整数后判断是否为0即可（0.5正好对应一个二进制位，如果是其他数字，需要进行计算才可以了。） 中心思想： （1）除数升倍至整数，然后进行整除取余运算。 （2）如果严格来说的话，0.3也是0.5的倍数，只是倍数0.6倍。从这个角度来讲，那么你这道题目就是假命题了。

浮点数是不能精确表示的，所以这个问题实际上有个精度的问题。 对于楼主的问题,如果支持C99可以fabs(fmod(x, 0.5)) < 0.0001判断 否则可以试试 x = fabs(x); if (fabs(x*2.0 - floor(x*2.0)) < 0.0001)

引用 7 楼 GKatHere 的回复:呃... 整数部分清0， 再检测是否等于0.5或0， 忘0了  乘以2之后检测小数是否接近0，这样更简单。


Question: C语言关于结构体定义使用的错误

引用 5 楼 elflun 的回复:知道了，我傻了 都傻过

“变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。

struct student stu_1; struct student *p = &stu_1;

变量声明和定义可以放在函数外面，作为全局或者静态的变量； 但是p=&stu_1;运算语句需要放在函数体内才可以。

struct student stu_1;    //1 struct student *p;        //2 这2条语句放在main函数外是可以的，声明成全局变量。  p=&stu_1;   执行语句要放在函数内才能执行

知道了，我傻了


Question: c语言如何实现web socket

搜“CGI C源代码”

tinyhttp一个轻量级的webServer，可以参考


Question: PAT 乙级 1030. 完美数列(25)

在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

#include<stdio.h> #include<stdlib.h>   int sort_function(const void *a,const void *b) {     return *((double *)a)-*((double *)b); } int main() {     int N, i, j, sum = 0;     double p, *a;      scanf("%d%lf", &N, &p);      a = (double *)malloc(sizeof(double) * N);     if (!a) {         fprintf(stderr, "malloc error!\n");         return -1;     }     for(i = 0; i < N; i++)         scanf("%lf", &a[i]);      qsort(a, N, sizeof(double), sort_function);      for(i = 0; i < N; i++){         for(j = N-1; j > 0; j--){             if(a[j] <= a[i] * p) {                 if(sum < j - i)                     sum = j - i;                 else                     break;             }         }     }     printf("%d\n",sum+1);     free(a);     return 0; }  栈上的空间是有限的，不建议你在栈上申请太大的空间。需要多少就申请过少，但是C语言不支持可变数组，所以在栈上申请了空间。 对于缩小运行时间，从你这个程序里来讲，从减少循环次数开始吧，若想减少循环次数，那么就要从算法上考虑了。

还是有一组运行超时


Question: 求指教指针问题，字符串的插入

栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……

strcp是局部变量，在函数myInsert调用结束后，该数组就会自动释放。在main函数栈里没有意义了。 把strcp定义成static则该变量的生命周期就发生了变化因为其存放在数据段（生命周期是整个程序），不是随着myInsert函数栈的结束而释放，而是等待程序运行结束而释放。 也可以把strcp定义成全局的变量，原理是类似的，主要是变量的生命周期变成了整个程序。

引用 2 楼 JianDan808 的回复:[quote=引用 1 楼 ipqtjmqj 的回复:] strcp改成static 十分感谢，运行成功，是因为局部变量执行结束后被内存空间被释放的原因吗[/quote] 对的。默认都是在栈上，函数返回就自动释放了。

改成static ，难道那个局部变量还要保存状态吗？   引用 1 楼 ipqtjmqj 的回复:strcp改成static 程序改成如下，试一下？  #include <stdio.h> #include <stdlib.h> #include <string.h>   char *myInsert(char *s,char *q, int n){     int i = 0;     char *str2;    static char strcp[50];     str2 = strcp;     for(i = 0; *s != '\0';i++){         if(i == n-1){             for( ; *q!='\0';){                 str2[i] = *q;                 i++;                 q++;             }         }         str2[i] = *s;         s++;     }     str2[i+1] = '\0';     return str2;   } //字符串插入 int main() {     char *strin, *str, *st,*st1;      int i;     str = "Hello,world!";     strin = "pig";            st = myInsert(str, strin, 3);    puts(st);     st = myInsert(str,strin,3);     puts(st1);       return 0; }

引用 1 楼 ipqtjmqj 的回复:strcp改成static 十分感谢，运行成功，是因为局部变量执行结束后被内存空间被释放的原因吗

strcp改成static


Question: 读取文件 c语言

某某某的文章

引用 4 楼 赵4老师的回复:仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8   essaie blabla是什么意思

随机必然有重复，所谓“不重复的随机”实际上是洗牌。洗牌算法参考下面： #include <stdio.h> #include <stdlib.h> #include <time.h> int d[6]; int i,n,a,b,t; int c,j; void main() {     srand(time(NULL));     printf("shuffle 0..n-1 demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=0;i<n;i++) d[i]=i;/* 填写0～n-1 */             for (i=n;i>0;i--) {/* 打乱0～n-1 */                 a=i-1;b=rand()%i;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=0;i<n;i++) printf("%d",d[i]);             printf("\n");         }     }     printf("shuffle 1..n demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=1;i<=n;i++) d[i]=i;/* 填写1～n */             for (i=n;i>1;i--) {/* 打乱1～n */                 a=i;b=rand()%i+1;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=1;i<=n;i++) printf("%d",d[i]);             printf("\n");         }     } }

如果每行长度都相同的话，可以用fseek来跳转到指定的行

目前的系统文件不支持随机访问读取，建议你把文件内容读到内存，然后通过随机数产生的数字，在内存中查找。


Question: c tcp server端怎么解析发来的结构体数据

服务器接收的信息是字节流，而字节流!=结构体， 因为不同操作系统和不同编译器对数据类型占用字节是不同的，所以直接转入结构体是不正确的， 需要做判断长度等等工作，如果字节流长度都是固定的还好办，如果是不定长的就还有其他问题。  5楼的链接看了一下，竟是些鸡同鸭讲的东西，其实简单讲就是以下几点：  1、文本型的数据传输协议，适合结尾符分割，你如HTTP协议。 2、字节流数据传输协议，适合定长包头+长度+不定长内容+校验码这样处理。 3、网络问题不可能全都靠协议解决，需要客户端+服务器端程序处理各种意外情况。  以上三点可以概括那个帖子中的正确内容，其他的都是胡搅蛮缠。

按占用字节数解析的，跟结构体无关

引用 6 楼 zfh19921230 的回复:一个server 绑定两个端口怎么写啊,求大神回复啊 使用两个exe

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

如果是运输层以上的数据，或者通过recv得到数据。直接用类型强制转换即可。比如你的接收缓冲区是char buf[1024];那么，你直接用struct s param = *(struct s *)buf;即可，或者struct s *pparam = (struct s *)buf; 需要有一个前提，即client端也需要发送的是一个struct s的结构体；即send的buf为，struct s param, memcpy(buf, param, sizeof(param));  主要是一点：client端发的是什么，server就反过来解析即可。

一个server 绑定两个端口怎么写啊,求大神回复啊

接收到的是一串二进制，假设指针p指向这串二进制，直接用（struct s *）p取出结构体，然后访问结构体成员不就行了吗。

简单的可直接转换二进制，但是要求struct必须是pod类型，并且需要注意大小端问题。

一般在实际项目中，都要做消息序列化与反序列化


Question: 热烈庆祝本人受关注人数即将突破12000大关！散分！！

大佬。。。。。。。。

我刚接触这个，还有很多不懂，希望能有人指点我。我可能问题比较多，因为菜了点，希望能加我微信，嘻嘻

第一次进CSDN 默默试试

这真的是新手乐园吗到处都是大佬

大神牛逼~已关注！！！

赵老师，程序出现问题了，可以请教您吗？

去年的了？

膜拜大神……………………

赵4老师，能否帮忙看下C++托管类的问题？  谢谢！  C#调用C++托管类出现not supported by the language的错误。 问题链接https://bbs.csdn.net/topics/392487346

分数有点少了

关注赵四老师

在网上回答问题的，是赵老师的AI机器人吧！

才开始学c，希望给力，啦啦啦


Question: 看了好久，代码运行结果还是不对，请问有人知道为什么吗？

#include <stdio.h>  #include <stdlib.h>    int main()  {      int number,i;      float *score,*p;      float total_score=0,average;      printf("How many students?");      scanf_s("%d",&number);      score=(float *)malloc(number*sizeof(float));      p = score;      //或者score=(float *)calloc(number,sizeof(float));      if(score==NULL)      {          printf("Not enough memory.");          exit(1);      }      for(i=0;i<number;i++)      {          scanf_s("%f",score);//scanf_s("%f",score[i]);经测试不能这样输入          total_score+=*score;          score++;//改变指向的地址      }      average=total_score/number;      printf("Average score=%.2f\n",average);      free(p);//释放不能是score 因为score地址已经变了      return 0;  }

for(i=0;i<number;i++)    {                 scanf("%f",score);                 total_score+=score[i];          score++;                         } //score是一个float指针变量，指向malloc分配的一块内存的首地址。你的整个程序没有指针++的操作，score一直指向首地址 //输入的值不断的覆盖之前的数值

scanf("%f",score); 这句话，你赋值的时候一直都是在给首地址赋值，而没有使用后面的空间啊


Question: 请问，mysql 分页语句怎么写，本人网站数据超出60W，数据表已经单3G多，一次读取每次都耗尽内存，所以我现在想请各位大婶帮个忙，

select ... limit m, n


Question: 数组下标的最大值

在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 容量大小从小到大：栈≤全局数据≤堆≤文件≤硬盘≤磁盘阵列≤云存储 当程序需要使用比如2GB～1TB左右的存储时，最简单的办法恐怕得是用文件读写模拟内存读写了吧。windows参考_fseeki64函数，linux参考fseeko64函数。 FILE *fA;fA=fopen("A","rb+");_fseeki64(fA,10000000000i64*sizeof(int),SEEK_SET);fputc(fA,0);//int A[10000000000]; int B; _fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fread(&B,1,sizeof(int),fA);//B=A[9999999999]; _fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fwrite(&B,1,sizeof(int),fA);//A[9999999999]=B; fclose(fA);  在现实世界中，除时间和空间可能是无限的以外，其它任何事物都是有限的。

每个函数调用都有一个栈帧，里面存储局部变量和返回地址，栈帧大小可以由编译器设定，但不能超过系统的最大值，一般1M。要使用大的内存空间，就要用new或malloc申请堆内存。

你这样定义数组，建议不要在嵌入式设备上运行你的程序。

引用 2 楼 taodm 的回复:你开这么大的数组得到是学编程呢还学折腾？ 只是觉得对栈，堆，32，,64程序的一些东西还不了解，感觉和那些有关

引用 1 楼 user-6 的回复:栈空间太小了。 通过编译器设置了栈空间为536870912*4*8+了已经，不管设置多大都会有这个问题

引用 3 楼 u013069997 的回复:因为栈空间是有限的，并不是无限大。如果你是用new  malloc 申请的空间就可以这么大的  但是通过编译器设置了栈保留大小为536870912*4*8+了啊？

你开这么大的数组得到是学编程呢还学折腾？

栈空间太小了。


Question: 求教大神这个为什么答案错误

首先，你问的问题都没有表达清楚，你应该是自己写的一个代码，实际输出结果错误，想要知道错误原因吧？  下面我自己写的代码，经检验无问题，你参考一下看看你自己错哪里了 #include <stdio.h>  int main(){        float  p,q,temp;       int i, j;             //i表示班级最少人数，j表示及格人数       int k = 0;        for(i=1; ;i++){             for(j=1; j<i ; j++){                  temp = (float) j  / (float) i ;     //这里是关键，不能使用整型数据直接进行除法                  if(  temp*100 >p  && temp*100<q )  {k=1;  break;}             }             if( k==1) break;         }       printf("%d %d\n",i,j);        return 0; }

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

#include<stdio.h>  int main() {     float p,q;     int i;      scanf("%f%f", &p, &q);     for(i = 1; ; i++) {         if((int)(i*q/100.0)-(int)(i*p/100.0) == 1) {             printf("%d\n",i);             break;         }      }      return 0; }  代码通过了你的测试用例，能够获得想要的结果。有些地方做了微调，参考一下吧

什么意思呢，看不到题目


Question: 大家好，请问指针的p+i和p[i]有什么区别

p+i表示指针p向“后”偏移i后的指针 p[i]一般表示数组的第i个元素

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

p+i表示指针偏移一定的单位，偏移的单位=sizeof(*p) * i

引用 2 楼 coverlo 的回复:我懂了 p[i]中存放的是变量， p+i 是一个指针， 所以p[i] ==*(p+i)      p+i中存放的是p[i]的地址 +++ 就是这样的理解～

p+i是一个指针 p[i]是一个数组的元素，和*（p+i）是一样的，只是写法不同，这里的一样是完全一样，即产生的机器码相同

引用 2 楼 coverlo 的回复:我懂了 p[i]中存放的是变量， p+i 是一个指针， 所以p[i] ==*(p+i)      p+i中存放的是p[i]的地址  p + i 的结果代表p指针先前移动多少位置，所以得到的依旧是指针 p[i] 是取从p开始的内存，第 i 个位置的值

p[i]  => *(p+i)


Question: 关于二叉查找树的问题

free(T);这样肯定有问题啊。你本来是要构造，那你把节点所指空间都释放了还怎么玩呢

#include <stdio.h> #include <stddef.h> #include <stdlib.h>  #ifndef _Tree_H  struct TreeNode; typedef struct TreeNode *Position; typedef struct TreeNode *SearchTree;  void MakeEmpty (SearchTree *T); /*  * Position Find( int X, SearchTree T );  * Position FindMin( SearchTree T );  * Position FindMax( SearchTree T );  * SearchTree Insert( int X, SearchTree T );  * SearchTree Delete( int X, SearchTree T );  * */ #endif /*_Tree_H*/  struct TreeNode {     int Element;     SearchTree Left;     SearchTree Right; }; SearchTree MakeEmpty2(void) {     SearchTree T;     int data;      printf("Please input data: \n");     scanf("%d", &data);      if (data == -1) {         T =  NULL;     } else {         T = (SearchTree)malloc(sizeof(struct TreeNode));         T->Element = data;         T->Left = MakeEmpty2();         T->Right = MakeEmpty2();     }      return T; }  void MakeEmpty (SearchTree *T) {     int data;     printf("Please input data: \n");     scanf("%d", &data);      if (data == -1) {         *T =  NULL;     } else {         *T = (SearchTree)malloc(sizeof(struct TreeNode));         (*T)->Element = data;         MakeEmpty(&((*T)->Left));         MakeEmpty(&((*T)->Right));     } }  int visit(SearchTree T) {     return T->Element; }  // 先序遍历 void preOrderTraverse(SearchTree T) {     if(T)     {         printf("data = %d\n", visit(T));         preOrderTraverse(T->Left);         preOrderTraverse(T->Right);     } }  // 中序遍历 void inOrderTraverse(SearchTree T) {     if(T)     {         inOrderTraverse(T->Left);         printf("data = %d\n", visit(T));         inOrderTraverse(T->Right);     } }  // 后序遍历 void postOrderTraverse(SearchTree T) {     if(T)     {         postOrderTraverse(T->Left);         postOrderTraverse(T->Right);         printf("data = %d\n", visit(T));     } }     int main( void ) {     SearchTree T;     /*     //T = (SearchTree)malloc(sizeof(SearchTree));     T = (SearchTree)malloc(sizeof(struct TreeNode));     T->Left = NULL;     T->Right = NULL;     */     MakeEmpty(&T);     preOrderTraverse(T);     return 0; }  demo作为一个参考吧

引用 5 楼 pengzhixi 的回复:1. 分配的大小应该是 sizeof( struct TreeNode )，而不是sizeof( SearchTree ) 你是要分配一个结构体大小，而不是一个指针大小的内存。 2. 分配之后需要将那段内存清零，否则你那个递归构造T->Left， T->Right可能由于内存不干净而导致非法访问 哦，我还以为使用typedef后两个就等价了。。。 分配后的内存清零是使用 free()函数吗？在什么地方使用啊，不是很懂这个。。。

引用 3 楼 qq_36230830 的回复:[quote=引用 2 楼 user-4 的回复:] 没仔细看 ....  T = malloc( sizeof( TreeNode ) )SearchTree与TreeNode指的不是一个东西吗？ 我换了以后编译不通过 报错信息： [Error] 'TreeNode' undeclared (first use in this function) [Note] each undeclared identifier is reported only once for each function it appears in [/quote] 改成这样：T = (SearchTree)malloc( sizeof(struct  TreeNode ) ) ;

引用 2 楼 user-4 的回复:没仔细看 ....  T = malloc( sizeof( TreeNode ) )SearchTree与TreeNode指的不是一个东西吗？ 我换了以后编译不通过 报错信息： [Error] 'TreeNode' undeclared (first use in this function) [Note] each undeclared identifier is reported only once for each function it appears in

#include <stdio.h> #include <stddef.h> #include <stdlib.h>  #ifndef _Tree_H  struct TreeNode; typedef struct TreeNode *Position; typedef struct TreeNode *SearchTree;  SearchTree MakeEmpty (SearchTree T ); /* Position Find( int X, SearchTree T ); Position FindMin( SearchTree T ); Position FindMax( SearchTree T ); SearchTree Insert( int X, SearchTree T ); SearchTree Delete( int X, SearchTree T ); */ #endif /*_Tree_H*/  struct TreeNode { 	int Element;  	SearchTree Left; 	SearchTree Right; };  SearchTree MakeEmpty ( SearchTree T ) { 	if( T != NULL) 	{ 		MakeEmpty( T->Left ); 		MakeEmpty( T->Right ); 		free(T); 	} 	return NULL; } int main( void ) { 	SearchTree T;     T = malloc( sizeof( SearchTree ) ); 	T = MakeEmpty( T ); 	return 0; } 上面的不知怎么少了个分号。。。


Question: 1468 求一个数n以内的素数个数

引用 9 楼 sanredfish 的回复:判断一个数N是否为素数，只要判断它能否被小于N/2的素数除就可以了。而小于N/2的素数个数远小于你现在的遍历（数值越大越明显）  你的isprime函数可以这样： 建立静态一个数组，存储计算到的素数 用数组里小于N/2的所有素数依次去除N，判断是否能够整除。如果有能够整除的数，就退出返回非素数，否则返回素数。  素数数组可以在程序加载的时候计算，也可以在调用时候现算。 然后你的统计素数个数，就遍历去查这个数组就好，当一个元素刚好大于给出的n而前一个小于给出的数值n，它所在的位置i就是小于n的素数个数。  另外要注意的就是题目有没有限制输入的数据大小，如果较大需要考虑大数算法，思路还是一样的 。

既然你说偶数除了2以外，都不是素数，那么就可以不判断偶数 这么写： for(i=3; i <= n; i+=2)

看n的范围上限大不大，不大的话（在内存上限允许的情况下），考虑编译期建表 保证运行时间超短

#include <stdio.h>  int isprime(int t) {     int i;      if (t != 2 && !(t % 2))         return 0;      for(i = 2; i*i <= t; i++)         if (!(t % i))             return 0;     return 1; }   int main() {     int n,count,i;      while(scanf("%d",&n) != EOF && n) {         count = 0;         if(n <= 1) {             ;         } else {             count++;             for(i = 3; i <= n; i++)                 if(isprime(i))                     count++;         }         printf("Total prime is %d \n",count);     }     return 0; }  目前你的这个判断素数方法效率已经比较高了，减少判断的次数少于一半以上。 另外，素数一定是奇数，偶数除了2以外，没有一个是素数的。

试了试很多年前写的代码,  求PI(2.56E11) 大约6秒,  NTH_prime(1E10) 大约1分钟 ...   #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <math.h>  #define XPREVN		(64*1024*1024)				/**/ #define XSQRTPREVN	(8*1024) #define XPREVPI		(4*1024*1024)				/* PI(XPREVN) : 3957809 */ #define XMAXNTH		((LLong)10*1000*1000*1000)	/* NTH( 1E10 ) == 252097800623 */ #define XMAXPIN		((LLong)XSQRTPREVN * XSQRTPREVN * XSQRTPREVN)  int		*X_small_prime, X_pi_small_prime; int		*X_pi_prev_N, *X_prev_V;  #define XPREVDM		(7) #define XPREVQ		(2*3*5*7*11*13*17) #define XPREVPHQ	(1*2*4*6*10*12*16)  #ifdef _MSC_VER #pragma warning( disable : 4244 ) typedef __int64		LLong; #define LLFmt		"I64d" #else typedef long long	LLong; #define LLFmt		"Ld" #endif  static LLong phiX_p(LLong x, LLong a) { 	if (a == XPREVDM) 		return x / XPREVQ * XPREVPHQ + X_prev_V[x % XPREVQ]; 	if (x < X_small_prime[a - 1]) 		return 1; 	return phiX_p(x, a - 1) - phiX_p(x / X_small_prime[a - 1], a - 1); }  LLong phiX(LLong X) { 	LLong cubeRootX, max, len3, len2, s, i, k; 	LLong sum, p; 	 	if (X <= XPREVN) 		return X_pi_prev_N[X];  	fputc('.', stderr); 	max = (LLong)(pow((double)X, 2. / 3) + 2); 	cubeRootX = (LLong)(pow((double)X, 1. / 3) + .5); 	if (cubeRootX*cubeRootX*cubeRootX > X) 		--cubeRootX; 	len3 = X_pi_prev_N[cubeRootX];  	sum = 0; s = 0; k = max - 1; 	for (i = len3; ; ++i) 	{ 		p = X_small_prime[i]; 		if (p * p > X) break;  		s += X_pi_prev_N[k] - X_pi_prev_N[(int)((double)X / p)]; 		k = (int)((double)X / p);  		sum += s; 	} 	len2 = X_pi_prev_N[p - 1];  	sum = (len2 - len3)*X_pi_prev_N[max - 1] - sum; 	sum = len3 * (len3 - 1) / 2 - len2 * (len2 - 1) / 2 + sum;  	return phiX_p(X, len3) - sum + len3 - 1; }  void initSmallPrime() { 	char *mark = (char*)calloc(1, XPREVN / 2 + 1); 	int i, j; 	X_small_prime = (int*)calloc(sizeof(int), XPREVPI); 	X_pi_prev_N = (int*)calloc(sizeof(int), XPREVN + 1); 	X_prev_V = (int*)calloc(sizeof(int), XPREVQ + 1);  	for (i = 3; i <= XSQRTPREVN; i += 2) 	{ 		if (mark[i / 2]) continue; 		for (j = i*i / 2; j <= XPREVN / 2; j += i) 			mark[j] = 1; 	} 	X_small_prime[0] = 2; 	X_pi_small_prime = 1; 	X_pi_prev_N[0] = X_pi_prev_N[1] = 0; 	X_pi_prev_N[2] = 1; 	for (i = 3; i <= XPREVN; i += 2) 	{ 		if (mark[i / 2]) 		{ 			X_pi_prev_N[i + 1] = X_pi_prev_N[i] = X_pi_prev_N[i - 1]; 		} 		else 		{ 			X_pi_prev_N[i + 1] = X_pi_prev_N[i] = 1 + X_pi_prev_N[i - 1]; 			X_small_prime[X_pi_small_prime++] = i; 		} 	} 	free(mark);  	for (i = 0; i < XPREVQ; ++i) 		X_prev_V[i] = i; 	for (i = 1; i <= XPREVDM; ++i) 		for (j = XPREVQ - 1; j >= 0; --j) 			X_prev_V[j] -= X_prev_V[j / X_small_prime[i - 1]]; }  static LLong NTH_prime_x(LLong x); LLong NTH_prime(LLong x) { 	if (x <= X_pi_small_prime) 		return X_small_prime[x - 1]; 	return NTH_prime_x(x); }  int main() { 	int j__func = 0; 	LLong a; 	clock_t now = clock(); 	initSmallPrime(); 	printf("init time cast : %lf seconds\n", (double)(clock() - now) / CLOCKS_PER_SEC);  	while (1 == scanf("%" LLFmt, &a)) 	{ 		if (a <= 0) 			break;  		if (a >= XMAXPIN) 		{ 			printf("%" LLFmt " Out of range\n", a);			 		} 		else 		{ 			if (a <= XMAXPIN) 			{ 				now = clock(); 				printf("phiX( %" LLFmt " ) == %" LLFmt "\n", a, phiX(a)); 				printf("phiX time cast : %lf seconds\n", (double)(clock() - now) / CLOCKS_PER_SEC); 			}  			if (a <= XMAXNTH) 			{ 				now = clock(); 				printf("NTH_prime( %" LLFmt " ) == %" LLFmt "\n", a, NTH_prime(a)); 				printf("NTH_prime time cast : %lf seconds\n", (double)(clock() - now) / CLOCKS_PER_SEC); 			} 		} 	}  	return 0; }  static LLong NTH_prime_helper(LLong x, LLong xMIN, LLong xMAX, LLong piMIN, LLong piMAX) { 	LLong n, piN;  	while (1) 	{ 		if (piMIN == x) 			return xMIN;  		if (xMAX - xMIN <= 2) 			return xMAX;  		n = (xMIN + xMAX) / 2 + 2 * x - piMIN - piMAX; 		n |= 1; 		if (n == xMIN) 			n += 2; 		else if (n == xMAX) 			n -= 2; 		piN = phiX(n);  		if (piN >= x) 		{ 			xMAX = n; 			piMAX = piN; 		} 		else 		{ 			xMIN = n; 			piMIN = piN; 		} 	}  	return xMAX; }  static LLong NTH_prime_get_upper(LLong x, LLong *xMIN, LLong *piMIN, LLong *piUpper) { 	LLong n = *xMIN, piN = *piMIN, xMAX, piMAX;  	while (1) 	{ 		xMAX = 1 | (LLong)(n + (x - piN + 1)*log(n)); 		piMAX = phiX(xMAX); 		if (piMAX >= x) 			break; 		n = xMAX; 		piN = piMAX; 	}  	*xMIN = n; 	*piMIN = piN; 	*piUpper = piMAX; 	return xMAX; }  static LLong NTH_prime_get_lower(LLong x, LLong *xMAX, LLong *piMAX, LLong *piLower) { 	LLong n = *xMAX, piN = *piMAX, xMIN, piMIN;  	while (1) 	{ 		xMIN = 1 | (LLong)(n + (x - piN - 1)*log(n)); 		piMIN = phiX(xMIN); 		if (piMIN < x) 			break; 		n = xMIN; 		piN = piMIN; 	}  	*xMAX = n; 	*piMAX = piN; 	*piLower = piMIN; 	return xMIN; }  static LLong NTH_prime_x(LLong x) { 	LLong initX, piINIT; 	LLong xMIN, piMIN, xMAX, piMAX;  	initX = 1 | (LLong)(1.05 * x * log(x)); 	initX |= 1; piINIT = phiX(initX);  	if (piINIT >= x) 	{ 		xMAX = initX; 		piMAX = piINIT; 		xMIN = NTH_prime_get_lower(x, &xMAX, &piMAX, &piMIN); 	} 	else 	{ 		xMIN = initX; 		piMIN = piINIT; 		xMAX = NTH_prime_get_upper(x, &xMIN, &piMIN, &piMAX); 	}  	return NTH_prime_helper(x, xMIN, xMAX, piMIN, piMAX); }

Finding prime numbers - Kenneth Haugland  Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers

求 PI(N) 复杂度可以到 O(N^(2/3)),  现在的机器 1秒应该可以求出 100亿左右,  简单点筛法大约在 O(N*lnln(N)) ..

这段代码系统显示时间过长，还有没有减少时间复杂度的方法，多谢指导

筛法....


Question: c语言 如何让数在一行中不断变化

console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309

在linux终端下控制光标位置： http://blog.csdn.net/kevinshq/article/details/8179252 在windows命令行下控制光标位置： http://blog.sina.com.cn/s/blog_5059be880100xmpn.html

printf("Hello world!"  ); printf("\r你好世界!"  ); printf("\b你好世界!"  ); 试试这个代码

没看懂楼主的问题，若楼主需要不用其他变量来覆盖原先固定的数值，可以用到ASCII码的自加。 你说的用这个思路写贪吃蛇是什么意思，用数组来代替蛇的长度？

在控制台让后面的数据覆盖前面的，系统默认貌似实现不了吧，用界面做会简单很多，比如MFC QT

这就是一个控制台版本的贪吃蛇

你得在变换之间加 pause (sleep 比如），要不太快了你看不到变化过程。


Question: C语言求助

谢谢了，是return ret；

char* ret = dst;  assert(dst && source);  while((*dst++ = *source++) != '\0');  return dst;  作为返回值，这样子就可以使用链式表达式了  因为复制dst的时候自增，导致最后dst的指向不是原来的地址，所以需要一个临时的变量记录首地址以作返回


Question: 初学者关于数据结构中的插入算法

#include <stdio.h> #include <stdlib.h> #include <stdbool.h>  #define MAX_SIZE 100  typedef int Data;  //顺序表的数据类型 typedef struct {     Data data[MAX_SIZE];     int last; }Seqlist,*pSeqlist;  //创建空的顺序表 Seqlist* creat(void) {     pSeqlist L = (pSeqlist)malloc(sizeof(Seqlist));      //分配空间失败     if(!L) {         printf("malloc fail\n");         return NULL;     }      //分配空间成功，初始化为空表     L->last = 0;      return L; }  /*  功能：插入数据     参数：L  待插入的顺序表     ipos  插入位置，从0开始     e  待插入的数据     返回值：true  插入成功     false  插入失败     */ bool insert(pSeqlist L, int ipos, Data e) {     int i;     //ipos无效     if(ipos < 0 || ipos > L->last+1) {         printf("ipos无效\n");         return false;     }      //顺序表满     if(L->last >= MAX_SIZE-1) {         printf("顺序表满，无法插入\n");         return false;     }      //为待插入数据e腾出ipos的位置并插入     for(i = L->last; i >= ipos; i--) {         L->data[i+1] = L->data[i];     }      //将数据e存储在ipos位置     L->data[ipos] = e;     (L->last)++;     return true; }  int main() {     int i, j;      pSeqlist ph = creat();     for(i = 0; i < 10; i++) {         insert(ph, i, i);     }     insert(ph, 5, 128);     for(j = 0; j < 11; j++) {         printf("%d\n", ph->data[j]);     }     return 0; }  /* 这一段代码觉得从没执行过，last的初始值为-1，有些不太理解 for(int i=L->last;i>=ipos;i--) {     L->data[i+1]=L->data[i]; } */  程序没问题，我将maxsize改成了MAX_SIZE，建议宏使用大写。

for(int i=L->last;i>=ipos;i--) { L->data[i+1]=L->data[i]; } 这段代码执行了一次，应该是对第一个数据赋值吧

谢谢，问题已经解决了

Rebuild之后再试试，我这里测试没有出现这个问题


Question: linux   C语言   函数返回值

一样的，如果你不需要返回值，可以用while( fgetc(fp) != EOF)，如果需要，那么就用上一个形式

判断的结果是一样的  while（（ch = fgetc(fp)）  != EOF） 的含义是先把fgetc(fp) 赋值给 ch，保持 ch 是最新读入的字符 那么在while {} 中你就可以用 ch 这个变量去知道刚读入的字符是什么


Question: 关于toupper函数的一个疑问

原型：     extern int toupper(int c); 用法：     #include <ctype.h> 功能：     将字符c转换为大写英文字母 说明：     如果c为小写英文字母，则返回对应的大写字母；否则返回原来的值。

toupper的返回值才是变成大写后的值  而参数是通过值传递的，函数中使用的都是一个复制后的值，ch又怎么可能变化

返回值才是返回大写字母，参数本身是不会改变的

仅仅 toupper(ch) 只是得到一个值，后面如果是 switch(ch)，则比较的依据如果是 ch，前面应该把大写的字母存回到 ch，即把 toupper(ch); 改成 ch = toupper(ch); 就行了


Question: 求素数问题。

for( x=n; n <= m; x++ )             {                 int i, isprime = 1;                 for(i=2;i<x;i++)  直接从n开始，加个calculate纯属多余

#include <stdio.h>  int main(void) {      int i, j;     int m,n,sum;     int isprime = 1;      sum = 0;     scanf("%d%d", &n, &m);      for(i = n; i <= m; i++) {         isprime = 1;         for(j = 2; j < i; j++) {             if(!(i % j)) {                 isprime = 0;                 break;             }         }         if(isprime) {             if(j >= i){                 sum++;                 printf("%d is prime!\n", i);             }         }     }       printf("total number = %d\n", sum);      return 0; }  代码变量有点乱～ 这是我的一个demo，你可以参考一下

n和m是表示第n个素数，i是第n个数，x是数，x和n以及m并没有直接的联系

首先你这程序的意思是找到2到n之间所有的素数和，和你给的题意不符。你可以先建一个表，列出足够数量的所有素数


Question: 帮我纠正一下我哪里做的不完善。

Finding prime numbers - Kenneth Haugland  Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers

用打表法，先直接算出200个素数，然后累加就行了

将第13行去掉。不然当n==1的时候，会算多一个2.

你试试1   2就知道了。  边界问题

我提两点： 1.使用自定义函数，能使代码阅读起来更清晰，都放在main函数里，还不加一些注释，读起来稍微费劲（再加上格式不整齐）；如果代码复杂一些，读起来更是不舒服； 2. 判断素数的效率，主要看一下循环次数，明显下一个程序的循环次数小于上一个程序的循环次数。循环次数差距至少是2备以上。

好像是n=1的时候有问题吧，是不是把2算了两次啊？手头没有编译器，你自己确定一下

引用 1 楼 qq423399099 的回复:多测试一些极端，边界情况  条件范围内，正确啊

多测试一些极端，边界情况


Question: 用memset初始化二维数组

代码如下：  #include <iostream> #include <stdlib.h>  using namespace std;  void  test_memset_for_c() { #define nrows 100 #define ncolumns 100 	int** array1 = (int**)malloc(nrows * sizeof(int *)); 	for (int i = 0; i < nrows; i++) 	{ 		array1[i] = (int*)malloc(ncolumns * sizeof(int)); 		memset(array1[i], 0, ncolumns * sizeof(int)); 	}  }  void  test_memset_for_cpp() { #define LEN 100 	int arr[LEN][LEN]; 	for (int i = 0; i < LEN; i++) 	{ 		memset(arr[i], 0, LEN * sizeof(int)); 	} }  int main() { 	cout << "Hello World!" << endl; 	test_memset_for_c(); 	test_memset_for_cpp(); 	return 0; }

引用 5 楼 love_QJP 的回复:[quote=引用 4 楼 paschen 的回复:] memset(a, 1, sizeof(a)) 这样我试了  不对[/quote]  你别对参数这样子用，别对退化为指针的数组用。

要for循环来memset二维数组,目前手机打字，后天上班了给你弄。

for (){  for() {   a[i][j]=1;  } }

只有char型才可以，可以用fill

引用 4 楼 paschen 的回复:memset(a, 1, sizeof(a)) 这样我试了  不对

memset(a, 1, sizeof(a))

memset 是按字节来操作的, 如果 a 的类型是 char 就可以, memset(a, 1, 100 * 100) 就行了

能不能用memset把二维数组初始化为1

解释的清楚一点


Question: 借用缓冲区溢出重写返回地址，跳到编写的shellcode却提示no line number infomation?

调用约定 https://msdn.microsoft.com/zh-cn/magazine/9b372w95.aspx

这里什么功能

no line number information倒是没什么好奇怪的，毕竟这个地址的code是你填充的，不是由源文件编译得到的； 问题在于下面的SIGSEGV，个人的第一反应是这shellcode能正确工作？


Question: 求大哥们教教小弟二级C遇到的问题，不耽误大哥多少时间的。

引用 4 楼 user-1 的回复:啊呀，不好意思 循环条件while(tmp!=end)改成while(tmp<=end),用你的数据试试吧，应该没错了。  谢谢前辈指导，感激不尽。没什么可以回报的，唯有祝福前辈新的一年里平平安安，心想事成！

引用 1 楼 user-1 的回复:#include<stdio.h> #include<string.h> void test(char* s) { 	char* tmp=s; 	char *end=tmp; 	while(*end!='\0') 	end++; 	 	end--; 	 	while(tmp!=end) 	{ 		char t=*tmp; 		*tmp=*end; 		*end=t; 		 		tmp++; 		end--; 	} } int main(void) { 	char s[]="hello world"; 	test(s); 	printf("%s",s);  }   希望对你有帮助，代码写得挺简陋的。   没有没有，前辈百忙中能帮小弟的忙，就是对小弟最大的帮助了，更别谈代码的问题了。只是小弟斟酌再三，进行了调试后，还是有些微的不足之处。不知是不是小弟的电脑出现了问题，运行后的程序答案是对的，但似乎进入了循环，报错了。不知前辈运行的时候有没有出现类似的问题。小弟能力有限，调试后发现的问题，地址的问题。因为水平问题，就不说愚见了。如果前辈看到小弟的回复，百忙中能帮小弟再看看问题，小弟实感荣幸之至。谢谢！


非常感谢楼上两位,问题解决了,原来是语法错误哈哈

虽然不是很懂你想说什么。帮你改了两个错误。加黑的地方。 #include<stdio.h>  char * substr(char *s,int pos,int len)  {   int i;   char *start,*mid,*end;   for(i=0;i<pos-1;i++)   {     s++;   }   start=s;              //找到子串的首地址   for(i=0;i<len+1;i++)   {     s++;   }   mid=s;               //找到子串的末尾字符的下一个地址，在这里打算插入'\0' while(*s!='\0')    s++;   end=s;               //找到整个字符串末尾+1的地址    for(s=end-1;s>=mid;--s)   *(s+1)=*(s);   *s='\0';    return start;  }  int main(void)  {   int pos=10,len=11;   char *p;   char s[50]="shanghai a beautiful city";   p=substr(s,pos,len);   while(*p!='\0')   {     printf("%c",*p); p++;    }   printf("\n");   } 运行结果：

里面破坏了源字符串 main 用的时候源字符串是一个常量字符串, 不可写的, 里面进行写操作就会出错


Question: 想列出从2开始的一共200个素数，x未知。自己写的程序运行没有输出，麻烦请指教下。

谢谢，你真利害

#include <stdio.h>  int main(void) {       int calculate=1, x;       //200？应该从1开始      //while(calculate<=200)    //外层while不需要      //{             for( x = 2; calculate <= 200; x++ )    //把200作为结束条件             {                 int i, isprime = 1;   //isprime放在for里面，每次开始判断前都要重置这个数                  for(i=2;i<x;i++)   //不要等于，不然x%i最终都会等于0                  {                     if(x%i==0)                     {                         isprime=0;                         break;                     }                 }                 if(isprime==1)      //if也要放在for里                  {                     printf("%d,%d\n",calculate,x);                     calculate++;                 }             }     //}     return 0; }


Question: apue中的一个小程序的疑惑，请教大家

printf("parent sleep ?");里面加个换行符吧。

仅供参考：//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

24行，赋值运算优先级小于比较运算，所以要加括号


Question: 请教一个问题大神们

你一旦调用了int b()函数就执行了这个函数所有的语句不论调用的是不是赋值语句。当然也执行puts("ppp");这个语句。

只要你调用了函数,那么这个函数就会执行它自己函数内部的指令,包括在返回之前的输出.你可以理解这个函数返回VOID 那么是不是要输出PPP

楼主，程序不是只在主程序里跑的，choice=menu();这句会调用menu()这个函数的，也就是会执行里面的代码，所以里面的输出语句就都输出了啊

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

choice=menu(); 会执行menu()这个函数，最后menu()函数的返回值会赋值给choice。

puts("ppp"); 输出了ppp这几个字符

大神们 能理解我的意思么？？choice=menu（）这是一个赋值语句啊，只是赋一个结果给choice。 往下这句choice==2  report（），这句话我就理解

你们好像没太理解我意思，这是书上一个例题。打印一个菜单 #include<stdio.h> #define QUIT 3 /*函数原型*/ int menu(void); void report(void); int main(void)/*主函数开始*/ { 	int choice=0; 	printf("\"We\'d like to  you to the meun\"\n"); 	printf("Are you ready to make a choice \?\n"); 	while(choice!=QUIT) 	{ 		choice=menu(); 		if(choice==1)  			printf("\nBeeping"); 		else 		{ 			if(choice==2) 				report(); 	}} 		printf("you chose to quit\n"); 		return 0; 	} 	int menu(void) 	{ 		int a=0; 		do 		{ 			printf("\n"); 			printf("\n1-BEEP"); 			printf("\n2-display"); 			printf("\n3-quite"); 			printf("\n"); 			printf("\nentr a selectin:"); 			scanf("%d",&a); 		}while(a<1||a>3); 		return a; 	} 	void report(void) 	{ 		printf("\nsample report"); 		printf("\n\nseq"); 	}/*结束*/ choice=menu()是不是把menu函数的返回值赋给choice，应该返回的是1或者2，但是程序会把menu函数里的菜单打印出来，我不理解为啥会打印菜单，主程序也没有这个功能啊。

return的返回是不会打印在屏幕上的，不知题主怎么确定它的返回值是ppp的，puts语句就是类似printf打印语句一样的。所以楼主看到的ppp是puts语句打印在屏幕上的。楼主理解不？

楼上正解， 代码可以这样修改：  int b(); main {int a; a=b(); } int b() {int c; puts("input:"); scanf("%d",&c); return c;}

什么叫“还带着ppp”？ ppp 是输出到屏幕的一个字符串，跟返回值没关系。 如果把“ppp”换成“请输入一个数字：”是不是容易理解一些？


Question: 请问为什么会有这个警告？见图，谢谢

因为你第6个参数是int*类型的，如果要输出指针的地址，可以用%p，如果要以十进制方式输出，可以输出时强制转换成int，这样就不会有警告了

j本来就是数组的首地址，取地址+1然后解引用

j 是 int * 型 &j 是 int ** 型 &j + 1 是 int ** 型 *(&j + 1)  是 int * 型

为什么警告说*(&j + 1)是int *类型的？明明是int类型啊


Question: C语言问题

你的程序思路不对  仅用不超过10个的变量  我来说下思路吧 首先,因为是从高位算起,所以你需要一个变量H来存储上次高位的数之和,还需要一个变量C存储本次输入的2个数字之和 首先H置0  H=0 1 录入本次2个数字,并且计算出和C 2 如果本次之和C大于10,那么上次2个数之和H需要++ ,并且本次数C-=10 3 输出上次高位计算的和H,并且将本次的和存入H   H=C 3 如果数字全部输入完成就输出H,否则继续1

谢谢zzzz

当N是123456时，k多大？s可能有多大？你程序中的变量存不下这么大的数


Question: 结果不对，那错了。

#include <stdio.h> #include <ctype.h> #include <string.h> /* for strlen*/  #define MAX_LEN  4 /* 0: character, 1: digit, 2: space, 3:other*/ #define MAX_STR_LEN 128  int cnt[MAX_LEN];  void count(char *src, int cnt[]) {     int i;      for (i = 0; src[i]; i++) {         if (isalpha(src[i]))             cnt[0]++; /* charaters */         else if (isdigit(src[i]))             cnt[1]++; /* digits */         else if (isspace(src[i]))             cnt[2]++; /* space */         else             cnt[3]++; /* others */     } }  int main(void) {     char str[MAX_STR_LEN] = { 0 };      fgets(str, MAX_STR_LEN-1, stdin);     str[strlen(str)-1] = 0;      count(str, cnt);      printf("英文：%d, 数字：%d, 空格：%d, 其他: %d\n", cnt[0], cnt[1], cnt[2], cnt[3]);     return 0; }  循环调用计算函数这样效率不高，如果能调用一次而实现计算所有的字符，那么就一次实现。 以上是我的想法，可以参考一下。

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

for(int i  = 0; i < 4; i++){ //这的代码会循环 4 次 }  你的代码问题太多，多改改吧。比如 if(h>='a'&&h<='z'||h>='A'&&h<='Z') 或操作两边是不是该用括号括起来？ y=y++; 一般是写成y++;


Question: c语言中链表操作文件问题：修改或删除文件某一内容

如果要提高效率，要用到类似数据库的逻辑删除好了 在数据记录上设置一个标记， 表示是否有效 如果删除了， 把这个标记比如0改成1， 文件大小不变， 不影响前后的内容 直接定位写就好了

我现在遇到的情况和你一样    想通过链表实现对文件数据的修改

引用 7 楼 paschen 的回复:如果你要提高效率，需要定制合理的文件存储方案，使得可以直接移动文件指针，读取需要的部分并进行修改/删除，而不必重新  [quote=引用 5 楼 qq352642663 的回复:] [quote=引用 3 楼 paschen 的回复:] 如果你要提高效率，需要定制合理的文件存储方案，使得可以直接移动文件指针，读取需要的部分并进行修改/删除，而不必重新全部读入修改再保存 是不是使用fseek和ftell函数就可以实现？[/quote]  是的[/quote]  好牛的

如果你要提高效率，需要定制合理的文件存储方案，使得可以直接移动文件指针，读取需要的部分并进行修改/删除，而不必重新  引用 5 楼 qq352642663 的回复:[quote=引用 3 楼 paschen 的回复:] 如果你要提高效率，需要定制合理的文件存储方案，使得可以直接移动文件指针，读取需要的部分并进行修改/删除，而不必重新全部读入修改再保存 是不是使用fseek和ftell函数就可以实现？[/quote]  是的

引用 2 楼 Potato_Lyy 的回复:所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。http://bbs.csdn.net/topics/391975224谢谢，你分享的方法好像合适，

引用 3 楼 paschen 的回复:如果你要提高效率，需要定制合理的文件存储方案，使得可以直接移动文件指针，读取需要的部分并进行修改/删除，而不必重新全部读入修改再保存 是不是使用fseek和ftell函数就可以实现？

引用 1 楼 loneking2001 的回复:1 重新保存文件就行了； 2 （1）就是最好的办法，除非文件超级大，大到需要自己开发文件系统的程度，可以通过直接写硬盘的方式解决。比如 Oracle 数据库就可以直接访问硬盘分区，比访问数据库文件效率高些。 目前只是学了c语言然后想用结构体和文件操作等知识来实现一个管理系统而已。所以暂时不会用到数据库。 我的疑惑只是不知道如何使用文件操作函数来修改或者删除文件。 所以我想到了两种实现方式： 1.直接操作文件修改或者删除文件中的内容 2.将文件中的内容读入链表再进行修改删除，然后覆盖原文件。  请问哪种实现方式可行？具体思路是怎么样的呢


Question: 求教一下这个问题用c语言怎么实现的

引用 1 楼 user-5 的回复:我没分了，怎么办 听说每天回帖可得10分。

引用 5 楼 kellen_ 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] [quote=引用 1 楼 user-5 的回复:] 我没分了，怎么办 听说每天回帖可得10分。[/quote] 我想问问题也没分。。。。都不可以用钱冲[/quote] 难道CSDN不欢迎富二代？ 打钱给CSDN的版主，让他给你充！

引用 3 楼 zhao4zhong1 的回复:[quote=引用 1 楼 user-5 的回复:] 我没分了，怎么办 听说每天回帖可得10分。[/quote] 我想问问题也没分。。。。都不可以用钱冲

引用 1 楼 user-5 的回复:我没分了，怎么办  每天回帖即可获得10分可用分！小技巧：教您如何更快获得可用分 你还可以输入10000个字符

简单点的说就是：前行*后列再相加 int a[2][3];//矩阵1 int b[3][3];//矩阵2 int c[3][3];//新矩阵 c[0][0]=a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0];//c矩阵的第一行第一列元素 c[0][1]=a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1];//c矩阵的第一行第二列元素 //以此类推，即可得到A(2*3)*B(3*3)的结果C(3*3)

我没分了，怎么办


Question: 对于这段代码，为什么只声明了一个一维数组，却能fgets输入多个字符串到该数组？程序运行时的内存、缓冲区是怎样使用的？

如同记分牌，改变每个分数的值（这里是改变没 bit  的0和1）

因为每一次输入都是存到同一个字符数组中，下一次的输入会覆盖上一次的

就是那一块连续的内存，下一次的循环得到的字符串会覆盖上一次的内存。

分时复用


Question: C语言快速排序

引用 3 楼 Potato_Lyy的回复:快速排序可见: http://m.blog.csdn.net/article/details?id=6684558  http://developer.51cto.com/art/201403/430986.htm 这是两个网站注意分开一下

int partition(int a[], int p, int r)就是把a数组下标范围为p到r的元素分成两部分，然后返回枢轴的下标，结果是枢轴前面的都小于枢轴元素，枢轴后面的都大于枢轴元素。这里用第一个元素（下标为p）作为枢轴，也就是比较标准， while(i<r && a[++i]<x);是找到从左边起第一个大于等于x的数（不能越界，所以有i<r）， while(a[--j]>x);是找到从右边儿起第一个小于等于x的数（最左边儿有x，不会越界），然后将这两个数交换，然后继续找，直到左边儿的都小于x右边儿的都大于x，然后通过swap(a,p,j);把x（还在第一个位置）放到中间来，最后返回x的下标 大概就是这个样子吧，你举个例子跑一遍就明白了，或者去找一篇关于快速排序的博客看看


Question: 字符串输入停止工作，加上取地址符号就能跑了，求大神指导指导

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];

这是二维数组

还可以写成你可以写成scanf("%s %s %c",a[i],b[i],&c[i]);  %s 和 %c 叫做格式控制符，需要和后面的变量一一对应

因为c是一维数组，c[i]代表的是一个字符，不可以这么写，  而c是一个一维数组，c代表这个数组的首地址，所以你可以直接写c，  a，和b是二维数组，a[i],b[i],代表的还是数组，相当于是数组的首地址，所以不需要加&。  输入的语句应该是这样：  你可以写成scanf("%s %s %s",a[i],b[i],c);

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

不管是%c还是%s都需要地址与其匹配 c[i]代表的是一个字符，必须取地址才行

scanf中性别的输入需要地址符，&c[i]或者c+i；

这个问题要说明白比较费劲，跟C语言指针和数组的转化有关，如果是新手你会用就可以了 a和b是二维数组，所以a[i]是一个行指针char(*)[21]，而scanf函数%s对应的实参要求类型为char*，这两种类型是可以隐式转化的，所以没有问题，而且你加了取址符&也没有问题，因为这里无论取多少次地址其类型也不会改变 c是本身是一个数组，但%c对应的也是一个char*，c[i]是一个char类型，必须加取址符&才能转化为char*类型

只有c[i]前需要取地址符号 因为a[i]、b[i]已经是能存放20个字符字符串的字符数组了 c本身才是字符数组，c[i]只能存单个字符

c[i] 改成 &c[i]  scanf要的是buffer的地址


Question: (*p)或者*p,怎么都是p->num?

给赵4老师点个赞，

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

注意.和*的优先级，如果不确认优先级那就使用括号！

注意.和*的优先级 http://www.jb51.net/article/37282.htm

p是一个指向结构体的指针是吧，那(*p).num和p->num是等价的，而因为结合性的问题，*p.num的意思是*（p.num），即只有num是一个指针而p是一个结构体变量时才应该这么用

(*p).num 与 p->num 等价，通常写成后者  *p.num  实际是 *(p.num)


Question: C语言实例资料

引用 5 楼 ck2333的回复:http://bbs.csdn.net/topics/350132261?locationNum=7&fps=1 楼主可以根据自己的需要自己进行选择。 感谢！看来c三本圣经是必读的啊。

后三本实例，前面参考书一起发了。

引用 1 楼 user-2的回复:C Primer Plus  C语言程序设计：现代方法：第2版(被誉为"近10年来最好的一部C语言著作") C和指针 或者谭浩强《C程序设计》 以上任选一本就差不多了，以下为参考书： 《深入理解C指针》 《C陷阱与缺陷》 《C专家编程》 《C语言点滴》 《C语言课程设计案例精编》 C语言程序开发范例宝典 C语言经典编程282例 在看《C专家编程》,里面似乎并没有很多实例，不过还是值得一看，准备再去了解一下你说的其他书籍，感谢回复。

引用 1 楼 u010165006 的回复:《C语言课程设计案例精编》 C语言程序开发范例宝典 C语言经典编程282例  TC（Turbo C）老代码（小游戏）最好看懂了以后，理解了算法和过程，用VC改写成Windows平台的。   楼主如果想用C玩玩图形、小游戏编程，可以了解一下EasyX，EasyX是Windows平台最简单的绘图函数库（名副其实），兼容BC和TC的绘图函数，在VC下用EasyX来编程跟在TC下编程绘图差不多是完全一样的。EasyX既可以绘图，也支持图像显示和处理。  下载一个EasyX包，里面有完整的函数手册EasyX_Help.chm，有示例。EasyX官网有很多网友上传的实例，包括游戏。  仅供参考： 用绘图语句画机器猫（初学C语言的同学必看） http://blog.163.com/tab_98/blog/static/1192409720150316223680/


Question: 大家好，在做一个小工具的时候遇到了麻烦。

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。

直接用sprintf+system调用ren

引用 2 楼 u010165006 的回复:用sprintf加一个int变量构造文件名。  非常感谢！！！！我百度了好一会你说的那个sprintf，我也自己实验了几次，成功了！！！非常感谢

引用 2 楼 u010165006 的回复:用sprintf加一个int变量构造文件名。  我好像理解你什么意思了，就是用你的放噶构造一个字符串出来，但是在那个rename里面的参数要怎么写呢？刚接触没多长时间，有点不懂。麻烦了。

引用 2 楼 u010165006 的回复:用sprintf加一个int变量构造文件名。  ee，，不好意思哈，，没太看懂，，能把rename那句给写一下示范么？感激不尽

用sprintf加一个int变量构造文件名。

麻烦大家帮忙看一下  ，谢谢了


Question: 求教，怎么在窗口上显示一个网页！

感谢感谢!!!

你是用C++吗？要看你使用哪种框架，比如VCL、MFC，都有各自的控件，不是单一DLL的问题。  VCL是C++ Builder使用的框架，图形用户界面可以学习C++ Builder，架构先进，入门比较容易。  C++ Builder的较新版本——RAD Studio XE3以上版本添加对iOS和Android的支持工具包，让开发者编写的Delphi/C++应用可以同时在Windows、OS X、iOS和Android平台上运行。现在最新版本是RAD Studio 10.1。  仅供参考： 初学者学习C++ Builder第一个程序（模拟聊天室），经典！ http://blog.163.com/tab_98/blog/static/11924097201693033057497/ C++ Builder绘图示例（模拟时钟） http://blog.163.com/tab_98/blog/static/11924097201611324819376/ 从C语言的菜单界面管理系统到C++ Builder的图形用户界面，一个简单的电话簿Demo例子 http://blog.163.com/tab_98/blog/static/1192409720158673337998/  C++ Builder写的《ZEC 纸牌游戏21点》 http://blog.163.com/tab_98/blog/static/119240972016115113039304/ C++ Builder写的《ZEC 僵尸版打地鼠》 http://blog.163.com/tab_98/blog/static/11924097201601084117748/ C++ Builder写的《ZEC 推箱子》 http://blog.163.com/tab_98/blog/static/11924097201612011839642/  书籍推荐： 《C++Builder 6程序设计教程（第二版）》 （陆卫忠，刘文亮　等编著 /2011-04-01 /科学出版社） 《C++Builder6编程实例精解》（赵明现），PDF，是数字版的，非扫描版的，里面还有一个俄罗斯方块游戏的完整实现。 《精彩C++Builder 6程序设计》（台湾 吴逸贤），里面有10几个简单小游戏的实现，可以自己看懂以后再重写，才是自己掌握的。 《C++ Builder 5高级编程实例精解》（刘滨 编著）都是较大的实用的程序。

浏览器控件 是哪个DLL  哪个函数，函数不知道我可以自己查，最重要是哪个DLL。

除非你想自己写个浏览器内核来解析、渲染网页。

用浏览器控件。字数。。


Question: 代码为何在慕课网上运行不了？

你把有的分号用的都是中文的全角分号，要改成英文的分号就行了

楼主的程序很简单，自己就错误提示就能知道哪里出错了~~~

在printf函数中支持全角输出~但它的ASCII码明显不同于半角的ASCII码~编译器当然不支持全角输出咯~

不要包含全角字符。一律用半角。

冒号与分号用了全角了


Question: 不知道为啥子这编译器连C primer plus里的程序清单码进去都经常处问题，现在问题说不清楚，看图吧OTZ

书上的代码是这样的 //praisel.c——使用不同类别的字符串 #include <stdio.h> #define PRAISE "What s super marvelous name!" int main(void) { char name[40];  printf("What's your name?\n"); scanf("%s",name); printf("Hello,%s,%s\n",name,PRAISE);  return 0; } 我只是将scanf()函数改为了scanf_s()函数，而且为了暂停看输出添加了getchar()函数（我只知道getchar()在之前的练习里能起到暂停的作用，具体的原理完全不知道，因为书上还没讲） 基于你上面的解释我想我应该理解了原因了，谢谢。

你是用Linux系统吗？Linux下好像fflush(stdin)无效，有另外办法。

不是第一次输入跑到下面去了，而是scanf、getchar都是从键盘缓冲区读取，缓冲区有东西getchar直接就取走了，缓冲区为空的时候才会等待键盘输入。

由于新人对ffulsh(stdin)的作用不懂，而且getchar()也只是经提点单纯想用来暂停运行中的程序而已，所以一旦按照书上的代码无法输出正确的结果就，懵逼了。

上面代码的作用其实就是取代了getchar()函数用于暂停了运行中的程序而已吧，但是问题是在第一个scanf_s()函数输入的数据跑到了下面去了，在另外一个程序我用了两个scanf_s()函数，中间不管加不加上ffulsh(stdin)，第二个scnaf_s函数都会读取到第一个函数输入空格后的参数耶？望解答

试试： printf("What's your name?\n");  scanf_s("%s",name,10); printf("Hello,%s,%s\n",name,PRAISE);  system("pause"); return 0;

还是不行，用了下分析里的对解决方案运行代码分析（表示不知道这个是啥，但是好像能看出问题是什么 得出两个警告： 严重性	代码	说明	项目	文件	行	禁止显示状态 警告	C4566	character represented by universal-character-name '\u00A0' cannot be represented in the current code page (936)	4.2	c:\users\administrator\desktop\c语言\c primer plus\示例程序\第四章示例程序\4.2\4.2\4.2.cpp	8	  还有 严重性	代码	说明	项目	文件	行	禁止显示状态 警告	C6031	返回值被忽略: “getchar”。	4.2	c:\users\administrator\desktop\c语言\c primer plus\示例程序\第四章示例程序\4.2\4.2\4.2.cpp	12	活动  第一个我看不懂，不过第二个返回值被忽略，对这个很是在意，望解答

试试： printf("What's your name?\n");  scanf_s("%s",name,10); printf("Hello,%s,%s\n",name,PRAISE);  fflush(stdin); getchar(); return 0;

这样？ //praisel.c——使用不同类别的字符串 #include <stdio.h> #define PRAISE "What s super marvelous name!" int main(void) { 	char name[40];  	printf("What's your name?\n");  	scanf_s("%s",name,10); 	fflush(stdin); 	getchar(); 	printf("Hello,%s,%s\n",name,PRAISE);  	getchar(); 	return 0; } 还是不行啊，程序依旧会一闪而过OTZ不知道是不是我fflush(stdin);加的位置不对

输入A B，A B连同回车符会进入键盘缓冲区，第一次scanf得到"A"，接着getchar();自动得到'B'，不需要再输入。 在getchar();之前fflush(stdin);清空键盘缓冲区试试。

现在的程序代码 //praisel.c——使用不同类别的字符串 #include <stdio.h> #define PRAISE "What s super marvelous name!" int main(void) { 	char name[40];  	printf("What's your name?\n"); 	scanf_s("%s",name,10); 	getchar(); 	printf("Hello,%s,%s\n",name,PRAISE);  	getchar(); 	getchar(); 	getchar(); 	getchar();//这里用了四个getchar()函数 	return 0; }

现在发现在pritnf()函数后面添加四个getchar()函数就就能正常运行，但是程序实际运行还是按一次回车键后才退出的，而不是四个。现在问题就是不知道前三个getchar()函数吞掉了什么。


Question: HDU1234 开门人和关门人，有看了下一其他些写法，但是实在不知道这样写为啥通不过 ，提交后显示的是wrong answer

蟹蟹1楼的解答 确实是这里出了问题

网上找下AC的代码吧。 1.看看你们的输入输出格式是不是一致 2.多测试一些样例

两个cmp函数最外层的else，是不是应该比较的是xiaoshi？


Question: 有关连线图的问题

在图中，a^ c^ d^ d* e^ e* 为一个ArraySingle[] = {0,4,6,7,8,9}; 每个数组的值都是一位hex数。 而组合的用ArrayDouble[] = { ... }, 每个数组的值都是两位hex数。例如 c^d*的组合在ArrayDouble中为0x45。  然后， 第一个选ArraySingle中的一个数X，再在ArrayDouble找低位数是X的2位数Y(=0xUX)，然后再获得Y的高位数U，在ArrayDouble继续找到相同高位为U的2位数，若找到则继续在ArrayDouble中找下一个，若没有找到则在ArraySingle中找最后一个2位数的低位。  以上简单说下思路，当然中间会有短路径和长路径。

a^中符号^表示什么意思呀


Question: 运行的时候没有输入字符，程序就结束了，但是程序里面有getchar函数

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

当然不会输出了。因为  c !='\n' 。当你输入回车的时候，那么就不会再继续走循环里面啦。 lim-1 && (c = getchar()) !=EOF&& c !='\n' 当键入回车键， 那么 c 就==‘\n’ 那么久不满足循环的条件。然后就程序不会走循环体内部代码。  你得吧 if(c == '\n')         {             s[i] = c;             ++i;         }         s[i] = '\0';         if(i-1 > 80)         printf("%s",s); 挪到循环外面去。  你的 这代码也有问题：s[i] = '\0';           if(c == '\n')         {             s[i] = c;             ++i;         }         s[i] = '\0';   s[i] = c;  这里先把输入的字符赋值给了 s[i]， ' 然后下面又把  s[i] = '\0'; 给复制一遍。不就清空掉buffer串了么。  楼主需要学会使用 单步调试功能啊。

确实是多了一个“=”号。但是运行的时候输入了超过80个的字符串，然而还是不输出，不知道咋回事

lim没有初始化，==是比较运算符


Question: 做C primer plus的练习遇到的问题

是软件问题 现在好了

测试没有问题

5. 编写 一个 程序, 生成 以下 输出: Brazil, Russia,India, China  India, China,  Brazil, Russia 除了 main() 以外, 该 程序 还要 调用 两个 自定义 函数: 一个 名为 br(), 调用一次 打印 一次“ Brazil, Russia”; 另一个 名为 ic(), 调用 一次 打印 一次“ India, China”。 其他 内容 在 main() 函数中完成。

没毛病啊。。

题目是什么啊？


Question: C语言菜单

#include <stdio.h> #include <string.h> #include <windows.h>  static void menu(void);  void main() {     int select, ret = -1;     system("cls");  //清屏。     menu();      printf("                    请选择：（1/2/3/0）");     ret = scanf("%d",&select);     if (ret <= 0)         select = 1;     switch(select) {         case 1:             printf("选择：%d\n", select);             //system("pause");             // x();             break;         case 2:             printf("选择：%d\n", select);             // y();             break;         case 3:             printf("选择：%d\n", select);             // z();             break;         case 0:         default:             exit(0);             break;     } }  static void menu(void) {     printf(" \n");     printf("                    ======================================\n");     printf("                                   菜  单\n");     printf("                    ======================================\n");     printf(" \n");     printf("                                  1  录入\n");     printf("                                  2  处理\n");     printf("                                  3  打印\n");     printf(" \n");     printf("                                  0  退出\n");     printf(" \n");     printf("                    ======================================\n");      printf(" \n");  }  select为int类型，如果输入a,b,c等非数字字符，那么scanf就因类型匹配错误而返回0，根据这个返回值来确认select的值。

楼主的程序因为初始化为1了。

你应该把把case1放在default之前，两个共用一个执行语句块儿，把case0中的语句拿出来单独执行。


Question: fgets()函数

上楼说错了~是stdio.h我汗~

fgets用stdin.h就可以了~ 如果想保险就加上stdlib.h 那个代码测试没有问题~能正常输入~如果不行就发完整版代码~ 正常应该是没有问题的~

输入中间带空格的字符串包括数字也解决了。

已经解决了。将 printf("请输入：\n");中的“\n”删除就可以了。 但还有一问题：代码原本是为了输入中间带空格的字符串，现在可以输入中间带空格的字符串了，例如 “a b”，但不能输入“1 2”,希望把1、2...当作字符对待。

不会啊，你是不是前面还有代码，估计是接收了你之前输入完在缓冲区中留下的换行符  fets前加个getchar()看下


Question: 关于一道C语言编程题

去重复可以用先把结果排序，然后去重，for循环，用一个临时变量=-1，和a（i）比较，相同，总数就减1，不同就把a（i）赋值给临时变量

引用 5 楼 ooolinux的回复:内层循环和外层循环也可以反过来，1克的放在最内层循环，20克的放在最外层循环，这样计算就是从最小到最大。 做出来了，谢谢

引用 6 楼 u010165006 的回复:计算出来的总克数，重复的去除，0也去除，就可以了。  我想问下到了这步 。。怎么剔除重复的？

我也是初学者的思路：定义一个数组 int arr[20]; int *p = arr; 然后循环遍历数组，使用if     else if     else类型的 if(*p = 1)  *p++; num1++; else if(*p = 2) *p++; num2++; .... num+质量然后遍历时候就会找到

这个应该是动态规划算法，看下背包算法九讲，或许可以找到答案

引用 7 楼 hyzhanc 的回复:[quote=引用 6 楼 u010165006 的回复:] 计算出来的总克数，重复的去除，0也去除，就可以了。  我想问下到了这步 。。怎么剔除重复的？[/quote]  可以用一个动态数组，每次计算出来的总克数，在数组中搜索有无相同的，没有相同的就插入。

计算出来的总克数，重复的去除，0也去除，就可以了。

引用 2 楼 user-6的回复:全组合问题~要把相同质量的砝码分开写~写成1 1 1 1 1 2 2 2 3 3 5 5 10 20来写~可参考排列组合算法~ 那还得自己写个排列组合算法吧

引用 1 楼 ooolinux的回复:用6层for循环，第一层循环从0~5，第二层0~3（代表个数），第一层循环变量*1克，第二层循环变量*2克，全部相加。 还是不太懂，循环这么多层不太明白


Question: 字母排序的这串代码如何理解

3楼说的没错，你少了len = strlen( a ); 典型的冒泡排序。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

长度len个字符，需要排序len-1趟，所以i=0到len-2，共len-1 每一趟中需要比较的次数是不同的，是逐趟少一次

引用 2 楼 m0_37403659 的回复:[quote=引用 1 楼 yangyangsnr 的回复:] 冒泡排序啊，每个字母根据ascii值比较大小  那个len-2跟len-1是啥意思？[/quote] 哦，那你这段代码应该少一句话，在gets(a)下面应该加上 len = strlen( a ); 然后，len就表示了字符串a的长度

引用 1 楼 yangyangsnr 的回复:冒泡排序啊，每个字母根据ascii值比较大小  那个len-2跟len-1是啥意思？

冒泡排序啊，每个字母根据ascii值比较大小


Question: 一个关于c语言程序的小问题，求教各位

引用 11 楼 Grevi 的回复:#include <stdio.h> char genA[100][4],genB[100][4];	 int solution1(int munA); int solution2(int numA,int numB);  int main() { int i,j; int n;  int numA,numB; printf("请输入基因组A的基因数目\n"); scanf("%d",&numA); printf("请输入基因组B的基因数目\n"); scanf("%d",&numB); printf("请输入A的基因序列，\n格式为at  ahctchdt\n（没有字母的部分用空格代替即可）\n"); for(i=0;i<numA;i++) for(j=0;j<4;j++) scanf("%c",&genA[i][j]); printf("请输入B的基因序列\n（格式同上）\n"); for(i=0;i<numB;i++) for(j=0;j<4;j++) scanf("%c",&genB[i][j]);  printf("请选择计算方式，1或2\n");  fflush(stdin);//这里需要清除标准输入缓冲区，或者前面加个getchar();也可以，但是不推荐这么做  scanf("%d",&n); switch(n) { case 1: solution1(numA); break; case 2: solution2(numA,numB); break; } printf("感谢您的使用！\n"); return 0; } 解答的这么详细，真的谢谢你

//请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];

加个循环结构以及退出菜单条件~

引用 8 楼 rabbit_calm的回复:[quote=引用 1 楼 ai977313677 的回复:] 在scanf之前清除一下缓冲区fflush(stdin) 或者创建一个char变量，去读取回车之类的字符。 谢谢您，但是我不太明白为什么要这么做？[/quote] 大概就是说，你的所有输入都会保存在一个叫缓冲区的东西里，然后scanf会从缓冲区中读取字符，回车之类的字符都会保存进去，所有scanf的时候要注意把这些无用字符读取掉，防止后续操作出现误读。

引用 4 楼 qq423399099 的回复:两处scanf %c之前都加一句fflush(stdin)来清空输入缓冲区（因为%c会读取输入缓冲区遗留的回车符） 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 您可以再说的详细一点吗？我的问题和缓冲区有什么关系啊？谢谢您

引用 1 楼 ai977313677 的回复:在scanf之前清除一下缓冲区fflush(stdin) 或者创建一个char变量，去读取回车之类的字符。 谢谢您，但是我不太明白为什么要这么做？

引用 5 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0]; 我是初学者，缓冲什么的海不太懂，您能大概告诉我一下为什么这么做吗？是因为我的缓冲区不够用了吗？

你执行完switch之后就是打印那句话啊，不显示才奇怪吧 你应该去调试你那两个函数


Question: 图的简单路径遍历

楼主的程序有什么问题？？？只贴一段程序不易看出来啥问题。

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

不懂哪一步错了！


Question: c语言bug

根据scanf函数的返回值进行判断，scanf()函数返回成功赋值的数据项数

引用 3 楼 yyyyzf的回复:while(scanf("%d",&row)!=1)     fflush(stdin); 试试用上面的代码~fflush(stdin)是用来清除缓冲区~如果是写一些正规大型的程序~则可以考虑调用自己写的输入函数~进行输入合法性判断~

用gets和atoi代替scanf("%d",&row)

各位大神，帮忙解决一下，一位c语言菜鸟


Question: C语言中的EOF

Linux：Ctrl+D Windows：Enter、Ctrl+Z、Enter

例子说明吧： 遇到这个表达式：scanf("%d%d",&a,&b)!=EOF; 如果a和b都被成功读入，那么上面表达式的结果为2； 如果只有一个读入，那么上面表达式的结果为1； 如果a&&b都没有读入，那么上面表达式的结果为0（若a没有读入，则直接放弃b的读入）； 如果遇到错误或者文件结尾，那么上面表达式的结果为EOF，对应的有符号数时-1； 如果遇到Crrl+Z，那么上面表达式的结果为EOF，对应的有符号数时-1;

一般情况下是这样的~ while(scanf("%d",&a)!=EOF) {} 退出循环条件一般是按ctrl+z 这可能是ac或者oj通过重定向对编译器输入文件的内容~而EOF的意义表示读入到文件的末尾~


Question: c语言 scanf()函数如何读入一个带空格的字符串

还不快快用上键盘事件。。。

三楼正解  引用 3 楼 fjjfxz 的回复:scanf函数好象本身就是把空格作为数据分隔符 想读入带空格的字符串，得用如gets()之类的函数

建议暂时使用gets()函数来完成功能 等入门后学习使用fgets()函数来完成  gets(char *string); fgets(char * s, int n,FILE *stream);  char a[20]={0}; printf("请输入： "); gets(a); printf("%s",a); system("pause");

还是不行啊！ 如果是：scanf("%[^\n]%*c",a); 运行结果是： 请按任意键继续… 如果改为：scanf("%s%[^\n]%*c",a); 运行结果仍然是： 请输入：I love you  I请按任意键继续…

scanf("%[^\n]%*c",a);%*c是用来吸收末尾的'\n'~~这样就可以了~~


Question: 关于二维数组的赋值问题

引用 3 楼 cfjtaishan 的回复:因为第一层循环之后就有了一个回车动作：printf("\n");  非常感谢三楼

楼主认为应该在第几行呢。  int array2[3][2]={{4,2},{5},{6}};//按行初始化

哈，没注意到换行啊

因为第一层循环之后就有了一个回车动作：printf("\n");

因为你用 {} 限定了，这是起始一行了

为什么不呢？


写不进去那么如果fd是阻塞 那么就会一直阻塞，否则返回EAGAIN。看库实现在你传递的第3个参数为0的时候会返回0.当然具体其他情况是否还会返回0需要看一些内核实现。至于steven这里的处理方式主要还是与作者写书时这个函数的实现有关。Where this volume of IEEE Std 1003.1-2001 requires -1 to be returned and errno set to [EAGAIN], most historical implementations return zero

On success, the number of bytes written is returned (zero indicates nothing was written).  On error, -1 is returned, and errno is set appropriately.         If count is zero and fd refers to a regular file, then write() may return a failure status if one of the errors below is detected.  If no errors are detected, 0 will be returned without  caus‐        ing any other effect.  If count is zero and fd refers to a file other than a regular file, the results are not specified. 这是write的返回值说明；

我感觉是进不进去的时候

谢谢各位～～

写缓冲区满


Question: 求组，类型转换ASII码


Question: nginx 怎么在body过滤模块里发送content_length响应头

我看到nginx原生的 image_filter 可以将response 缓存起来，最后再发送响应头和响应体。但是不知道怎么实现的缓存response，正在调试源码。

百度搜相关关键字。


Question: 在eclipse中编写c代码为什么有random（）报错，明明已经写了#include

顶楼上。

srandom random函数是Unix下才有的。        #include <stdlib.h>         long int random(void);         void srandom(unsigned int seed);         char *initstate(unsigned int seed, char *state, size_t n);        char *setstate(char *state);     Feature Test Macro Requirements for glibc (see feature_test_macros(7)):         random(), srandom(), initstate(), setstate(): _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500

#include <stdlib.h>  void srand( unsigned seed );   int rand( void );  #include <stdlib.h> #include <time.h>   srand( time(NULL) );    for( i = 0; i < 10; i++ )      printf( "Random number #%d: %d\n", i, rand() );

随机函数应该是srand()和rand()，没有见过random呢。

ISO C的stdlib.h中只有srand与rand两个函数


Question: C语言小程序，不管输入几结果都是，*不是质数。代码哪里有错吗？

我没有看到main函数的对应大括号，这是个错误，一楼说的也是个错误 运行错误时，编译器会提示错误的行数以及为何出错 学会看编译器的调试错误提示是一项必备且特别重要的技能 能自己独立完成的，尽量不用去请求别人，不会很难，要相信自己的能力呀  引用 2 楼 qq423399099 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

非常感谢各位，我粗心了，呜呜。。。。。

1楼正解、你的for语句括号里的内容没有执行

for 语句后面多了一个分号


Question: #if defined.......................................

#开头的是预处理指令，在编译之前


Question: c语言

完全不明白楼上都在回答什么。。。 你这个跳过是因为你的scanf_s用法不对，scanf_s读取%s或者%c的时候必须多传入一个参数用来指定读取的字符的长度，否则会出错。 PS：要注意输入的姓名不要超过4个字符（因为你设的二维数组的第二维长度是5，最后还要放'\0'）  #include <iostream> using namespace std; int main() { 	char name_array[100][5] = { 0 }; 	char sex_array[100] = { 0 }; 	int age_array[100] = { 0 }; 	float att_array[100] = { 0 }; 	int operation = 0; 	int max_number = 0; 	int inc_number = max_number + 1; 	printf("请输入你想增加的学号为%d学生的姓名\n", inc_number); 	scanf_s("%s", &name_array[inc_number - 1], 5); 	fflush(stdin); 	printf("请输入你想增加的学号为%d学生的性别\n", inc_number); 	scanf_s("%c", &sex_array[inc_number - 1], 1); 	fflush(stdin); 	printf("请输入你想增加的学号为%d学生的年龄\n", inc_number); 	scanf_s("%d", &age_array[inc_number - 1]); 	system("pause");  	return 0; }

进行的操作：（1.增加信息 2.修改信息 3.删除信息 4.查询信息 0.退出） 1 请输入你想增加的学号为1学生的姓名 fdffd 请输入你想增加的学号为1学生的性别 请输入你想增加的学号为1学生的年龄 请输入你想输入的学号为1学生的出勤率 增加信息成功！ 请输入你想增加的学号为2学生的姓名

我赶快去试试

printf("请输入你想增加的学号为%d学生的姓名\n", inc_number); char ch; int i = 0; while (ch = getchar()!='\n') {     i++;     scanf("%c", &name_array[inc_number - 1][i]); }  //fflush(stdin); printf("请输入你想增加的学号为%d学生的性别\n", inc_number); scanf("%c", &sex_array[inc_number - 1]); //fflush(stdin); ch = getchar(); printf("请输入你想增加的学号为%d学生的年龄\n", inc_number); scanf("%d", &age_array[inc_number - 1]); 看看我改动了些什么，应该是你回车没有被下一个scanf读取掉了，然后你问的.....应该是第二个总是被跳过吧

那该怎么办啊 最后一个scanf一直都是跳过的

fflush(stdin) 不是所有编译器都支持哦！这本来就不是标准里面的东西


Question: 这两个值相等吗？

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

值是相等的，但是意义是不等的。给你打个注释自己看

抛开编译错误的可能性，是相等的  int main(int argc, const char * argv[]) {     // insert code here...     int a;     int *p;          p = &a;     *p = 0x500;          printf("%p,%d\n%p,%d\n", p,*p, &a, a);     printf("1:%d,%d\n", p, *(&p));     printf("2:%d,%d\n", p, &(*p));         /*     a = (int )(*(&p));     if(a == (int)p)         printf("equal!\n");     else         printf("not equal!\n");          a = (int )(&(*p));     if(a == (int)p)         printf("equal!\n");     else         printf("not equal!\n");     */     return 0; } // 0x7fff5fbff6dc,1280 // 0x7fff5fbff6dc,1280 // 1606416092,1606416092 // 1606416092,1606416092

都赋值了，当然相等了。 但是那个赋值是有问题的，为什么要把指针变成整数呢？

相等撒 (int )(*(&p)) 和(int )(&(*p))，形式再怎么变来边去，其本质不都是p吗！！


Question: 怎么初始化结构体指针里面的结构体指针？

在楼主分配一个字节大小为sizeof(struct A)之后 *paa只是一个指向分配后的内存块的结构体指针 要是想楼主标题所说 初始化结构体指针里面的结构体指针 似乎需要用到二级指针的把

自己写个initial函数？

c++的话，可以通过创建一个结构体的构造函数在主函数中调用然后就能初始化了。

直接memset(paa, 0, sizeof(struct A))

指针初始话一般初始化为NULL


Question: 如何用C读写文件中的数据，并对数据进行处理

可以读取excel中的数据，注意格式。

1：百度“C读写文件” 2：可以，但是很麻烦


Question: 这什么这样定义一个数组报错

char c[] 定义一个数组c，数组的每个元素是char类型，就是一个字符 char *s[] 定义一个数组s，数组的每个元素是char *类型，可以指向一个C语言字符串（的首地址，结尾为'\0'字符）

回去看汇编，汇编有对这方面的解释

引用 11 楼 liuxingrui4p 的回复:[quote=引用 10 楼 ipqtjmqj 的回复:] [quote=引用 9 楼 qq_29648555 的回复:] 没想到有这么多人回答，谢谢大家。 看了大家的回答，我产生了这样的想法不知道对不对。  1是指针，其实这个指针不是指向的一唯数组，而是多唯的。 “sun”是装在一个数组里，“Mon”是装在另一个数组里，，依次等等。。 只是这些数组的地址有一定的关系。  2是一唯数组的赋值，一个一唯数组只能赋一个字符串，我这样就把多个 字符串赋给一个一唯数组，这样是赋不了的。  错误的重点：是我以为1指针指的是一唯数组，其实不是的。 你错了，1是一维数组，数组中元素类型是指针[/quote]  请问1的写法是不是有限制，个数太多会不会把栈撑爆[/quote] 现在的栈都很大的，爆不了，另外字符串常量存在静态区，1的写法只存储字符串的地址

引用 10 楼 ipqtjmqj 的回复:[quote=引用 9 楼 qq_29648555 的回复:] 没想到有这么多人回答，谢谢大家。 看了大家的回答，我产生了这样的想法不知道对不对。  1是指针，其实这个指针不是指向的一唯数组，而是多唯的。 “sun”是装在一个数组里，“Mon”是装在另一个数组里，，依次等等。。 只是这些数组的地址有一定的关系。  2是一唯数组的赋值，一个一唯数组只能赋一个字符串，我这样就把多个 字符串赋给一个一唯数组，这样是赋不了的。  错误的重点：是我以为1指针指的是一唯数组，其实不是的。 你错了，1是一维数组，数组中元素类型是指针[/quote]  请问1的写法是不是有限制，个数太多会不会把栈撑爆

引用 9 楼 qq_29648555 的回复:没想到有这么多人回答，谢谢大家。 看了大家的回答，我产生了这样的想法不知道对不对。  1是指针，其实这个指针不是指向的一唯数组，而是多唯的。 “sun”是装在一个数组里，“Mon”是装在另一个数组里，，依次等等。。 只是这些数组的地址有一定的关系。  2是一唯数组的赋值，一个一唯数组只能赋一个字符串，我这样就把多个 字符串赋给一个一唯数组，这样是赋不了的。  错误的重点：是我以为1指针指的是一唯数组，其实不是的。 你错了，1是一维数组，数组中元素类型是指针

引用 7 楼 xsklld 的回复:理论上用字符串字面值初始化char*也是不规范的，见样例。 不过C语言里似乎是允许的。

理论上用字符串字面值初始化char*也是不规范的，见样例。

第二种写法只能存一个字符串，不能存多个

字符指针组和字符数组的区别。第一个是指针数组，每个指针都可以存放一个字符串的地址。而第二个是字符数组，里面存放一个字符串。

你是在定义数组，首先要明白数组里放的什么，也就是数组类型，第一个里放的是字符指针，“abcd”这种字符串常亮在这种情况下表示指向第一个字符的指针，所以可以正常复制，第二个里放的是字符，所以要用字符初始化，而上面也说了“abcd”在这种上下文环境中代表的是一个指针，而不是字符，所以就不对了

用二维数组 char    www[][4] = {"Sun", "Mon"}; 就可以了

1定义的是字符指针数组，将字符串赋值给字符指针是可以的 2定义的是字符数组，将字符串赋值存放字符是不可以的。

因为char只有一个字节，存不了地址，char *是4个字节，可以存地址