Question: 文件读取问题

行吧，我在理解理解，谢谢你

你还是没理解，有没有EOF字符不重要，指不指向EOF字符不重要，feof都不会因此而为真。 feof为真的理由只有一个，那就是刚才有别的函数曾经撞上文件尾，撞是个动词，生动表达了某函数企图跨越文件尾读取数据然而失败了的过程。  四老师给出的解决方案是 while(1) { fgets(...); if(feof(p))break; others... ... } ...

谢谢耐心解答，我想问一下能将文件内容想成asd\nEOF吗，刚开始文件指针指向a，每读入一个字符往后移一位，如果这样的话，那第一次循环结束p不就是指向EOF吗，第二次循环判断feof返回1跳出循环

函数又没长眼睛，它没法在撞到文件末尾之前就知道前方是文件末尾。 你的循环执行第一次，没到结尾，读入第一行，去掉末字符（当时是换行）剩下正常字符在str里面。 循环第二次，没撞上过文件尾，因此条件为真，进入循环体。fgets读取新行失败，有两个后果，第一是撞过了文件尾，下次feof会返回真；第二是str没有更新，还是原来的内容。接下去去掉末字符，按你的说法的话这时去掉的是'd'。文件指针说的是读取位置吧，它没有返回开头，还在末尾呢。 循环条件第三次，这次因为feof为真，所以循环条件为假，跳过循环。 综上。 这样写的代码总会在最后是空行的时候出问题，建议参考四老师在其他帖子的回复进行修改。


Question: 请问，以上程序为何不能输出汉字

汉字应该用字符串保存，你怎么用int

现在程序可以这么写了啊？ 请问：1. getch(); 的返回值范围？ 2. printf(“%c%c”,a,b); 的输出内容？ 3. 你能不能解释一下a=(dat&0xff00)>>8;和b=dat&0x00ff; 的可能输出结果？ 4. 如果输出汉字，编码应该是16位字长，但是那么多编码方案你准备为哪种编程？ 5. 如果你不准备想清楚编码和算法有关的事，至少你应该研究一下把两个%c数据合成一个16位字长的数据吧？不然你怎么输出中文？

赵4老湿不老实！没有正面回答我滴问题！差评！中午不准吃饭！  实际上， wprintf 是将宽字符转换为多字节字符输出。正因为有一个转换过程，等价于 wcstomb，所以需要根据当前区域设置来决定如何将宽字符转换为多字节字符。

setlocale, _wsetlocale Define the locale.  char *setlocale( int category, const char *locale );  wchar_t *_wsetlocale( int category, const wchar_t *locale );  Routine Required Header Compatibility  setlocale <locale.h> ANSI, Win 95, Win NT  _wsetlocale <locale.h> or <wchar.h> 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  If a valid locale and category are given, the function returns a pointer to the string associated with the specified locale and category. If the locale or category is invalid, the function returns a null pointer and the current locale settings of the program are not changed.  For example, the call  setlocale( LC_ALL, "English" );  sets all categories, returning only the string English_USA.1252. If all categories are not explicitly set by a call to setlocale, the function returns a string indicating the current setting of each of the categories, separated by semicolons. If the locale argument is a null pointer, setlocale returns a pointer to the string associated with the category of the program’s locale; the program’s current locale setting is not changed.  The null pointer is a special directive that tells setlocale to query rather than set the international environment. For example, the sequence of calls  // Set all categories and return "English_USA.1252" setlocale( LC_ALL, "English" ); // Set only the LC_MONETARY category and return "French_France.1252" setlocale( LC_MONETARY, "French" ); setlocale( LC_ALL, NULL );  returns   LC_COLLATE=English_USA.1252; LC_CTYPE=English_USA.1252; LC_MONETARY=French_France.1252; LC_NUMERIC=English_USA.1252; LC_TIME=English_USA.1252  which is the string associated with the LC_ALL category.  You can use the string pointer returned by setlocale in subsequent calls to restore that part of the program’s locale information, assuming that your program does not alter the pointer or the string. Later calls to setlocale overwrite the string; you can use _strdup to save a specific locale string.  Parameters  category  Category affected by locale  locale  Locale name  Remarks  Use the setlocale function to set, change, or query some or all of the current program locale information specified by locale and category. “Locale” refers to the locality (country and language) for which you can customize certain aspects of your program. Some locale-dependent categories include the formatting of dates and the display format for monetary values.   _wsetlocale is a wide-character version of setlocale; the locale argument and return value of _wsetlocale are wide-character strings. _wsetlocale and setlocale behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tsetlocale setlocale setlocale _wsetlocale    The category argument specifies the parts of a program’s locale information that are affected. The macros used for category and the parts of the program they affect are as follows:  LC_ALL  All categories, as listed below  LC_COLLATE  The strcoll, _stricoll, wcscoll, _wcsicoll, and strxfrm functions  LC_CTYPE  The character-handling functions (except isdigit, isxdigit, mbstowcs, and mbtowc, which are unaffected)  LC_MONETARY  Monetary-formatting information returned by the localeconv function  LC_NUMERIC  Decimal-point character for the formatted output routines (such as printf), for the data-conversion routines, and for the nonmonetary-formatting information returned by localeconv   LC_TIME  The strftime and wcsftime functions  The locale argument is a pointer to a string that specifies the name of the locale. If locale points to an empty string, the locale is the implementation-defined native environment. A value of “C” specifies the minimal ANSI conforming environment for C translation. The “C” locale assumes that all char data types are 1 byte and that their value is always less than 256. The “C” locale is the only locale supported in Microsoft Visual C++ version 1.0 and earlier versions of Microsoft C/C++. Microsoft Visual C++ supports all the locales listed in Appendix A, Language and Country Strings. At program startup, the equivalent of the following statement is executed:  setlocale( LC_ALL, "C" );  The locale argument takes the following form:  locale :: "lang[_country[.code_page]]"              | ".code_page"             | ""             | NULL  The set of available languages, countries, and code pages includes all those supported by the Win32 NLS API. The set of language and country codes supported by setlocale is listed in Appendix A, Language and Country Strings.  If locale is a null pointer, setlocale queries, rather than sets, the international environment, and returns a pointer to the string associated with the specified category. The program’s current locale setting is not changed. For example,  setlocale( LC_ALL, NULL );  returns the string associated with category.   The following examples pertain to the LC_ALL category. Either of the strings ".OCP" and ".ACP" can be used in place of a code page number to specify use of the system default OEM code page and system-default ANSI code page, respectively.  setlocale( LC_ALL, "" );  Sets the locale to the default, which is the system-default ANSI code page obtained from the operating system.  setlocale( LC_ALL, ".OCP" );  Explicitly sets the locale to the current OEM code page obtained from the operating system.  setlocale( LC_ALL, ".ACP" );  Sets the locale to the ANSI code page obtained from the operating system.  setlocale( LC_ALL, "[lang_ctry]" );  Sets the locale to the language and country indicated, using the default code page obtained from the host operating system.  setlocale( LC_ALL, "[lang_ctry.cp]" );  Sets the locale to the language, country, and code page indicated in the [lang_ctry.cp] string. You can use various combinations of language, country, and code page. For example:  setlocale( LC_ALL, "French_Canada.1252" ); // Set code page to French Canada ANSI default setlocale( LC_ALL, "French_Canada.ACP" ); // Set code page to French Canada OEM default setlocale( LC_ALL, "French_Canada.OCP" ); setlocale( LC_ALL, "[lang]" );  Sets the locale to the country indicated, using the default country for the language specified, and the system-default ANSI code page for that country as obtained from the host operating system. For example, the following two calls to setlocale are functionally equivalent:  setlocale( LC_ALL, "English" ); setlocale( LC_ALL, "English_United States.1252" ); setlocale( LC_ALL, "[.code_page]" );  Sets the code page to the value indicated, using the default country and language (as defined by the host operating system) for the specified code page.   The category must be either LC_ALL or LC_CTYPE to effect a change of code page. For example, if the default country and language of the host operating system are “United States” and “English,” the following two calls to setlocale are functionally equivalent:  setlocale( LC_ALL, ".1252" ); setlocale( LC_ALL, "English_United States.1252");  For more information see the setlocale pragma in Preprocessor Reference.  Example  /* LOCALE.C: Sets the current locale to "Germany" using the  * setlocale function and demonstrates its effect on the strftime  * function.  */  #include <stdio.h> #include <locale.h> #include <time.h>  void main(void) {        time_t ltime;        struct tm *thetime;        unsigned char str[100];         setlocale(LC_ALL, "German");        time (<ime);        thetime = gmtime(<ime);         /* %#x is the long date representation, appropriate to         * the current locale         */        if (!strftime((char *)str, 100, "%#x",                       (const struct tm *)thetime))                printf("strftime failed!\n");        else                printf("In German locale, strftime returns '%s'\n",                        str);         /* Set the locale back to the default environment */        setlocale(LC_ALL, "C");        time (<ime);        thetime = gmtime(<ime);         if (!strftime((char *)str, 100, "%#x",                       (const struct tm *)thetime))                printf("strftime failed!\n");        else                printf("In 'C' locale, strftime returns '%s'\n",                        str); }   Output  In German locale, strftime returns 'Donnerstag, 22. April 1993' In 'C' locale, strftime returns 'Thursday, April 22, 1993'   Locale Routines  See Also   localeconv, mblen, _mbstrlen, mbstowcs, mbtowc, strcoll Functions, strftime, strxfrm, wcstombs, wctomb

引用 11 楼 均陵鼠侠 的回复:[quote=引用 7 楼 m0_51507696 的回复:][quote=引用 3 楼 赵4老师 的回复:]getwchar可以返回汉字 老师，您看一下，我将程序改成了这样，结果输出如图那样您觉得有可能是什么原因  #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <wchar.h>  int main(void){ 	int dat=0; 	while(1){ 		printf("输入：");  		dat=getwchar(); 		printf("%d——",dat); 		printf("%c%c",((dat&0xff00)>>8),(dat&0x00ff)); 	} 	system("pause"); 	return 1; }  [/quote]  大胆！你这是为难赵4老湿。  我来替赵4老湿回答你的问题。你只需要用下面的方法即可解决：  # include <locale.h> # include <wchar.h> # include <stdio.h>  int main (void) {     setlocale (LC_ALL, "chs");     wprintf (L"->%lc", getwchar ()); }  注：在Linux环境下，程序中的“chs”要改成“zh_CN.UTF-8”（如果默认是UTF-8编码）。  帮了赵4老湿这么大的忙，请赵老湿回答一下，为什么这个程序要用 setlocale 设置区域呢？如果不设置有什么问题？[/quote] https://www.baidu.com/s?wd=setlocale%20LC_ALL%20chs%20zh_CN.UTF-8

来，按你的意思改一波  #include<stdio.h> #include<conio.h> int main( void ) {     int a=0, b=0;     while(1)     {     	a=getch();     	printf("%c", a );     }     return 0;  }    注意，getch不回显，这个“哈哈哈”是printf输出来的

#include<stdio.h> #include<conio.h> int main( void ) {     int a=0, b=0;     a=getch();     b=getch();     printf("得到%c%c %x %x", a, b, a, b );     return 0;  }    这不是可行吗，B9 FE，这就是汉字'哈'的GBK编码呀

引用 7 楼 m0_51507696 的回复:[quote=引用 3 楼 赵4老师 的回复:]getwchar可以返回汉字 老师，您看一下，我将程序改成了这样，结果输出如图那样您觉得有可能是什么原因  #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <wchar.h>  int main(void){ 	int dat=0; 	while(1){ 		printf("输入：");  		dat=getwchar(); 		printf("%d——",dat); 		printf("%c%c",((dat&0xff00)>>8),(dat&0x00ff)); 	} 	system("pause"); 	return 1; }  [/quote]  大胆！你这是为难赵4老湿。  我来替赵4老湿回答你的问题。你只需要用下面的方法即可解决：  # include <locale.h> # include <wchar.h> # include <stdio.h>  int main (void) {     setlocale (LC_ALL, "chs");     wprintf (L"->%lc", getwchar ()); }  注：在Linux环境下，程序中的“chs”要改成“zh_CN.UTF-8”（如果默认是UTF-8编码）。  帮了赵4老湿这么大的忙，请赵老湿回答一下，为什么这个程序要用 setlocale 设置区域呢？如果不设置有什么问题？

引用 9 楼 m0_51507696 的回复:[quote=引用 6 楼 均陵鼠侠 的回复:]汉字处理是个复杂的话题，但是就你这个程序而言，又不是太难。 # include <stdio.h>  int main (void) {     char b [2048] = {0};     int c, x = 0;      while ((c = getchar ()) != EOF) b [x ++] = c;      printf (b); } 函数 getchar 每次只读取 1 个字节，然后扩展到 int 类型。所以，我们的任务是将这些字节依次读取并存储起来。这个程序的好处是不必考虑操作系统实际使用的执行字符集，因为发送给程序的字符编码与系统输出（即 printf 内部调用的操作系统接口部分）使用的字符编码方案总是一致的。  请问，这个printf (b);是怎么回事,没有格式控制字符串编译器会自动判断输出类型吗[/quote]  因为 printf 本来就是一个变参函数，第一个参数是指向字符串的指针，如果里面有格式控制字符，后面才会有别的参数：  int printf (const char * restrict, ...);

引用 6 楼 均陵鼠侠 的回复:汉字处理是个复杂的话题，但是就你这个程序而言，又不是太难。 # include <stdio.h>  int main (void) {     char b [2048] = {0};     int c, x = 0;      while ((c = getchar ()) != EOF) b [x ++] = c;      printf (b); } 函数 getchar 每次只读取 1 个字节，然后扩展到 int 类型。所以，我们的任务是将这些字节依次读取并存储起来。这个程序的好处是不必考虑操作系统实际使用的执行字符集，因为发送给程序的字符编码与系统输出（即 printf 内部调用的操作系统接口部分）使用的字符编码方案总是一致的。  请问，这个printf (b);是怎么回事,没有格式控制字符串编译器会自动判断输出类型吗

引用 6 楼 均陵鼠侠 的回复:汉字处理是个复杂的话题，但是就你这个程序而言，又不是太难。 # include <stdio.h>  int main (void) {     char b [2048] = {0};     int c, x = 0;      while ((c = getchar ()) != EOF) b [x ++] = c;      printf (b); } 函数 getchar 每次只读取 1 个字节，然后扩展到 int 类型。所以，我们的任务是将这些字节依次读取并存储起来。这个程序的好处是不必考虑操作系统实际使用的执行字符集，因为发送给程序的字符编码与系统输出（即 printf 内部调用的操作系统接口部分）使用的字符编码方案总是一致的。 引用 6 楼 均陵鼠侠 的回复:汉字处理是个复杂的话题，但是就你这个程序而言，又不是太难。 # include <stdio.h>  int main (void) {     char b [2048] = {0};     int c, x = 0;      while ((c = getchar ()) != EOF) b [x ++] = c;      printf (b); } 函数 getchar 每次只读取 1 个字节，然后扩展到 int 类型。所以，我们的任务是将这些字节依次读取并存储起来。这个程序的好处是不必考虑操作系统实际使用的执行字符集，因为发送给程序的字符编码与系统输出（即 printf 内部调用的操作系统接口部分）使用的字符编码方案总是一致的。   谢谢您，您的回答解决了我的问题

引用 3 楼 赵4老师 的回复:getwchar可以返回汉字 老师，您看一下，我将程序改成了这样，结果输出如图那样您觉得有可能是什么原因  #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <wchar.h>  int main(void){ 	int dat=0; 	while(1){ 		printf("输入：");  		dat=getwchar(); 		printf("%d——",dat); 		printf("%c%c",((dat&0xff00)>>8),(dat&0x00ff)); 	} 	system("pause"); 	return 1; }

希望对您有帮助，盼采纳：https://blog.csdn.net/it_xiangqiang/category_10581430.html

getwchar可以返回汉字

汉字不是占1个字节的字符（可以了解一下一个汉子占几个字节），之所以getch返回int就像getchar()返回int是一样的道理：类型提升；  因此如果要输出汉子，建议用字符串；


Question: c语言自定义输入一个数组，循环打出后数组改变了

引用 3 楼 qq_34918605 的回复:[quote=引用 1 楼 自信男孩 的回复:]#include <stdio.h>  int main() {     //int j = 1;     int j = 0;     int  arr[100] = { 0 };      printf("请输入你需要输入的数据 回车结束");     for (int i = 0; i < 100&&getchar()!='\n'; i++)     {         scanf("%d", &arr[i]);         j++;     }      for (int i = 0; i < j; i++)     {         printf("%d\n", arr[i]);     }      return 0; } 有什么办法解决前面应为getchar吞的元素从而直接输入数字，而且循环输出后莫名多了一个0 元素， 多以个0，已经给你解释了，因为j=1从1开始就出现，从0开始就没问题了。  解决getchar吞的问题，可以考虑用我下面的例子。

[quote=引用 2 楼 自信男孩 的回复:]#include <stdio.h>  int main() {     //int j = 1;     int j = 0, ret;     int  arr[100] = { 0 };      printf("请输入你需要输入的数据 回车结束");     for (int i = 0; i < 100; i++)     {         if ((ret = scanf("%d", &arr[i])) != 1)                 break;         j++;     }      for (int i = 0; i < j; i++)     {         printf("%d\n", arr[i]);     }      return 0; } 还是出现问题 直接打出了后面的空空间

#include <stdio.h>  int main() {     //int j = 1;     int j = 0, ret;     int  arr[100] = { 0 };      printf("请输入你需要输入的数据 回车结束");     for (int i = 0; i < 100; i++)     {         if ((ret = scanf("%d", &arr[i])) != 1)                 break;         j++;     }      for (int i = 0; i < j; i++)     {         printf("%d\n", arr[i]);     }      return 0; } 供参考～  退出输入使用ctrl+d(LINUX）或ctrl+z（Windows）

#include <stdio.h>  int main() {     //int j = 1;     int j = 0;     int  arr[100] = { 0 };      printf("请输入你需要输入的数据 回车结束");     for (int i = 0; i < 100&&getchar()!='\n'; i++)     {         scanf("%d", &arr[i]);         j++;     }      for (int i = 0; i < j; i++)     {         printf("%d\n", arr[i]);     }      return 0; } 供参考～  输入时需要注意下，在输入第一个数字之前先输入一个空格，用于匹配getchar();根据循环的执行顺序，首先执行int i=0;然后不是执行循环体，而是判断i < 100 && getchar() !='\n'，如果满足才会执行循环体。所以，如果输入的第一个字符是数字，那么这个数字的第一个数字就会被getchar()接收；  因此需要注意下，另外j应该从0开始。否则后面printf会多打印一个，甚至会导致越界，比如输入了100个，j=101；i<j，那么i=100是满足的，但是数组已经越界了。


Question: 实现pow()函数的源代码

1.你定义的变量全是整型无法接受到你想要的小数。 2.如果想用小数来表示开根号的运算那么你现在的算法公式也是错误的。

引用 5 楼 lin5161678的回复:注意 pow 可以传入小数  比如 pow(100.0, 0.5); 表示 √100 你好，我的代码运行传入小数，但运行的结果不正确，请问可以解惑吗？

希望对您有帮助，盼采纳：https://blog.csdn.net/it_xiangqiang/category_10768339.html

幂参数y可作已初始化的临时局部变量, 减少额外变量, 代码更紧凑: int pow(int x, int y) { 	int z; 	for (z = 1; y > 0; --y) 		z *= x; 	return z; }

引用 1 楼 自信男孩的回复:注意x, y接收的实参值可能会导致z溢出。需要考虑溢出的情况～比如10^15，int类型数据无法装的下～ 嗯嗯好的，谢谢哈


Question: 这个地方哪里错误了，求大佬指点

if这行少一个右括号，需要注意一下

引用 13 楼 赵4老师 的回复://是注释 ||才是或 楼主脖子歪了还是眼睛斜了或者楼主所处位置地心引力方向不是严格向下？  正解！

if((year -> if(year)

想复杂了，后来又忘记了。不少人编程时都是这样子的。 一个Bug坑一天，找到后发现什么也没干，就崩溃了。

if 左边多一个（

学代码要看注释啊，下面都说了（)的问题。

第7行没错， 第6行错了，   if 语句的条件，多了一个左括号 ‘(‘ ， 删除一个 左括号即可。

啊这个。。。。

左括号和右括号数量不一样。。。

引用 11 楼 qq_45773596的回复:[quote=引用 2 楼 赵4老师的回复:]前一句if后多一个（ 不是的if()     中间//是或，所以两个语句在()内。不是这个问题，我看了[/quote] 难道我的思路有问题吗，我再试试

引用 2 楼 赵4老师的回复:前一句if后多一个（ 不是的if()     中间//是或，所以两个语句在()内。不是这个问题，我看了

借楼，发一个小玩意儿。GNU C 扩展的功能，详情参见：https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Statement-Exprs.html # include <stdio.h>  int main (void) {     printf ("%d\n", ({int n = 1, sum = 0;                       for (; n <= 100;) sum += n ++;                       sum;})); }

引用 2 楼 赵4老师的回复:前一句if后多一个（ 这个没问题，你再看看

我看了，不是

第6行，多了一个左括号

说句重一点的话，你在代码的规范性上做的很差。按照规范你再写一遍代码，肯定就没问题。

好象不够复杂，再合并一下。请用 GCC 编译运行。 # include <stdio.h>  int main (void) {     printf (({int year; scanf ("%d", & year); year % 400 == 0 ? "yes.\n" : "no.\n";})); }

赵4老湿有理有据。建议用下面这段代码测试一下，如果能用 GNU C 一次性编译执行而没有问题，说明是个细心的银。 # include <stdio.h>  int main (void) {     int year;      printf (({scanf ("%d", & year); year % 400 == 0 ? "yes.\n" : "no.\n";})); }

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


Question: 求解大哥们

希望对您有帮助，盼采纳：https://blog.csdn.net/it_xiangqiang/category_10581430.html

解什么？问题说明确一下吧


Question: 关于单链表删除指定位置结点的问题

这个代码删除除头结点外的节点是没问题的。但是如果删除头结点，这个就会有问题，需要额外处理一下～

这个没问题：int ListDelete(LinkList *L,int i,ElemType *e) {     int j;     LinkList p,q;     p = *L;     j = 1;     while (p->next && j < i)     {         p = p->next;         ++j;     }     if (!(p->next) || j > i) return 0;     q = p->next;  //q指向i=3结点的头部     p->next = q->next; // p->next 指向i=3结点的尾部，即i=4结点的头部，                        //等同于 p->next = p->next->next,把i=2结点的尾部指针指向i=4结点的头部     *e = q->data;     free(q);   //释放q     return 1; }

这里面有， 希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html。


Question: C语言程序设计题，帮帮忙。

希望对您有帮助，盼采纳：https://blog.csdn.net/it_xiangqiang/category_10768339.html

调用prime函数求大于m的10最小素数之和？这题目没看懂呢。

引用 1 楼 qzjhjxj的回复:调用prime函数求大于m的10最小素数之和？这题目没看懂呢。 10个最小素数之和

供参考：#include<stdio.h>  int isPrime(int n) {     int i;     if(n<=3) return n>1;     for(i=2;i*i<=n;i++)         if(n%i==0)return 0;     return 1; }  int main() {     int m,i,j=0,sum=0;     scanf("%d",&m);     for(i=m+1;;i++){         if(isPrime(i)){            sum += i;            if(++j==10)break;         }     }     printf("sum=%d\n",sum);         return 0; }

英语没有量词嘛。 求大于m的10个最小素数之和。

判断质数可参


Question: 为什么第二个i++没有进行加1，而是直接等于上一个i++后的值?

问题的根源是很多人没意识到，表达式是有值的，在一个大的表达式中，运算符操作的是子表达式的值。如果需要，任何表达式都有一个值，即使是 void 表达式，也会有一个（空）值。  表达式 i ++ 的值是左值 i 递增前的原值，同时，这个表达式还有一个将 i 的存储值加一的副作用。因此， x = i ++; 是将表达式 i ++ 的值赋给 x （同时 i 的存储值递增）。传统的解释是将 i 的值赋给 x ，然后 i 再递增，但它无法从逻辑上解释，i 是和 ++ 结合的，它凭什么，有什么义务要把自己的值赋给左边的 x 呢？毕竟，赋值运算符的右操作数是 i ++ 而不是 i  。  表达式 ++ i 的值是左值 i 递增后的新值，同时，这个表达式还有一个将 i 的存储值加一的副作用。因此， x =++ i; 是将表达式 ++ i 的值赋给 x （同时 i 的存储值递增）。传统的解释是先递增 i ，再把 i 赋给 x，但它同样无法从逻辑上解释，i 是和 ++ 结合的，它的义务是按照 ++ 的要求完成递增，它凭什么，有什么义务要把递增后的值赋给左边的 x 呢？毕竟，赋值运算符的右操作数是 ++ i 而不是 i  。

希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html

因为s1[i++]是先以i++为整体的值作为s1的下表，然后在改变i的值，原因是这儿的自增是后增，如果是++i就是相反的。


Question: 用C语言编写一个简单的模拟打卡程序


Question: 求助：C语言程序在Linux系统下可以运行，在Windows系统里没有报错却无法运行该怎么解决

引用 2 楼 it_xiangqiang的回复:希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 好的好的，我学习一下，谢谢你

在windows下把路径改了，但是没有用，应该是null的问题，我上机试试，谢谢你

/home/cbp/score.c这个在windows有这个路径和文件吗？  if((fd = fopen("/home/cbp/score.c", "rw" ))<0){ perror("open:"); exit(1); } 这个有问题呢，fd应该是和NULL比较。 原因是这个地方没有执行到exit，其实是因为找不到文件fd是NULL了，但是NULL < 0又不满足，所以没有exit，后面直接用fd出现段错误了。  解决办法：  if((fd = fopen("/home/cbp/score.c", "rw" ))==  NULL){ perror("open:"); exit(1); } 在Windows下试试，看看能不能直接运行perror和exit（windows下没有/home/目录）  楼主需要了解windows 和LINUX系统的区别，不能拿到代码就用，因为会有移植的问题～


Question: 求100以内的素数

修正11#楼的第19行：if(n%i==0) return 0;

引用 9 楼 智者知已应修善业的回复:２楼的文字点击即可达例子，查看例子中代码。 好的，了解了，谢谢哈

供参考：//方法1：  int f(int n) {     int i;     if(n<=1) return 0;     for(i=2;i<n;i++)         if(n%i==0) break;     if(i<n) return 0;     else    return 1; }  //方法2： int f(int n) {     int i;     if(n<=3) return n>1;     for(i=2;i*i<n;i++)         if(n%i==0) retrun 0;     return 1; }

希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

２楼的文字点击即可达例子，查看例子中代码。

在２楼判断质数可参就是链接地址，难道这都不知？

提供的网址？

引用 5 楼 智者知已应修善业的回复:按提供的网址例子修改即可。 提供的网址？

按提供的网址例子修改即可。

函数f有问题呢，你的if (i < n)和else都应该放在循环外呢，而不是应该是循环内。  if (i < n) y=0; else y = 1; 这几条语句放到循环外应该就是没问题了。试试～

引用 2 楼 智者知已应修善业的回复:判断质数可参 大神，请问有修改方案吗

判断质数可参

不用看，准是判断质数有问题。


Question: C 语言中，关于 ( ) 运算符的解释

在 for 语句中，关键字 for 后面的圆括号以及被括住的部分并不是语句，更不是复合语句，它只是组成 for 语句的一个成份：  for (声明/表达式1； 表达式2； 表达式3） 语句  下面这个程序，在标准C中是非法的、不可思议的，但它就是可以用 GNU C 编译并正常运行： # include <stdio.h>  int main (void) {     int n = 1, sum = 0;     printf ("%d\n", ({for (; n <= 100;) sum += n ++; sum;})); }

引用 6 楼 十敷 的回复:[quote=引用 3 楼 均陵鼠侠的回复:]这种写法在标准的C和C++中都是不合法的，属于 GNU C 的扩展。在 GNU C 中，可以用一对圆括号将复合语句括起来，如此一来，你就可以在表达式中使用循环语句、选择语句和局部变量。  具体的说明，详见 GCC 的这篇文档：https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Statement-Exprs.html 那这么说来 for 循环也是gnuc 拓展嘛？ [/quote] for 怎么是 GNU C 的扩展呢？说说你的理由。

引用 3 楼 均陵鼠侠的回复:这种写法在标准的C和C++中都是不合法的，属于 GNU C 的扩展。在 GNU C 中，可以用一对圆括号将复合语句括起来，如此一来，你就可以在表达式中使用循环语句、选择语句和局部变量。  具体的说明，详见 GCC 的这篇文档：https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Statement-Exprs.html 那这么说来 for 循环也是gnuc 拓展嘛？

引用 7 楼 均陵鼠侠的回复:[quote=引用 6 楼 十敷 的回复:][quote=引用 3 楼 均陵鼠侠的回复:]这种写法在标准的C和C++中都是不合法的，属于 GNU C 的扩展。在 GNU C 中，可以用一对圆括号将复合语句括起来，如此一来，你就可以在表达式中使用循环语句、选择语句和局部变量。  具体的说明，详见 GCC 的这篇文档：https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Statement-Exprs.html 那这么说来 for 循环也是gnuc 拓展嘛？ [/quote] for 怎么是 GNU C 的扩展呢？说说你的理由。[/quote] 第一 用小括号括的复合语句 第二 在括号里可以用局部变量 其实我都不大了解啥是gnu 只是看到您的解释突发奇想

引用 3 楼 均陵鼠侠 的回复:这种写法在标准的C和C++中都是不合法的，属于 GNU C 的扩展。在 GNU C 中，可以用一对圆括号将复合语句括起来，如此一来，你就可以在表达式中使用循环语句、选择语句和局部变量。  具体的说明，详见 GCC 的这篇文档：https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Statement-Exprs.html 感谢大哥解惑

Order of Evaluation This section discusses the order in which expressions are evaluated but does not explain the syntax or the semantics of the operators in these expressions. The earlier sections in this chapter provide a complete reference for each of these operators.  Expressions are evaluated according to the precedence and grouping of their operators. (Table 1.1 in Chapter 1, Lexical Conventions, shows the relationships the C++ operators impose on expressions.) Consider this example:  #include <iostream.h>  void main() {     int a = 2, b = 4, c = 9;      cout << a + b * c << "\n";     cout << a + (b * c) << "\n";     cout << (a + b) * c << "\n"; }  The output from the preceding code is:  38 38 54  Figure 4.1   Expression-Evaluation Order     The order in which the expression shown in Figure 4.1 is evaluated is determined by the precedence and associativity of the operators:   Multiplication (*) has the highest precedence in this expression; hence the subexpression b * c is evaluated first.   Addition (+) has the next highest precedence, so a is added to the product of b and c.   Left shift (<<) has the lowest precedence in the expression, but there are two occurrences. Because the left-shift operator groups left-to-right, the left subexpression is evaluated first and then the right one.  When parentheses are used to group the subexpressions, they alter the precedence and also the order in which the expression is evaluated, as shown in Figure 4.2.  Figure 4.2   Expression-Evaluation Order with Parentheses    Expressions such as those in Figure 4.2 are evaluated purely for their side effects — in this case, to transfer information to the standard output device.  Note   The left-shift operator is used to insert an object in an object of class ostream. It is sometimes called the “insertion” operator when used with iostream.

Expression Statement Expression statements cause expressions to be evaluated. No transfer of control or iteration takes place as a result of an expression statement.  Syntax  expression-statement:  expressionopt ;  All expressions in an expression statement are evaluated and all side effects are completed before the next statement is executed. The most common expression statements are assignments and function calls. C++ also provides a null statement.    {语句1;语句2;} //将两个语句组合成一个语句 Compound Statements (Blocks) A compound statement consists of zero or more statements enclosed in curly braces ({ }). A compound statement can be used anywhere a statement is expected. Compound statements are commonly called “blocks.”  Syntax  compound-statement :  { statement-listopt }  statement-list :  statement statement-list  statement  The following example uses a compound statement as the statement part of the if statement (see The if Statement for details about the syntax):  if( Amount > 100 ) {     cout << "Amount was too large to handle\n";     Alert(); } else     Balance -= Amount;  Note   Because a declaration is a statement, a declaration can be one of the statements in the statement-list. As a result, names declared inside a compound statement, but not explicitly declared as static, have local scope and (for objects) lifetime. See Scope in Chapter 2 for details about treatment of names with local scope.    (语句) //将语句当作表达式计算其值 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, ( ).


Question: 这道题，中间那里出错了。运行没问题，输出错误

希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html

程序没看出什么问题，输出是什么错误？输入又是什么内容，这些建议都贴出来吧。


Question: 求助 大一C语言课程设计

引用 4 楼 weixin_52677262 的回复:[quote=引用 2 楼 it_xiangqiang的回复:] 希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 咋还要付钱[/quote] 你认为呢？这是推销个人付费博客的，几乎每个帖子都发，谁付钱给谁看，csdn也推荐这个很无语；

引用 2 楼 it_xiangqiang的回复:希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 咋还要付钱🐶

引用 2 楼 it_xiangqiang的回复:希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 咋还要付钱，而且没看见有什么与我的问题相关的啊😂


Question: 大佬们，我这个哪里出问题了，我是个新手。

计算机代码不允许使用中文符号

#include<stdio.h> int main(void) { 	int a=2,b=3; 	a=a+b; 	b=a-b; 	a=a-b; 	printf("%d,%d\n",a,b); 	return 0; } 注意细节问题，把结构背清楚 而且你这个运算意义不大，可以尝试四则运算

好歹发一下源码啊！

注意中英文和单词拼写错误～这是最基本的语法问题～

这个教程适合你，希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html

哪里错了呀，是空格还是啥出问题了

是  printf  不是 prirtf        另外怀疑你的 " " 用的是中文字符， 关闭输入法

第四行mint ,多打了m 呀，int a=2,b=3;


Question: 返回值是什么?为什么?

忽视了, 应该设置变量保存初始地址

引用 3 楼 aguang 的回复:char *mystrcpy(char *s,const char *t) { 	while (*s++=*t++); 	*s='\0'; 	return s; } 返回字符串末尾地址？

返回值是目的串的地址，这个函数用于字符串拷贝，将源串拷贝到目的串（那个参数是目的串地址可以自由指定），可以通过两种方式获取目的串的地址，一个是参数，再一个就是这个返回值。  楼主写的不对，应该返回s1。另外，既然是所有都拷贝，因此，不需要用两个循环变量，用一个即可，或者一个也不用，如下供参考～  char *mystrcpy(char *dst, const char *src) {     char *tmp = dst;      while (*src)         *dst++ = *src++;     *dst = 0; //'\0'      return tmp; }

函数需要返回的是数组s1的第一个元素的指针，相当于返回&s1[0]，楼主的函数返回的是  return s2; ,  修改如下，供参考：char *mystrcpy(char *s1,char *s2) {     int i=0;     for(i=0;s2[i];i++)         s1[i] = s2[i];     s1[i] = '\0';     return s1;//返回的是s1的首地址 }

根据C语言定义, 对于 'T s[常量表达式]' 即s是T类型的数组;   表达式s的值是指向数组中第1个对象的指针(表达式&/ziseof情形除外). 所以s的值是一个地址,而且 *s==s[0]

这里面有，希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html


Question: 求帮助

希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

scanf是一种方式输入，printf是一种方式输出，fprintf是不是也算一种  fgets，fputs也算一种输入输出？


Question: 不太清楚哪里错了，一直显示错误(๑´0`๑)

这里面有，希望对您有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

方法多 #include <stdio.h> int main() {   int n, b=0,s=0;   for (; (n=getchar())&&n!='\n'; b++, s += n-'0')   printf("%d %d\n", b, s);   return 0; } #include <stdio.h> int main (void) {     int a=0,b=0,c;     scanf("%d",&c);     for(;c>0;a++,b+=c%10,c/=10);     printf("%d %d",a,b); }

引用 4 楼 早打大打打核战争 的回复:思路决定代码：  #include <stdio.h>  int main() {   int n, b, s;    for (b = s = 0; ~scanf("%1d", &n); b++, s += n);   printf("%d %d\n", b, s);    return 0; }  还需要提醒一句吧，怎么输出结果（终止循环）  ctrl+d(linux)或ctrl+z（Windows）

修改如下，供参考：#include<stdio.h>  int main()  {     int n,i=0,x=0,y;      scanf("%d",&n);      if(n<=1000000000&&n!=0)      {        while(n)//for(i=1;i<=9;i++)          {            y=n%10;            x+=y;            n=n/10;            i++;            //if(n==0)                          //    break;                          // else                          // i++;         }     printf("%d %d",i,x);    }          return 0; }

#include<stdio.h> #include <ctype.h> int main(void) {  #if 1     char digit[128], *pstr;     int cnt = 0, sum = 0;      fgets(digit, sizeof(digit), stdin);      if (digit[0] == '-') {         printf("Error input!\n");         return -1;     }     pstr = digit;     while (*pstr) {         if (isdigit(*pstr)) {             sum += *pstr - '0';             cnt++;         }         pstr++;     }      printf("%d %d\n", cnt, sum); #else     int n,i,x=0,y;      scanf("%d",&n);      if(n<=1000000000&&n!=0)     {         for(i=1;i<=9;i++)          {             n=n/10;             y=n%10;             x+=y;             if(n==0)                 break;             else                 i++;         }         printf("%d %d",i,x);     } #endif     return 0;  } 供参考～

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


Question: C#文件内容修改

所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。http://bbs.csdn.net/topics/391975224


Question: 引发了未经处理的异常:读取访问权限冲突。 q 是 0xCCCCCCCC，求大佬解答

#include<stdio.h> #include<stdlib.h>  typedef int Elemtype; typedef struct link {     int elem;     struct  link* next; }link;  link * initLink() {     link *p = (link *)malloc(sizeof(link));//创建一个头结点     if (!p)         exit(0);     link* temp = p;//声明一个指针指向头结点，用于遍历链表     //生成链表     for (int i = 1; i < 5; i++) {         link* a = (link*)malloc(sizeof(link));         if (!a)             exit(0);         a->elem = i;         a->next = NULL;         temp->next = a;         temp = temp->next;     }      return p; } //void bianli(link* p) void bianli(link* phead) {     if (!phead)         return;     //link* q = phead;     link* q = phead->next;      //while (q->next)     while (q)     {         //q = q->next;         printf("%d",q->elem);         q = q->next;     }     printf("\n"); }  int main() {     link* p = initLink();     //bianli(&p); //visit     bianli(p); //visit      return 0; } 供参考～  参数类型不匹配，其他问题详见代码～

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html

供参考：#include<stdio.h> #include<stdlib.h> typedef int Elemtype;  typedef struct link {     int     elem;     struct  link* next; }link;  link * initLink() {     link* p = (link*)malloc(sizeof(link));//创建一个头结点     link* temp = p;//声明一个指针指向头结点，用于遍历链表      //生成链表     for (int i = 1; i < 5; i++) {          link* a = (link*)malloc(sizeof(link));          a->elem = i;          a->next = NULL;          temp->next = a;          temp = a; //  temp = temp->next;     }     return p; } void bianli(link* p) {     link* q = p;     while (q->next)     {           q = q->next;           printf("%d ",q->elem);     }     printf("\n"); }   int main() {     link* p = initLink();     bianli(p);           //bianli(&p);          return 0; }

111求解啊


Question: 谁能帮我写个完整的C语言程序解决这个问题，谢谢！


Question: c语言  表达式中连续多次自增运算相加为什么表达式会自加1

求值顺序未定义，编译器可以自行决定，甚至同一编译器不同选项的情况下可以有不同的结果，第一个表达式，5+6+7、 6+6+7、7+7+7都有可能

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

当着出这个题目的人面骂他是傻X。然后扔一份C++的标准到他脸上让他自己看


Question: 求助帖 这道C语言不知道错哪了

小白写的，可以参考   #include<stdio.h>  int main() { 	const int length = 9; 	int numbers[length] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  	for (int i = 0; i < 9; i++) 	{ 		printf("%d ", numbers[i]); 	} 	printf("\n");  	printf("要移动的次数："); 	int moveCounts; 	scanf_s("%d", &moveCounts);  	int temp; 	for (int i = 0; i < moveCounts; i++) 	{ 		temp = numbers[length - 1]; 		for (int j = length - 1; j > 0; j--) 		{ 			numbers[j] = numbers[j - 1]; 		} 		numbers[0] = temp; 	}  	for (int i = 0; i < length; i++) 	{ 		printf("%d ", numbers[i]); 	}  	return 0; }

供参考：#include<stdio.h> #define N 9 int main() {     int i,j,n,m;     int a[N]={12,54,85,39,51,76,90,14,20};     printf("请输入要移动的位数:");     scanf("%d",&n);     for(i=0;i<n;i++){         for(j=N-1,m=a[j];j>0;j--){             a[j] = a[j-1];         }         a[j]=m;     }     for(i=0;i<N;i++){         printf("%d ",a[i]);     }     printf("\n");          return 0; }


Question: c语言桌面程序无响应

代码完整贴上来。

引用 1 楼 user-2的回复:个人觉得SDK纯API方式编写Windows程序已经过时了，效率太低，了解一下原理就可以了，主要是消息机制。  图形用户界面（GUI）编程可以学习C++ Builder，架构先进（和C#一样拖控件），入门比较容易。  　　C++ Builder是真正的可视化的开发工具。C++ Builder可以用鼠标拖拉控件加上设置属性轻松的“设计”出一个程序的图形用户界面，利用可视的组件/控件像“搭积木”一样，以“所见即所得”的方式搭建应用程序的界面，这也是C++ Builder这个名字中Builder的概念。这样，只需要用C++语言编写业务逻辑代码，类似于DOS下文本界面编程，只要专注于实现业务逻辑功能就可以了，代码非常简洁。数据的输入和表现，都在图形用户界面，非常直观、易用。这就是RAD开发（Rapid Application Development，快速应用程序开发）。  书籍推荐： 《C++Builder 6程序设计教程（第二版）》 （陆卫忠，刘文亮　等编著 /2011-04-01 /科学出版社）（当当网） 《C++Builder 6编程实例精解》（赵明现），PDF，是数字版的，非扫描版的，里面还有一个俄罗斯方块游戏的完整实现。 《精彩C++Builder 6程序设计》（台湾 吴逸贤），里面有10几个简单小游戏的实现，可以自己看懂以后再重写，才是自己掌握的。 《C++ Builder 5高级编程实例精解》（刘滨 编著）都是较大的实用的程序。  C++ Builder 6.0几个示例程序项目源代码下载：       C++ Builder第一个程序（模拟聊天室）v1.11 C++ Builder模拟数字双时钟示例（未完成）v0.2.1 C++ Builder纸牌游戏Demo v0.05 C++ Builder不规则图像透明贴图（位图的透明显示）三种方法及简单动画v1.3 C++ Builder写的《ZEC 四则运算练习程序》 海底海星情景v0.9.2 C++ Builder简单电话簿Demo例子v1.11 不是就是想简单尝试一下，但是总是找不到bug在哪，一开始输入数据好好的，每次到了一定程度就卡死不动了


Question: 要求是回文数又是素数，为什么两个代码运行出来不一样。

两个方法都存在漏洞和错误，第一种里，for(f=2;f<=e;f++)if(b%f==0)return 0; ，如果b素数时，if(b%f==0)return 0; 这条语句不会被执行到，也就意味着到函数运行结束，也没有一个明确的返回值，主函数里的if()判断靠什么去判断呢， 这是潜在的隐患。第二种是错上加错，不但第一种的隐患没排除，还把判断if(b%f!=0) return 1; 条件搞反了，把不是 素数的也归到素数里去了，假如b=9时，9%2!=0成立，马上return 1。

引用 2 楼 qzjhjxj的回复:修改第一个，供参考：#include<stdio.h> #include<math.h> int sushu(int b); int huiwen(int c); int main() {     int a;     for(a=100;a<1000;a++)     {         if(sushu(a) && huiwen(a))            printf("%d\n",a);     }          return 0; }  int sushu(int b) {     int e,f;     e=sqrt(b);     for(f=2;f<=e;f++)        if(b%f==0)return 0;     return 1; }  int huiwen(int c) {     int g,h;     g=c/100;     h=c%10;     if(g==h)        return 1;     return 0; } 第二种方法的，第二个自定义函数为啥不对。

引用 1 楼 user-2的回复:两个都不对啊，验证素数的函数总得既能返回0又能返回1吧？这样才符合逻辑啊。 错在第二个自定义函数if的判断

引用 1 楼 user-2的回复:两个都不对啊，验证素数的函数总得既能返回0又能返回1吧？这样才符合逻辑啊。 第一个对的，第二个不对

两个都不对啊，验证素数的函数总得既能返回0又能返回1吧？这样才符合逻辑啊。


Question: 用C语言实现排名

相同的成绩，不同的排名，给的条件不充分，如果按字面的理解很简单就实现了。


Question: 【C语言求助】一道有yi点难的链表题

引用 6 楼 qzjhjxj的回复: 谢谢你一直以来的帮助

引用 6 楼 qzjhjxj的回复: 哈哈哈 我这边C语言的洗礼结束了，但是学习不会止步。 最后的期中考题独立完成，爽爽哒 要去学Python了。。。

大家先不用回复，我再改改，这个版本甚至都不完善

C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html

供参考~ 欢迎大家找错（滑稽）#include <stdio.h> #include <stdlib.h> #include <time.h> /*  1.链表与数组综合操作(本题满分100分，每问20分)  a) 生成一个长度100、取值范围在0-300的整数构成的链表，并打印  b) 将其按从小到大的顺序插入到另一个链表，并遍历打印  c) 将这个排好序的链表的结果写入到文件1000_numbers.txt  d) 再从文件读入数据，存储到一个数组，并打印  e) 统计出现频次最多的数字，并打印 */ struct node {     int num;     struct node *next; }; struct node *creat_lianbiao() {     //生成一个长度100，取值范围在0-300的随机整数构成的链表...Done     //int num;     srand( time(0) );      int i = 0;     struct node  *head = NULL, * p = head, *newnode = NULL;     while(1)     {          newnode = (struct node *)malloc(sizeof(struct node));         newnode->num = rand()%301 ;         //printf("%d ",newnode->num);          if(head == NULL)         {             head = newnode;             p = head;         }          else if(head != NULL)         {              p->next = newnode;             p = p->next;         }          i++;          if(i == 100)         {             p->next = NULL;             break;         }      }     //p=head;     return head; } //遍历打印链表的函数 void print_lianbiao(struct node *head) {     struct node *p = head;     int i = 0;     while(p != NULL)     {         i++;         printf("the %dth number: ", i );         printf("%d\n", p->num );         p = p->next;      } } /*核心部分：   说明：       1.本题不能在原链表里排序后再插入到另一个链表       2.不能使用链表进行插入       3.我的想法是：循环，找出每次循环的最小值，                     把这个最小值所在的结点插入到新建的链表里，同时在原链表里删除该结点                     这样在下一次循环的时候就不会找到上次的最小值       4.问题是循环无法执行下去  */ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ struct node *creat_sort_lianbiao(struct node *head) {     struct node *p = head, *head_2 = NULL ,*p_min = head ,*p_2 = head_2 ,*newnode_2 = NULL ,*tmpnode = NULL;     int min = p_min->num ,i = 0;      while(1)//     {         p = head;         min = head->num;         p_min = head;         while(1)//每次循环找当前链表里的最小值         {              if(min > p->num)//如果min记录的大于当前值             {                 //printf("Done...\n");                 min = p->num;                 p_min = p;//把当前值的地址给p_min              }             printf("min=%d\n",min);             if(p->next == NULL) break; //如果到尾了，break             p = p->next;         }         p = head;          i++;         while(1)//每次循环把原链表的min值所在地址赋给p_2，并将原链表的该结点删除         {              if(p_min == head)             {                        newnode_2 = (struct node *)malloc(sizeof(struct node));//开辟节点                     newnode_2->num = p_min->num;                     newnode_2->next = NULL;                    // p_2->next->next = (struct node *)malloc(sizeof(struct node));//再开辟节点                      if(head_2 == NULL)//如果head_2是空链表                     {                         //printf("%d",head_2);                         head_2 = newnode_2;                         p_2 = head_2;                         p_2->next = NULL;                          tmpnode = head;                         head = head->next;                         free(tmpnode);                          p = head;                          //printf("%d\n",head_2);                         printf("p_2->num = %d\n", p_2->num );                         break;                      }                     else if(head_2 != NULL)                     {                         //p_2 = head_2;                         p_2->next = newnode_2;                         p_2 = p_2->next;                         p_2->next = NULL;                          tmpnode = head;                         head = head->next;                         free(tmpnode);                          p = head;                          printf("p_2->num = %d\n", p_2->num );                         break;                      }              p = p->next;              }              else if(p_min != head)             {                   if(p->next == p_min)//循环搜索，如果匹配到p_min                 {                     printf("I find it !\n");                      newnode_2 = (struct node *)malloc(sizeof(struct node));//开辟节点                     newnode_2->num = p_min->num;                     newnode_2->next = NULL;                     // p_2->next->next = (struct node *)malloc(sizeof(struct node));//再开辟节点                      if(head_2 == NULL)//如果head_2是空链表                     {                         //printf("%d",head_2);                         head_2 = newnode_2;                         p_2 = head_2;                         p_2->next = NULL;                         p->next = p->next->next; //删除原链表中的min值的节点                         free(p_min);                          //printf("%d\n",head_2);                         printf("p_2->num = %d\n", p_2->num );                         break;                      }                     else if(head_2 != NULL)                     {                          p_2->next = newnode_2;                         p_2 = p_2->next;                         p_2->next = NULL;                         p->next = p->next->next;                         free(p_min);                          printf("p_2->num = %d\n", p_2->num );                         break;                      }                  }                 p = p->next;              }           }         printf("The %dth round\n",i);         if(i == 100)//如果执行了100次就结束         {             //printf("Done...\n");             break;         }      }     //printf("Done...\n");     return head_2;    } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  void main() {     printf("This is the mid-term exam of 张圣儒 no.20344152\n");     printf("第一题：\n");     struct node * head = NULL, * p = head ,* head_2=NULL;      head = creat_lianbiao();//生成一个长度100，取值范围在0-300的随机整数构成的链表...Done     print_lianbiao(head);//打印原链表...Done     putchar('\n');     putchar('\n');     head_2 = creat_sort_lianbiao(head);//生成新的链表     //printf("Done...");     print_lianbiao(head_2);//打印新的链表   }  （a）（b）步运行结果：

啊。。。经过艰苦的奋斗，我终于。。。终于完成了，bug也修完了(没想到是被自己解决的)

第二大段注释那里“不能用链表排序”打错了，应该是“不能用数组辅助排序”


Question: 请问这个杨辉三角的第五行的113是怎么得到的啊？

建议贴代码。百度下。

引用 1 楼 舉杯邀明月的回复:代码有BUG呗，第5行的数据是 1 4 6 4 1 才对。  怎么解决啊？

代码有BUG呗，第5行的数据是 1 4 6 4 1 才对。


Question: c语言求助


Question: c语言求助

引用 5 楼 qzjhjxj的回复:怎么不对？可以把sum <=3000条件改小点，改为sum <=10 看看是否是正确。 没错谢谢是自己电脑问题

引用 5 楼 qzjhjxj的回复:怎么不对？可以把sum <=3000条件改小点，改为sum <=10 看看是否是正确。 谢啦

引用 5 楼 qzjhjxj的回复:怎么不对？可以把sum <=3000条件改小点，改为sum <=10 看看是否是正确。 应该没错，我不管改成多少他这个结果都和我第一次输入的数据算出来的结果一样，可能电脑有点问题

引用 2 楼 qzjhjxj的回复:供参考：#include<stdio.h>  void main() {      int i=1,sum=0;      while(sum<=3000)      {          sum += i;          i++;      }      printf("1+2+3+...+%d=%d\n",--i,sum);       } 为什么我这个运行以后的结果好像不太对

变量i没有被初始化

声明一下，我只是看 main 函数的返回类型是 void 觉得不顺眼，所以回复一下，哈哈哈。 # include <stdio.h>  int main (void) {     int n = 1, sum = 0;      while ((sum += n ++) <= 3000) ;      printf ("%d\n", n); }


Question: c语言求助

引用 1 楼 浪客的回复:楼主太懒，提示中把题目答案几乎都给出来了。   #include <stdio.h>  void print(int A[4])  //后面都是相同的输出，图省事 { 	for (int i = 0; i < 4; i++) 	{ 		printf("%d\t", A[i]); 	} 	printf("\n"); }  int main() { 	int C[4][4], AB[4], BB[4], AC[4], i, j; 	int A[4][4] = { 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 }; 	int B[4][4] = { 2,4,6,8,10,12,14,16,18,20,22,24,46,28,30,32 };  	// C=A+B 	for (i = 0; i < 4; i++) 	{ 		for (j = 0; j < 4; j++) 		{ 			C[i][j] = A[i][j] + B[i][j]; 		} 	}  	printf("Array C[4][4]:\n"); 	for (i = 0; i < 4; i++) 	{ 		for (j = 0; j < 4; j++) 		{ 			printf("%d\t", C[i][j]); 		} 		printf("\n"); 	}  	// AB 	for (i = 0; i < 4; i++) 	{ 		AB[i] = A[1][i];	//第二行：A[1][0]...A[1][3] 	} 	printf("\nArray AB[4]:\n"); 	print(AB);  	// BB 	for (i = 0; i < 4; i++) 	{ 		BB[i] = B[i][2];	//第三列：B[0][2]...B[3][2] 	} 	printf("\nArray BB[4]:\n"); 	print(BB);  	// AC 	for (i = 0; i < 4; i++) 	{ 		AC[i] = A[i][i]+B[i][i];	//这个数组中，对角线行列索引相等 	} 	printf("\nArray AC[4]:\n"); 	print(AC);  	return 0; }   为什么运行有错误


Question: c语言求助

引用 1 楼 weixin_57293030的回复:第一个 if 写的不对  if(n>m)  好像是m>n

引用 2 楼 weixin_57293030的回复:第一个回复写反了，应该是  if(m>n)

供参考：#include<stdio.h> void main() {     int m,n,t,i,sum=0,count=0;     printf("Enter m,n:");     scanf("%d%d",&m,&n);     if( m > n){t=m;m=n;n=t;}     for(i=m;i<=n;i++)        if(i%3==0 && i%5!=0)        {           sum += i;           count++;        }     printf("sum=%d;count=%d\n",sum,count);      }

第一个回复写反了，应该是  if(m>n)

第一个 if 写的不对  if(n>m)


Question: 谁能帮我写个完整的C语言程序，解决这个问题，谢谢！

供参考：#include<stdio.h> #include<math.h>  int sort(float *a,int n) {     int   i,j;     float t;     for(i=0;i<n-1;i++)         for(j=0;j<n-i-1;j++)             if(fabs(*(a+j)) < fabs(*(a+j+1)))//从大到小                {                   t      =*(a+j);                   *(a+j) =*(a+j+1);                   *(a+j+1)=t;                } }  int main() {     float a[10];     int   i;     for(i=0;i<10;i++)         scanf("%f",&a[i]);     sort(a,10);     for(i=0;i<10;i++)         printf("%.2f%c",a[i],i<9?',':'\n');      return 0; }

好人一生平安！！！


Question: 求助

C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html

int main 是不是要return一个int呢？

楼主这个代码没什么问题，解释见注释，供参考：//程序内容是实现回文数的判断：  //还有一个问题： //为了存储输入数字每一位上的数，我在程序中定义了一个容量为9999的数组，怎么实现根据输入数字 //的位数来定义数组的容量啊？？   #include <stdio.h>  int main() {             //问题一：     int b[10];//C语言中int的取值范围为：-2147483648 ~ 2147483647，十进制最大是10位数，所以b[？]不用这么大      int a,n=0,i=0,j=0,c;     printf("请输入一个数\n");     scanf("%d",&a);     c=a;     //如果在这里加入动态数组的定义，最前面的 int b[10]; 定义需删除或在头部加'//' 改为注释     //根据输入数字的位数来定义数组容量：你先需计算出输入数字的位数n，     //然后: int *b = (int *)malloc(sizeof(int)*n); memset(b,0,sizeof(int)*n);      for(a=c;a>=10;a=a/10)     {         b[i]=a%10;         i=i+1;     }     b[i]=a%10;     if(i%2==1)     {        for(n=0;n<(i+1)/2;n++)        {           if(b[n]==b[i-n])           {              j=j+1;           }        }        if(j==(i+1)/2)           printf("True");        else           printf("False");     }     else     {       for(n=0;n<=i/2;n++)       {           if(b[n]==b[i-n])           {              j=j+1;           }       }       if(j==i/2+1)          printf("True");       else          printf("False");     }     //如果定义b[]是动态的，在代码结束语句之前输入：free(b);显式释放数组，或不加 = 隐式释放。          return 0; }   //问题二： // error: redefinition of 'main'编译错误,main的重复定义 //这个题库的操作方法就是：只需要补上 欠缺的代码 即可


Question: 萌新求助，我到底哪里错了？

重点在第8行末或第9行末的‘;'号 ，scanf("%d%d",&hour2,&minute2); int t1 = hour1 * 60 + minute1; #include<stdio.h>  int main() {      int hour1,minute1;      int hour2,minute2;      scanf("%d%d",&hour1,&minute1);      scanf("%d%d",&hour2,&minute2);      int t1 = hour1 * 60 + minute1;      int t2 = hour2 * 60 + minute2;      int t  = t2-t1;      printf("时间差是%d小时%d分钟。",t/60,t%60);            return 0; }

你违背了你的编译器规则，变量声明要在执行语句之前。


Question: 萌新求助！

引用 3 楼 qzjhjxj的回复:两句scanf() 输入在后，计算t值在前，它们用什么计算呢？这样改下，供参考：#include<stdio.h>  int main() {      int hour1,minute1,t1,t2,t;      int hour2,minute2;       scanf("%d%d",&hour1,&minute1);      scanf("%d%d",&hour2,&minute2);       t1 = hour1 * 60 + minute1;      t2 = hour2 * 60 + minute2;      t  = t2-t1;      printf("时间差是%d小时%d分钟。",t/60,t%60);            return 0; } 感谢！学会了！

scanf后面写t1=hour1*60+minute1；t2=hour2*60+minute2;t=t2-t1;

输入完后再赋值，hour1，minute1，hour2，minute2，还没开始输入数值赋值，你初始化时就用来给t1和t2和t赋值了，后面输入完数据后又没有给t1，t2，t，赋值。


Question: 谁能帮我写个C语言程序解决这个问题吗，谢谢

引用 6 楼 qzjhjxj的回复:编译之前，我放在#2楼的修正说明，int i=0；那里你改过了吗？#include<stdio.h> //#include<string.h>  int main() {     char str[1024][64]={0},tmp[64]={0};     int  i=0,j,k;     while(gets(str[i++])!=NULL);//ctrl+z 结束输入     for(j=0;j<i-1;j++)         for(k=0;k<i-j-1;k++)             if(strcmp(str[k],str[k+1])>0){                strcpy(tmp,str[k]);                strcpy(str[k],str[k+1]);                strcpy(str[k+1],tmp);             }     for(j=0;j<i;j++) puts(str[j]);     system("pause");     return 0; }   //zwtr //fhoenf //hefe //afe geg^Z  //afe geg //fhoenf //hefe //zwtr //请按任意键继续. . .  开始运行不了是我的问题，谢谢作者！

引用 4 楼 qzjhjxj的回复:什么样的问题？ 程序无法执行，或者发生运行时错误

什么样的问题？

引用 1 楼 qzjhjxj的回复:供参考：#include<stdio.h> #include<string.h>  int main() {     char str[1024][64]={0},tmp[64]={0};     int  i,j,k;     while(gets(str[i++])!=NULL);//ctrl+z 结束输入     for(j=0;j<i-1;j++)         for(k=0;k<i-j-1;k++)             if(strcmp(str[k],str[k+1])>0){                strcpy(tmp,str[k]);                strcpy(str[k],str[k+1]);                strcpy(str[k+1],tmp);             }     for(j=0;j<i;j++) puts(str[j]);          return 0; } 谢谢，但好像运行有点问题

修正楼上第7行，i 初始值int  i=0,j,k;

#include <stdio.h> #include <stdlib.h> #include <string.h>  #define MAXLINES 1000 #define BUFSIZE 10000  int readlines(char *[],char buf[],int); void qsort1(char *[],int,int); void writelines(char *[],int);  int main() {     int nlines;     char *lineptr[MAXLINES];     char buf[BUFSIZE];      if ((nlines=readlines(lineptr,buf,MAXLINES))>0){         qsort1(lineptr,0,nlines-1);         writelines(lineptr,nlines);         return 0;     }else{         printf("error");         return 1;     } } #define MAXLINE 100 int readlines(char *lineptr[],char v[],int maxlines) {      int nlines,len;     char line[MAXLINE];     char *p =v;     char *top = v+BUFSIZE;     int getline(char *,int);      nlines =0;     while ((len = getline(line,MAXLINE)) > 0){         if (nlines >= maxlines || (p + len) > top ){             return -1;         }else{             line[len-1] = '\0';             strcpy(p,line);             lineptr[nlines++] = p;             p += len;          }     }      return nlines; }  int getline(char *s,int imt) {     int c;     char *t =s;     while (--imt > 0 && (c = getchar()) != EOF && c != '\n')         *s++ = c;     if (c == '\n')         *s++ = c;     *s = '\0';     return s-t; }  void writelines(char *s[],int n) {     while (n-- > 0)         printf("%s\n",*s++); }  void qsort1(char *v[],int left,int right) {     int lastc,i;     void swap(char *[],int,int);      if (left >= right)         return;     swap(v,left,(left+right)/2);     lastc =left;     for (i = left+1;i<=right;i++)         if (strcmp(v[i],v[left])<0)             swap(v,++lastc,i);     swap(v,lastc,left);     qsort1(v,left,lastc-1);     qsort1(v,lastc+1,right); } void swap(char *v[],int i,int j) {     char *temp;      temp = v[i];     v[i] = v[j];     v[j] = temp; }


Question: 谁能帮我写个C语言程序结解决一下，谢谢

#include <stdio.h> #include <ctype.h> #include <stdlib.h> #define NUMBER '0' #define N 10  //输入浮点数个数  int main(void) {     int i,c,getfloat(char *);     float tmp,a[N], *s,*p = a;     char b[100];      i=0;     printf("请输入10个浮点数(空格或回车符分隔): \n");     while (i < N && (c = getfloat(b)))     {         if (c == NUMBER)         {             *p++ = atof(b);             i++;         }         else if ((c == '\n' || c == EOF) && i < N)             printf("已输入%d个数, 请继续输入%d个数: ",                    i, N - i);         else         {             printf("error: 请输入浮点数.");             exit(1);         }     }     for (p = a + i - 1; p > a; p--)         for (s = a; s <= p - 1; s++)             if (abs(*s) < abs(*(s + 1)))             {                 tmp = *s;                 *s = *(s + 1);                 *(s + 1) = tmp;             }     for (p = a; p < a + i; p++)         printf("%2.2f ", *p);      return 0; }  int getfloat(char *s) {     int c;     static int lastc = 0;      if (lastc == 0)         c = getchar();     else     {         c = lastc;         lastc = 0;     }     while (isspace(s[0] = c) && c != '\n' && c != EOF)         c = getchar();     s[1] = '\0';     if (isdigit(c) || c == '-' || c == '.')     {         while (isdigit(*++s = c = getchar()) || c == '-' || c == '.')             ;         *s = '\0';         lastc = c;         return NUMBER;     }     return c; }

#include <stdio.h> #include <stdlib.h> #include <math.h>  #define N 10  int main(){     float *p;          p=(float *)malloc(sizeof(float)*N);          for(int i=0;i<N;i++)     {       scanf("%f",p+i);      }          float tmp;     for(int i=0;i<N-1;i++)     {         for(int j=i;j<N;j++)         {             if(fabs(*(p+i)) < fabs(*(p+j)))              {                 tmp=*(p+i);                 *(p+i)=*(p+j);                 *(p+j)=tmp;              }         }     }          for(int i=0;i<N;i++)     {         printf("%.2f\n",*(p+i) );     }          return 0; }

引用 1 楼 浪客的回复:大概这样子。  float a[10],*p,tmp; p=a; for(int i=0;i<9;i++) {   for(int j=1;j<10;j++)   {     if(abs(*(p+i))<abs(*(p+j)))     {       tmp=*(p+i);*(p+i)=*(p+j);*(p+j)=tmp;     }   } }   能写个完整的程序吗，有点不能理解，希望写个完整的程序，谢谢！


Question: 函数

引用 1 楼 user-2的回复:供参考对照：#include<stdio.h>  int isprime(int a) {     int i;     if(a<=3)return a>1;     for(i=2;i*i<=a;i++)     {         if(a%i==0)return 0;     }     return 1; }  int outprime(int z) {      int j,cnt=0;      for(j=2;j<z;j++)      {          if(isprime(j))          {             printf("%4d",j);             cnt++;             if(cnt%6==0)printf("\n");          }      } }  int main() {      int t;      printf("请输入你想要求哪一个数范围内的质数:");      scanf("%d",&t);      outprime(t);            return 0; } 哇塞，感谢感谢

C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html


Question: 急急急，

引用 1 楼 阿麦的回复:存在 x !=y, 但f(x)=f(y)，就不存在反函数，否则存在反函数  大概是这个代码，没验证，意思到了。  const int N=100; int main() {     int cnt[N]={0};     bool Yes=True;     for(int x=0;x<n;x++) {         cnt[f(x)]++;     }     for(int x=0; x <n && Yes; x++) {         Yes = cnt[x] < 2;     }     // Yes 为 True 就是存在反函数，否则不存在     return 0; } 谢谢大哥 牛逼


Question: Char变量输入一个大于127的值，返回的结果问题

计算机底层是以二进制补码形式存储的，取数时会还原成原码，char占1字节，也就是8位，最高位为符号位，把197转成二进制就是11000101，而正数的原码反码补码都是一样的，但因为这里最高位为1，机器会把他当做负数，把它转换为原码之后就是-59了

引用 10 楼 均陵鼠侠的回复:[quote=引用 6 楼 拜你所赐 的回复:][quote=引用 5 楼 均陵鼠侠 的回复:][quote=引用 4 楼 拜你所赐 的回复:][quote=引用 3 楼 均陵鼠侠 的回复:]这是一个简单而又复杂的问题。  首先， %c 和 %d 都要求对应的变参是 int 类型。唯一不同的是，%c 是将这个 int 类型的变参转换为 unsigned char 类型的字符，然后予以显示，而 %d 则是将它转换为有符号十进制格式的数字字符予以显示。  其次，程序是没有问题的。尽管传入的变参是 char 类型的，但依照默认实参转换（default argument conversion）的规则，它是被转换为 int 类型之后传递给 printf 的。  最后，对于 printf 来说， %c 是将传入的值按 int 类型（的长度）取出，然后转换（缩小）为 unsigned char 类型（的长度），将它视为字符编码，然后打印这个字符； %d 是将传入的值按 int 类型（的长度）取出，拆分数位并转换为有符号十进制数字字符打印输出。这里的关键是， %d 要求这个转换过程必须区分数值的正负。这很好办，只需要判断其二进制形式的最高位（符号位）就可以了：为0是正数，为1是负数。然而，在197和198这两个数值的二进制形式中，符号位似乎并不是1。这就回到了开始：在将 char 类型的值转换为 int 类型并传递给 printf 时，是如何转换的？再往前，两个常量197和198的类型都是 int ，将它们赋给变量 c1 和 c2 时，需要从 int 转换为 char ，这个转换过程又是怎样的？  这就涉及到数值转换规则。首先，将一个整数类型的值转换为另一个除_Bool之外的整数类型时，如果这个值能够用新类型来表示，则转换后的值不变。  来看 char c1, c2; c1 = 197; c2 = 198;  在这里，如果 char 等价于 unsigned char ，那么，在主流的机器上，它可以表示的数值范围是 0到255，所以能够容纳，且 printf 不可能打印两个负值。显然，在楼主的环境下，char实际上是signed char。在主流的机器上，它可以表示的数值范围是-127到+128，故无法表示 197 和 198 ，需要转换。  但是，如果新类型是有符号的并且无法表示这个值，转换的结果要依赖于具体的编译器，甚至可能触发信号机制。即，C语言没有规定如何转换。  在很多平台上（显然包括楼主所在的机器环境），是直接把长度为 int 的 197 截断为 char 类型的长度。所以，最终它表示有符号数-59。   您好，非常感谢您的回复，我使用的编译器是VS2012。我是一个C语言的初学者，我对您的回复还有一些疑问，在您的回复中说到“在197和198这两个数值的二进制形式中，符号位似乎并不是1。”197 -->11000101      198  -->  11000110    直接转化成二进制的首位是否会直接成为符号位呢？烦请您帮忙把197到-59的过程详细说一下吗？[/quote]  对，我这两句话没说明白。  赋给 c1 和 c2 的值来自于常量 197 和 198 ，这两个常量的类型是 int 。所以，它们的最高位不是1，而是0。即，如果 int 类型的长度是 32 位，则 197 的二进制形式为 00000000000000000000000011000101 。把它截断为 char 类型的长度时，如果 char 类型的长度是 8，则截断后是 11000101 。[/quote]十分感谢您的解答，还有一个问题我没有搞明白，例如197.对于截断后的二进制11000101。它的最高位是1，即后面表示数值的二进制是“1000101”，转变成二进制之后为69。但是取其补码之后即为“0111010”它的十进制是“58”。截断之后为什么不是直接输出它的十进制而是取其补码呢？这点我有点搞不明白。[/quote] 对机器来说，截断之后，如果最高位是1，即表明它是一个负数，而负数本身就是采用补码的，不需要也不会再次转换为补码。要么是你把机器想得太复杂了，要么是一些不正确的说法影响了你的思维。  另一方面，负数有三种表示方法：符号带大小、对1的补码和对2的补码，C语言并没有限定采用哪种表示方法，这个取决于平台和编译器，只不过对2的补码是普遍的情况。无论采用哪种表示方法，从编程和运行的层面上基本上看不到，也不需要过问，毕竟它不影响输出和结果的正确性。所以，说负数采用补码，眼光过于局限了。[/quote] 谢谢老师，看了老师的回复才豁然开朗，钻了牛角尖，把机器想的太过于复杂了，十分感谢老师的解答！

引用 6 楼 拜你所赐 的回复:[quote=引用 5 楼 均陵鼠侠 的回复:][quote=引用 4 楼 拜你所赐 的回复:][quote=引用 3 楼 均陵鼠侠 的回复:]这是一个简单而又复杂的问题。  首先， %c 和 %d 都要求对应的变参是 int 类型。唯一不同的是，%c 是将这个 int 类型的变参转换为 unsigned char 类型的字符，然后予以显示，而 %d 则是将它转换为有符号十进制格式的数字字符予以显示。  其次，程序是没有问题的。尽管传入的变参是 char 类型的，但依照默认实参转换（default argument conversion）的规则，它是被转换为 int 类型之后传递给 printf 的。  最后，对于 printf 来说， %c 是将传入的值按 int 类型（的长度）取出，然后转换（缩小）为 unsigned char 类型（的长度），将它视为字符编码，然后打印这个字符； %d 是将传入的值按 int 类型（的长度）取出，拆分数位并转换为有符号十进制数字字符打印输出。这里的关键是， %d 要求这个转换过程必须区分数值的正负。这很好办，只需要判断其二进制形式的最高位（符号位）就可以了：为0是正数，为1是负数。然而，在197和198这两个数值的二进制形式中，符号位似乎并不是1。这就回到了开始：在将 char 类型的值转换为 int 类型并传递给 printf 时，是如何转换的？再往前，两个常量197和198的类型都是 int ，将它们赋给变量 c1 和 c2 时，需要从 int 转换为 char ，这个转换过程又是怎样的？  这就涉及到数值转换规则。首先，将一个整数类型的值转换为另一个除_Bool之外的整数类型时，如果这个值能够用新类型来表示，则转换后的值不变。  来看 char c1, c2; c1 = 197; c2 = 198;  在这里，如果 char 等价于 unsigned char ，那么，在主流的机器上，它可以表示的数值范围是 0到255，所以能够容纳，且 printf 不可能打印两个负值。显然，在楼主的环境下，char实际上是signed char。在主流的机器上，它可以表示的数值范围是-127到+128，故无法表示 197 和 198 ，需要转换。  但是，如果新类型是有符号的并且无法表示这个值，转换的结果要依赖于具体的编译器，甚至可能触发信号机制。即，C语言没有规定如何转换。  在很多平台上（显然包括楼主所在的机器环境），是直接把长度为 int 的 197 截断为 char 类型的长度。所以，最终它表示有符号数-59。   您好，非常感谢您的回复，我使用的编译器是VS2012。我是一个C语言的初学者，我对您的回复还有一些疑问，在您的回复中说到“在197和198这两个数值的二进制形式中，符号位似乎并不是1。”197 -->11000101      198  -->  11000110    直接转化成二进制的首位是否会直接成为符号位呢？烦请您帮忙把197到-59的过程详细说一下吗？[/quote]  对，我这两句话没说明白。  赋给 c1 和 c2 的值来自于常量 197 和 198 ，这两个常量的类型是 int 。所以，它们的最高位不是1，而是0。即，如果 int 类型的长度是 32 位，则 197 的二进制形式为 00000000000000000000000011000101 。把它截断为 char 类型的长度时，如果 char 类型的长度是 8，则截断后是 11000101 。[/quote]十分感谢您的解答，还有一个问题我没有搞明白，例如197.对于截断后的二进制11000101。它的最高位是1，即后面表示数值的二进制是“1000101”，转变成二进制之后为69。但是取其补码之后即为“0111010”它的十进制是“58”。截断之后为什么不是直接输出它的十进制而是取其补码呢？这点我有点搞不明白。[/quote] 对机器来说，截断之后，如果最高位是1，即表明它是一个负数，而负数本身就是采用补码的，不需要也不会再次转换为补码。要么是你把机器想得太复杂了，要么是一些不正确的说法影响了你的思维。  另一方面，负数有三种表示方法：符号带大小、对1的补码和对2的补码，C语言并没有限定采用哪种表示方法，这个取决于平台和编译器，只不过对2的补码是普遍的情况。无论采用哪种表示方法，从编程和运行的层面上基本上看不到，也不需要过问，毕竟它不影响输出和结果的正确性。所以，说负数采用补码，眼光过于局限了。

数值197是int类型, 赋值于char类型c1, 高位将被截去,即为11000101  当输出格式为%c: 按C定义:字符输出不会是负值, 所以结果为"?"; 当输出格式为%d: char类型变量如果没有加限定符(signed/unsigned),由机器本身规则确定是按符号数或无符号数处理.  就楼主例子, 由于对c1/c2没有用限定符,楼主机器是按符号数输出的.

计算机是按补码来存储的，所以截断后的11000101是补码，其中最高位的1是符号为表示是负数，后7位补码1000101转为原码是0111011，十进制是59，所以就是-59

引用 1 楼 user-5 的回复:百度“负数、补码” %c问号的原因是因为找不到对应的ASCII字符 我知道%c是找不到字符  就是不是很理解他那个%d输出的原理

引用 5 楼 均陵鼠侠 的回复:[quote=引用 4 楼 拜你所赐 的回复:][quote=引用 3 楼 均陵鼠侠 的回复:]这是一个简单而又复杂的问题。  首先， %c 和 %d 都要求对应的变参是 int 类型。唯一不同的是，%c 是将这个 int 类型的变参转换为 unsigned char 类型的字符，然后予以显示，而 %d 则是将它转换为有符号十进制格式的数字字符予以显示。  其次，程序是没有问题的。尽管传入的变参是 char 类型的，但依照默认实参转换（default argument conversion）的规则，它是被转换为 int 类型之后传递给 printf 的。  最后，对于 printf 来说， %c 是将传入的值按 int 类型（的长度）取出，然后转换（缩小）为 unsigned char 类型（的长度），将它视为字符编码，然后打印这个字符； %d 是将传入的值按 int 类型（的长度）取出，拆分数位并转换为有符号十进制数字字符打印输出。这里的关键是， %d 要求这个转换过程必须区分数值的正负。这很好办，只需要判断其二进制形式的最高位（符号位）就可以了：为0是正数，为1是负数。然而，在197和198这两个数值的二进制形式中，符号位似乎并不是1。这就回到了开始：在将 char 类型的值转换为 int 类型并传递给 printf 时，是如何转换的？再往前，两个常量197和198的类型都是 int ，将它们赋给变量 c1 和 c2 时，需要从 int 转换为 char ，这个转换过程又是怎样的？  这就涉及到数值转换规则。首先，将一个整数类型的值转换为另一个除_Bool之外的整数类型时，如果这个值能够用新类型来表示，则转换后的值不变。  来看 char c1, c2; c1 = 197; c2 = 198;  在这里，如果 char 等价于 unsigned char ，那么，在主流的机器上，它可以表示的数值范围是 0到255，所以能够容纳，且 printf 不可能打印两个负值。显然，在楼主的环境下，char实际上是signed char。在主流的机器上，它可以表示的数值范围是-127到+128，故无法表示 197 和 198 ，需要转换。  但是，如果新类型是有符号的并且无法表示这个值，转换的结果要依赖于具体的编译器，甚至可能触发信号机制。即，C语言没有规定如何转换。  在很多平台上（显然包括楼主所在的机器环境），是直接把长度为 int 的 197 截断为 char 类型的长度。所以，最终它表示有符号数-59。   您好，非常感谢您的回复，我使用的编译器是VS2012。我是一个C语言的初学者，我对您的回复还有一些疑问，在您的回复中说到“在197和198这两个数值的二进制形式中，符号位似乎并不是1。”197 -->11000101      198  -->  11000110    直接转化成二进制的首位是否会直接成为符号位呢？烦请您帮忙把197到-59的过程详细说一下吗？[/quote]  对，我这两句话没说明白。  赋给 c1 和 c2 的值来自于常量 197 和 198 ，这两个常量的类型是 int 。所以，它们的最高位不是1，而是0。即，如果 int 类型的长度是 32 位，则 197 的二进制形式为 00000000000000000000000011000101 。把它截断为 char 类型的长度时，如果 char 类型的长度是 8，则截断后是 11000101 。[/quote]十分感谢您的解答，还有一个问题我没有搞明白，例如197.对于截断后的二进制11000101。它的最高位是1，即后面表示数值的二进制是“1000101”，转变成二进制之后为69。但是取其补码之后即为“0111010”它的十进制是“58”。截断之后为什么不是直接输出它的十进制而是取其补码呢？这点我有点搞不明白。

百度“负数、补码” %c问号的原因是因为找不到对应的ASCII字符

引用 4 楼 拜你所赐 的回复:[quote=引用 3 楼 均陵鼠侠 的回复:]这是一个简单而又复杂的问题。  首先， %c 和 %d 都要求对应的变参是 int 类型。唯一不同的是，%c 是将这个 int 类型的变参转换为 unsigned char 类型的字符，然后予以显示，而 %d 则是将它转换为有符号十进制格式的数字字符予以显示。  其次，程序是没有问题的。尽管传入的变参是 char 类型的，但依照默认实参转换（default argument conversion）的规则，它是被转换为 int 类型之后传递给 printf 的。  最后，对于 printf 来说， %c 是将传入的值按 int 类型（的长度）取出，然后转换（缩小）为 unsigned char 类型（的长度），将它视为字符编码，然后打印这个字符； %d 是将传入的值按 int 类型（的长度）取出，拆分数位并转换为有符号十进制数字字符打印输出。这里的关键是， %d 要求这个转换过程必须区分数值的正负。这很好办，只需要判断其二进制形式的最高位（符号位）就可以了：为0是正数，为1是负数。然而，在197和198这两个数值的二进制形式中，符号位似乎并不是1。这就回到了开始：在将 char 类型的值转换为 int 类型并传递给 printf 时，是如何转换的？再往前，两个常量197和198的类型都是 int ，将它们赋给变量 c1 和 c2 时，需要从 int 转换为 char ，这个转换过程又是怎样的？  这就涉及到数值转换规则。首先，将一个整数类型的值转换为另一个除_Bool之外的整数类型时，如果这个值能够用新类型来表示，则转换后的值不变。  来看 char c1, c2; c1 = 197; c2 = 198;  在这里，如果 char 等价于 unsigned char ，那么，在主流的机器上，它可以表示的数值范围是 0到255，所以能够容纳，且 printf 不可能打印两个负值。显然，在楼主的环境下，char实际上是signed char。在主流的机器上，它可以表示的数值范围是-127到+128，故无法表示 197 和 198 ，需要转换。  但是，如果新类型是有符号的并且无法表示这个值，转换的结果要依赖于具体的编译器，甚至可能触发信号机制。即，C语言没有规定如何转换。  在很多平台上（显然包括楼主所在的机器环境），是直接把长度为 int 的 197 截断为 char 类型的长度。所以，最终它表示有符号数-59。   您好，非常感谢您的回复，我使用的编译器是VS2012。我是一个C语言的初学者，我对您的回复还有一些疑问，在您的回复中说到“在197和198这两个数值的二进制形式中，符号位似乎并不是1。”197 -->11000101      198  -->  11000110    直接转化成二进制的首位是否会直接成为符号位呢？烦请您帮忙把197到-59的过程详细说一下吗？[/quote]  对，我这两句话没说明白。  赋给 c1 和 c2 的值来自于常量 197 和 198 ，这两个常量的类型是 int 。所以，它们的最高位不是1，而是0。即，如果 int 类型的长度是 32 位，则 197 的二进制形式为 00000000000000000000000011000101 。把它截断为 char 类型的长度时，如果 char 类型的长度是 8，则截断后是 11000101 。

引用 3 楼 均陵鼠侠 的回复:这是一个简单而又复杂的问题。  首先， %c 和 %d 都要求对应的变参是 int 类型。唯一不同的是，%c 是将这个 int 类型的变参转换为 unsigned char 类型的字符，然后予以显示，而 %d 则是将它转换为有符号十进制格式的数字字符予以显示。  其次，程序是没有问题的。尽管传入的变参是 char 类型的，但依照默认实参转换（default argument conversion）的规则，它是被转换为 int 类型之后传递给 printf 的。  最后，对于 printf 来说， %c 是将传入的值按 int 类型（的长度）取出，然后转换（缩小）为 unsigned char 类型（的长度），将它视为字符编码，然后打印这个字符； %d 是将传入的值按 int 类型（的长度）取出，拆分数位并转换为有符号十进制数字字符打印输出。这里的关键是， %d 要求这个转换过程必须区分数值的正负。这很好办，只需要判断其二进制形式的最高位（符号位）就可以了：为0是正数，为1是负数。然而，在197和198这两个数值的二进制形式中，符号位似乎并不是1。这就回到了开始：在将 char 类型的值转换为 int 类型并传递给 printf 时，是如何转换的？再往前，两个常量197和198的类型都是 int ，将它们赋给变量 c1 和 c2 时，需要从 int 转换为 char ，这个转换过程又是怎样的？  这就涉及到数值转换规则。首先，将一个整数类型的值转换为另一个除_Bool之外的整数类型时，如果这个值能够用新类型来表示，则转换后的值不变。  来看 char c1, c2; c1 = 197; c2 = 198;  在这里，如果 char 等价于 unsigned char ，那么，在主流的机器上，它可以表示的数值范围是 0到255，所以能够容纳，且 printf 不可能打印两个负值。显然，在楼主的环境下，char实际上是signed char。在主流的机器上，它可以表示的数值范围是-127到+128，故无法表示 197 和 198 ，需要转换。  但是，如果新类型是有符号的并且无法表示这个值，转换的结果要依赖于具体的编译器，甚至可能触发信号机制。即，C语言没有规定如何转换。  在很多平台上（显然包括楼主所在的机器环境），是直接把长度为 int 的 197 截断为 char 类型的长度。所以，最终它表示有符号数-59。   您好，非常感谢您的回复，我使用的编译器是VS2012。我是一个C语言的初学者，我对您的回复还有一些疑问，在您的回复中说到“在197和198这两个数值的二进制形式中，符号位似乎并不是1。”197 -->11000101      198  -->  11000110    直接转化成二进制的首位是否会直接成为符号位呢？烦请您帮忙把197到-59的过程详细说一下吗？


Question: 大佬来看看这个代码

供参考：//用筛法求N之内的素数  #include<stdio.h> int main() { 	int n; 	bool prime[1000]; 	for(int i=0;i<1000;i++) 	{ 		prime[i]=0;//假设所有数都是素数 	} 	scanf("%d",&n); 	for(int i=2;i<=n;i++) 	{ 		if(prime[i]==0)//每次将一个素数的所有倍数标记为非素数 		{ 			for(int j=i*2;j<=n;j=j+i)//从二倍开始标记素数的倍数为非素数 			{ 				prime[j]=1; 			} 		} 	} 	for(int i=2;i<=n;i++) 	{ 		if(prime[i]==0)printf("%d\n",i); 	}     //system("pause");     return 0; }

看不懂

#include<stdio.h> void main() {     int m,n;      scanf("%d%d",&m,&n);     for (int j, i = m; i <= n; i++)     {          for (j = 2; j  < i; j++)         {             if (i % j == 0)                 break;         }         if(j==i)printf("%d ",i);     } }

搞错了，代码是这个： #include <stdio.h> #include <stdlib.h> #define N 100 void Siftprime(int a[], int n); void DoublePrime(int a[],int n);  //筛法求素数 void Siftprime(int a[], int n) { 	int i,j; 	for (i=2;i<=n;i++) 	{ 		a[i]=i; 	} 	for (i=2;i<=n;i++) 	{ 		for (j=i+1;j<n;j++) 		{ 			if (a[i]!=0&&a[j]!=0&&a[j]%a[i]==0) 				a[j]=0; 		} 	} }  void DoublePrime(int a[],int n) { 	int i; 	for (i=3;i<n;i++) 	{ 		if (a[i]!=0&&a[i+2]!=0) 			printf("%4d/%d",i,i+2); 	} }  int main() { 	int a[N+1]; 	Siftprime(a,N); 	DoublePrime(a,N); 	return 0; }


Question: C语言

C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html

随机必然有重复，所谓“不重复的随机”实际上是洗牌。洗牌算法参考下面： #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");         }     } }

大概这样子吧   #include <stdbool.h>  //引入bool类型  bool chachong(int *arr, int index, size_t n) { 	if (!index || !n)   //忽略0值和第一个值 	{ 		return true; 	}  	while (n) //从数组中找重复的值 	{ 		if (arr[n - 1] == index) 		{ 			return true; 		} 		n--; 	}  	return false; }  //////////////// int arr[13] = {0}; size_t i=0; while (i < 13) { 	do 	{ 		arr[i] = rand() % 55; 	} while (chachong(arr, arr[i], i)); 	 	i++; }

随机打乱顺序后直接给前面的即可


Question: 这不就正常的解法吗？为什么总是部分正确。找了好久不知道哪里错了，大佬看看

引用 2 楼 自信男孩的回复:strcmp不是比较地址值的大小，而是比较地址内数据的大小～ 兄弟，谢了，总以为数组和指针都是一个东西

strcmp不是比较地址值的大小，而是比较地址内数据的大小～

int mystrcmp(const char *a, const char *b) {     assert(a && b);       while (*a && *b) {         if (*a > *b)             return 1;         if (*a < *b)             return -1;         a++, b++;     }      if (*a == 0 && *b == 0)   //0即'\0'         return 0;     if (*a == '\0')         return -1;     if (*b == '\0')         return 1;      return 0;  }  供参考～


Question: 求助贴

参见eigen。


Question: C语言数组处理

非常不错的解答

引用 10 楼 lin5161678 的回复:[quote=引用 9 楼 自信男孩 的回复:][quote=引用 8 楼 lin5161678 的回复:]错的就只是 vla长度是0 并且越界 这两点 和指针没有任何关系  理解不一样～[/quote] 那就是你理解错了[/quote] 把数组理解为指针有错吗（当然数组和指针还是有区别的）？数组名除了不能做左值外，还有其他的区别吗？

引用 9 楼 自信男孩 的回复:[quote=引用 8 楼 lin5161678 的回复:]错的就只是 vla长度是0 并且越界 这两点 和指针没有任何关系  理解不一样～[/quote] 那就是你理解错了

引用 8 楼 lin5161678 的回复:[quote=引用 7 楼 自信男孩 的回复:][quote=引用 6 楼 lin5161678 的回复:][quote=引用 3 楼 自信男孩 的回复:]a数组的长度需要事先定义好，C语言不支持可变数组长度的。C支持 这里错的不是用变了定义数组大小 这里错的是越界 并且数组大小是0 [/quote] 这里定义的其实就是一个指针，还是一个野指针。对于野指针的使用结果是未定义的。  可变数组可能描述的有歧义，这个在C语言里应该怎么描述呢？应该描述成：不定长数组；当然这里也不是不定长的，而是指定义了一个长度不足的（或者直接理解为一个野指针或许更好）[/quote]错的就只是 vla长度是0 并且越界 这两点 和指针没有任何关系[/quote]  理解不一样～

引用 7 楼 自信男孩 的回复:[quote=引用 6 楼 lin5161678 的回复:][quote=引用 3 楼 自信男孩 的回复:]a数组的长度需要事先定义好，C语言不支持可变数组长度的。C支持 这里错的不是用变了定义数组大小 这里错的是越界 并且数组大小是0 [/quote] 这里定义的其实就是一个指针，还是一个野指针。对于野指针的使用结果是未定义的。  可变数组可能描述的有歧义，这个在C语言里应该怎么描述呢？应该描述成：不定长数组；当然这里也不是不定长的，而是指定义了一个长度不足的（或者直接理解为一个野指针或许更好）[/quote]错的就只是 vla长度是0 并且越界 这两点 和指针没有任何关系

引用 6 楼 lin5161678 的回复:[quote=引用 3 楼 自信男孩 的回复:]a数组的长度需要事先定义好，C语言不支持可变数组长度的。C支持 这里错的不是用变了定义数组大小 这里错的是越界 并且数组大小是0 [/quote] 这里定义的其实就是一个指针，还是一个野指针。对于野指针的使用结果是未定义的。  可变数组可能描述的有歧义，这个在C语言里应该怎么描述呢？应该描述成：不定长数组；当然这里也不是不定长的，而是指定义了一个长度不足的（或者直接理解为一个野指针或许更好）

引用 3 楼 自信男孩 的回复:a数组的长度需要事先定义好，C语言不支持可变数组长度的。C支持 这里错的不是用变了定义数组大小 这里错的是越界 并且数组大小是0

引用 30 楼 lin5161678 的回复:[quote=引用 27 楼 自信男孩 的回复:]  你解析的通透，能被别人理解吗？你通透了，那是你的，不能给别人。在论坛里是帮助别人解决问题，不是炫耀你理解的通透了。 愿意思考当然能够理解 请问 数组类型在特定情况下会隐式转换为指向数组第一个元素的指针 而不是数组是指针 这句话 哪一个字不理解? 没有先入为主并且放弃思考的人 都能理解这句话[/quote] 我真没说过数组就是指针吧，如果说了，那我确实说错了，我道歉，向楼主和看到的帖子的朋友们道歉：我传播了错误的论点。

引用 32 楼 均陵鼠侠 的回复:[quote=引用 28 楼 自信男孩 的回复:][quote=引用 25 楼 均陵鼠侠 的回复:]我的发言看起来象是在吵架吗？这是从哪里看出来的。我本不想参与这个讨论，但是看到小林同学在场，所以也掺和一下。如果觉得我是在吵架，我就不说话了，反正CSDN我很少来，就是隔一段时间来瞅瞅。我又不拿CSDN的好处，没必要在这里为一些非常简单的话题浪费时间。 代码写出来是让别人看的，不是炫耀的。写出对的，但是别人不容易理解的代码，意义仅限于自己的吧，代码的可读性呢？  int g; ( & g) [0] = 5; 对于这样的代码～[/quote]我都不知道说什么好了，你为什么总抓不住重点。我强调的是要引入“整数名”和“浮点名”，而且认为“整数名也是数组，也是指针”，所以举了这样一个例子，你又往代码的可读性上扯。没有可读性就不是代码了？没有可读性就不能运行了？它是不是合法的C语言代码呢？这样唠嗑啥时候才能是个头哇。[/quote] 那就不要唠了，那你还回复啥呀～既然知道没有头，越来越不在楼主的频道上了。嘴上说着没意思唠了，手上还很诚实～

引用 28 楼 自信男孩 的回复:[quote=引用 25 楼 均陵鼠侠 的回复:]我的发言看起来象是在吵架吗？这是从哪里看出来的。我本不想参与这个讨论，但是看到小林同学在场，所以也掺和一下。如果觉得我是在吵架，我就不说话了，反正CSDN我很少来，就是隔一段时间来瞅瞅。我又不拿CSDN的好处，没必要在这里为一些非常简单的话题浪费时间。 代码写出来是让别人看的，不是炫耀的。写出对的，但是别人不容易理解的代码，意义仅限于自己的吧，代码的可读性呢？  int g; ( & g) [0] = 5; 对于这样的代码～[/quote]我都不知道说什么好了，你为什么总抓不住重点。我强调的是要引入“整数名”和“浮点名”，而且认为“整数名也是数组，也是指针”，所以举了这样一个例子，你又往代码的可读性上扯。没有可读性就不是代码了？没有可读性就不能运行了？它是不是合法的C语言代码呢？这样唠嗑啥时候才能是个头哇。

引用 29 楼 均陵鼠侠 的回复:我说小林，我在#24楼的发言难道不好笑吗？为什么不笑？[/quote] 我受过严格的训练  无论有多好笑 我都不会笑 除非忍不住

引用 27 楼 自信男孩 的回复:你解析的通透，能被别人理解吗？你通透了，那是你的，不能给别人。在论坛里是帮助别人解决问题，不是炫耀你理解的通透了。 愿意思考当然能够理解 请问 数组类型在特定情况下会隐式转换为指向数组第一个元素的指针 而不是数组是指针 这句话 哪一个字不理解? 没有先入为主并且放弃思考的人 都能理解这句话

引用 26 楼 lin5161678 的回复:[quote=引用 22 楼 自信男孩 的回复:]我说小林，我在#24楼的发言难道不好笑吗？为什么不笑？

引用 25 楼 均陵鼠侠 的回复:我的发言看起来象是在吵架吗？这是从哪里看出来的。我本不想参与这个讨论，但是看到小林同学在场，所以也掺和一下。如果觉得我是在吵架，我就不说话了，反正CSDN我很少来，就是隔一段时间来瞅瞅。我又不拿CSDN的好处，没必要在这里为一些非常简单的话题浪费时间。 代码写出来是让别人看的，不是炫耀的。写出对的，但是别人不容易理解的代码，意义仅限于自己的吧，代码的可读性呢？  int g; ( & g) [0] = 5; 对于这样的代码～

引用 26 楼 lin5161678 的回复:[quote=引用 22 楼 自信男孩 的回复:] 好吧，继续这样的沟通没有意义，我一说访问，你就提出char和int的区别，这么说还有struct ,union等等这些类型访问的区别呢，所以，这样的反驳我无话可说。你理解的并不是我理解的，看来这句话在我们的沟通中是成立的。  建议不要总批判的去理解别人的话，能从对方的话语中理解或吸收有用的东西，这样是进步的源泉，上来就反对，如果反对的全对还好说，不全对，我感觉没多少意义，除了能获取自己很厉害的快感，还能干啥？ 你的观点不存在值得吸收的内容 所谓的数组是指针  是一个错误的 对理解C语言毫无帮助 对编程实践毫无价值的说法 并且早就被解析通透并早已被我摒弃  数组隐式转换为指向数组第一个元素 可以解释一切关于数组和指针相关的内容 数组是指针 只会遇到越来越多的困惑 越思考越撕裂 放弃思考才会认为这个解释很合理[/quote] 你的语言里透漏出霸气：  并且早就被解析通透并早已被我摒弃  你解析的通透，能被别人理解吗？你通透了，那是你的，不能给别人。在论坛里是帮助别人解决问题，不是炫耀你理解的通透了。

引用 22 楼 自信男孩 的回复:好吧，继续这样的沟通没有意义，我一说访问，你就提出char和int的区别，这么说还有struct ,union等等这些类型访问的区别呢，所以，这样的反驳我无话可说。你理解的并不是我理解的，看来这句话在我们的沟通中是成立的。  建议不要总批判的去理解别人的话，能从对方的话语中理解或吸收有用的东西，这样是进步的源泉，上来就反对，如果反对的全对还好说，不全对，我感觉没多少意义，除了能获取自己很厉害的快感，还能干啥？ 你的观点不存在值得吸收的内容 所谓的数组是指针  是一个错误的 对理解C语言毫无帮助 对编程实践毫无价值的说法 并且早就被解析通透并早已被我摒弃  数组隐式转换为指向数组第一个元素 可以解释一切关于数组和指针相关的内容 数组是指针 只会遇到越来越多的困惑 越思考越撕裂 放弃思考才会认为这个解释很合理

“因为这么理解了，对于很多的使用，比如访问数组或指针地址的方式；便于更好的使用和运用；”------恰恰相反，就是因为和稀泥，搞不清楚，所以很难使用和运用，更谈不上写出优美、简练的代码。你看看赵4老湿平时写的程序就知道了。他的程序我一次也没有读过，太。。。怎么说呢，太闹心了。  我准备建议WG14引入一批新的术语，叫做“整数名”、“浮点名”。而且，因为以下代码 int g; ( & g) [0] = 5; 可以正常工作，所以我决定下一个结论：整数名在某些条件下等同于数组；在某些条件下也等同于指针。

引用 21 楼 均陵鼠侠 的回复:[quote=引用 15 楼 自信男孩 的回复:][quote=引用 14 楼 lin5161678 的回复:][quote=引用 11 楼 自信男孩 的回复:] 把数组理解为指针有错吗（当然数组和指针还是有区别的）？数组名除了不能做左值外，还有其他的区别吗？ 首先 数组名是左值表达式 然后 数组理解为指针当然是错的  数组本质是内存中一块连续的内存块 相同类型的元素的集合 指针显然完全另一回事  根本区别 数组是一种聚合类型 指针是一种标量类型 两者是C类型系统完全不同 各自独立的组成部分   (int[10])value //是错的 (int*)value //是对的   sizeof(数组类型)和sizeof(指针类型)有区别  int arr[10]; //&arr 是一个数组指针类型表达式 类型是 int(*)[10] int* p; //&p 是一个二级指针表达式 类型是 int**  等等  两者区别多的是  所谓的数组是指针 完全的是对 数组在特定情况下会隐式转换为指向数组第一个元素的指针 这个规则的误读[/quote]  数组和指针在访问上没有区别的，我认为在一些方面是可以将数组理解为指针，也可以把指针理解为数组，你罗列这么多，咱们关注点不一样呢，你关注区别，我专注类似。为什么要关注类似，因为这么理解了，对于很多的使用，比如访问数组或指针地址的方式；便于更好的使用和运用；  指针和数组如果完全一样，我想也没必要定义两个名称了，这个起码的区别我想我还是能够分辨的吧。 比如数组名作为参数传递，那么形参的处理，编译器是按照指针来处理的，虽然你定义的参数是数组形式；  多方面的看待问题，而不是两个面的去评价一个问题：要么对，要么错；不同场景下，可以有不同的理解；  数组和指针有区别又有相似性；我想这个观点你应该认同吧[/quote]  按照这个观点，发明高级语言是错误的，是不必要的。因为这番言论完全否定了抽象的必要性，而高级语言正是对底层以及低一级层次的逻辑抽象。每种语言都要自圆其说，都有其自洽性和完备性，数据类型必须是层次分明的。  分析C语言程序，自然要站在C语言自身的逻辑圈子里进行，你拿汇编语言层面的事物来解释C语言的东西，已经超越了C语言本身的逻辑。更何况，在机器语言里，哪还有什么数组和指针，都是一连串的字节或者比特。[/quote] 你这么理解也没错，但是这是再讨论问题吗？这是在吵架，说一些看是对的，但是与议题无关的内容，这样你觉得很厉害了？


Question: 求助

for(i=100;i<1000;i++)  ;  ------------- for(i=100;i<1000;i++) 多余的分号


Question: GIS粘贴出大问题！求大神解救！

C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html

Excel中复制的内容粘贴在谷歌阅览器中的特定网址中才会变成相同乱码

关闭输入法再试试


Question: 关于c语言中布尔形式

在C99之前，严格来说，C语言是没有布尔类型的。但是这并不妨碍C语言的工作，以及它和其它语言的接口，毕竟在编程语言里的惯例是0为假，非0为真。问题在于，很多人觉得这是一个和语言完备性有关的瑕疵和缺陷，就好比别人家里煮奶有专用的奶锅，你家里炒菜和煮奶都用同一个铁锅。  在WG14，很多委员都具有C++的背景，这些捣子特别喜欢往C标准里添加C++的玩意儿，但多数不会被标准委员会采纳，因为里面很多都是私货。也就是厂商的代表都希望把自己公司的扩展特性加入到标准里。  也许是起哄的人太多，WG14最终妥协了，决定把布尔类型加入到C语言的下一个标准C99里。理想情况下，这需要引入一个关键字boolean，或者至少是一个好记的bool。但是，在此之前，有很多完美主义的程序员为了图方便，满足自己的语言洁癖，已经在程序中定义了自己的“bool”，而且这样的程序肯定有成千上万。为了能够正常编译这些已有的程序，C99决定引入一个带有下划线的关键字_Bool，这样就很难有冲突了。  关键字_Bool被用作类型指定符，用来声明变量，或者函数的参数和返回类型。这种类型的变量具有以下特点：  1，它是一种无符号整数类型； 2，至少可以保存0和1两个值； 3，将任何标量值转换为_Bool类型时，零值转换为零，非零值转换为1；  C语言规定，除了位域（bit-fields），任何对象（变量）都是由一个或多个连续的字节组成。因此，_Bool类型的长度至少是一个字节。  为了方便，在C语言的标准库部分增加了一个头<stdbool.h>。这个头非常简单，就定义了几个宏：  # define bool	_Bool  # define true	1 # define false	0  # define __bool_true_false_are_defined	1  最后一个宏__bool_true_false_are_defined是个标记，用于表明前面的三个宏已经定义，可以使用。

引用 2 楼 淘豚 的回复:[quote=引用 1 楼 自信男孩的回复:]枚举定义的，FALSE=0，TRUE=1；  enum是一个关键字，类似struct，union 在布尔形式c语言中到底起什么作用？[/quote] 它就是一种整型值，真或假；

引用 1 楼 自信男孩的回复:枚举定义的，FALSE=0，TRUE=1；  enum是一个关键字，类似struct，union 在布尔形式c语言中到底起什么作用？


Question: 救救孩子吧

怎么理解：int *y=0;  就算是C语言太灵活而不够稳定吧？编译器确实可能把*y和*z按照野指针处理了。

#include <stdio.h> #pragma warning(disable:4996) void separate(float x, int* y, float* z); int main() { 	float data, z; 	int y; 	printf("从键盘输入一个实型数据："); 	scanf("%f", &data); 	separate(data, &y, &z); 	printf("%d,%f", y, z); } void separate(float x, int* y, float* z) { 	*y = x; 	*z = x - *y;   }

引用 6 楼 智者知已应修善业 的回复:  void separate(float x, int *y, float *z) { 	*y = (int)x; 	*z = x - *y; }   	float data, *z = (float*)malloc(1); 	int *y = (int*)malloc(1); 	printf("从键盘输入一个实型数据："); 	scanf_s("%f", &data); 	separate(data, y, z); 	printf("%d,%f", *y, *z); 误人子弟第一名  你就不能好好看看 malloc的参数是什么意思么 全部传递1哦

引用 4 楼 智者知已应修善业 的回复: 	float data, *z = (float*)malloc(1); 	int *y = (int*)malloc(1); 错的 新朋友别学

#include <stdio.h>  void separate(float x,int *y,float *z);  //void main () int main (void) {     //float data, *z;     float data, z;     //int *y;     int y;      printf ("从键盘输入一个实型数据：");     scanf ("%f",&data);     printf("%f\n", data);     separate (data, &y, &z);     //printf ("%d,%f",*y,*z);     printf ("%d,%f", y, z); }  void separate(float x,int *y,float *z) {     *y = (int)x;     *z = x - *y; } 供参考～  两个指针都是野指针，需要分配空间，或者直接用普通变量吧

z和y是指针没有指向数据的空间

void separate(float x,int *y,float *z); int main() {     float data, z;     int y;     printf ("从键盘输入一个实型数据：");     scanf ("%f",&data);     separate (data, &y, &z);     printf ("%d,%f",y, z); } void separate(float x,int *y,float *z) {      *y = (int)x;     *z = x - *y;  }

引用 楼主 栀九lyp的回复: #include <stdio.h> void separate(float x,int *y,float *z); void main () { 	float data, *z; 	int *y; 	printf ("从键盘输入一个实型数据："); 	scanf ("%f",&data); 	separate (data,y,z); 	printf ("%d,%f",*y,*z); } void separate(float x,int *y,float *z) {  	*y = (int)x; 	*z = x - *y;    } 为什么我这样总是运行不出来


Question: vs写的cpp里中文莫名其妙乱码

原因就是： 比如原来的汉字编码是utf8的； 但被无脑编辑器误当gbk进行了一次gbk到utf8的转换。


Question: 有人知道这个怎么写吗

引用 1 楼 赵4老师的回复:#include <stdio.h> void main() {     int x,y;     int *maxaddress(int *a,int*b);     int *minaddress(int *a,int*b);     void process(int *a,int *b,int *(*fun)(int *a,int *b));     printf("从键盘输入两个整数，逗号分隔：");     scanf("%d,%d",&x,&y);     printf("最大地址为：");     process(&x,&y,maxaddress);     printf("最小地址为：");     process(&x,&y,minaddress); }  int *maxaddress(int *a,int*b) {     if (*a>*b) return a;     else return b; }  int *minaddress(int *a,int*b) {     if (*a<*b) return a;     else return b; }  void process(int *a,int *b,int *(*fun)(int *a,int *b)) {     printf("%p\n",fun(a,b)); } //从键盘输入两个整数，逗号分隔：1,2 //最大地址为：003FFAA0 //最小地址为：003FFA9C //  谢谢老师指导


Question: MinGW合并静态库有没有简单点的办法？

引用 楼主 六道佩恩 的回复:目前找到的方法都是ar把.a解开成.o再合并 感觉这样挺麻烦的，有没有更简单的方法 像MSVC的lib合并静态库就好方便  如果实在只能用这种方法的话，怎样让分解的目标文件都集中到一个文件夹？不然ar合并*.o容易把不相关的.o文件合并进来 mkdir libABC cd libABC ar x lib/A.a ar x lib/B.a ar x lib/C.a ar rcu libABC.a *.o ranlib libABC.a //Generate an index to speed access to archives

引用 6 楼 六道佩恩 的回复:刚简单测试了下，用lib合并.o为.a是可行的 .o和.obj应该都是符合PE结构的，.a和.lib应该也都是吧，这样看的话，用lib管理应该是可以的吧？ 可以用十六进制编辑器对比一下.a和.lib，看看是否符合PE的格式 就算在Windows下可以用lib来管理，但在Linux下还是要使用ar的方式 另外，在Windows下，也是建议使用先提取obj，再合并，这样可以去除不必要的obj，只选取需要的obj再合并为lib  方法1: lib.exe lib1.lib lib2.lib /out:new.lib   方法12: lib.exe可以把lib文件里的obj文件取出来，然后把这些obj文件重新合并成一个lib文件即可。 步骤如下： 1、列出lib文件中的obj文件      lib lib1.lib /list      lib lib2.lib /list 2、提取出obj文件，大小写一定要和上一步列出的一致      lib lib1.lib /extract:.\Debug\lib1.obj /out:lib1.obj      lib lib2.lib /extract:.\Debug\lib2.obj /out:lib2.obj 3、合并obj文件到新的lib      lib lib1.obj lib2.obj /out:new.lib

程序猿的问题用程序解决嘛，手工能做，仅仅是麻烦的这种事是最适合写代码解决的了。 看哪个工具命令好用就自己仿一个。

引用 3 楼 Intel0011 的回复:mkdir libABC cd libABC ar x lib/A.a ar x lib/B.a ar x lib/C.a ar rcs libABC.a *.o 刚简单测试了下，用lib合并.o为.a是可行的 .o和.obj应该都是符合PE结构的，.a和.lib应该也都是吧，这样看的话，用lib管理应该是可以的吧？

引用 3 楼 Intel0011 的回复:mkdir libABC cd libABC ar x lib/A.a ar x lib/B.a ar x lib/C.a ar rcs libABC.a *.o 可以问下.o和.lib的区别吗，如果兼容的话，用lib来合并如何？

引用 3 楼 Intel0011 的回复:mkdir libABC cd libABC ar x lib/A.a ar x lib/B.a ar x lib/C.a ar rcs libABC.a *.o  也就是，没办法更简单的办法或相关工具是吗


Question: 整理了62套C需要小游戏源码，送给大家

链接怎么进去啊

C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html


Question: 大佬们帮小白纠下错

感谢大佬们的回答，我懂了好多

对题目理解有问题：题意应该是十个数据，输出九个数据，第一个数据与第二个数据的和，第二个数据与第三个数据的和，。。。 审题要仔细，对题意理解错了、很容易的送分题就错过了。

引用 6 楼 自信男孩 的回复:[quote=引用 5 楼 qzjhjxj 的回复:][quote=引用 3 楼 自信男孩 的回复:][quote=引用 1 楼 qzjhjxj 的回复:]供参考：#include<stdio.h>  int main() {     int a[10]={0},b[5]={0},i,j;     for(i=0;i<10;i++)         scanf("%d",&a[i]);     for(i=0,j=0;i<10;i+=2,j++)         b[j]=a[i]+a[i+1];     for(j=0;j<5;j++){         printf("%3d",b[j]);         if((j+1)%3==0||(j+1)==5)printf("\n");     }          return 0; } for(i=0,j=0;i<10;i+=2,j++)           b[j]=a[i]+a[i+1];  //这个地方应该会越界吧，当i=9时，i+1就是10[/quote]不会出现9，i=i+2,到8就跳出了。 [/quote] 确实，不会，没看你的i+=2，这个相邻元素，理解上有分歧～[/quote]楼主的想法

引用 5 楼 qzjhjxj 的回复:[quote=引用 3 楼 自信男孩 的回复:][quote=引用 1 楼 qzjhjxj 的回复:]供参考：#include<stdio.h>  int main() {     int a[10]={0},b[5]={0},i,j;     for(i=0;i<10;i++)         scanf("%d",&a[i]);     for(i=0,j=0;i<10;i+=2,j++)         b[j]=a[i]+a[i+1];     for(j=0;j<5;j++){         printf("%3d",b[j]);         if((j+1)%3==0||(j+1)==5)printf("\n");     }          return 0; }  for(i=0,j=0;i<10;i+=2,j++)           b[j]=a[i]+a[i+1];  //这个地方应该会越界吧，当i=9时，i+1就是10[/quote]不会出现9，i=i+2,到8就跳出了。 [/quote] 确实，不会，没看你的i+=2，这个相邻元素，理解上有分歧～

引用 3 楼 自信男孩 的回复:[quote=引用 1 楼 qzjhjxj 的回复:]供参考：#include<stdio.h>  int main() {     int a[10]={0},b[5]={0},i,j;     for(i=0;i<10;i++)         scanf("%d",&a[i]);     for(i=0,j=0;i<10;i+=2,j++)         b[j]=a[i]+a[i+1];     for(j=0;j<5;j++){         printf("%3d",b[j]);         if((j+1)%3==0||(j+1)==5)printf("\n");     }          return 0; } for(i=0,j=0;i<10;i+=2,j++)           b[j]=a[i]+a[i+1];  //这个地方应该会越界吧，当i=9时，i+1就是10[/quote]不会出现9，i=i+2,到8就跳出了。

#include<stdio.h>  #define SIZE    10 int main() {     int a[SIZE], b[SIZE]={0};     int i, j;      for(i = 0; i < SIZE; i++)         scanf("%d", &a[i]);      for (i = 0, j = 0; i < SIZE-1; i++) {         b[j++] = a[i] + a[i+1];     }      for (i = 0; i < j; i++)         printf("%d%c", b[i], (i+1) % 3 ? ' ':'\n');      /*     for(i=0,j=0;i<10;i+=2,j++)         b[j]=a[i]+a[i+1];     for(j=0;j<5;j++){         printf("%3d",b[j]);         if((j+1)%3==0||(j+1)==5)printf("\n");     }     */      return 0; } 供参考～  相邻两个元素之和，比如0 1 2 3 4 5 6 7 8 9 ，楼主的理解是0 1， 2 3等等，我的理解是0 1, 1 2, 2 3等等这样的一组，这样也叫相邻两个元素吧

引用 1 楼 qzjhjxj 的回复:供参考：#include<stdio.h>  int main() {     int a[10]={0},b[5]={0},i,j;     for(i=0;i<10;i++)         scanf("%d",&a[i]);     for(i=0,j=0;i<10;i+=2,j++)         b[j]=a[i]+a[i+1];     for(j=0;j<5;j++){         printf("%3d",b[j]);         if((j+1)%3==0||(j+1)==5)printf("\n");     }          return 0; }  for(i=0,j=0;i<10;i+=2,j++)           b[j]=a[i]+a[i+1];  //这个地方应该会越界吧，当i=9时，i+1就是10


Question: 我想问一下newline  in constant和 error C2018: unknown character '0xb7'的错误

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

供参考：void sta(table *x) {     int a,b,c,d,e;     float A,B,C,D,E,NUM;     int i;     a=b=c=d=e=0;     NUM=(float)x->length;     for(i=x->length;i>0;i--)     {         if(x->r[i].score>100||x->r[i].score<0)            printf("错误！%s同学的分数超出上限！\n",x->r[i].name);         else if(x->r[i].score>=90&&x->r[i].score<=100)a++;         else if(x->r[i].score>=80&&x->r[i].score<=89) b++;         else if(x->r[i].score>=70&&x->r[i].score<=79) c++;         else if(x->r[i].score>=60&&x->r[i].score<=69) d++;         else if(x->r[i].score>=0 &&x->r[i].score<=60) e++;      }     A=(float)a/NUM;//A=NUM/(float)a;     B=(float)b/NUM;//B=NUM/(float)b;     C=(float)c/NUM;//C=NUM/(float)c;     D=(float)d/NUM;//D=NUM/(float)d;     E=(float)e/NUM;//E=NUM/(float)e;     printf("总共有%d位同学\n"            "分数于90到100的同学有%d位,占总人数的%f\n"            "分数于80到89的同学有%d位,占总人数的%f\n"            "分数于70到79的同学有%d位,占总人数的%f\n"            "分数于60到69的同学有%d位,占总人数的%f\n"            "分数于60以下同学有%d位,占总人数的%f\n",            x->length,a,A,b,B,c,C,d,D,e,E); }

哦对了，第一个错误对应这行printf("总共有%d位同学\n

switch (x->r[i].score/10) {             //case 8:             case 9:             case 10:                 a++;                 break;               case 8:                 b++;                 break;               case 7:                 c++;                 break;               case 6:                 d++;                 break;               case 0:             case 1:             case 2:             case 3:             case 4:             case 5:                 e++;                 break;               default:             printf("错误！%s同学的分数超出上限！\n",x->r[i].name);         } 改一下  供参考～

void sta(table *x) {     int a,b,c,d,e;     float A,B,C,D,E,NUM;     int i;     a=b=c=d=e=0;     NUM=(float)x->length;     for(i=x->length;i>0;i--)     {  #if 1         switch (x->r[i].score/10) {             case 8:             case 9:             case 10:                 a++;                 break;              case 8:                 b++;                 break;              case 7:                 c++;                 break;              case 6:                 d++;                 break;              case 0:             case 1:             case 2:             case 3:             case 4:             case 5:                 e++;                 break;              default:             printf("错误！%s同学的分数超出上限！\n",x->r[i].name);         } #else         if(x->r[i].score>100||x->r[i].score<0)             printf("错误！%s同学的分数超出上限！\n",x->r[i].name);         else if(x->r[i].score>=90&&x->r[i].score<=100)             a++;         else if(x->r[i].score>=80&&x->r[i].score<=89)             b++;         else if(x->r[i].score>=70&&x->r[i].score<=79)             c++;         else if(x->r[i].score>=60&&x->r[i].score<=69)             d++;         else if(x->r[i].score>=0&&x->r[i].score<=60)             e++; #endif     }     /*     A=NUM/(float)a;     B=NUM/(float)b;     C=NUM/(float)c;     D=NUM/(float)d;     E=NUM/(float)e;     */      A= a/NUM;     B= b/NUM;     C= c/NUM;     D= d/NUM;     E= e/NUM;     printf("总共有%d位同学\n             分数于90到100的同学有%d位\n             占总人数的%f\n             分数于80到89的同学有%d位\n             占总人数的%f\n             分数于70到79的同学有%d位\n             占总人数的%f\n             分数于60到69的同学有%d位\n             占总人数的%f\n             分数于60以下同学有%d位\n             占总人数的%f\n",x->length,a,A,b,B,c,C,d,D,e,E); } 供参考～

2#楼第16行修改为：else if(x->r[i].score>=0 &&x->r[i].score<=59) e++;

printf("总共有%d位同学\n 分数于90到100的同学有%d位\n 占总人数的%f\n 分数于80到89的同学有%d位\n 占总人数的%f\n 分数于70到79的同学有%d位\n 占总人数的%f\n 分数于60到69的同学有%d位\n 占总人数的%f\n 分数于60以下同学有%d位\n 占总人数的%f\n",x->length,a,A,b,B,c,C,d,D,e,E); //应改为 printf("总共有%d位同学\n" "分数于90到100的同学有%d位\n" "占总人数的%f\n" "分数于80到89的同学有%d位\n" "占总人数的%f\n" "分数于70到79的同学有%d位\n" "占总人数的%f\n" "分数于60到69的同学有%d位\n" "占总人数的%f\n" "分数于60以下同学有%d位\n" "占总人数的%f\n",x->length,a,A,b,B,c,C,d,D,e,E);

要么每行成对的双引号，要么在\n后面敲回车前敲一个反斜线


Question: 请问这第一题怎么用C语言完成啊

引用 1 楼 qzjhjxj的回复:供参考：#include<stdio.h> #define N 6 //200  int main() {     int i,score[N],cnt_fail=0;     printf("请输入%d个学生成绩:",N);     for(i=0;i<N;i++)         scanf("%d",&score[i]);     for(i=0;i<N;i++){         if(score[i]<60){            printf("%d ",score[i]);            cnt_fail++;         }     }     printf("\n");     for(i=0;i<N;i++){         if(score[i]>=60)            printf("%d ",score[i]);     }     printf("\n");     printf("cnt_fail:%d, cnt_pass:%d\n",cnt_fail,N-cnt_fail);          return 0; } 虽然考试过了还是谢了

#include <stdio.h>  #define N   200 int main(void) {     int total, score[N], tmp, ret;     int i, cnt_fail = 0, idx;      idx = 0;     for(i=0;i<N;i++) {         ret = scanf("%d", &tmp);         if (ret != 1)             break;         if(tmp < 60){             cnt_fail++;             printf("%d ", tmp);         } else  {             score[idx++] = tmp;         }     }     total = i;      for (i = 0; i < total - cnt_fail; i++)         printf("%d ", score[i]);     putchar(10);      printf("%d %d\n", cnt_fail, total-cnt_fail);      return 0; } 供参考～  在第一个循环里可以完成尽可能多的事情～

你没有必要2个循环判断，一个for就能统计完所有的了


Question: 关于结构体指针定义指针变量

引用 11 楼 赵4老师 的回复:a前面的&和*们都是运算符你知道不？赵4老湿顾左右而言它，是在遮掩什么？这么说吧， 1，a是数组类型的变量，不是sizeof和一元&的操作数，所以自动转换为指向数组首元素的指针； 2，一元*运算符作用于指针，得到指针所指向的实体，即，* a 得到数组的首元素（但不是指第一个元素的值，而是这个元素本身，是个左值）； 3，一元&运算符要求它的操作数必须是左值或者函数指示符，其结果是得到一个指针（但不是左值）。在这里，* a 是左值，& * a 的结果是指针。 。。。。。。  要点是（2）。很多人一概认为一元 * 运算符是“取值”，这是很荒谬的。

就等价于 CreateBiTree(BiTNode** T)

就是二级指针啊

a前面的&和*们都是运算符你知道不？

引用 9 楼 赵4老师 的回复:自己眼拙看不到&和*的定义还怪别人答非所问。 引用 6 楼 均陵鼠侠 的回复:补充一下，我就想知道，a是什么，& a 得到了什么，从而* & a 又是什么，最后& * & a 又得到了什么。请赵4老湿明示。^  我问的不是这些运算符有什么用，是什么。

自己眼拙看不到&和*的定义还怪别人答非所问。

引用 7 楼 赵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 | //+------------------+-----------------------------------------+---------------+   答非所问。看来很多IT人士的语文水平都不行。

引用 3 楼 赵4老师 的回复:《牛肉干》 C语言上机课，某女同学偷偷吃起牛肉干。 有一粒牛肉干掉到了键盘上，卡在7和8键之间。 女同学就在键盘上抠啊、抠啊、抠啊…… 程序里一行代码变成这个样子： int *pa=&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&a; 后来的结局是 ————程序顺利通过编译，运行结果正确！  请赵4老湿从语法（semantic）的角度解释一下原理。


Question: 为啥没有输出哇？好奇怪

就是你代码里的指针呀，跟1楼比较一下，那个是正确的，先给指针定个小目标嘛。

引用 1 楼 user-2 的回复:变量，指针变量，指针，地址，供参考：#include<stdio.h>  int main() {     int *A,*B,*C,a,b,c,t;     scanf("%d%d%d",&a,&b,&c);     A=&a;B=&b;C=&c;     printf("1:%d,%d,%d\n",*A,*B,*C);     if(*A > *B)     {         t =*A;         *A=*B;         *B=t;     }     if(*A > *C)     {         t =*A;         *A=*C;         *C=t;     }     if(*B > *C)     {         t =*B;         *B=*C;         *C=t;     }     printf("2:%d,%d,%d\n",*A,*B,*C);          return 0; } 可以解释一下为什么要这么做吗？

引用 2 楼 forever74 的回复:向无目标指针的目标写入数据，有可能引起核弹意外发射。 无目标指针是什么意思？

需要对指针变量、地址各是什么，深入的学习下，结合上面代码的找找感觉。我们定义：int *A,*B,*C; 三个是指针变量，这三个变量里只能放得下地址门牌号，我们把他们看成三个抽屉。我们又定义了：int a,b,c;  三个变量，我们把他们看成是三间房子，然后把三个宝贝放到三间房子里。现在，我们想把放在a 和 b 房子里的宝贝据为己有，那怎么才能找到他们？我们拉开抽屉A找到a家地址，然后驱车前往取得，然后从抽屉B里得到b家地址，同样驱车前往拿到他们，就是这么个感觉。

向无目标指针的目标写入数据，有可能引起核弹意外发射。


Question: 有没大佬教我指针，学了一学期的C语言，前面还好，直到指针就不知道咋办了。差点挂科了

C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html

谭浩强的书教的挺详细的

内存里面都是记录01的电路（可以理解为微型晶体管）。逻辑上，每个数据在内存里都有自己的位置，可以理解为线性的（分页之类的都在系统层面解决了）。  1.  指针，就是一个整数，一般用32位编译器就是INT32,用64位编译器是INT64，里面记录了一个地址。以64位编译器为例子。 2.  指针本身是一个整数，也占用8字节地址。因此，也可以用另一个整数记录该指针自身的地址，也就是“指针的指针”。 3.  地址本身没有类型, char *, int * int ** classA * 这些指针的取值、指针本身的size都是INT64。  C里的指针类型，是为了告诉编译器如何使用以该整数为起点的内存。携带的信息有： （1）单元的大小。比如，对char 指针做++,前进1字节。对 int * ,前进4字节，对 int (*)[4]，前进16字节。 （2）单元的类型，比如 int, double, float. （3）单元的属性，比如是不是 const.

以前的回答，感觉很生动。于是找来复制一份你看看：  参加过运动会吧。 我指着（站在左上角的）你说 ：看这一排走的真整齐（排 指针） ：这迎面走来的是3年纪4班的同学们。他们...（班 指针） ：下面将要入场的是3年纪的同学们。他们...（年级 指针）  显然，我都是指着左上角的的你 也就是指向的位置都是相同的。  但是类型不一样。  当我需要指向下一排的时候，则，（排 指针 ++） 当我需要指向下一个班级的时候，则，（班级 指针++） ...  而我，就是那个指针。站在某一处【这里强调的意思是，这个指针(我)也是占了空间的】。

不复杂怎么能显出老师的水平高呢？ 不对学生显出老师的水平高，学生怎么能服老师，进而能听进去老师讲的知识点呢？

不用把代码写的这么复杂吧，把函数，指针，数组类型全部套在一起，看的人头都大了。完全可以封装一下,使用时就这几种: 类型，这种类型的指针，这种类型的数组, 这种类型的指针数组。 比如这种函数类型可以单独定义出来:   typedef char(* Fun())[5];  char num[5]; char (*x00())[5] {     return # }  char (*(*x[3])())[5];  //可以写成 Fun* x[3];  char (*(*x0 )())[5]; //可以写成 Fun* x0;

百度下指针，多看几篇，然后思考，然后再看，然后思考上手看编译出来结果是咋个的. 指针相当于一个门牌号，可以任意强转，只是安全性你自己负责.

你这个贴子的下面，都是讲指针的，随便找篇看看就差不多了

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

理解和讨论之前请先学会如何观察！

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495


Question: 关于宏定义与指针

引用 2 楼 user-1 的回复:供参考：#include<stdio.h>  #define change(a,b)  t=(a),(a)=(b),(b)=t #define compare(a,b) (a)>(b)?change((a),(b)):NULL  int main() {     int *a,*b,*c,t,A,B,C;     scanf("%d%d%d",&A,&B,&C);     a=&A;b=&B;c=&C;     printf("1: %d,%d,%d\n",*a,*b,*c);      compare((*a),(*b));     compare((*a),(*c));     compare((*b),(*c));     printf("2: %d,%d,%d\n",*a,*b,*c);      return 0; } 感觉和我另一个帖子犯的错误好像啊

深入理解指针、地址、变量的概念，然后结合上面的代码再找找感觉。

我怀疑是宏定义不能用指针的问题，然后宏定义里也没加*，但是还是错了。


Question: 链表问题

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

修改如下，供参考：#include<stdio.h> #include<stdlib.h>  typedef struct Syracuse {     int    value;     struct Syracuse *next; } Syracuse_t;  void display_SyracuseSeq(Syracuse_t *ptrL);//头指针ptrL，作用带替printf输出序列 Syracuse_t * create_SyracuseSeq(int n);//运行函数，当值到1就结束 void destroy_SyracuseSeq(Syracuse_t **adptrL);//释放内存函数  int main(int agrc, char *argv[])//argc记录了用户在运行程序的命令行中输入的参数的个数。 {     Syracuse_t *ptrL;     int n=4; // value of u0     ptrL=create_SyracuseSeq(n);     display_SyracuseSeq(ptrL);     destroy_SyracuseSeq(&ptrL);     display_SyracuseSeq(ptrL);          return EXIT_SUCCESS; } void display_SyracuseSeq(Syracuse_t *ptrL)//头指针ptrL，作用带替printf输出序列 {     Syracuse_t *p;     p=ptrL->next; //p=ptrL;     printf("Syracuse sequence starts with: ");     while(p)  //->value!=1)     {        printf(" %d ", p->value);        p=p->next;     }               //printf(" %d ", p->value);     printf("\n"); } Syracuse_t * create_SyracuseSeq(int n) {     Syracuse_t *ptrL,*tail;     Syracuse_t *p;     ptrL=(Syracuse_t * )malloc(sizeof(Syracuse_t));     ptrL->value=n;     ptrL->next=NULL;     tail=ptrL;     while(n >= 1)//while(ptrL&&ptrL->value!=1)     {         p=(Syracuse_t * )malloc(sizeof(Syracuse_t));         if (n%2 == 0)             p->value = n/2;         else             p->value = 3*n + 1;         p->next=NULL;         tail->next=p;         tail=p;         n--;     }     return ptrL; } void destroy_SyracuseSeq(Syracuse_t **adptrL) {     Syracuse_t *p;     p=(*adptrL)->next;     while(p!=NULL) //NUll     {         (*adptrL)->next=p->next;         free(p);         p=(*adptrL)->next;     } }


Question: 大佬帮帮忙keil程序问题

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

无图无真相