Question: C语言 如何把十六进制数据转变为图片

仅供参考：#include <stdio.h> #include <string.h> #include <conio.h> FILE *fi,*fo; int r; unsigned int n,c; long offset; //------------------------------------------------------- void main(int argc,char *argv[]) {     if (argc<3) {         cprintf("Hex2Bin srcfile desfile");         return;     }     if ((fi=fopen(argv[1],"rb"))==NULL) {         cprintf("Can not find file %s",argv[1]);         return;     }     if ((fo=fopen(argv[2],"wb"))==NULL) {         fclose(fi);         cprintf("Can not create file %s",argv[2]);         return;     }     n=0;     while (1) {         offset=ftell(fi);         r=fscanf(fi,"%2x",&c);         if (EOF==r) break;//         if (1==r) {             fputc(c,fo);             n++;         } else {//0==r             fseek(fi,offset,SEEK_SET);//因为VC6的Release版及其VC7,8,9,10,...版的fscanf未按约定保持offset不变，所以此处必须恢复offset             r=fgetc(fi);             if (EOF==r) break;//         }     }     fcloseall();     cprintf("OK to Hex2Bin %d bytes.",n); }

引用 6 楼 ynsenyu 的回复:收藏一下楼上的，我倒是写过一个bin2hex的，主要是想包含二进制数据文件，用rc提取比较麻烦 #include <stdio.h> #include <string.h> #include <conio.h> FILE *fi,*fo; unsigned int n; int c; //------------------------------------------------------- void main(int argc,char *argv[]) {     if (argc<3) {         cprintf("Bin2Hex srcfile desfile");         return;     }     if ((fi=fopen(argv[1],"rb"))==NULL) {         cprintf("Can not find file %s",argv[1]);         return;     }     if ((fo=fopen(argv[2],"w"))==NULL) {         fclose(fi);         cprintf("Can not create file %s",argv[2]);         return;     }     n=0;     while (1) {         c=fgetc(fi);         if (EOF==c) break;         n++;         if (1==n)        fprintf(fo,  "0x%02X",c);         else {             if (1==n%16) fprintf(fo,"\n0x%02X",c);             else         fprintf(fo, ",0x%02X",c);         }     }     fcloseall();     cprintf("OK to Bin2Hex %u bytes.",n); }

前两个字节为ffd8，说明这个已经是jpg格式了，只不过是将二进制的图片数据转存为了hex字符串。  直接从文件中读取这个字符串，写个hex2bin函数，将其转回成二进制格式即可。

是裸rgba数据不？

txt文档保存图片？数据格式是什么？要转换到jpg也要知道jpg压缩格式。 格式转换一下，保存成文件。。。 http://blog.csdn.net/zhengzhoudaxue2/article/details/7693258 找找C中有没有对应转码的库，研究一下。 第一个图片会比较困难，但是一个完成以后下一个会好很多了


Question: C语言结构体数组指针问题

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

为什么多了一个空格就错了，原理是什么啊，求大神详细告知

学会使用scanf

scanf格式串中的最后一个空格去掉，其余的也是多余


都讲太复杂了  pthread_cond_wait() 必须与pthread_mutex_lock() 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程（线程乙）通过pthread_cond_signal()或pthread_cond_broadcast，把该线程（线程甲）唤醒，使pthread_cond_wait()通过(返回)后 1，如果此时发信号pthread_cond_signal()的线程乙已经释放锁，线程甲自动获得该mutex。 2，如果此时发信号pthread_cond_signal()的线程乙还没有释放锁，则线程甲继续睡眠直到线程乙释放锁后，线程甲再获得mutex  就这么个道理

引用 2 楼 user-3 的回复:你上面贴的代码（好像是我写的）有问题，似乎是我随手写的，没仔细检查。  先说一下条件变量的作用： 条件变量的作用是，仅当某个特定值满足某个条件时才执行后续的操作。  考虑下面这种情况：假设在线程1中，只有当（count > N） 时才需要执行后续操作，但这个count值是由其他线程（可能有多个）修改的，本线程并不知道什么时候才能满足条件。 如果需要后续的操作能即使响应，假使不使用条件变量，那么需要在一个循环中不断检测count值，这将极大的消耗CPU资源； 但如果用sleep等待，有可能会导致后续操作延误，而无法及时完成。  为了解决上面这种问题，于是引入了条件变量，在线程1中用下面这种方式来等待： pthread_cond_wait(&cond, &mutex)； 只要不满足预定的条件，那么上面这行将一直保持阻塞状态，不会占用任何CPU资源。  ================ 其他线程： 当操作count值的另外某个线程执行到另count = N时， // 1. 先给mutex加锁，用于包含cond变量，确保不会有其他线程重复触发条件激活的信号 pthread_mutex_lock(&mutex); // 2. 发个信号，告知条件就绪 pthread_cond_signal(&cond);  // 此时，pthread_cond_wait会激活，线程1开始支持后续操作 // 3. 解锁 pthread_mutex_lock(&mutex); -----------------------  线程1： 当pthread_cond_wait执行时，检查cond状态， a. 如果cond出于阻塞状态，先解锁mutex，并将该线程挂起在后台； b. 如果cond激活，那么就加锁mutex，并完成此次等待操作，允许执行线程1后续的工作。  具体流程是：  // 必须先加锁，才能执行pthread_cond_wait，否则会出现不可预知的结果 pthread_mutex_lock(&mutex);    while(1) // 如果需要反复执行 {         pthread_cond_wait(&cond, &mutex);  // 该行执行后，若cond为阻塞状态，则mutex将解锁         // 由于（b）步骤的操作，mutex此时出于加锁状态         // do some work               // finish work        if (满足某个终止条件）break;        // 由于是个循环，此时会返回到pthread_cond_wait行，注意此时mutex还是加锁状态 } pthread_mutex_unlock(&mutex); // 如果因为某些原因直接跳出了循环，需要解开被pthread_cond_wait加的锁   ======================================  在使用条件变量时有个注意事项，即必须确保线程1中的 pthread_cond_wait已经执行了之后，才能在其他线程中执行pthread_cond_sig操作，否则会出现不可预知的结果（我以前曾遇到过这种情况，找了很久才发现原因）。 可以在用pthread_create创建了线程1后。先 usleep几毫秒，然后在创建其他工作线程，这样可以确保取得预期的效果。 b. 如果cond激活，那么就加锁mutex，并完成此次等待操作，允许执行线程1后续的工作。  这句话建议修改一下，如果cond激活，得分两种： 1. 如果线城1已经获得锁，那就继续保持锁的状态  2. 如果线城1没有拿到锁，才加锁。

引用b. 如果cond激活，那么就加锁mutex，并完成此次等待操作，允许执行线程1后续的工作。  这句话建议修改一下，如果cond激活，得分两种： 1. 如果线城1已经获得锁，那就继续保持锁的状态  2. 如果线城1没有拿到锁，才加锁。  感谢提醒。  不过我又考虑了一下，似乎在合理设计的情况下，不应出现在cond激活的同时，本线程也取得了锁的情况。 这是因为: （1） 当第一次调用pthread_cond_wait时，cond是阻塞的，此时本线程会释放锁，同时使线程阻塞在该函数上，会等待激活信号。 （2） 由于(1)的操作，当其他线程发出激活信号时，本线程是必然处于没拿到锁的状态，此时本线程将主动加锁(mutex_lock)，并将cond重置为阻塞状态。操作成功后再结束pthrad_cond_wait等待。 （3）由于(2)的操作，在下一次调用pthread_cond_wait之前，mutex锁将始终被本线程占有，其他线程没有机会解除cond的阻塞，所以又回到步骤（1）  在（1）～（3）这个循环中是不可能同时出现“cond激活，而本线程取得锁”的情况（除了pthread_cond_wait内部实现中的那次原子操作）。  如果出现那种情况，可能有两个原因： 1. 在其他线程中过早地调用了pthread_cond_signal，其他线程先激活了cond，而本线程还没来得及开始第一次cond_wait调用。 2. 其他线程在没先加锁的情况下直接调用了cond_signal。  如果出现以上两种行为，那么将可能导致无法预期的结果，在程序设计时就一定要避免。  =======================  另外，我在4楼贴的代码有bug，最初我只设计了一个【工作者线程】，生成随机数时用了rand()。后来考虑支持多个【工作者线程】，改换成了多线程安全的rand_r(&seed); 贴代码时忘了改main（）函数中的初始化种子的部分了。 需要将第52行的 srand(time(NULL)); 修改为 seed = time(NULL);  我另外写了一个实现多个工作者线程的完整版本，并修复了很多bug。 详见： http://bbs.csdn.net/topics/391922234

不好意思，仔细看了一下，上面贴出的代码不是我写的（只是代码注释风格和我有点儿像）  贴一个使用条件变量的示例： 根据主贴中的代码，稍微做了一些改动，去掉了用scanf接受数据的代码，因为scanf使线程处于阻塞状态，不太容易看出条件变量的效果   /*  * test3.c  * Copyright 2016 Che Hongwei <htc.chehw@gmail.com>  * The MIT License (MIT)  *   */  #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <time.h>  #define N 6  /* ************************  * 在使用条件变量时，尽可能地创建一个单独的互斥锁，将其仅用于同步条件变量cond，  * 假使为了省事，将该mutex用在了其他地方，如果实现的逻辑有出了差错，可能会出现不可预知的结果  * 为此，下面自定义了一个结构体，将cond和mutex强行捆绑在一起，避免误用  * */ typedef struct cond_mutex { 	pthread_cond_t c; 	pthread_mutex_t m; }cond_mutex_t;  /* ************************  * 初始化 互斥锁 和 条件变量   * */ cond_mutex_t cm =  { 	PTHREAD_COND_INITIALIZER, 	PTHREAD_MUTEX_INITIALIZER };     static void * wait_thread(void * param);   // 等待线程 static void * worker_thread(void * param); // 工作者线程  // 用一个mutex来同步对count 和 data 的操作 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static int count = 0; static int data[N];  unsigned int seed; volatile int quit = 0; // notify threads to quit  int main(int argc, char ** argv) { 	int rc; 	pthread_t th[2]; 	srand(time(NULL)); 	void * ret_code = NULL; 	 	// 创建等待线程 	rc = pthread_create(&th[0], NULL, wait_thread, NULL); 	if(0 != rc) 	{ 		perror("pthread_create"); 		exit(1); 	} 	usleep(5000); // 5 ms 	 	// 创建工作者线程 	rc = pthread_create(&th[1], NULL, worker_thread, NULL); 	if(0 != rc) 	{ 		perror("pthread_create"); 		exit(1); 	} 	 	 	char c = 0; 	printf("press enter to quit.\n"); 	while(1) 	{ 		scanf("%c", &c); 		if(c == '\n') break; 	} 	 	quit = 1; 	pthread_cond_broadcast(&cm.c); // 激活在所有线程中正在等待中的条件变量 	 	pthread_join(th[0], &ret_code); 	pthread_join(th[1], &ret_code); 	 	 	rc = (int)(long)ret_code; 	 	pthread_mutex_destroy(&mutex); 	pthread_cond_destroy(&cm.c); 	pthread_mutex_destroy(&cm.m); 	return rc;	 }  static void * worker_thread(void * param) { 	int value; 	while(!quit) 	{		 		value = rand_r(&seed) % 1000; 		pthread_mutex_lock(&mutex); // 先加锁之后，再修改data和count值 		if(quit) // 有可能在锁定等待期间被用户强行退出 		{ 			break; 		} 		data[count++] = value;		 		if(count == N) 		{ 			pthread_mutex_lock(&cm.m);			 			pthread_cond_signal(&cm.c); 			pthread_mutex_unlock(&cm.m);			 		} 		pthread_mutex_unlock(&mutex); // 解锁 		usleep(100000); // 100 ms; 	} 	pthread_exit((void *)(long)0); }  static void * wait_thread(void * param) { 	int i, sum; 	pthread_mutex_lock(&cm.m);	 	while(!quit) 	{ 		pthread_cond_wait(&cm.c, &cm.m); 		if(quit) break; //有可能是在等待期间被用户干预，强制退出的（在while中判断时quit可能还是0） 		 		pthread_mutex_lock(&mutex); // 先上锁，避免其他线程修改 data 和 count 值 		sum = 0; 		printf("data = "); 		for(i = 0; i < N; ++i) 		{ 			sum += data[i]; 			printf("%d, ", data[i]); 		} 		 		printf("average = %d\n", sum / N); 		count = 0; 		pthread_mutex_unlock(&mutex); 		 	} // end while 	 	pthread_mutex_unlock(&cm.m); 	 	pthread_exit((void *)(long)0); }

补充： （上一条回复中有一点没表达清楚） 线程1中的 （a）和（b）步骤是 在 pthread_cond_wait函数内部实现的，对cond和mutex状态的改变是一个原子操作。

csdn的例子


Question: c语言多重switch，最里面那层使用break，是跳出本层还是所有switc呢

break 退出当前层， return 退出当前函数 exit退出程序   goto跳到标签位置

只是跳出本层

break;goto;return;throw;exit(1);taskkill;shutdown;拔电源插头;……

break只对循环语句有用，即switch  for while这些，对条件语句不起作用。 break只能跳出本循环，也即只能跳出一层。 想实现多层跳出可以自己用多个break加条件判断实现，也可以用goto语句。不过编码规范好像不建议用goto。

如果想跳出多层循环除了用goto，再就自定义判断逻辑，一层层跳出。

break会直接跳出最内层的循环或switch语句块，不理睬if语句 break其作用大多情况下是终止上一层的循环，以C语言来说，break在switch（开关语句）中在执行一条case后跳出语句的作用。 1. break语句对if-else的条件语句不起作用。   2. 在多层循环中，一个break语句只向外跳一层。

break 只能跳出一层 switch 或者循环 如果是 if else break 是不管的。 他只管 switch 或者循环

跳出本层，可以使用一些标志变量控制要跳出的层，或直接 goto ，一般不建议使用超过两层的 switch 。

又试了一下for语句 #include <stdio.h> #include <stdlib.h> main() {int i=0;int j;     for(i=0;i<5;i++)         {for(j=0;j<5;j++)         if(j==0)break;}  printf("%d",i); } 也是只break最里层

#include <stdio.h> #include <stdlib.h> main() {     int a[]={2,3,5,4},i;     for(i=0;i<4;i++)     switch(i%2)     {case 0:switch(a[i]%2)        {case 0:a[i]++;break;         case 1:a[i]--;         };  case 1:a[i]=0; } for(i=0;i<4;i++)printf("%d",a[i]);printf("\n"); } 试了一下，里面的break只跳出里层


Question: 在dec-c++下搭建wpcap环境报错

引用 3 楼 zhao4zhong1 的回复:项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项 赵老师，我重下了winpcap包，重新配置了一下，现在好了！

引用 1 楼 zhao4zhong1 的回复:Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt  Visual Studio 6/2005/2008/2010/2012/2013 各版本编译器 下载 http://bbs.csdn.net/topics/390812579 赵老师，我载了vc2010按网上的教程搭好了环境但是编译还是报错


Question: 我一直有个问题弄不懂,C是不支持多线程的，Linux内核是C标准写的，那它怎么支持多线程呢？

引用 3 楼 chehw_1 的回复:多线程是操作系统的功能，这不是C语言要做的事。 C语言是用最简洁的语法来实现任意复杂的功能，包括让操作系统实现多线程支持。  “C语言本身不支持多线程，所以不能实现多线程“ 这种概念是错误的。 这就好比C语言本身虽然不支持“面向对象”和“模板”，但却可以用C来实际实现“面向对象”和“模板”。比如GTK+就是完全用C写出了“面向对象”编程的模式，包括实现类的继承；而gmp库，虽然是用C、汇编编写的，但大量使用来C方式的模板。  有些C标准库的函数在最初设计时可能不是线程安全的，这是因为在这些库最初写成的时候，还没发明出多线程的概念，由于在实现时使用了很多全局变量，加上函数声明的限制，后期也很难引入对多线程的支持。  比如rand()函数，早期使用了一个全局变量做为种子，所以该函数在多线程环境下一定是不安全的，由于该函数不附带任何参数，因此也无法简单的将其改成支持多线程。为了支持多线程，后期只能另外引入一个rand_r（）函数，多传递一个参数来用于同步。  也就是说，不是C不支持多线程，而是C的标准库中的一些函数未必支持多线程。这需要C程序员在多线程编程下自己格外注意这些库函数的使用，避免因为误用了某些多线程不安全的库函数而造成不可预知的后果。   大神，学习了!

引用 1 楼 user-2 的回复:线程的原理是把多个同时跑的代码段放在内核创建的一个队列中，快速的循环执行，从最底层来讲线程不可能是同步的。从应用层看一般都认为线程是同步的。应该就是这样理解吧。   哦哦，原来是这样，感谢指导!


Question: 严重性	代码	说明	项目	文件	行 错误(活动)		不能将 "struct Student" 类型的值分配到 "struct Student" 类型的实体	ch

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

编译器太老了吧

严格来说没有写赋值操作符就不要直接赋值吧，用memcpy好些

没什么问题啊


Question: 【C语言debug】for information on how your program can cause an assertion failure

这个题我也是服了，不让改动其他函数里的内容，结果文件指针fp指向的文件in.dat是只读的，然后文件在该路径下不存在。楼主可以改文件路径为  fp = fopen("in.dat","r") ; wf = fopen("out.dat","w") ; 考试应该不会出现这样的情况。

NONO函数中,这两句有问题 fp = fopen("c:\\test\\in.dat","r") ; wf = fopen("c:\\test\\out.dat","w") ; 打开失败了(不存在"c:\\test\\in.dat这个文件)，或者是没有权限在这个目录下写文件 楼主fopen以后应该判断下指针是否为NULL if(fp != NULL && wf != NULL){ .............. }

下面调用文件时候路径不对


Question: c语言读取文件的问题。新手求助！！！

谢谢大神 谢谢！！！！

注释写在代码里了，相当于从一个文件里提取出碰到的第一组的连续的数字 比如一个文件: asd2358395bb 12312asd  运行结果：提取出的是2358395   #include <iostream> using namespace std; int Read_Num(FILE *fp)  { 	char temp[8]; //用来存储读到的数字字符 	int i=0; //用来记录当前字符数组的位置 	int stop=0; //标志是否读到了数字（仅读一组数字） 	char ch; //记录当前读到的字符 	while(!stop) 	{ 		ch=fgetc(fp); //读取一个字符 		if(ch==EOF)    //判断是否读到了文件尾 			break; 		while(ch>='0'&&ch<='9')//读到的是否是一个数字字符 		{ 			stop=1;//标志位置1 			temp[i++]=ch;//当前数字字符存到数组里，然后i+1 			ch=fgetc(fp);//继续读取字符 		} 	} 	temp[i]=0;//在当前数组最后填0 	return atol(temp);//将字符串转为长整数并返回 } int main() { 	FILE *fp; 	fp = fopen("E:\\out_1.txt", "r"); 	cout << Read_Num(fp) << endl; 	system("pause"); 	return 0; }


Question: C语言怎样把链表存入文件，然后从文件读取到链表

自己去找下c如何读写文件的知识点看下。网上一堆

仅供参考：//文件1: //编号12 23 34； //文件2： //编号 x y z //1 3.45 4.2 3.6 //2 2.45 4.2 3.6 //  ........ //277 4.00 8.38 9.92 //278 5.00 8.38 9.92 #include <stdio.h> FILE *f1,*f2,*f3; char ln[80]; int r,n,n2,n21; float x,y,z; int xyz_of_line(int nn,float *xx,float *yy,float *zz) {     n2=-1;//跳过第一行:编号 x y z     rewind(f2);     while (1) {         if (NULL==fgets(ln,80,f2)) break;         n2++;         if (n2==nn) {             r=sscanf(ln,"%d%f%f%f",&n21,xx,yy,zz);             if (4==r) {                 if (n21==nn) {                     return 1;                 } else {                     printf("WARNING:编号 error in line %4d:%s",nn,ln);                     return 1;                 }             } else {                 printf("ERROR:Format error in line %4d:%s",nn,ln);                 return 0;             }         }     }     return 0; } void main() {     f1=fopen("文件1","r");     if (NULL==f1) {         printf("ERROR:fopen 文件1 error!\n");         return;     }     f2=fopen("文件2","r");     if (NULL==f2) {         fclose(f1);         printf("ERROR:fopen 文件2 error!\n");         return;     }     f3=fopen("文件3","w");     if (NULL==f3) {         fclose(f2);         fclose(f1);         printf("ERROR:fopen 文件3 error!\n");         return;     }     while (1) {         r=fscanf(f1,"%d",&n);         if (1==r) {             r=xyz_of_line(n,&x,&y,&z);             if (1==r) {                 printf("%4d:x=%g,y=%g,z=%g\n",n,x,y,z);                 fprintf(f3,"%4d:x=%g,y=%g,z=%g\n",n,x,y,z);             } else {                 printf("ERROR:Can not read line %4d!\n",n);             }         } else if (0==r) {             fgetc(f1);         } else break;     }     fclose(f3);     fclose(f2);     fclose(f1); }

引用 1 楼 zhao4zhong1 的回复:fprintf fscanf不是很懂额，我文件部分学的不好

fprintf fscanf


Question: 求解 关于char *p[100]

#include <stdio.h> char *p[5]; char d[5][6]={ {0,1,2,5,4,0,}, {0,0,5,4,4,0,}, {0,0,0,0,0,0,}, {1,1,1,1,1,1}, {5,5,5,5,5,5}, }; char num[30]; int x,i,j; int main() {     for (i=0;i<5;i++) p[i]=d[i];     x=0;     for(i=0;i<5;i++) {         for(j=0;j<6;j++) {             num[x]=p[i][j];             x++;         }     }     for (i=0;i<30;i++) printf("%d",num[i]);//012540005440000000111111555555     return 0; }

那我怎么提取数据呢？

char *p[100] 这个是指针数组，每一个元素均为指针，每个指针都指向一个字符串


Question: hdu 2089 超时....

不要重复处理。如果测试数据中有几个范围都是在1~10^6范围内就可能会超时了。下面的代码先进行预处理，参考下 #include <stdio.h> #include <string.h> int flag[1000010];  void preprocess() { 	char str[10] = { 0 }; 	int i = 0; 	for (i = 1; i <= 1000000; i++) 	{ 		sprintf(str, "%d", i); 		if (strstr(str, "62") || strstr(str, "4")) 		{ 			flag[i] = flag[i - 1]; 		} 		else 		{ 			flag[i] = flag[i - 1] + 1; 		} 	} }  int main() { 	memset(flag, 0, sizeof(flag)); 	int m, n; 	preprocess(); 	while (scanf("%d%d", &n, &m) != EOF) 	{ 		if (n == 0 && m == 0)break; 		printf("%d\n", flag[m]  - flag[n-1]); 	} 	return 0; }

不对哦qaqaqa

while(scanf("%d %d",&n,&m)!=EOF) 应改为 while(scanf("%d%d",&n,&m)==2)


Question: 我的C++程序调试时出现“Program received signal SIGSEGV，Segmentation fault.”是什么原因，求指导。

双引号位置错了，scanf("%4d/%2d/%2d,&iYear,&iMonth,&iDay");改为scanf("%4d/%2d/%2d",&iYear,&iMonth,&iDay);

有几个问题： 1.scanf处双引号，上面已经说了 2.case和后面的数字要分开 3.if((iYear % 4 == 0) && (iYear % 100 != 0) || (iYear % 400 == 0))后面不应该加分号，而且应该加上else  #include<iostream> using namespace std;  int main(){ 	int iYear,iMonth,iDay,iDays;bool bFlag=true; 	cout<<"请输入日期（年/月/日)："<<endl; 	scanf("%4d/%2d/%2d",&iYear,&iMonth,&iDay); 	switch(iMonth) 	{ 	case 1:; 	case 3:; 	case 5:; 	case 7:; 	case 8:; 	case 10:; 	case 12:iDays=31;break; 	case 4:; 	case 6:; 	case 9:; 	case 11:iDays=30;break; 	case 2: if((iYear % 4 == 0) && (iYear % 100 != 0) || (iYear % 400 == 0)) iDays=29; 			else iDays=28;break; 	default:bFlag=false; 	} 	if(bFlag) 		cout<<"此日期对应月的天数是："<<iDays<<endl; 	else 		cout<<"输出错误："<<endl;  	system("pause"); }

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

改了，还是显得那个


Question: 怎么看待以下代码片？？？

明白了，未定义行为问题。。。。

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

引用 9 楼 小灸舞的回复:参考下：http://www.cnblogs.com/chenyg32/p/3708164.html 这个也没必要研究，自己都没法知道输出啥结果来 确实，写程序的时候避开这样的问题就好了。 不研究编译器的话，就了解了解当增长见识好了，不必深究。。。

引用 8 楼 IAYXNS 的回复:表达式求值顺序问题 可以参考下面两篇文章 http://m.blog.csdn.net/article/details?id=37833767  http://bbs.csdn.net/wap/topics/370153775  话说csdn客户端上怎么结帖，不能让类问题继续祸害别人了，病毒一样的存在。。。  关于C,C++表达式求值顺序  http://bbs.csdn.net/topics/370153775

引用 5 楼 IAYXNS 的回复:[quote=引用 3 楼 小灸舞的回复:]这题主要有两个知识点： 1.printf的顺序是自右向左（会有压栈操作） 2.前++和后++的区别(不仅仅是先加1再计算，和先计算再加1的区别，还涉及是否是引用的区别) 第一步执行++a,由于是前++，所以先将a的值加1（a变为了6），再将a压栈（注意！是将a的引用压栈，而非6这个数字） 此时栈中为（从栈底开始）是a 第二步执行a,将a压栈（此时是a的引用，而非6这个数字），此时栈中为（从栈底开始）是a,a 第三步执行a++,由于是后++,(注意了，后++是将数字压栈，而非a的引用)，所以将6这个数字压栈，然后执行a=a+1(此时a为7) 此时栈中为（从栈底开始）是a,a,6 第四步执行a,将a压栈（此时是a的引用，而非7这个数字），此时栈中为（从栈底开始）是a,a,6,a 然后格式化输出，出栈顺序为a,6,a,a(此时的a是7) 所以输出的是7，6，7，7  注：楼主也不必要太纠结于结果，因为不同的编译器可能结果不同 看得似懂非懂，看来我还是功力不够啊[/quote] VS2015 输出 6,6,6,6 G++ 5.3输出 7,6,7,7 intel C++输出 7,5,7,7 这些结果都是合法的。 编译器可以自由处理未定义行为。

引用 3 楼 qq423399099 的回复:这题主要有两个知识点： 1.printf的顺序是自右向左（会有压栈操作） 2.前++和后++的区别(不仅仅是先加1再计算，和先计算再加1的区别，还涉及是否是引用的区别) 第一步执行++a,由于是前++，所以先将a的值加1（a变为了6），再将a压栈（注意！是将a的引用压栈，而非6这个数字） 此时栈中为（从栈底开始）是a 第二步执行a,将a压栈（此时是a的引用，而非6这个数字），此时栈中为（从栈底开始）是a,a 第三步执行a++,由于是后++,(注意了，后++是将数字压栈，而非a的引用)，所以将6这个数字压栈，然后执行a=a+1(此时a为7) 此时栈中为（从栈底开始）是a,a,6 第四步执行a,将a压栈（此时是a的引用，而非7这个数字），此时栈中为（从栈底开始）是a,a,6,a 然后格式化输出，出栈顺序为a,6,a,a(此时的a是7) 所以输出的是7，6，7，7  注：楼主也不必要太纠结于结果，因为不同的编译器可能结果不同除了 最后一句话 其他全部说错了 请不要误导其他人

引用 3 楼 小灸舞的回复:这题主要有两个知识点： 1.printf的顺序是自右向左（会有压栈操作） 2.前++和后++的区别(不仅仅是先加1再计算，和先计算再加1的区别，还涉及是否是引用的区别) 第一步执行++a,由于是前++，所以先将a的值加1（a变为了6），再将a压栈（注意！是将a的引用压栈，而非6这个数字） 此时栈中为（从栈底开始）是a 第二步执行a,将a压栈（此时是a的引用，而非6这个数字），此时栈中为（从栈底开始）是a,a 第三步执行a++,由于是后++,(注意了，后++是将数字压栈，而非a的引用)，所以将6这个数字压栈，然后执行a=a+1(此时a为7) 此时栈中为（从栈底开始）是a,a,6 第四步执行a,将a压栈（此时是a的引用，而非7这个数字），此时栈中为（从栈底开始）是a,a,6,a 然后格式化输出，出栈顺序为a,6,a,a(此时的a是7) 所以输出的是7，6，7，7  注：楼主也不必要太纠结于结果，因为不同的编译器可能结果不同 看得似懂非懂，看来我还是功力不够啊

引用 2 楼 user-6的回复:5.5.6.7有什么看待的 你去运行试试


Question: 请问C可以用QT做GUI吗?我想学C写文本编辑器，除了用API还有其他方法吗?

RegMpad: MDI Notepad Sample  Click to open or copy the files for the RegMpad sample.  This sample demonstrates how to use the Multiple Document Interface (MDI) functions to create an MDI notepad.  RegDB.c implements the semantics of the registry interface for this application. The visible interfaces and data structures are defined in RegDB.h.  The NT Registry is an object database consisting of keys and values. Keys have names and may contain other keys and values. A value is a name paired with a data object and a data type. The keys in the registry are analogous to the directories in a file system. In that vein the values are analogous to files.  Access to a key and its associated set of values is mediated by a key handle. Four key handles are given as predefined constants. Those handles correspond to the roots of key trees which have special significance. Handles for the other keys in the registry database may be constructed via the Registry's Open and Create interfaces using an existing key handle and a relative path string.  Building SDK Samples   This sample uses the following keywords:  _alloca; _lclose; _llseek; _lread; _mbschr; _mbslen; _mbsncmp; aboutdlgproc; addaccessallowedace; addfile; alreadyopen; bringwindowtotop; changefile; charnext; charprev; charupper; checkdlgbutton; closeallchildren; closehandle; commandhandler; createappkeys; createmutex; defframeproc; deletedc; dialogbox; dialogboxparam; dlgdirlist; dlgdirselectex; enablemenuitem; enddialog; equalsid; escape; fileexists; find; finddlgproc; findnext; findprev; freelibrary; freesid; get_em_setsel_mps; get_wm_command_cmd; get_wm_command_hwnd; get_wm_command_mps; get_wm_mdiactivate_factivate; getcmdline; getcommandline; getcurrentprocess; getcurrentthread; getcurrentuserinfo; getdevicecaps; getdlgitem; getdlgitemtext; getfilename; getinitializationdata; getlasterror; getmenu; getprinterdc; gettextextentpoint; gettokeninformation; getwindow; getwindowlong; getwindowtext; getwindowtextlength; getwindowword; id; initializeacl; initializeapplication; initializeinstance; initializesecuritydescriptor; inituser; installapp; isdbcsleadbyte; isdlgbuttonchecked; iswild; loadconfiguration; loadcursor; loadfile; loadicon; loadlibrary; loadstring; local_findtext; localalloc; localfree; locallock; localrealloc; localunlock; lstrcpy; lstrlen; makeintresource; makelong; messagebox; mperror; mpframewndproc; mpmdichildwndproc; myreadfile; open; openfile; openprocesstoken; openthreadtoken; printdlgproc; printfile; querycloseallchildren; queryclosechild; realslowcompare; regclosekey; regcreatekeyex; regdeletekey; regdeletevalue; regflushkey; registerclass; regopenkeyex; regqueryvalueex; regsetvalueex; releasemutex; runningasadministrator; saveasdlgproc; saveconfiguration; savefile; selectfile; senddlgitemmessage; sendmessage; setdlgitemtext; setsecuritydescriptordacl; setsecuritydescriptorowner; setwindowlong; setwindowword; setwrap; showwindow; storeappconfig; strcpy; unreferenced_parameter; waitforsingleobject; winmain; wsprintf

MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 参考MSDN98中自带的相关例子代码。

引用 4 楼 yyxgs 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 参考Linux下vi的源代码 ？  我想做windows下的[/quote] 参考Notepad++源代码。

引用 5 楼 zhao4zhong1 的回复:[quote=引用 4 楼 yyxgs 的回复:] [quote=引用 3 楼 zhao4zhong1 的回复:] 参考Linux下vi的源代码 ？  我想做windows下的[/quote] 参考Notepad++源代码。[/quote]   你上次就是这么说的，我弄了一半天，还是看不了..

参考Linux下vi的源代码 ？

引用 1 楼 user-2 的回复:文本编辑器就那么点菜单，爱用什么用什么。 和编辑器的功能相比，界面不算什么。   我是初学者，不是C该怎么才能做界面?

引用 3 楼 zhao4zhong1 的回复:参考Linux下vi的源代码 ？  我想做windows下的

文本编辑器就那么点菜单，爱用什么用什么。 和编辑器的功能相比，界面不算什么。


Question: c语言简单的问题，求解决

形参的改变不影响实参

如果想改变传递的参数，只能 传递其指针或者引用


Question: 求浮点数的实际储存（有效位数以后的）是不是也是保存了一定精度的呢？

浮点数存的不是二进制分数，而是二进制的科学计数法

浮点数格式 http://bbs.csdn.net/topics/390676437

通常程序实现是 显示时会是存储值的近似值，而且之后用的仍然是原来存储的值

显示的时候，经过了一次 二进制 浮点数，到 10进制 ASCII码 小数（浮点数）的转换 和保存的并不相同 至于 保存的值 是多少 可以按照浮点数二进制格式，查看一下 不必去猜测 虽然不同平台可能不同，但也比猜测靠谱。 至少了解一种实现方式是多少，怎么做的 。

实际保存的可能是二进制的 13421773/134217728 。  显示出来的和保存的两码事。（这里有一次进制转换，和近似）但是显示不会影响实际保存的值。


Question: if 和 else 语句都被执行，并且在 if 和 else 语句中打印同一个由键盘获得的字符串，打印结果不同

明白了，谢谢大家的解答，麻烦了

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

估计是第二次循环进的else，是问题最适合楼主单步跟踪去发现了

稍微分析下： 1.输入0+回车（输入缓冲区变成0\n） 2.fgets(me, 10, stdin); //fgets会连换行符也读走(此时me读走了0和回车),输入缓冲区变为NULL 3.判断strstr(me, "0") //结果为true 4.printf("输入时间类型："); 5.scanf("%d", &num); //输入0+回车（输入缓冲区变成0\n）,注意了！！！scanf是不会读走回车的，此时输入缓冲区变成了\n 6.if(!num)为true 7.printf("me 是 %s\n", me); 打印 8.由于此时输入缓冲区不为NULL，所以继续执行fgets(me, 10, stdin);(me读走了剩余的回车) 9.if(strstr(me, "0"))为false 10.执行else分支，printf("me 是 %s\n", me);  注：所以楼主感觉if和else都执行了，其实第二次并不是NULL，而是读取遗留下来的回车符，无论去掉while(1)还是fgets都只会执行了一次，也就是说第8-10步都不会执行了，自然不会执行else分支了 所以问题出在scanf这里，楼主可以将scanf("%d", &num);改为scanf("%d%*c", &num);//用%*c匹配掉遗留下来的回车符


Question: c语言命令行。新手求助！！！

引用 12 楼 w_1239729535yq 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] 为什么不 cd Clanguage ..\p376-5 I file.txt 呢?= =为什么 这样就可以了 好神奇。[/quote] 弄清楚啥叫“当前目录”。

引用 11 楼 zhao4zhong1 的回复:为什么不 cd Clanguage ..\p376-5 I file.txt 呢?= =为什么 这样就可以了 好神奇。

引用 8 楼 w_1239729535yq 的回复:引用 7 楼 trytry1992 的回复:把绝对路径加上去因为回显的是 can't open file 所以 路径应该没问题  因为尝试着读取 才会显示都不出来 。。不知道为什么  哭  回显的是你自己输入的内容，你甚至可以在打开失败时输出打开成功，检查路径是否正确  http://en.cppreference.com/w/c/io/fopen

把绝对路径加上去

明显路径不对，这种问题就该先把全路径去调试。

引用 5 楼 w_1239729535yq 的回复:引用 4 楼 zhangxiangDavaid 的回复:把file.txt和执行文件放在一起已经放在一起了  执行就这样  你确定不是.c文件/

把file.txt和执行文件放在一起


Question: C链表文件信息管理--代码正确，执行直接结束？

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

据我分析，你的main函数内，top它只是个地址，又没分配具体空间，下面的函数确一直在用top，给star分配了空间一次都没用，把top=star吧。


Question: C语言程序问题

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

1./*为什么要将temp赋给tail??????*/ 因为这个tail是记录当前结点的位置.当有新的结点来的时候直接将新的结点赋值给tail->next.就能把新的结点直接添加到链表中. 2. /*为什么这里输出不了删除节点后的链表*/ 因为你删除的时候调用的o = del(p);中的p已经不是头指针了,你前面已经将头指针指向最后的NULL了. 3. /*为什么这个else会跟着①的if??????*/ 当你输入删除的序号时候.会输入一个回车符.loop: scanf("%c",&choose);这句会接收到回车,所以会直接跳到最后一个else


Question: c语言结构体数组中如何输入不限个数的数组

结构体变长的妙用——0个元素的数组  typedef struct st_type  {  int nCnt;  int item[];  }type_a;   这样我们就可以定义一个可变长的结构，用sizeof(type_a)得到的只有4，就是sizeof(nCnt)=sizeof(int)那个0个元素的数组没有占用空间，而后我们可以进行变长操作了。   type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));   这样我们就产生了一个长为100的type_a类型的东西用p-> item[n]就能简单地访问可变长元素，原理十分简单，分配了比sizeof(type_a)多的内存后int item[];就有了其意义了，它指向的是int nCnt;后面的内容，是没有内存需要的，而在分配时多分配的内存就可以由其来操控，是个十分好用的技巧。

malloc, realloc自己封装一个结构体。假设你存放数据的结构体的struct elem 则这样定义一个结构体 struct array  { struct elem *data; int size; int capacity; }; size为已存放的数据长度， capacity为可用空间。 每次发现size == capacity时，就realloc, 增大空间。 再定义一些操作，比如push_back


Question: linux中c语言中的int指针

别人的虚拟机可以用的话，证明程序应该是没有问题的，你要不要试试重新安装一下虚拟机试试看啊，没准是虚拟机的问题不是程序问题，我这边也帮你测试一下。或者你可以直接私信我

虚拟机也分16位、32位、64位吧。


Question: 很简单的问题

控制台只能显示一部分，这很容易想到……

控制台行数不是无限的，超过后之前的内容就没了

内容太多，控制台上面还有，只是无法恢复显示了。


Question: 中缀表达式转换为后缀表达式，求大神帮忙找错，

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


Question: 有关C语言的面试题，没参函数不能返回一个地址吗？

引用 4 楼 baidu_28726667 的回复:[quote=引用 2 楼 qq423399099 的回复:] 只有f2是对的 f1返回的是局部变量的地址，在函数结束时，生命周期就结束了，你取一个生命周期结束的地址所对应的值，结果是不确定的 f3中ptr指针你不初始化，它里面存了一个未知的值（地址），你将那个地址所对应的值修改成5，极有可能触发异常（因为该地址对应的区域可能无法访问） return &x一样的 return (&x)  我改了下 f1的返回值不是指针只是int 的话。直接return x; 这样是不会警告的。跟返回指针有什么不同？变量和指针在函数结束后都会消失吧。为何指针的会warning?[/quote] C/C++里如int类型的返回值是复制出去的，和函数内的x不是同一个，只是值相同而已，而返回指针却是返回同一个指针

引用 2 楼 qq423399099 的回复:只有f2是对的 f1返回的是局部变量的地址，在函数结束时，生命周期就结束了，你取一个生命周期结束的地址所对应的值，结果是不确定的 f3中ptr指针你不初始化，它里面存了一个未知的值（地址），你将那个地址所对应的值修改成5，极有可能触发异常（因为该地址对应的区域可能无法访问） return &x一样的 return (&x)  我改了下 f1的返回值不是指针只是int 的话。直接return x; 这样是不会警告的。跟返回指针有什么不同？变量和指针在函数结束后都会消失吧。为何指针的会warning?

f1返回的是局部变量10，f1结束，变量10也就消失了  return &x 跟 return (&x)在这里是一样的  如果是个表达式就不一样了

f3指针未初始化，可能是任意值，如果没有 *ptr=5; 也算正确，没有语法错误，但是加了这句就是作死了。  f1虽然可能导致错误，但是你不用返回值就没事  最后 ， 1 + 1 和 (1 + 1) 一样么


Question: 这样对么，为什么？？？

引用 4 楼 ZiSheng 的回复:[quote=引用 2 楼 wang0635 的回复:] "123" "345" "567" "8910" "dff" 与 "1233455678910dff" 一样。 有进一步的解释吗？还是只需记着就ok了？谢谢！[/quote] 编译器会把它们连接成一个字符串

引用 2 楼 wang0635 的回复:"123" "345" "567" "8910" "dff" 与 "1233455678910dff" 一样。 有进一步的解释吗？还是只需记着就ok了？谢谢！

C++ String Literals A string literal consists of zero or more characters from the source character set surrounded by double quotation marks ("). A string literal represents a sequence of characters that, taken together, form a null-terminated string.  Syntax  string-literal :  "s-char-sequenceopt" L"s-char-sequenceopt"  s-char-sequence :  s-char s-char-sequence s-char  s-char :  any member of the source character set except the double quotation mark ("), backslash (\), or newline character escape-sequence  C++ strings have these types:   Array of char[n], where n is the length of the string (in characters) plus 1 for the terminating '\0' that marks the end of the string   Array of wchar_t, for wide-character strings  The result of modifying a string constant is undefined. For example:  char *szStr = "1234"; szStr[2] = 'A';      // Results undefined  Microsoft Specific   In some cases, identical string literals can be “pooled” to save space in the executable file. In string-literal pooling, the compiler causes all references to a particular string literal to point to the same location in memory, instead of having each reference point to a separate instance of the string literal. The/Gf compiler option enables string pooling.  END Microsoft Specific  When specifying string literals, adjacent strings are concatenated. Therefore, this declaration:  char szStr[] = "12" "34";  is identical to this declaration:  char szStr[] = "1234";  This concatenation of adjacent strings makes it easy to specify long strings across multiple lines:  cout << "Four score and seven years "         "ago, our forefathers brought forth "         "upon this continent a new nation.";  In the preceding example, the entire string Four score and seven years ago, our forefathers brought forth upon this continent a new nation. is spliced together. This string can also be specified using line splicing as follows:  cout << "Four score and seven years \ ago, our forefathers brought forth \ upon this continent a new nation.";  After all adjacent strings in the constant have been concatenated, the NULL character, '\0', is appended to provide an end-of-string marker for C string-handling functions.  When the first string contains an escape character, string concatenation can yield surprising results. Consider the following two declarations:  char szStr1[] = "\01" "23"; char szStr2[] = "\0123";  Although it is natural to assume that szStr1 and szStr2 contain the same values, the values they actually contain are shown in Figure 1.1.  Figure 1.1   Escapes and String Concatenation    Microsoft Specific   The maximum length of a string literal is approximately 2,048 bytes. This limit applies to strings of type char[] and wchar_t[]. If a string literal consists of parts enclosed in double quotation marks, the preprocessor concatenates the parts into a single string, and for each line concatenated, it adds an extra byte to the total number of bytes.   For example, suppose a string consists of 40 lines with 50 characters per line (2,000 characters), and one line with 7 characters, and each line is surrounded by double quotation marks. This adds up to 2,007 bytes plus one byte for the terminating null character, for a total of 2,008 bytes. On concatenation, an extra character is added to the total number of bytes for each of the first 40 lines. This makes a total of 2,048 bytes. (The extra characters are not actually written to the string.) Note, however, that if line continuations (\) are used instead of double quotation marks, the preprocessor does not add an extra character for each line.  END Microsoft Specific  Determine the size of string objects by counting the number of characters and adding 1 for the terminating '\0' or 2 for type wchar_t.  Because the double quotation mark (") encloses strings, use the escape sequence (\") to represent enclosed double quotation marks. The single quotation mark (') can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a string, you must type two backslashes (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)  To specify a string of type wide-character (wchar_t[]), precede the opening double quotation mark with the character L. For example:  wchar_t wszStr[] = L"1a1g";  All normal escape codes listed in Character Constants are valid in string constants. For example:  cout << "First line\nSecond line"; cout << "Error! Take corrective action\a";  Because the escape code terminates at the first character that is not a hexadecimal digit, specification of string constants with embedded hexadecimal escape codes can cause unexpected results. The following example is intended to create a string literal containing ASCII 5, followed by the characters five:  \x05five"  The actual result is a hexadecimal 5F, which is the ASCII code for an underscore, followed by the characters ive. The following example produces the desired results:   "\005five"     // Use octal constant. "\x05" "five"  // Use string splicing.

引用 1 楼 yuelengdihai 的回复:可以，但是达不到你想要的效果，最外面两个“之间就是你的自负串  也就是：123" "345" "567"      "8910" "dff 你想要的应该是一个二维数组 不是二维数组，对于这样的字符串的赋值方式第一次见。 char result[] ="1233455678910dff"一直以为应该这样。 今天看到一个程序用到类似这样的方法 #define VERSION "3.6.0.5" #define APPNAME "DCM"  static char app[] =APPNAME VERSION 迷惑了。。


Question: c语言读取文件，将对应属性存在结构体链表中

再供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

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

引用 3 楼 jyxuan94 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。 大大不知道我有没有理解错误，你的意思是通过代码在文本中进行修改吗?但是排序还有刷选怎么做到[/quote] 听话，先按我说的做！

引用 1 楼 zhao4zhong1 的回复:所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。 大大不知道我有没有理解错误，你的意思是通过代码在文本中进行修改吗?但是排序还有刷选怎么做到

你先实现：把数据读到结构体数组(或链表)中.


Question: C和汇编结合时，发现同一个C文件中函数无法正确访问全局变量

《程序员的自我修养——链接、装载与库》


Question: [c菜鸟求助]制作旅店信息管理系统怎样用递归创建链表然后全部储存进文件，并且以后还能读取？

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

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

是不是因为p1，p2枚释放


Question: 如何用C语言程序访问带用户名密码的共享文件夹？各位大神

直接使用API

用那些api，windows下的。能不能列出来

system("net use ...");


Question: 求助这个代码可以通过编译，但是执行的时候提示停止运行

代码段太少了看不出来


Question: 菜鸟求助一个类的作用

返回void**类型啊


Question: 3种数组赋值有什么区别呢？

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

p1和p2完全一样，是结尾有\0，是char[7]类型 p3结尾没\0，你用strlen得到的结果是不确定的，p3是char[6]类型

strlen 用于以零结尾的字符串，p3 不是以零结尾的字符串。  你违反了协议，就不要期望得到有意义的结果。

字符串会在末尾多存储一个’\0‘，用于判断字符串结束，但'\0'不属于字符串中的字符 sizeof是用来计算变量占的内存空间，strlen是用来计算字符串长度的（不计算’0‘） 至于 char p3[]={'a','b','c','d','e','f'}; strlen(p3) //该值是个不确定值，与编译器，机器字节序等有关，strlen会根据'\0'判断字符串结束，p3中没有该字符，所以会在p3所在内存区，继续往后搜寻'\0'

字符串和字符数组有区别，字符串以字符数组的形式存储，末尾自动加'\0'。p3赋值不能这样写，要显式写上末尾的0。


Question: C语言和汇编后对应不上

在DEBUG下运行程序

引用 1 楼 user-2 的回复:关闭优化试试，你要相信编译的的黑魔法优化 谢谢！ 但是，我用的codewarrior10.6 ，已经关闭了C语言和汇编的所有优化，只是因为用了BANK，所以开了默认的MMU优化没有关闭，还需要在哪里关闭优化么？

关闭优化试试，你要相信编译的的黑魔法优化


Question: 如何用c语言给定义过的结构体增加成员

引用 4 楼 u013179272 的回复:请问，如果这样 struct student{  char name[20];  int age;  char sex;  int weight;  void *attr;  };  给这个里面增加N个不确定的变量，  其他地方给这N个变量赋值，怎么处理呢？ 用版主说的方法2，void*链接过去是最好的方法。 他的方法3会产生4200警告，不是最好的方案。

引用 2 楼 jyxuan94 的回复:[quote=引用 1 楼 qq423399099 的回复:] 有几个思路，LZ可以参考下 1.添加一些多余的成员（也就是说，不管是否需要，都添加进去）  2.另外添加指针（如void *, 根据需要动态产生attr的结构）  struct student{  char name[20];  int age;  char sex;  int weight;  void *attr;  };   3.结构体变长的妙用——0个元素的数组  typedef struct st_type  {  int nCnt;  int item[];  }type_a;   这样我们就可以定义一个可变长的结构，用sizeof(type_a)得到的只有4，就是sizeof(nCnt)=sizeof(int)那个0个元素的数组没有占用空间，而后我们可以进行变长操作了。   type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));   这样我们就产生了一个长为100的type_a类型的东西用p-> item[n]就能简单地访问可变长元素，原理十分简单，分配了比sizeof(type_a)多的内存后int item[];就有了其意义了，它指向的是int nCnt;后面的内容，是没有内存需要的，而在分配时多分配的内存就可以由其来操控，是个十分好用的技巧。   注：如果可以用C++，不妨可以用多态试试    谢谢大大，有几个问题想问下，因为大多时候录入的都是字符串，而c没有string类型，多数的时候用的是二维数组，或者指针数组，那么方法2是不是改成 void *arr[100],如果是，赋值的时候是*（arr+i）的形式还是a[i]比较好 方法三是不是这样就可以了： typedef struct st_type  {  int nCnt;  char item[][100];  }type_a;  type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));  [/quote] 方法2：可以用指针数组的形式void *arr[100];   type_a a; a.arr[0] = (char *)("asdads"); cout << (char *)a.arr[0] << endl;  方法3： type_a *p = (type_a *)malloc(sizeof(type_a) +  5 * 100 * sizeof(char)); strcpy(p->item[0], "asd"); cout << p->item[0] << endl;

引用 1 楼 qq423399099 的回复:有几个思路，LZ可以参考下 1.添加一些多余的成员（也就是说，不管是否需要，都添加进去）  2.另外添加指针（如void *, 根据需要动态产生attr的结构）  struct student{  char name[20];  int age;  char sex;  int weight;  void *attr;  };   3.结构体变长的妙用——0个元素的数组  typedef struct st_type  {  int nCnt;  int item[];  }type_a;   这样我们就可以定义一个可变长的结构，用sizeof(type_a)得到的只有4，就是sizeof(nCnt)=sizeof(int)那个0个元素的数组没有占用空间，而后我们可以进行变长操作了。   type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));   这样我们就产生了一个长为100的type_a类型的东西用p-> item[n]就能简单地访问可变长元素，原理十分简单，分配了比sizeof(type_a)多的内存后int item[];就有了其意义了，它指向的是int nCnt;后面的内容，是没有内存需要的，而在分配时多分配的内存就可以由其来操控，是个十分好用的技巧。   注：如果可以用C++，不妨可以用多态试试    谢谢大大，有几个问题想问下，因为大多时候录入的都是字符串，而c没有string类型，多数的时候用的是二维数组，或者指针数组，那么方法2是不是改成 void *arr[100],如果是，赋值的时候是*（arr+i）的形式还是a[i]比较好 方法三是不是这样就可以了： typedef struct st_type  {  int nCnt;  char item[][100];  }type_a;  type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));


Question: 很简单的帮忙看看，这段代码可以计算所输入整数的阶乘吗？

仅供参考：#include<stdio.h> #define N 1000    //要计算的N long s[N]={1,1},n=N,t=2,a=1,b=0; int main()//雨中飞燕之作 {     for(;a<=*s||(++t<=n?(b=0,a=1):0);(*s==a++&&b)?(*s)++:0)         s[a]=(b+=s[a]*t)%10000,b/=10000;     for(printf("%d",s[*s]);--*s>0;) printf("%04d",s[*s]);     return 0; }

scanf("%d",n);应该改成scanf("%d",&n); 楼主还要注意，由于是用int存的，当阶乘太大的时候是会超出int范围的，计算出来的结果是不对的 int范围是- 2^31 ~ 2^31 - 1 （也就是说在12!到13!之前，超过12!就无法用int表示了，楼主可以考虑用char数组存大数）


Question: 使用vs编程中出现错误求解

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

Readscore    s大写

引用 3 楼 baidu_34326351 的回复:int Readscore(int score[]) { 	int i = -1; 	do { 		i++; 		printf("Input score:"); 		scanf_s("%d", &score[i]);  	} while (score[i] >= 0); 	return i; } 查看全部的这个函数  大小写对应

哪里错了呢！

ReadScore怎么定义的

秒沉？？！！！


Question: 注册表

会被杀毒软件过滤。

参考注册表API函数


Question: 大家帮我看看这个很简单的小程序为啥错了

谢谢这位大神!

c = a + b 应该放到printf前一名，不然a、b还未初始化


Question: 小弟新人，请问这种写法是什么意思？

谢谢哦，谢谢哦

取指定地址上的4字节整型值。 就是把一个常量数值地址强制转为成指针int32指针，再用星号取其值。


Question: 不允许强制装换到类型P

谢了！原来是编译器的问题，我重启后就可以了

引用 2 楼 Never_Setttle 的回复:那应该怎么改  ip = (P)malloc(sizeof(P));

那应该怎么改

你的P相当于是struct info*类型 而你malloc的大小是struct info类型的大小


Question: 嵌入式C语言能够使用句柄吗？

引用 11 楼 modyhank 的回复:其实不太明白结构体指针的内存是怎么分配的， 如果是分配一个内存块，那么句柄也是一个内存块，两者应该是等价的啊。  “句柄”一词容易引起歧义，很可能被认为是Windows下的HANDLE概念。（所以尽量避免不要这么写） Windows下的HANDLE表示该"句柄“对应的内存是由操作系统来维护，该内存不是你分配的，你自己也不能随便释放，需要通过系统调用（比如CloseHandle等，具体要看是什么类型的HANDLE），由系统来维护。  普通的指针指向的内存很多是由程序员自己从堆上分配的，此时程序员需要自己去释放该内存。

引用 9 楼 modyhank 的回复:其实我想问的是这这样定义的区别是什么，大家都讨论句柄去了，应该是我表达出了问题； 我的理解是： test_Obj是一个结构体数据类型，test2 是一个结构体指针， test_Handle是一个数据类型， 这样定义：test_Handle    test2   应该就是等同于这样定义 test_Obj     *test2。 ------------------------------------------------------------------------------------------------------------- 但是我第二次回复的那段代码， 类型之间的转换好绕口啊，无法理解。  你第二次回复中的代码书写本身有问题，不要纠结于垃圾代码为什么要这么书写。

typedef struct {  word A;  word B; }test_Obj; test_Obj   *test2;  //  test2 是结构体指针 typedef     test_Obj     *test_Handle; --------------------------------------------------------- 其实我想问的是这这样定义的区别是什么，大家都讨论句柄去了，应该是我表达出了问题； 我的理解是： test_Obj是一个结构体数据类型，test2 是一个结构体指针， test_Handle是一个数据类型， 这样定义：test_Handle    test2   应该就是等同于这样定义 test_Obj     *test2。 ------------------------------------------------------------------------------------------------------------- 但是我第二次回复的那段代码， 类型之间的转换好绕口啊，无法理解。

引用 6 楼 jiqiang01234 的回复:句柄其实就是用“结构体指针”实现的。所以，只要是c语言就能用 -------------------------------------------------  头像好像我的一位大学老师啊

句柄可以看成是系统底层指向某数据结构的指针数组的下标，我觉得。

句柄其实就是用“结构体指针”实现的。所以，只要是c语言就能用

句柄其实就是用“结构体指针”实现的

引用 3 楼 zhao4zhong1 的回复:啥叫“句柄”？  语法是没有问题的，编译器可以通过，没有句柄这个说法吗？ 我感觉这样写的目的可以增强可读性吧，不然形参传递的时候结构指针就可以了。  这是老外的一段代码里面看到的，大体结构是这样： test_Handle   Process (void *p,const word counts) {    test_Handle     testhandle;    test_Obj *TestObj;     testhandle = (test_Handle) p;    TestObj = (test_Obj *) testhandle ;     memset(TestObj,0,sizeof(test_Obj ));        return (testhandle);  }

句柄是操作系统内核的资源分配方式、、   实际中也是个结构体、、      这么管理没有问题

啥叫“句柄”？

没问题啊，编译器能处理指针和结构体，怎么定义都OK 类似用c写面向对象的代码也很多，但是实际上封装、继承等都不是非常好

没有这个说法吧，没见过这么定义的


Question: 这个代码是老师给的，输入正确，输出的后两位数不对

看楼上几位，学习了

检查字符串是否以\0结尾，否则输出时会一直输出到\0，而DEBUG下，栈会用0xCC进行填充，所以会输出烫字

i=atoi(strNo);  前 面加上 strNo[i] = '\0'; 不过，strNo至少要有11个元素空间

引用 1 楼 Y_noo 的回复:输出总有烫，不知问题出在哪里 编译器设成UTF_8格式

输出总有烫，不知问题出在哪里


Question: 请帮忙看下 问题在哪

els e throw "NO FOUND"<<endl;  首先 else那中间多了个空格  其次，后面的throw "NO FOUND"<<endl; 不知你要干嘛，是不是要表示cout<<"NO FOUND"<<endl;


Question: 运行时总有一个错误 'int86' : undeclared identifier

DOS下的程序

是不是少包含了什么头文件，看看int86在哪里

bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028

转到int86定义看看


Question: 请大神详细描述下dfs ，真的不是很懂，为什么这个题目里边调用dfs后vis[i]要置为0呢

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

vis的下标表示要填的数,值表示是否填了,先尝试把数字填入之后又取回.就像走迷宫,每个路口有两条路,每一条路都尝试走一遍(vis[i]置1),走到头发现不通就回来(vis[i]置0)


Question: c语言实现图片复制

不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

fp1=fopen("d:\\cs\\cs.jpg","wt++") 改成  fp1=fopen("d:\\cs\\cs.jpg","wb++") 试下。以前也遇到过类似情况，对于图片的写入好像要用二进制方式写。

我的电脑是win7 32位，难道是系统的问题吗？

代码基本没做修改  #include<stdio.h> #include<stdlib.h>  int main(){     FILE *fp;     FILE *fp1;      char str[256];     scanf("%s",str);     if((fp=fopen(str,"rb+")) == NULL)     {         printf("ERROR");         exit(1);     }      if((fp1=fopen("2.jpg","wt++")) ==NULL)     {         printf("error1");         exit(1);     }     fseek(fp,0L,SEEK_END);     long length;     long n,cpyfinish;     length = ftell(fp);     rewind(fp);      char pBuffer[1]={0}; //    unsigned char buff;   //while (!feof(fp))     while(length>0)     {         n = fread(pBuffer, 1, 1, fp);         cpyfinish =fwrite(pBuffer, 1, n, fp1);         length-=cpyfinish;     }       if(ferror(fp))         puts("读取出错");     else         puts("读取成功");      fclose(fp);     fclose(fp1);      return 0; }


Question: 菜鸟求助一个经典的动态规划题

还不给注册……

#include "stdafx.h" #include<string.h> #include<stdlib.h> void lower(char *a) { 	for (int i = 0; a[i] != '\0'; i++) { 		if (a[i] >= 'A' && a[i] <= 'Z') { 			a[i] = a[i] - 'A' + 'a'; 		} 	} } int max(int a, int b) { 	return (a > b ?  a : b); }  int main() { 	char a[100] = "aaa", b[100] = "abb"; 	int dp[100][100]; 	//scanf("%s%s", a, b); 	lower(a); 	lower(b); 	for (int i = 1; a[i - 1] != '\0'; i++)  		for (int j = 1; b[j - 1] != '\0'; j++) { 			dp[i - 1][j-1] = 0; 		}  	for (int i = 1; a[i-1] != '\0'; i++) {		 		for (int j = 1; b[j-1] != '\0'; j++) { 			if (a[i-1] == b[j-1]) { 				dp[i][j] = dp[i - 1][j-1] + 1; 			} 			else { 				dp[i][j] = max(dp[i - 1][j],dp[i][j-1]); 			} 		} 	} 	printf("%d\n", dp[strlen(a)][strlen(b)]); 	system("pause");     return 0; } 上面那个不能处理有重复字符的字符串

#include "stdafx.h" #include<string.h> #include<stdlib.h> void lower(char *a) { 	for (int i = 0; a[i] != '\0'; i++) { 		if (a[i] >= 'A' && a[i] <= 'Z') { 			a[i] = a[i] - 'A' + 'a'; 		} 	} } int max(int a, int b) { 	return (a > b ?  a : b); }  int main() { 	char a[100] = "abb", b[100] = "aca"; 	int dp[100]; 	//scanf("%s%s", a, b); 	lower(a); 	lower(b); 	dp[0] = 0; 	for (int i = 1; a[i-1] != '\0'; i++) { 		for (int j = 1; b[j-1] != '\0'; j++) { 			if (a[i-1] == b[j-1]) { 				dp[i] = max(dp[i - 1] + 1,dp[i]); 			} 			else { 				dp[i] = max(dp[i - 1],dp[i]); 			} 		} 	} 	printf("%d\n", dp[strlen(a)]); 	system("pause");     return 0; 终于能上网了

电脑上不了网，只能手机发图片了

引用 4 楼 qq_29120981 的回复:不区分大小写的话先把字符串预处理一下 这个呢  #include<stdio.h> #include<string.h> #define MAX 100  int main(void) { 	char str1[MAX]={0},str2[MAX]={0},buf[MAX]; 	int i,j,k,l,ans,len,flag=0; 	ans = 0; 	scanf("%s%s",str1,str2); 	len = strlen(str1)>strlen(str2)?strlen(str2):strlen(str1); 	for(i=1;i<=len;i++) 	{ 		for(k=0;k<len;k++) 		{ 			for(l=0;l<i&&l+i<len;) 			{ 				for(j=0;j<i;j++,l++) 					if(strlen(str1)>len&&str2[l+k]!=0) 						buf[j] = str2[l+k]; 					else if(strlen(str1)<=len&&str2[l+k]!=0) 						buf[j] = str1[l+k]; 				buf[j] = 0; 				//printf("%s\n",buf); 				if(strstr(strlen(str1)>len?str1:str2,buf)==NULL) 					break; 				if(i>ans) 				{ 				    ans = i; 				    flag = !flag; 				    break; 				} 			} 			if(flag)             {                 flag = !flag;                 break;             } 		} 	}  	printf("%d",ans); 	return 0; }

引用 3 楼 qq_29120981 的回复:仅供参考  #include<stdio.h> #include<string.h> #define MAX 100  int main(void) { 	char str1[MAX],str2[MAX],buf[MAX]; 	int i,j,k,l,ans,len; 	ans = 0; 	scanf("%s%s",str1,str2); 	len = strlen(str1)>strlen(str2)?strlen(str2):strlen(str1); 	for(i=1;i<=len;i++) 	{ 		for(k=0;k<len;k++) 		{ 			for(l=0;l<i;) 			{ 				for(j=0;j<i;j++,l++) 					if(strlen(str1)>len) 						buf[j] = str2[l+k]; 					else 						buf[j] = str1[l+k]; 				buf[j] = 0; 				//printf("%s\n",buf); 				if(strstr(strlen(str1)>len?str1:str2,buf)==NULL) 					break; 				if(i>ans)  					ans = i; 			} 		} 	} 	 	printf("%d",ans); 	return 0; } 大胸第，你这个程序跑不出结果

不区分大小写的话先把字符串预处理一下

测试用例是4个。。。。。。

大神们，这道题测试用例有3个，我就是case2不通过。这道题评论有12页，评论里提出来的用例我全通过，就是平台上的case2不通过，很苦恼


Question: 不知是关于“自增”还是printf顺序结构的问题

这是在同一条语句中，属于未定义行为，编译器可以自由实现  关于C,C++表达式求值顺序  http://bbs.csdn.net/topics/370153775

参见函数参数压栈的顺序

这种结果其实很看编译器的脸 比如第二个，我用VS2012打印出来就是2 1 总体来说有几个点： 1.printf计算顺序是从右往左的 2.我们在写代码时，应该尽量避免类似下面的无确定意义的表达式出现，因为很有可能不同的编译器，会采用不同的理解方式。


Question: linux下不用读写锁，实现读者-写者？

楼上回答的很经典

int flag=0； if（!flag） { //读取 flag=1; } if(flag) { //写 flag=0; }

引用 1 楼 yuelengdihai 的回复:信号量和互斥体 锁本质是一样的啊   有没有我要的例子，有点花，贡献个链接也行啊，我插了很久，找不到

信号量和互斥体 锁本质是一样的啊


Question: 这两个段代码的test函数差异在于是否赋值，结果差异这么大是为什么？？？

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

修改一下 test1 输出 d 的地址，你会发现，地址没有变化 this is test1,&d =00000000009ffddc,d=0,c=1 this is test1,&d =00000000009ffddc,d=1,c=2 this is test1,&d =00000000009ffddc,d=2,c=3 this is test2,a=1,b=1 this is test2,a=1,b=2 this is test2,a=1,b=3

在循环中每次调用 test1的时候 d 分配在同一个位置 第一次 d=0 是不确定的 以后 d 没被破坏的话，可以保持上次的值 但是这个显然是巧合，而不是必然的。 这跟 d没有初始化，也没赋值,d 的值不确定，没有任何冲突。。。

d应该是一个局部变量，为啥d的值会像静态变量一样保持下来？

引用 2 楼 u012405375 的回复:两函数的差异void test1()  的int d; 和void test2()int a=1;   然后得出的两个结果d=0,1,2和a=1,1,1   --------这个要怎么解释呢  引用 1 楼 user-4 的回复:static int c=1; 只是在第一次时初始化，之后并不会执行c=1操作，而是保留上一次调用后的值  哪里不懂！静态变量不会随函数结束而销毁！


Question: C语言发送http get请求源码的问题

网站不允许这样访问，加上agent试试

使用wireshark抓包，先在浏览器中打开，看抓到的包。再用你自己的程序发送，抓包看有什么不同。


Question: C语言数组问题

整形提升  有什么问题么

在C#中都TM属于越界了  有啥用， 就算编译完善  也是一大堆破问题

int 与 char字符直接有对应关系。看看ASCII码表就明白了，如‘A'字符对应的是65

另外alphabet[string[i]]++;应改为alphabet[(unsigned char)string[i]]++;

char可以被隐式转换为整型，只不过不能超过127

引用 2 楼 paschen 的回复:除非你定义string到int的隐式转换  之前看错了，你string[i]是char类型，其字符的值就是索引号

C/C++中 char字符默认可以自动转换为int类型

楼主这样写，我试了下，不能统计string字符数组中各字符的个数。我把alphabet打印出来全是0。

除非你定义string到int的隐式转换

把char这个字符转换成int，实际上市int作为下表。


Question: 给定x值，求多项式P(x)的值

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

引用 1 楼 yuelengdihai 的回复:Polylist PolyCreate() 这个函数写错 了 1,scanf("%d,%d",&c,&e) 下面那句要去掉 2，aa=Ploycreate();函数明写错了／／与上面不一直 3，struct Polylist *aa;这句改为struct Polynode *aa;

Polylist PolyCreate() 这个函数写错 了


Question: 求大神指教，输入命令行参数的问题

引用 6 楼 zhao4zhong1 的回复:现在的码农竟然99%都不会在cmd窗口中输入cd命令设置当前目录为程序所在目录，输入程序名运行程序了！ 谢啦，已经会了。我现在连一个码农都算不上

引用 5 楼 vanchristin 的回复:main.exe就是你编译生成的可执行文件啊，不一定是main，但是肯定会有一个exe 首先用cd命令切换到exe在的文件夹，然后输入main.exe count one 谢谢，早就已经会了。还有我直接用的文件名，没有.exe，就直接运行了

还有我是在windows系统下用的C-FREE

引用 1 楼 qq_29120981 的回复:输入cd /d 你程序的路径(比如main.exe在E盘main文件夹下就输入 cd /d e:\main) 然后输入main count one(count one 就是传进去的参数)  main.exe是什么？我文件夹里找了一下找不到。不会是运行的主程序吧。我是在windows系统下用的C-FREE.

main.exe是什么？我文件夹里找了一下找不到。不会是运行的主程序吧。


Question: 哪位大神帮我瞅瞅哪里错了，编译通过可就是结果错误.

还有建议楼主写代码的时候，对于代码做一定的注释，这样不仅自己看着更为直观，也方便别人看你代码时，对于你所写代码的理解

对于结果出错的问题，首先建议LZ先进行单步调试，看看问题出现在什么地方，是哪里和预期的结构是不一样的

读数据的流程都不对，读取的数据不对，算法估计也不对，凭直觉，算法应该用广搜


Question: c语言中将有符号short值赋给无符号int，出现一些难以理解的结果，请指点

懂了，谢谢各位。感觉编译器对这种赋值的处理不太合理，扩展位按照右值的符号类型，而不是按照左边变量的符号类型，这样用来传递signed char的值时会出错。printf函数打印的时候又涉及了实际参数向形式参数赋值，所以才会出现问题

b本身是一个正数，%d会导致把b强制转成负数即-32767后打印输出，这个很基础的东东，要用%u。

下面来分析下： short类型占两个字节，而unsigned int占4个字节，把short型数据赋值给int或者unsigned int型数据时，如果short型数据是负的，则扩展的比特位全是1,；如果short型数据是正的，则扩展的比特位全是0. -32767的补码（计算机中都是按补码存的这个楼主应该知道吧）是1000 0000 0000 0001 但在计算机中存储的形式却是0000 0001 1000 0000（因为我们的电脑一般都是小端模式，即低位字节低地址） 将该值赋给unsignd int时，起初的unsigned int存储的二进制为0000 0000 0000 0000 0000 0000 0000 0000 （打印语句1） 变成了0000 0001 1000 0000 1111 1111 1111 1111（因为short是负值，所以用1扩展） （打印语句2） 无符号数和有符号数 在存储上并没有区别 在使用的时候 如果符号不匹配 C会做自动转换 你要用%u输出才能得到正确的值FFFF8001（十进制就是4294934529）（打印语句3） 注：我这里用union能清晰的看到int在内存中的存储

跟输出函数关系不大，我关心的是变量b内存中实际的01代码，比如讲char变量赋值给int，关心的是char变量的ASCII码是否正确储存在int变量中

printf输出无符号整数的格式符是 %u 有符号的才用 %d

我觉得可能是你在输出时使用%d的原因

事实上，我在用C++用cout<<b<<endl; 来输出时，是没问题的

这个问题可能在下面的场合会出现，比如要将一个char类型的变量赋值给一个无符号整型数，如果char的值大于等于128，并且假设char变量为signed类型，则会出现错误，并且这种bug挺隐蔽的

引用 16 楼 sdghchj 的回复:[quote=引用 14 楼 yolzin 的回复:] [quote=引用 13 楼 sdghchj 的回复:] [quote=引用 10 楼 yolzin 的回复:] unsigned short a = -32767； printf("%d",a);   //输出结果为32769 printf("%u",a);    //输出结果为32769 所以问题的关键不在于%d和%u，而在于短字节数向长字节数赋值时的扩展位 我该怎么说你好，人家用的是unsiged int 去格式化成字符串，你拿个unsighed short直接格式化能说明啥问题？[/quote] 没看懂你的意思，不过这个问题我已经搞懂了，举这个例子是为了说明问题，谢谢[/quote] unsigned short a = -32767；实际上a就是32769，用%d或者%u去格式化时，都是先将其转成4字节整数，而不论是有符号还是无符号的4字节，最高位都是0，值是32769，还在65535范围内，远小于2的31次方。楼主是short a = -32767;  unsigned int b = a;此时两字符有符号先转成4字节有符号，最高位符号1不变，再转成无符号，其数值范围已经超过2的31次方了，所以用%d和%u正负是不一样的。[/quote] 我觉得printf("%d")的形式参数为signed int，printf（“%u“）的形式参数为unsigned int，拿unsigned int b作为实际参数时存在一个复制操作，unsigned int b的最高位为1，因此再给有符号int和无符号int赋值后对最高位的定义不同所以输出的结果不一样

引用 14 楼 yolzin 的回复:[quote=引用 13 楼 sdghchj 的回复:] [quote=引用 10 楼 yolzin 的回复:] unsigned short a = -32767； printf("%d",a);   //输出结果为32769 printf("%u",a);    //输出结果为32769 所以问题的关键不在于%d和%u，而在于短字节数向长字节数赋值时的扩展位 我该怎么说你好，人家用的是unsiged int 去格式化成字符串，你拿个unsighed short直接格式化能说明啥问题？[/quote] 没看懂你的意思，不过这个问题我已经搞懂了，举这个例子是为了说明问题，谢谢[/quote] unsigned short a = -32767；实际上a就是32769，用%d或者%u去格式化时，都是先将其转成4字节整数，而不论是有符号还是无符号的4字节，最高位都是0，值是32769，还在65535范围内，远小于2的31次方。楼主是short a = -32767;  unsigned int b = a;此时两字符有符号先转成4字节有符号，最高位符号1不变，再转成无符号，其数值范围已经超过2的31次方了，所以用%d和%u正负是不一样的。

引用 11 楼 user-7 的回复:以下假设 sizeof(short) == 2 , sizeof(int) == 4 。（在不同的配置下，可能有不同的结论） #include <stdio.h> int main() {     short a = -32767; 1) -32767 是 int 2) -32767 将通过类型转换转换为 short     根据类型转换的规则，由于 short 可以表示 -32767，转换结果为 -32767 (short 类型)   unsigned int b = a; 3) 这里也有一个类型转换。     由于 unsigned int 无法表示 -32767 ，根据无符号整数的类型转换规则，结果 b 的值为 UINT_MAX + 1 - 32767   int c;   //printf("%d",c = (b<=0));   4) b <= 0;     b 为 unsigned int ， 0 为 int 。     经过整型提升，两侧类型不变。结果两侧类型不同。    根据Usual arithmetic conversions 规则，两侧都被转化为 unsigned int 。    经过类型转化后，两侧值不变，b <= 0 结果为真，结果为 1 ，类型为 int 。（C 语言关系运算符结果为 int ） 5) c = (b<=0)     赋值号两侧均为 int ，无需类型转换，结果为1 6) c = (b<=0) 位于 printf 的 ... 参数的位置，需要进行整型提升。提升结果类型与值均不变   printf("%d",b); 7) b 为 unsigned int ，位于 printf  ... 参数的位置，需要进行整型提升。提升结果，类型与值均不变。 8) "%d" 用于输出 int ，而参数类型（经提升后）为 unsigned int 。根据 printf 的协议，两者不一致是为“未定义行为”     “未定义行为”意味着可能出现任何结果：包括但不限于：产生期望的结果，产生未期望的结果，产生随机结果，产生无法解释的结果，运行时错误，编译错误，等等 ... (在 gcc 的某些版本的特定编译选项组合下，这里确实会是一个 warning 或 error） 9) printf 不会根据类型标识符对参数进行类型转换。 10) 输出无符号整型，需要使用 %u 。   return 0; }  感觉有些地方有错误

引用 13 楼 sdghchj 的回复:[quote=引用 10 楼 yolzin 的回复:] unsigned short a = -32767； printf("%d",a);   //输出结果为32769 printf("%u",a);    //输出结果为32769 所以问题的关键不在于%d和%u，而在于短字节数向长字节数赋值时的扩展位 我该怎么说你好，人家用的是unsiged int 去格式化成字符串，你拿个unsighed short直接格式化能说明啥问题？[/quote] 没看懂你的意思，不过这个问题我已经搞懂了，举这个例子是为了说明问题，谢谢

引用 10 楼 yolzin 的回复:unsigned short a = -32767； printf("%d",a);   //输出结果为32769 printf("%u",a);    //输出结果为32769 所以问题的关键不在于%d和%u，而在于短字节数向长字节数赋值时的扩展位 我该怎么说你好，人家用的是unsiged int 去格式化成字符串，你拿个unsighed short直接格式化能说明啥问题？

引用 3 楼 wang0635 的回复:printf输出无符号整数的格式符是 %u 有符号的才用 %d+1


Question: strcspn的用法？

原型：size_t strcspn(const char *s, const char * reject); strcspn()从参数s 字符串的开头计算连续的字符, 而这些字符都完全不在参数reject 所指的字符串中. 简单地说, 若strcspn()返回的数值为n, 则代表字符串s 开头连续有n 个字符都不含字符串reject 内的字符. 楼主给的keys[] = "1234567890";   从起始位置开始一个计数，只要字符串中出现1,2,3,4,5,6,7,8,9,0中的任何一个数字，函数就返回了，返回值是该位置之前字符串的长度（并不是要完全匹配上key才行，只要匹配到key中的任何一个字符就行） 所以返回了4,，打印值是5


Question: 谁能讲讲C语言中的命令行参数？

项目、属性、配置属性、调试、命令参数：填写命令行参数。

我包含了啊，而且没用命令行参数前，程序还能运行，不知怎么回事？求高手搭救，谢谢

引用了头文件，没有给出对应的库文件，或者源代码 因此，找不到函数定义

引用 7 楼 u014579402 的回复:_tprintf( TEXT("\r\n使用方法:\r\n") );这里TEXT是什么这是个宏 #if defined(UNICODE)||defined(_UNICODE) #define TEXT(x)  L##x #else #define TEXT(x) x #endif  _T ,TEXT 的定义都是一样的， 如果在 UNICODE 环境中，就是 UNICODE字符串，否则是 ASCII 或者 MBCS字符串 这是VC常用的宏

错误	9	error LNK2019: 无法解析的外部符号 "double __cdecl GetAngle(double)" (?GetAngle@@YANN@Z)，该符号在函数 "bool __cdecl GeodesyBackward(double,double,double,double,double &,double &)" (?GeodesyBackward@@YA_NNNNNAAN0@Z) 中被引用	D:\Geodesy\Src\Geodesy\Geodesy.obj	Geodesy 错误	10	error LNK2019: 无法解析的外部符号 "double __cdecl GetRadian(double)" (?GetRadian@@YANN@Z)，该符号在函数 "bool __cdecl GeodesyBackward(double,double,double,double,double &,double &)" (?GeodesyBackward@@YA_NNNNNAAN0@Z) 中被引用	D:\Geodesy\Src\Geodesy\Geodesy.obj	Geodesy 为什么我用了命令行参数后会出现这些错误？谢谢大家

DOS年代运行程序都是输入命令行的，由常驻内存的command.com这个DOS下命令解释器（类似Linux下的sh、bash）解释执行 比如： edit  a1.txt dir  /a  /w edit.exe是外部命令，就是一个具体的程序名字，由command.com调用执行 dir是command.com的内部命令，直接执行它自身的部分代码 命令后面的就是命令的参数 如edit  a1.txt，argc==2, argv[0]=="edit", argv[1]=="a1.txt" 你也可以在命令行cmd（Win-R组合键，输入cmd运行）下运行你的程序，后面输入参数。  在Win7下假如你用VC，假如你的程序目录在D:\C\151023_t2，可执行文件在D:\C\151023_t2\Debug，你在资源管理器窗口里打开D:\C\151023_t2文件夹，按住Shift键然后右键点击Debug文件夹，出现右键菜单，选择【在此处打开命令窗口】，就出现一个黑色的命令行窗口，输入：dir【回车】可以看到 151023_t2.exe ，输入：151023_t2【回车】可以运行这个程序，输入：151023_t2  aa  bbb【回车】可以带参数运行这个程序，aa和bbb就是两个参数。

Windows　下　还可以通过设置快捷方式　的某些参数。 执行　带命令行参数的　可执行文件

命令行参数，可以在控制台　用命令方式　输入 一个可执行文件，对于操作系统来说，就是一个外部命令 也可以，通过　exec 系列函数调用在别的程序控制下　执行可执行文件 命令行参数　在exec 系列函数　的参数里传入 也可以用　于　shell 文件　作为其中的一个命令　执行 命令行参数就是　shell 文件 的一个语句的某一部分。 Ｄｏｓ, 下　批处理文件　.bat　 Windows　下　.bat,.cmd,.vbs,.js  unix，linux 下　sh命令文件　.sh 等等，都属于　这种　shell  脚本文件

引用 3 楼 u014579402 的回复:编译好的程序叫test，又给他传了两个参数，分别是hello和world？这些是要自己写进去的吗？test在哪里写 test是生成的可执行程序

getopt

main函数传递两个参数，argc和argv。argc是int类型的，它表示的是命令行参数的个数。不许要用户传递，它会根据用户从命令行输入的参数个数，自动确定。argv是char**类型的，它的作用是存储用户从命令行传递进来的参数。它的第一个成员是用户运行的程序名字。  #include <stdio.h>   void main(int argc,char** argv)   {           printf("%d\n",argc);           printf("%s\n",argv[0]);           printf("%s\n",argv[1]);           printf("%s\n",argv[2]);   }    下面来看个程序：编译好的程序叫test，又给他传了两个参数，分别是hello和world


Question: C语言 递归算法求思路

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

#include "stdafx.h" #include<stdlib.h> char b[27] = "abcdefghigklmnopqrstuvwxyz"; void p(char *a, int n,int index,int c) { 	if (n == index) { 		printf("("); 		for (int i = 0; i < n; i++) { 			if (i != 0) { 				printf(",%c", a[i]); 			} 			else { 				printf("%c", a[i]); 			} 		} 		printf(")"); 		return; 	} 	for (int i = c; i < 26 && n-index<=26-i; i++) {  		a[index] = b[i]; 		p(a, n,index+1,i+1); 	} }  int main() { 	char a[27]; 	for (int i = 1; i <= 26; i++) { 		p(a, i, 0, 0); 		printf("\n"); 	}  	 	system("pause");     return 0; }

用可变数组，比较字符大小。问一句，用什么语言编程？

必须按这样的顺序吗？还是列出所有子集就行？

递归轮次为检查后续一个char的依据


Question: FILE* 怎么能够与内存中的数组关联上

把你的数组写到一个临时文件中，再将这个临时文件的文件名传给库。

这个库有源码就能，没有源码不行

引用 3 楼 wozhaolala 的回复:引用 2 楼 wozhaolala 的回复:引用 1 楼 user-2 的回复:fread()，把文件内容读到内存不是得，已经把文件读到内存了，现在为了使用库里的函数解析内存中的文件库里的函数是基于FILE*解析文件内容的，先在我要传入已经读到内存的文件，让该函数解析文件在char类型数组里，其实也能不算文件，只是符合文件格式的一段内存数据而已

fread()，把文件内容读到内存


Question: 关于calloc的内存分配问题

应该是系统分配内存时，刚好将两个字符串地址分配的较近。  [root@localhost fu]# ./calloc  0xc77010 0xc77030  而strcpy的原理是“C语言标准库函数strcpy，把从src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间。”这样就导致了内存被覆盖，b也就打印出了某个地址的字符串了。

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

未定义异常，不是我们应该关注的事

你应该就是单步调试，直至出现按下任意键继续的情况，这样你就知道为什么了，注意查看b中的内容

strcpy(a, "Graduate School of Information Science and Technology");  这行中，你只给 a 分配了20个字节的空间，strcpy(a,b)，是将b中的内容复制到a中，并且要求b的空间要小于a的存储空间，即如果a有50个字节空间，因此b的内容占得空间要小于50个字节，假设b的内容占用100个字节空间，使用strcpy(a,b) 的话，b中只有50个字节的内容会拷贝到a中，剩下的50个字节将被丢弃。这种情况下，会报内存异常 Abnormal memory 的错误。

但是我的问题就是为何调试出来的b是“ology”，而打印在控制台的却是"cience and Technolog"。就是 为什么前边多了cience and Techn，而后边少了y。 。。。我是这个意思~一直搞不明白。

strcpy内存本来越界了啊，不要做这种后果不可预计的事。 a和b申请的内存块比较邻近而已，中间还有几个字节被其它占用了吧，明显少了“nformation ”


Question: crc校验的对象包括crc那个字段不？

建议先学会使用抓包软件比如wireshark

对第一个问题：刚百度了下CRC校验，我认为是不包括。 第二个不知道。


Question: 为什么if (i != 0 && j != 0){}和if(i==0&&j==0)continue;结果不一样

楼上正解。。

同时为0的反 和    同时不会0 ，不是一样的

基础布尔代数的运算:NOT(a AND b)等于(NOT a) OR (NOT b)

i != 0 && j != 0要i,j同时都不等于0 i==0&&j==0是要i,j同时都等于0才continue 如果i,j中有一个等于0，第一种情况是不会进{,,,,,},而第二种情况却是会执行一些代码的，不会被continue掉


Question: 求助HDOJ 1002为什么总是WA

仅供参考：#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110


Question: read读入数组后，怎样strstr一行一行的查找

谢谢大家的帮忙，问题解决了！ 原因：返回结果中，有1个字符串中包含2个结果，用了if(strstr(x,x))... else if(strstr(x,x))...导致的，改为if(strstr(x,x))...if(strstr(x,x))...后正常了。

引用 9 楼 zhao4zhong1 的回复:略改：#include <stdio.h> #include <string.h> #include <stdlib.h> const char * lpszBt = "<beatheart><probe_type>1</probe_type><probe_id>0800276D3191</probe_id><probe_ip>192.168.16.240</probe_ip><cpu>2</cpu><mem>81</mem><hd>32</hd><netcard><device>eth0</device><status>0</status><usage>0</usage><drop>0</drop></netcard><time>2013-4-23 16:21:23</time></beatheart>"; char tszBuffer[1024]; char tszMatch[128]; int getmark(char *src,char *mark) {     char *p,*q;     int L;     char mk1[83],mk2[84];      sprintf(mk1,"<%.80s>",mark);     sprintf(mk2,"</%.80s>",mark);     p=strstr(src,mk1);     if (!p) return 1;     q=strstr(p,mk2);     if (!q) return 2;     L=strlen(mk1);     strncpy(tszMatch,p+L,__min(q-p-L,127));tszMatch[__min(q-p-L,127)]=0;     return 0; } int main() {     strncpy(tszBuffer,lpszBt,1023);tszBuffer[1023]=0;     if (getmark(tszBuffer,"netcard")) return 1;     printf("%s\nnetcard=%s\n",tszBuffer,tszMatch);     strncpy(tszBuffer,tszMatch,1023);tszBuffer[1023]=0;     if (getmark(tszBuffer,"device")) return 1;     printf("%s\ndevice=%s\n",tszBuffer,tszMatch);     if (getmark(tszBuffer,"status")) return 1;     printf("%s\nstatus=%s\n",tszBuffer,tszMatch);     if (getmark(tszBuffer,"usage")) return 1;     printf("%s\nusage=%s\n",tszBuffer,tszMatch);     if (getmark(tszBuffer,"drop")) return 1;     printf("%s\ndrop=%s\n",tszBuffer,tszMatch);     return 0; } //<beatheart><probe_type>1</probe_type><probe_id>0800276D3191</probe_id><probe_ip>192.168.16.240</probe_ip><cpu>2</cpu><me //m>81</mem><hd>32</hd><netcard><device>eth0</device><status>0</status><usage>0</usage><drop>0</drop></netcard><time>2013- //4-23 16:21:23</time></beatheart> //netcard=<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //device=eth0 //<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //status=0 //<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //usage=0 //<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //drop=0   多谢了！

引用 8 楼 zhao4zhong1 的回复:楼主换个跑马头像吧，看着眼晕

read读入的数据包括空格、tab、回车等，有什麽办法过滤除想要的行？

楼主换个跑马头像吧，看着眼晕

谢谢大家帮忙，问题解决了。 使用strstr返回的地址再过滤就行了，开始用整个readbuf内容来过滤了导致的。

引用 4 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <string.h> #include <stdlib.h> const char * lpszBt = "<beatheart><probe_type>1</probe_type><probe_id>0800276D3191</probe_id><probe_ip>192.168.16.240</probe_ip><cpu>2</cpu><mem>81</mem><hd>32</hd><netcard><device>eth0</device><status>0</status><usage>0</usage><drop>0</drop></netcard><time>2013-4-23 16:21:23</time></beatheart>"; char tszBuffer[1024]; char tszMatch[128]; char mk1[83],mk2[84]; int getmark(char *src,char *mark) {     char *p,*q;     int L;      sprintf(mk1,"<%.80s>",mark);     sprintf(mk2,"</%.80s>",mark);     p=strstr(tszBuffer,mk1);     if (!p) return 1;     q=strstr(p,mk2);     if (!q) return 2;     L=strlen(mk1);     strncpy(tszMatch,p+L,__min(q-p-L,127));tszMatch[__min(q-p-L,127)]=0;     return 0; } int main() {     strncpy(tszBuffer,lpszBt,1023);tszBuffer[1023]=0;     if (getmark(tszBuffer,"netcard")) return 1;     printf("%s\nnetcard=%s\n",tszBuffer,tszMatch);     strncpy(tszBuffer,tszMatch,1023);tszBuffer[1023]=0;     if (getmark(tszBuffer,"device")) return 1;     printf("%s\ndevice=%s\n",tszBuffer,tszMatch);     if (getmark(tszBuffer,"status")) return 1;     printf("%s\nstatus=%s\n",tszBuffer,tszMatch);     if (getmark(tszBuffer,"usage")) return 1;     printf("%s\nusage=%s\n",tszBuffer,tszMatch);     if (getmark(tszBuffer,"drop")) return 1;     printf("%s\ndrop=%s\n",tszBuffer,tszMatch);     return 0; } //<beatheart><probe_type>1</probe_type><probe_id>0800276D3191</probe_id><probe_ip>192.168.16.240</probe_ip><cpu>2</cpu><me //m>81</mem><hd>32</hd><netcard><device>eth0</device><status>0</status><usage>0</usage><drop>0</drop></netcard><time>2013- //4-23 16:21:23</time></beatheart> //netcard=<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //device=eth0 //<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //status=0 //<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //usage=0 //<device>eth0</device><status>0</status><usage>0</usage><drop>0</drop> //drop=0    谢谢！谢谢！

引用 2 楼 ipqtjmqj 的回复:1.遍历readbuf,统计换行符有几个,从而知道有多少行. 2.假设第1步统计出有N行, 则 int **arrLine = (int **)malloc(N * sizeof(int *));用于存放每行字符串的首地址 3.重新遍历readbuf,将每行字符串的首地址保存到arrLine, 同时将换行符改成字符串结束标记'\0' 4.使用arrLine遍历每一行, 调用strstr若查到关键字则返回. 若该关键字不止出现在一行,则事先malloc N个bool,遍历时将其设为true或false. 若不支持bool,可改用int,0表示假,1表示真. 引用 2 楼 ipqtjmqj 的回复:1.遍历readbuf,统计换行符有几个,从而知道有多少行. 2.假设第1步统计出有N行, 则 int **arrLine = (int **)malloc(N * sizeof(int *));用于存放每行字符串的首地址 3.重新遍历readbuf,将每行字符串的首地址保存到arrLine, 同时将换行符改成字符串结束标记'\0' 4.使用arrLine遍历每一行, 调用strstr若查到关键字则返回. 若该关键字不止出现在一行,则事先malloc N个bool,遍历时将其设为true或false. 若不支持bool,可改用int,0表示假,1表示真.  非常感谢！每一步都给出来了。

字符串匹配  。


Question: C语言三维数组赋值问题

int main(int argc, char *argv[]) { 	int i, j, k; 	int a[20][20][20]; 	for (i = 0; i < 20;i ++) 	for (j = 0; j < 20; j ++) 	for (k = 0; k < 20; k++) 		a[i][j][k] = -1; 	for (i = 0; i < 20; i++){ 		for (j = 0; j < 20; j++){ 			for (k = 0; k < 20; k++){ 				printf("%d ", a[i][j][k]); 			} 			printf("\n"); 		} 		printf("\n\n"); 	} return 0; } 不知道楼主程序时什么样，我这边是正常值，估计楼主的n赋值不正确吧。可以打印一下输入之后n的结果。

仅供参考：//在堆中开辟一个3×4×5的3维int数组 #include <stdio.h> #include <malloc.h> int ***p; int i,j,k; void main() {     p=(int ***)malloc(3*sizeof(int **));     if (NULL==p) return;     for (i=0;i<3;i++) {         p[i]=(int **)malloc(4*sizeof(int *));         if (NULL==p[i]) return;         for (j=0;j<4;j++) {             p[i][j]=(int *)malloc(5*sizeof(int));             if (NULL==p[i][j]) return;         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 p[i][j][k]=i*20+j*5+k;             }         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 printf(" %2d",p[i][j][k]);             }             printf("\n");         }         printf("---------------\n");     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             free(p[i][j]);         }         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //--------------- // 20 21 22 23 24 // 25 26 27 28 29 // 30 31 32 33 34 // 35 36 37 38 39 //--------------- // 40 41 42 43 44 // 45 46 47 48 49 // 50 51 52 53 54 // 55 56 57 58 59 //---------------

你肯定没有执行到初始化那句，自己单步调试进行检查

可以把完整代码贴出来吗？


Question: 检验校验和程序

谢谢大神指导

C语言类型转换不能这样写，那句改成：checksum=~((long)(sum>>16)+(long)(sum&0x0000ffff)); 就可以了 如果是C++，就可以像你的那种写法


Question: 跪求解释

结果如下：  楼主是想知道为什么会得到这样的结果？（我这里以输入5为例） 第一个for循环，共循环5次，相当于5的5次方得到3125  for(i=1;i<=5;i++) 		d=d*n;  第二个for循环，循环3次 第一次，s=0+3125%10(s被赋值成5),d=3125/10(d被赋值成312) 第一次，s=5+312%10(s被赋值成7),d=312/10(d被赋值成31) 第一次，s=7+31%10(s被赋值成8),d=31/10(d被赋值成3) 所以return了8  for(i=1;i<=3;i++) {     s=s+d%10;     d=d/10; }

解释什么？ 传值与传址 局部变量与全局变量 static 先搞清楚内存分配


Question: 请大神帮我看一下这个C哪里错了

少了大括号。

如果if或者else if后的语句有多句，那么需要打上大括号：   #include <stdio.h> #include <math.h> int main() { 	int a,b,c,d,del,q; 	scanf("%d%d%d",&a,&b,&c); 	d=b*b; 	del=d-4*a*c; 	q=2*a; 	float m; 	float n; 	if(a=0,b=0) 		printf("Input error!\n"); 	else if (a=0,b!=0) 		printf("x=%f",-c/b); 	else if (a!=0,del=0) 		printf("x1=x2=%f",-b/q); 	else if (a!=0,del>0) 	{ 		m=(-b+sqrt(del)/q); 		n=(-b-sqrt(del)/q); 		printf("x1=%f,x2=%f",m,n); 	} 	else  		m=(-b+sqrt(-del)/q); 	n=(-b-sqrt(-del)/q); 	printf("x1=%f,x2=%f",m,n); 	return 0; }


Question: 水仙花数 怎么我写的运行不出来

sum要清零，不然还是上一个数的结果   int main() { 	int a, c, d, x, i, sum=0;  	for (i=100; i<=999; i++) 	{ 		x = i;  		for (a=1; i/a!=0; a*=10)             //12行 		{ 			c = i / a; 			d = c % 10; //15行  12--15行为把一个三位数分为个位 十位 百位 并 			sum = sum + (int)pow(d, 3); 		} //17行     		if (sum == x) 			printf("%d\n", x);  		sum = 0;  //清零，不然还是上一个数的结果 	}  	return 0; }

# include "stdio.h" # include "math.h"  int main (){ 	int i,j,k,n; 	for ( i=100;i<999;i++ ) { 		j = (int)i/100; 		k = (int)(i%100)/10; 		n = i%10; 		 		if ( pow(j,3)+pow(k,3)+pow(n,3) == i) 		printf ("%d是水仙花数！\n",i); 	} }   初学者编写，请参考

sum=0要写到外层循环里吧


Question: 一个好奇怪好奇怪的问题？看我代码，求解！！！

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

引用 3 楼 paschen 的回复:上面加上getchar()   getchar(); scanf("%c %d", &ch, &x);   不然你ch接收到的是上一次输入后的换行符 \n 我明白了

最好的办法是加空格 scanf(" %c %d", &ch, &x);

没啥问题啊，除非你输入Q 1之后没打回车

引用 1 楼 paschen的回复:还要等接收到一个值给x，scanf("%c %d", &ch, &x);这句才算执行完 我输入Q.  1,1不是已经赋值给了x吗？


Question: c++怎么设计按指定跳出返回到指定函数和怎么按任意键跳出返回到指定函数不用go

引用 4 楼 tkin2 的回复:很感谢你的解答，大概知道你的意思，但不是我想要的那种，水平有限，没全看懂，换过一种方式问吧，跳出while和for循环经典的方式，或者你自己常用的方式有哪几种吗。可否贴出来看看。 break,return,goto,longjmp,throw

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

一般小程序我都是嵌套一个循环的，打个比方： for (string st = "in"; st != "out";) 	{ 		/* -------*******------ */ 		getline(cin, st); 	} 但是感觉代码多了，这样做会比较复杂。

先按任意键理解。现在最想知道是，怎么按自己输入的字母跳出；初学，表达不全见谅；上一级比如说，main()函数，从这一级回到mian()函数；

一下子任意键一下子指定键，到底是任意还是指定？是我语文没学好还是你语文没学好？按任意键都返回了那你还输入处理什么东东？你所谓的上一级下一级又是什么？把下一级封装成一个函数不就得了么


Question: 对双向链表的操作

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

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  不要依赖调试器输出复杂数据结构！而要将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施”： //不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //


Question: 请问这个怎么用的？怎么会错误语法？

引用 7 楼 qq_34325718 的回复:[quote=引用 5 楼 yuelengdihai 的回复:] 楼上说的正确，name已经是地址了 好的谢谢，如何用microsoft Visual 2015C++如何将编码转化为EXE格式？[/quote]  点上面那个调试按钮，或者按F5

引用 5 楼 yuelengdihai 的回复:楼上说的正确，name已经是地址了 好的谢谢，如何用microsoft Visual 2015C++如何将编码转化为EXE格式？

scanf("%s",name);   不要把name放在字符串里面

楼上说的正确，name已经是地址了

scanf("%s",name);

引用 1 楼 yuelengdihai 的回复:scanf("%s",&name); 还是错误的？ 0.0

引用 楼主 qq_34325718 的回复:都是按照书上打的  为什么会错误？

scanf("%s",&name);


Question: 已知，一个int A, int B, int C三个变量，在不引入第四个变量的情况下，将B赋给A，将C赋给B，将A赋给C，怎样破？

仅供参考：#include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2

加减法可能溢出，溢出时结果不确定，所以不建议使用

讲道理，给个不引入第四个变量的理由？

先说两个变量不引入第三个变量怎么交换，3个之间交换可参照：  方法一：     a=a+b;     b=a-b;     a=a-b;  方法二： 	a=a^b;  	b=a^b;  	a=a^b;

AB互换，然后BC互换。互换两个整形变量有个全靠 ^ 的装逼方法 x^=y;y^=x;x^=y; 用这个就可以不用引入其他变量了。

既然两个能换，三个也是同样，n个也是。。。

引用 1 楼 wang0635 的回复:#include <stdio.h> int main() { 	int		a, b, c;  	scanf("%d%d%d", &a, &b, &c); 	printf("a = %d, b = %d, c = %d.\n", a, b, c);  	a ^= b, b ^= a, a ^= b;		//a <-> b 	b ^= c, c ^= b, b ^= c;		//b <-> c  	printf("a = %d, b = %d, c = %d.\n", a, b, c);      return 0; } 好吧，我服了，为什么你会想到这样


Question: 新手请教一个练习题目！

恩，看明白了，非常感谢你们！

11可以通过转换为整型，或者使用floor函数得到，68可以通过原数减去上一步得到的结果之后再乘100得到（乘100是单位换算成分）

#include <stdio.h> int main() {     double    a = 0;   //一个星期的薪水     double    b = 0;   //每天工作时间     double    c = 0;   //计算出来的平均小时工资率     printf("请输入一个星期的薪水和每天工作时间：");     scanf("%lf%lf", &a, &b);     c = a / 7 / b;     printf("your average hourly pay rate is %d dollars and %d cents.\n", (int)c, (int)((c - (int)c) * 100));     return 0; }


Question: 一个关于转义字符的疑问。。

引用 2 楼 qq_29120981 的回复:第一个，三位八进制足以表示所有ASCII码 第二个，不是 第三个，语法上没有错误，'\0014'前三个数字和\构成转义字符，后一个4单独，这和'ab'类似，标准没有规定它的值到底是'a'呢还是'b'呢，全依赖编译器实现。  谢谢回答，经过strlen()实测，为什么‘\0014’就可以解析为两个字符(\001和4)，而‘\x111’就会提示溢出，结果仍是长度为1？

引用 1 楼 wang0635 的回复:标准中说： 6.4.4.4 Character constants Syntax octal-escape-sequence:     \ octal-digit     \ octal-digit octal-digit     \ octal-digit octal-digit octal-digit hexadecimal-escape-sequence:     \x hexadecimal-digit     hexadecimal-escape-sequence hexadecimal-digit 看来，八进制的最多3位，十六进制可以有多位  第二个问题，负数如果是用补码，编程无符号数解释时，上面给出的结果就是对的  用strlen("\0014")得到2，用strlen("\x111")编译器却提示溢出，结果仍为1，而这是为什么？

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

溢出处理是由实现定义的，不同的编译器自己决定

引用 4 楼 yq_forever 的回复:[quote=引用 1 楼 wang0635 的回复:] 标准中说： 6.4.4.4 Character constants Syntax octal-escape-sequence:     \ octal-digit     \ octal-digit octal-digit     \ octal-digit octal-digit octal-digit hexadecimal-escape-sequence:     \x hexadecimal-digit     hexadecimal-escape-sequence hexadecimal-digit 看来，八进制的最多3位，十六进制可以有多位  第二个问题，负数如果是用补码，编程无符号数解释时，上面给出的结果就是对的  用strlen("\0014")得到2，用strlen("\x111")编译器却提示溢出，结果仍为1，而这是为什么？[/quote] C++03中，8进制转义字符可由1~3个数字组成，都是合法的；16进制转义字符的数字不限个数（>=1），并不是1~2位。 大部分编译器char都是八位，x111超过了上限，编译器会报错，可以用宽字符类型代替，改成这样：  (L"\x111")

引用 5 楼 小灸舞的回复:[quote=引用 4 楼 yq_forever 的回复:] [quote=引用 1 楼 wang0635 的回复:] 标准中说： 6.4.4.4 Character constants Syntax octal-escape-sequence:     \ octal-digit     \ octal-digit octal-digit     \ octal-digit octal-digit octal-digit hexadecimal-escape-sequence:     \x hexadecimal-digit     hexadecimal-escape-sequence hexadecimal-digit 看来，八进制的最多3位，十六进制可以有多位  第二个问题，负数如果是用补码，编程无符号数解释时，上面给出的结果就是对的  用strlen("\0014")得到2，用strlen("\x111")编译器却提示溢出，结果仍为1，而这是为什么？[/quote] C++03中，8进制转义字符可由1~3个数字组成，都是合法的；16进制转义字符的数字不限个数（>=1），并不是1~2位。 大部分编译器char都是八位，x111超过了上限，编译器会报错，可以用宽字符类型代替，改成这样：  (L"\x111") [/quote] 谢谢～