Question: 用c语言实现10个字符的插入排序

引用 2 楼 cyfcsd 的回复: void insert_sort(int A[],const size_t n) { 	size_t i,j,min; 	int temp; 	for(i=0;i<n-1;i++){ 		min=i; 		for(j=i+1;j<n;j++){ 		if(A[min]>A[j]) min = j; 		} 		temp = A[i]; 		A[i] = A[min]; 		A[min] = temp; 	} }  抱歉，写成选择了，版主正解

#include <stdio.h>   #include <stdlib.h>      void insertSort(char *, int);      int main()   {       int i;       char ch[10];      	printf("输入10个字符：\n");     for(i = 0; i < 10; i ++)       {           scanf("%c",ch + i);       }          //快速排序       insertSort(ch, 10);          //打印输出       for(i = 0; i < 10; i ++)       {           printf("%c ",ch[i]);       }       printf("\n");        return 0;   }      void insertSort(char *array, int len)   {       int i, j, temp;          for(i = 1; i < len; i ++)       {           temp = array[i];           for(j = i - 1; j >= 0; j --)           {               if(array[j] > temp)               {                   array[j + 1] = array[j];                   }else               {                   break;               }           }           array[j + 1] = temp;       }   }


Question: 下面几道题包括了各种算法思想，懂算法的大神请来指导一二

1) 三四相同,五六相同, 就二重循环了, 判断是不是完全平方数, 0不知道算不算了, 完全平方数好像%3不会等于2, 最多1到100枚举了 2) 优先队列, 取小 3) 直接dfs就可, 我以前应该回过代码, 你找找看吧 4) 类似约瑟夫环, 用数组做个简单的循环链表 5) 跟3差不多思想 6) 7.11 扩大100倍是711, 分解成因数为3*3*79,显然不可能是整数解, 那么就肯定是浮点误差造成的假象了,反正就四个数, 商店最小单位就是0.01, 三重循环枚举一下,为了避免过多重复 假设a<=b<=c, d=7.11-a-b-c, d>=c, 答案就一组

1.枚举 4.感觉和约瑟夫环挺像的……

2.ti排序,小的先服务. 3.带羊过河，第二次带狼（菜)过河，同时把羊运到对岸，第三次运菜（狼)过河，第四次运羊过河。


Question: 入栈中的 *S.top=e;究竟错在了什么地方？？

因为在传递给函数参数时使用结构体变量传递，而这样的话malloc等操作对原来结构体变量没有作用。传递函数参数应该使用结构体指针，将结构体变量的地址传递给函数，这样在函数里就可以修改原来的结构体变量。举个例子如下： #include <stdio.h> void interchange(int x, int y);  int main(void) { 	int x=5, y=10; 	printf("Originally x = %d and y = %d.\n", x, y); 	interchange(x, y); 	printf("Now x = %d and y = %d.\n", x, y); 	return 0; }  void interchange(int u, int v) { 	int temp; 	temp = u; 	u = v; 	v = temp; }  interchange（）使用的变量独立于函数main（），交换u和v的数值对x和y的数值没有任何影响。

chushihua(SqStack S)没加引用导致的 所有函数都变成这样的就可以了chushihua(SqStack &S）


Question: c结构体申明问题

应该是LinkListNode *header; sizeof(TLinkList)为8因为4字节存放指针指向地址，4字节存放整型数值。

引用 3 楼 merry_zsp 的回复:typedef struct _tag_LinkList { LinkListNode header; int length; }TLinkList; printf("%d\n%d\n",sizeof(TLinkList),sizeof(int) );  我发现sizeof(TLinkList)为8    sizeof(int) 为 4 那就是默认为结构体分配的大小是4咯？这是默认情况下为LinkListNode结构体分配的最小内存吗（因为定义只有一个指向本类型的指针  并没有指明大小）？ 还有一个问题就是  为什么指向下一个结点类型的指针是LinkListNode类型的而不是TLinkList类型的？这样有什么好处？ 新手不懂的比较多....  sizeof(TLinkList)为8 因为里面两个成员，header4字节，length4字节，  TLinkList你可以理解成是_tag_LinkList结体体别名，他是结体体类型，不是指针

LinkListNode是_tag_LinkListNode的一个别名，他们俩是一个意思 _tag_LinkListNode是一个结构体类型，注意这是个类型而不是变量，所以是不需要分配内存的，只有在_tag_LinkListNode a（或 LinkListNode a)时才会为变量a分配内存 后面一段是把起别名和定义放在一起了，可以分开理解：首先是定义一个结构体类型_tag_LinkList，然后给其起一个别名TLinkList，还是上面说的，这两个都是类型名，不涉及分配内存 header是上面定义的_tag_LinkListNode类型的变量，也就说header是一个结构体变量，它不是指针，而是结构体里有一个指针，可以理解为header内包含一个指针，结构体类型本身就是一个复合类型，只是这个只含一个指针罢了。这个指针指向的是_tag_LinkListNode的结构体

header不是指针，只是一个LinkListNode结构体，LinkListNode是_tag_LinkListNode的别名，所以第一个结构体声明里面成员是一个指向该结构体的指针，这就是链表的基本思想。


Question: 函数实现对10个排好序的元素进行折半法查找

你一定要从大到小找，就用这个。   #include<stdio.h> void print_s(int *p,int n); int sort(int a[],int n) {     int i,j;     for(i=1;i<n;i++)     {         for(j=0;j<n-i;j++)         {             if(a[j]<a[j+1])             {                 int temp=a[j];                 a[j]=a[j+1];                 a[j+1]=temp;             }         }     }     }  /*折半查找***************************/ int  find(int a[], int n, int x) { 	int low,high,mid; 	low = 0; 	high = n-1; 	while (low <= high) 	{ 		mid = (low+high)/2; 			 		if (a[mid]>x) 			low = mid+1; 		else if(a[mid]<x) 			high = mid-1; 		else 		return mid; 		 	} 	return -1;     /*****************************/ }  int main() { 	int ret;     int a[10]={11,12,13,14,15,16,17,18,19,20};     print_s(a,10); 	sort(a,10); 	print_s(a,10); 	ret = find(a,10,17); 	if (ret==-1) 		printf("没找到\n"); 	else 		printf("下标是：%d\n",ret); //    int i; //    for(i=0;i<10;i++) //    { //        printf("%d\n",a[i]); //    }     return 0; }  void print_s(int *p,int n) { 	int i; 	for (i = 0;i<n;i++) 	{ 		printf("%d ",*(p+i)); 	} 	printf("\n"); }

折半查找本来就是要在一个排序好的序列里找。为什么你要改成从大到小排序。初学的话，从小到大更好理解些。

你要在你的子函数里，排序后，再加一个循环，就是把你看的书上的代码加进去。 你的排序是实现的从大到小的排序，要改成从小到大的排序。 下面星号之间的，就是书上的代码。子函数参数要加一个要查找的关键字，要有返回下标的值。  #include<stdio.h> void print_s(int *p,int n); int sort(int a[],int n,int key) {     int i,j;     for(i=1;i<n;i++)     {         for(j=0;j<n-i;j++)         {             if(a[j]>a[j+1])             {                 int temp=a[j];                 a[j]=a[j+1];                 a[j+1]=temp;             }         }     }      print_s(a,10);      	/*折半查找***************************/      	int low,high,mid; 	low = 0; 	high = n-1; 	while (low <= high) 	{ 		mid = (low+high)/2; 			 		if (a[mid]<key) 			low = mid+1; 		else if(a[mid]>key) 			high = mid-1; 		else 		return mid; 		 	} 	return -1;     /*****************************/      } int main() { 	int ret;     int a[10]={11,12,13,14,15,16,17,18,19,20};     print_s(a,10); 	ret = sort(a,10,17); 	if (ret==-1) 		printf("没找到\n"); 	else 		printf("下标是：%d\n",ret); //    int i; //    for(i=0;i<10;i++) //    { //        printf("%d\n",a[i]); //    }     return 0; }  void print_s(int *p,int n) { 	int i; 	for (i = 0;i<n;i++) 	{ 		printf("%d ",*(p+i)); 	} 	printf("\n"); }

折半查找可参考 VC\crt\src\bsearch.c


Question: 请教高手一个C语言运算(可能是数据类型)的问题

引用 14 楼 chehw_1 的回复:检查一下sizeof(long)是否是4个字节。  在不同的操作系统和CPU架构下，long的长度是不同的 引用sizeof(long) =    OS           arch                            size Windows       IA-32                            4 bytes Windows       Intel® 64 or IA-64        4 bytes Linux              IA-32                           4 bytes Linux              Intel® 64 or IA-64       8 bytes Mac OS X       IA-32                          4 bytes Mac OS X      Intel® 64 or IA-64       8 bytes  答错地方了，请忽略吧

引用 11 楼 lanpad的回复:[quote=引用 10 楼 qq_29465155 的回复:] long是有符号的，61380对应efd4，高位填充出现bug了  long不是4个字节32bit的长度么？ 应该是“0000EFD4”吧？[/quote] 两个字节的无符号数，扩充到四个字节有符号数，不强转编译器可能忽略符号位是否有效的问题。在int 类型的符号位出现1，无符号数不强转会被当作整型数据负数的标志位。还有本来计算结果就有溢出，你用最大无符号数加1，加2，等等，试试它溢出是否有规律。

这里不应该用long类型，64位系统是8字节而32位系统是4字节的，这让你的算法（按位）出现不稳定的结果。同时既然是有移位操作，就不得使用带符号的类型，要用无符号的，例如u_int32_t，否则负数在移位过程中，高位是补1而不是补0

引用 10 楼 qq_29465155 的回复:long是有符号的，61380对应efd4，高位填充出现bug了  long不是4个字节32bit的长度么？ 应该是“0000EFD4”吧？

long是有符号的，61380对应efd4，高位填充出现bug了

你的是16位unsigned，计算结果超出类型范围，你每次调试结果可能都不一样。而立即数存放在代码区常量表，没有类型限制，执行时根据表达式调用2个寄存器（16位的）完成计算和赋值。

引用 7 楼 jinlu1990 的回复:  是不是跟编译器有关？有人说我的编译器有bug：  “你的编译器有bug C_sum_test = 10*61380 时，直接使得 C_sum_test 等于 613800，这是不正确的。因为 int * unsigned int的结果类型应该是 unsigned int，而 613800 已经是 long 型了。  如果你用符合标准的编译器（还要这鸟编译器的int是16位的），那么两段代码结果应该一致 即，低16位是 0x5DA8，高16位是 0x0000（既不是9也不是-11）”  我又试了几次，加一个强制类型转换就可以了  将“ C_sum  = A_cnt *61380;        //正确结果应为613800或0x95DA8”  改为  “ C_sum  = （unsigned long）A_cnt *61380;”或 “ C_sum  = A_cnt *（unsigned long）61380;”  就正确了  必须是“（unsigned long）” “（long）”都不对  不知道怎么回事？   ps：开发环境：ZSP IDE (integrated development environment) 基于GCC3.0编译器， 根据软件中提供的文档，该版本的GCC(GNU Compiler Collection)主要支持C89标准。

看代码，并不会出现LZ说的现象. 然后实际测试，也并没有出现错误。

试过 无效…… 引用 3 楼 shangyu0801 的回复:long C_sum_test;与long C_sum; 都改为unsigned long类型。long类型的如果高位时1，右移时高位是补1的。

请给出完整的程序。

跪求解决问题

没有分了，跪求给点吧


Question: int x[][3]={{1,2,3},{4, ,5 6}};C语言中这条初始化语句对不对

这种写法是对的吧。我编译通过了。 多换几个IDE试试。我在dev-c++上编译通过。

引用 2 楼 paschen 的回复:int x[][3]={{1,2,3},{},{4,5,6}};  这个C++下没问题， 不知C标准是否支持 是vc++吗，我编译没通过

引用 4 楼 caojinrong 的回复:[quote=引用 1 楼 paschen 的回复:] 应该是：int x[][3]={{1,2,3},{4,5, 6}}; 吧， 你逗号位置错了 引用int x[ ][3]={{1,2,3},{},{4,5,6}};不对，C语言中的二维数组是对齐的，第二下标规定为3，则每个元素长度都应为3而第二个元素为空，当然有些编译器是支持这种写法的，自动补0呗！[/quote]  这种{4, ,5 6} 肯定是不行的，估计书上印刷错了

引用 1 楼 paschen 的回复:应该是：int x[][3]={{1,2,3},{4,5, 6}}; 吧， 你逗号位置错了 引用int x[ ][3]={{1,2,3},{},{4,5,6}};不对，C语言中的二维数组是对齐的，第二下标规定为3，则每个元素长度都应为3而第二个元素为空，当然有些编译器是支持这种写法的，自动补0呗！

引用 1 楼 paschen 的回复:应该是：int x[][3]={{1,2,3},{4,5, 6}}; 吧， 你逗号位置错了 不是，书上原句就是我写的那个，所以我在怀疑是不是书错了。。。

引用 15 楼 zhao4zhong1 的回复:空初始化列表是一种语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。  铭记在心，谢谢老师

引用 10 楼 user-6 的回复:C语言不允许空 {}  做初始化  它的语法就生成不了 {} initializer:     assignment-expression     { initializer-list }     { initializer-list , }  initializer-list:     designationopt initializer initializer-list , designationopt initializer  [quote=引用 8 楼 paschen 的回复:] [quote=引用 7 楼 u013409924 的回复:] [quote=引用 6 楼 paschen 的回复:] [quote=引用 4 楼 caojinrong 的回复:] [quote=引用 1 楼 paschen 的回复:] 应该是：int x[][3]={{1,2,3},{4,5, 6}}; 吧， 你逗号位置错了 引用int x[ ][3]={{1,2,3},{},{4,5,6}};不对，C语言中的二维数组是对齐的，第二下标规定为3，则每个元素长度都应为3而第二个元素为空，当然有些编译器是支持这种写法的，自动补0呗！[/quote]  这种{4, ,5 6} 肯定是不行的，估计书上印刷错了[/quote]  这个也通不过是为啥？[/quote]  第二个元素用 {} VC6 不认，VS下可以，至于标准怎么说的不太清楚，等@user-6解释[/quote][/quote]  谢谢！

谢谢！ 引用 11 楼 lm_whales 的回复:int x[ ][3]={{1,2,3},{},{4,5,6}}; C 不接受空的 初始化表， C++原本也是不接受的 不过C++11 已经可以接受了 你可以试一试

引用 13 楼 user-6 的回复:C++ 从 98 年第一版标准开始就接受空初始化列表。  [quote=引用 11 楼 lm_whales 的回复:]  int x[ ][3]={{1,2,3},{},{4,5,6}}; C 不接受空的 初始化表， C++原本也是不接受的 不过C++11 已经可以接受了 你可以试一试[/quote]这个不清楚，不过VC据说标准执行的一向不是很好

C++ 从 98 年第一版标准开始就接受空初始化列表。  引用 11 楼 lm_whales 的回复:int x[ ][3]={{1,2,3},{},{4,5,6}}; C 不接受空的 初始化表， C++原本也是不接受的 不过C++11 已经可以接受了 你可以试一试

VC6 一下就不要考虑了 VC2013 对C++11 支持的听说也不好 据说 VC2015 支持的还可以  C99以及以后的版本，不知道有没有支持空的初始化表

C语言不允许空 {}  做初始化  它的语法就生成不了 {} initializer:     assignment-expression     { initializer-list }     { initializer-list , }  initializer-list:     designationopt initializer initializer-list , designationopt initializer 引用 8 楼 paschen 的回复:[quote=引用 7 楼 u013409924 的回复:] [quote=引用 6 楼 paschen 的回复:] [quote=引用 4 楼 caojinrong 的回复:] [quote=引用 1 楼 paschen 的回复:] 应该是：int x[][3]={{1,2,3},{4,5, 6}}; 吧， 你逗号位置错了 引用int x[ ][3]={{1,2,3},{},{4,5,6}};不对，C语言中的二维数组是对齐的，第二下标规定为3，则每个元素长度都应为3而第二个元素为空，当然有些编译器是支持这种写法的，自动补0呗！[/quote]  这种{4, ,5 6} 肯定是不行的，估计书上印刷错了[/quote]  这个也通不过是为啥？[/quote]  第二个元素用 {} VC6 不认，VS下可以，至于标准怎么说的不太清楚，等@user-6解释[/quote]

引用 8 楼 paschen 的回复:[quote=引用 7 楼 u013409924 的回复:] [quote=引用 6 楼 paschen 的回复:] [quote=引用 4 楼 caojinrong 的回复:] [quote=引用 1 楼 paschen 的回复:] 应该是：int x[][3]={{1,2,3},{4,5, 6}}; 吧， 你逗号位置错了 引用int x[ ][3]={{1,2,3},{},{4,5,6}};不对，C语言中的二维数组是对齐的，第二下标规定为3，则每个元素长度都应为3而第二个元素为空，当然有些编译器是支持这种写法的，自动补0呗！[/quote]  这种{4, ,5 6} 肯定是不行的，估计书上印刷错了[/quote]  这个也通不过是为啥？[/quote]  第二个元素用 {} VC6 不认，VS下可以，至于标准怎么说的不太清楚，等@user-6解释[/quote] 谢谢！

引用 7 楼 u013409924 的回复:[quote=引用 6 楼 paschen 的回复:] [quote=引用 4 楼 caojinrong 的回复:] [quote=引用 1 楼 paschen 的回复:] 应该是：int x[][3]={{1,2,3},{4,5, 6}}; 吧， 你逗号位置错了 引用int x[ ][3]={{1,2,3},{},{4,5,6}};不对，C语言中的二维数组是对齐的，第二下标规定为3，则每个元素长度都应为3而第二个元素为空，当然有些编译器是支持这种写法的，自动补0呗！[/quote]  这种{4, ,5 6} 肯定是不行的，估计书上印刷错了[/quote]  这个也通不过是为啥？[/quote]  第二个元素用 {} VC6 不认，VS下可以，至于标准怎么说的不太清楚，等@user-6解释

引用 6 楼 paschen 的回复:[quote=引用 4 楼 caojinrong 的回复:] [quote=引用 1 楼 paschen 的回复:] 应该是：int x[][3]={{1,2,3},{4,5, 6}}; 吧， 你逗号位置错了 引用int x[ ][3]={{1,2,3},{},{4,5,6}};不对，C语言中的二维数组是对齐的，第二下标规定为3，则每个元素长度都应为3而第二个元素为空，当然有些编译器是支持这种写法的，自动补0呗！[/quote]  这种{4, ,5 6} 肯定是不行的，估计书上印刷错了[/quote]  这个也通不过是为啥？


Question: 单片机c语言

阿拉伯数字、字母

可以用来传递任何信息。

广告牌  显示屏等，自己也可以弄一些小东西 LED显示屏就是集成的点阵


Question: 结构体变量名表示什么

楼主的帖子不错，让人彻底明白了结构体的变量名a到底是怎么回事了。其实a就是代表这个结构体整体，按照对齐方法按四个字节一组的方式放入61  62  63  0 , 0  0  0  0,  0  0  0  0, 0  0  0  0,  0  0  0  0,1 0 0 0   当你输出a时你就要写够足够的控制字符比如%d，一个%d输出一组的十进制值，比如第一组 61  62  63  0 （分别代表十六进制的a b c 0）它代表是十六进制整数 636261（变量的存储方式是低字节序的），换成十进制就是我们在控制台中看到的6513249，其他各组依次是0，最后一个是1，后面再输出就是我们想要看到的abc和1了

一般都没谁会对结构体进行整体赋值，但是能不能对结构体进行整体赋值呢？数组是不行的。就像给结构体初始化那样 typedef struct {    uint8 a；    uint8 b； } A; void main（void） {    A a；    a={1,2}； }

struct data{     char a[4];     int b;     }; struct data d; printf("%x"，d); 参数传递是这样的 printf 函数调用，为d 在堆栈中，准备一个足够容纳d的内存位置。可以假设为  struct data tmp ； 此时相当于在这里定义一个变量 定义式为struct data tmp=d 完成参数传递。 然后，进入printf函数内部，按照 "%x"格式，解释 这个 tmp  于是 tmp.a 这个数组，被看作 int tmpa; 你可以看作这里有个联合体 union{char a[4];int tmpa;}; 其他字段不是第一个字段，有对齐问题，按对齐处理。 对齐之后，按照 格式串指定的格式一一解析。  这个函数，因为是C的不定参数函数， 只能采取约定的方式处理，参数和格式的是一一对应的关系， 如果你的参数不是对应的，那是调用方违约， 对方检测不了，就只能盲目的按照约定好的方式输出。 所以， 第一参数如何传递， 第二格式 如何解释， 这两个因素，影响最终输出结果。 对结构体来说，没有对应的格式。 这本来就是不正确的。 所以结果也无法预期。 没有任何结果是合理的。

楼主想彻底弄明白的话，参考printf的源代码。 Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c

a结构体变量，只能做两种运算，整体引用（赋值，参数传递）或访问成员（点运算—地址方式简化，地址方式）。sizeof(struct <>)=24字节，内存对齐。a+1提示不匹配，&a+1是可以的，&a是int *类型，解析方式明确，a是（struct  <>const）类型 ，自定义，和数组又不同，解析方式按编译器设置。printf不会进行类型转换，如果a是按照24字节解析用整型输出不匹配，但c会执行，结果不确定。具体问题怎么分析，新人不太熟。

结构体变量的值是整个结构体。  printf 处理不了结构体。通过 printf 输出结构体，结果是没有意义的。

引用 1 楼 infoworld的回复:%x 是输出整数值的格式,所以会把结构体变量a当作一个整型值,结果就是强制转换a的前4个字节为整型值, 因为name里的指针地址是递增的,而变量的存储方式是低字节序的，所以int的16进制值是636261,接着是会把接着的2个整型值(分别是4个字节,name有20个字节)输出,0,0, 编译器会把a当作一个变量的集合,而不是一个单独的变量.   #include <stdio.h> #include <iostream>  typedef struct{     char name[20];     int value; }Student;   int main() { 	// a=0x61,b=0x62,c=0x63,0x0,0x0,,,,     Student a={"abc",1};     printf("%s %d\n",a.name,a.value);     printf("%x,%x\n",&a.name,&a.value);     printf("%x,%x,%x\n",a);      std::cout << &a << "," << &a.name << "," << &a.value << std::endl;     return 0; }   abc 1 28fee8,28fefc 636261,0,0 0x28fee8,0x28fee8,0x28fefc  你的回答结合四楼的回答让我明白了，我的理解是，printf语句先把后面的参数列表所表示的值放在临时内存中，然后再按前面控制字符串来输出，而a表示的是结构体整个内容（包括name和value），所以会出现636261，我试了下，在前面加入8个%x时，printf（"%x %x %x %x %x %x %x %x"，a，&a.name,&a.value）,这样a.name,a.value的地址能够正常输出，这和我的理解完全相符。之所以问题中会出现那问题只是控制字符串少了，而不是输出a后影响了a.name,a.value的地址。

引用 4 楼 lm_whales的回复:printf 输出结构体 就是整个结构体复制堆栈中，起码现在是这么做的 结构体在内存是什么样子，在堆栈中也还是什么样子。 可能唯一的差距，就是结构体尾部，补上多少字节。 结构体中字符串数组，就是把字符序列，按照对应的格式输出  #include<cstdio> using namespace std;  int main() {     struct data{     char a[4];     int b;     };      data d{"abc",10};     printf("%#x-%#x\n",d);//%x当作整型输出，大小端输出是不同的     printf("0x%08x-0x%08x\n",d);//           return 0; }  ///输出 ///0x636261-0xa ///0x00636261-0x0000000a 谢谢，"结构体整个复制到堆栈"让我一下明白了

结构体变量名，就是变量名。象int a，一样，只是不能直接输出，直接输出没有意义。取地址要用&，不用钻牛角尖，不直接输出就行了    #include<stdio.h> typedef struct{     char name[20];     int value; }Student;   int main() {     Student a={"abc",1};     printf("%p\n",&a);     printf("%p %s %d\n",&a,a.name,a.value);     printf("%x %x %x",&a,&a.name,&a.value);     return 0; }

和数组不同，结构体变量，现在是可以整体赋值的， 结构体中的数组，在结构体赋值的过程中， 也是可以针对每个元素一一赋值的  不过C还不能用初始化列表赋值。 C++11是可以的，因为C++的结构体和类没有太多不同。


根据你的意思，我觉得你应该要用strcat_s，这样会自动连接到上一个字符串的后面，不用像你写那么麻烦

debug调试

你的程序能编译吗？大括号不匹配啊

你的子函数没有贴出来。


Question: fscanf读取带含有回车文件的最后一个数字

引用 6 楼 chybeyond123456789 的回复:[quote=引用 3 楼 u012725046 的回复:] a+打开可以的 是fseek错了  大小不应该是偏移1个字节  fseek(fp, -sizeof(int), SEEK_END);      #include <stdio.h> int main() {     FILE *fp;     unsigned int flight_num;     unsigned int flag;     char flight_string[20];       fp = fopen("flight_num.txt", "r"); //第一次进入，文件不存在创建文件并写入0.     if (fp == NULL)     {         printf("open error!\n");         fp = fopen("flight_num.txt", "wt");         fprintf(fp, "%d\n\r", 0);         fclose(fp);     }     else     {         fclose(fp);         fp = fopen("flight_num.txt", "a+");         // printf("1th  %d\n",ftell(fp));         fseek(fp, -sizeof(int), SEEK_END);         // printf("2th  %d\n",ftell(fp));         fscanf(fp, "%d", &flight_num);          // printf("3th  %d\n",ftell(fp));         fprintf(fp, "%d\n\r", flight_num+1);          // printf("4th  %d\n",ftell(fp));         fclose(fp);         printf("%d", flight_num);     }     return 0; }  谢谢，但是这样只能计数到255，之后就从0开始了，怎么才能一直计数[/quote]  这个问题是之前没考虑到，文件中的都是char，直接用fseek移动sizeof(int)是4个字节，又从赵老师那长知识了  引用 5 楼 zhao4zhong1 的回复:不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  我是这么改的，直接fseek 4个字节，然后格式控制输出的格式，这么的话最多就只能到1000，然后从1开始，增加范围直接修改 移动字节数和格式控制就好了 PS：因为多个\n，所以fseek多移动了1鸽字节   fseek(fp, -4, SEEK_END); fprintf(fp,"%3d\n", flight_num+1);   效果图   代码   #include <stdio.h> int main() {     FILE *fp;     unsigned int flight_num;     unsigned int flag;     char flight_string[20];       fp = fopen("flight_num.txt", "r"); //第一次进入，文件不存在创建文件并写入0.     if (fp == NULL)     {         printf("open error!\n");         fp = fopen("flight_num.txt", "w+");         fprintf(fp, "%3d\n", 0);         fclose(fp);     }     else     {         fclose(fp);         fp = fopen("flight_num.txt", "a+");         fseek(fp, -4, SEEK_END);         fscanf(fp, "%d", &flight_num);            fprintf(fp,"%3d\n", flight_num+1);         fclose(fp);         printf("%d", flight_num);     }     return 0; }

另外文件打开失败不一定表示文件不存在，可以使用API FindFirstFile 等方式

引用 7 楼 qq_29120981 的回复:[quote=引用 3 楼 寒风_弄夜的回复:]a+打开可以的 是fseek错了  大小不应该是偏移1个字节  fseek(fp, -sizeof(int), SEEK_END);    #include <stdio.h> int main() {     FILE *fp;     unsigned int flight_num;     unsigned int flag;     char flight_string[20];       fp = fopen("flight_num.txt", "r"); //第一次进入，文件不存在创建文件并写入0.     if (fp == NULL)     {         printf("open error!\n");         fp = fopen("flight_num.txt", "wt");         fprintf(fp, "%d\n\r", 0);         fclose(fp);     }     else     {         fclose(fp);         fp = fopen("flight_num.txt", "a+");         // printf("1th  %d\n",ftell(fp));         fseek(fp, -sizeof(int), SEEK_END);         // printf("2th  %d\n",ftell(fp));         fscanf(fp, "%d", &flight_num);          // printf("3th  %d\n",ftell(fp));         fprintf(fp, "%d\n\r", flight_num+1);          // printf("4th  %d\n",ftell(fp));         fclose(fp);         printf("%d", flight_num);     }     return 0; }  谢谢，原来我理解错楼主的意思了[/quote] 没有，你的回答解决了我其中一个问题，我参考了另外一位楼主的答案

不知道你是不是要读取最后一行的数字。 我改的是把最后一行的数字加1，再追加一行。   /* 保存的数字追加到最后一行。新添加的行，在行首添加换行符。数字后不加换行符  */  #include <stdio.h> #include <stdlib.h> int main() { 	FILE *fp; 	unsigned int flight_num; 	unsigned int flag; 	char flight_string[20];  	fp = fopen("flight_num.txt", "r"); //第一次进入，文件不存在创建文件并写入0. 	if (fp == NULL) 	{ 		printf("open error!\n"); 		fp = fopen("flight_num.txt", "wt"); 		fprintf(fp, "\r\n%d", 0); 		fclose(fp); 	} 	else 	{ 		fclose(fp); 		fp = fopen("flight_num.txt", "a+"); 		if (fp == NULL) 		{ 			perror("fopen"); 			exit(1); 		} 		int i=-1; 		char ch; 		fseek(fp, i, SEEK_END); 		ch=fgetc(fp); 	 		//读到一行的换行符，再开始向文档尾读取数字  		while(ch!='\n') 		{ 			i--; 	        fseek(fp, i, SEEK_END); 	        ch = fgetc(fp); 		} 	     	     	i = 0;     	ch = fgetc(fp);     	     	//从上面找到的换行符的位置，向文档尾读取，把读到的数字放到数组里  	    while (!feof(fp)) 	    { 	        if (ch >= '0' && ch <= '9') 	        { 	            flight_string[i] = ch; 	            i++; 	        } 	        ch = fgetc(fp); 	    }  		//字符数组转换成数字   		flight_num = atoi(flight_string);   		fprintf(fp, "\r\n%d", (flight_num+1)); 		fclose(fp); 		printf("%d\n", flight_num+1); 	} }

引用 3 楼 寒风_弄夜的回复:a+打开可以的 是fseek错了  大小不应该是偏移1个字节  fseek(fp, -sizeof(int), SEEK_END);      #include <stdio.h> int main() {     FILE *fp;     unsigned int flight_num;     unsigned int flag;     char flight_string[20];       fp = fopen("flight_num.txt", "r"); //第一次进入，文件不存在创建文件并写入0.     if (fp == NULL)     {         printf("open error!\n");         fp = fopen("flight_num.txt", "wt");         fprintf(fp, "%d\n\r", 0);         fclose(fp);     }     else     {         fclose(fp);         fp = fopen("flight_num.txt", "a+");         // printf("1th  %d\n",ftell(fp));         fseek(fp, -sizeof(int), SEEK_END);         // printf("2th  %d\n",ftell(fp));         fscanf(fp, "%d", &flight_num);          // printf("3th  %d\n",ftell(fp));         fprintf(fp, "%d\n\r", flight_num+1);          // printf("4th  %d\n",ftell(fp));         fclose(fp);         printf("%d", flight_num);     }     return 0; }  谢谢，原来我理解错楼主的意思了

引用 3 楼 u012725046 的回复:a+打开可以的 是fseek错了  大小不应该是偏移1个字节  fseek(fp, -sizeof(int), SEEK_END);    #include <stdio.h> int main() {     FILE *fp;     unsigned int flight_num;     unsigned int flag;     char flight_string[20];       fp = fopen("flight_num.txt", "r"); //第一次进入，文件不存在创建文件并写入0.     if (fp == NULL)     {         printf("open error!\n");         fp = fopen("flight_num.txt", "wt");         fprintf(fp, "%d\n\r", 0);         fclose(fp);     }     else     {         fclose(fp);         fp = fopen("flight_num.txt", "a+");         // printf("1th  %d\n",ftell(fp));         fseek(fp, -sizeof(int), SEEK_END);         // printf("2th  %d\n",ftell(fp));         fscanf(fp, "%d", &flight_num);          // printf("3th  %d\n",ftell(fp));         fprintf(fp, "%d\n\r", flight_num+1);          // printf("4th  %d\n",ftell(fp));         fclose(fp);         printf("%d", flight_num);     }     return 0; }  谢谢，但是这样只能计数到255，之后就从0开始了，怎么才能一直计数

第一次打开文件成功后再次打开文件的模式用错了(第41行)，应该用写入模式(w+)而不是追加模式(a+)


Question: 一道字符串指针选择题..哪位大神来帮小弟解答一下

不知为什么开不了帖子..老是说文章内容不能含有特殊字符..无奈只能放在这里了。！！

如下题,答案我都知道,希望有详细易懂的解释 1．以下正确的程序段是（）。 A． char s;                               B． char *s; scanf("%s", &s);                             scanf("%s", s); C． char s;                               D． char s, *t=s; scanf("%s", &s);                           scanf("%s", t); 2．下面程序段的运行结果是（）。 #include "stdio.h" main() {     int m=10, n=20;     char *format="%s, m=%d, n=%d\n";     m*=n;     printf(format, "m*=n", m,n); } A． format, "m*=n", m, n                      B． format, "m*=n" C． m*=n, m=200, n=20                        D． 以上结果都不对 3．下面程序的功能是将八进制正整数字符串转换为十进制整数。请选择填空。 #include "stdio.h" #include "string.h"     main()     {         char *t, s;         int n;         t=s;         gets(t);         n=【1】;         while (【2】!= '\0') n=n*8+*t-'0';         printf("%d\n", n);     }     【1】A． 0           B． *t              C． *t-'0'             D． *t+'0'     【2】A． *t          B． *t++            C． *(++t)              D． t 4．以下正确的程序段是（）。 A． char s="12345", t="6543d21";    strcpy( s,t); B． char s, *t="12345";   strcat(s,t); C． char s=" ", *t="12345"; strcat(s, t); D． char *s="12345", *t="54321";  strcat (s,t); 5．不合法的main函数命令行参数表示形式是：（）。     A． main( int a, char *c)                  B． main(int argc, char *argv)     C． main( int arc, char **arv)               D． main( int argv, char*argc) 6．下面程序的功能是统计字串sub在母串s中出现的次数。请选择填空。 #include "stdio.h" #include "string.h"     main()b     {         char s, sub;//字符串函数         int n;         gets(s);         gets(sub);         printf("%d\n", count(s,sub));     }     int count( char *p, char *q)     {         int m, n, k, num=0;         for (m=0; p; m++)             for (【1】, k=0; q==p; k++, n++)  //b  c                 if(q=='\0')                 { num++;  break;}         return (num);     }     【1】A． n=m+1        B． n=m            C． n=0              D． n=1     【2】A． k             B． k++            C． k+1              D． ++k #include "stdio.h" #include "string.h"     main(int argc, char *argv)     {            int m, length=0;         for (m=1;m<argc; m++)  length+=strlen(argv);         printf("%d\n", length);     }   7.  程序编译连接后生成的可执行文件是file.out，若执行时输入带参数的命令行是：     ./file.out 1234  567  89↙     则运行结果是（）     A． 22              B． 17               C． 12             D． 9 8.假定下列程序的可执行文件名为file.out，则在该程序所在的子目录下输入命令行：     ./file.out  girl  boy↙     后，程序的输出结果是（）。 #include "stdio.h"     main(int argc, char *argv)     {            int m;         if (argc<=0) return;         for (m=1; m<argc ; m++)             printf("%c", *argv);     }     A． girl  boy        B． gb             C． gir              D． girlboy 9．设有一个名为file的C源程序，且已知命令行为：file  girl  boy  student， 则可得到以下运行结果的C源程序为（）     girl     boy     student     A． main( int argc, char *argv)     {           while (--argc>1)             printf("%s%c", *argv, (argc>1)? '\n'：' ');     }     B． main( int a, char * b)     {          while (a-->1)             printf("%s\n", *++b);     }     C． main( int argc, char *argv)     {           while (++argc>0)             printf("%s%c", *++argv, (argc>1) ? ' ' ：'\n');     }     D． main(int argc, char *argv)     {          while (argc>1)             printf("%s", *++argv);      }

引用 9楼我是你的主体 的回复:[quote=引用 4 楼 weixin_30460121 的回复:] char *s=“girl” //将字符串首地址赋值给       指针变量s(指针即地址) char *s; s=“girl” //同上  char *s; s="girl";这个不是s是指针变量只能存储地址吗..怎么能存储girl这个字符串[/quote]s="girl"并不是说将字符串常量“girl”赋值给s，而是将字符串常量的首地址赋值给s，s=“girl”=>s=&'g'

引用 8 楼 ddyyuan 的回复:[quote=引用 3 楼 Jammg 的回复:] char *s="string"； 被编译时，这个字符串常量是储存在字符串常量区的，他在整个程序的声明周期有效，编译时编译器会将字符串常量所在的地址返回给s,也就是说s指向字符串常量区的某个地方。 这是C语言中一个语法标准，记住就好了  后面的 char *s; s="girl";这个不是s是指针变量只能存储地址吗..怎么能存储girl这个字符串 [/quote] 这个字符串是存储在字符串常量区的，它的首地址才是储存在s，C语言规定这种语法就要这样被编译.

s存储的就是“gril”的首地址

引用 4 楼 weixin_30460121 的回复:char *s=“girl” //将字符串首地址赋值给       指针变量s(指针即地址) char *s; s=“girl” //同上  char *s; s="girl";这个不是s是指针变量只能存储地址吗..怎么能存储girl这个字符串

引用 3 楼 Jammg 的回复:char *s="string"； 被编译时，这个字符串常量是储存在字符串常量区的，他在整个程序的声明周期有效，编译时编译器会将字符串常量所在的地址返回给s,也就是说s指向字符串常量区的某个地方。 这是C语言中一个语法标准，记住就好了  后面的 char *s; s="girl";这个不是s是指针变量只能存储地址吗..怎么能存储girl这个字符串

B. 字符数组只能在初始化时赋初值.char s[10];s[10]="girl" (错)

A. char *s=“girl”;*s=“girl” （错）//s为字符串首地址，*s为首地址指向的字符，*s，=‘g’

引用 3 楼 Jammg 的回复:char *s="string"； 被编译时，这个字符串常量是储存在字符串常量区的，他在整个程序的声明周期有效，编译时编译器会将字符串常量所在的地址返回给s,也就是说s指向字符串常量区的某个地方。 这是C语言中一个语法标准，记住就好了  非常简单明了的解释，多谢

我也知道C对..然而..清楚详细的解释总是找不到唉

A错，左边是地址，右边是字符串，不能进行赋值;  B错，左边是类型为char的数组s，字符宽度为10。 右边是将数组初始化为字符串"girl" 。相当于先声明数组，再给数组赋值。左边这部分是对的。但是在等价于后面， s[10]相当于字符串s的第11个元素，一个是没有第11个元素，另外一个是右边是字符串，肯定不对。  C对。编译通过……为啥，不知道。我没学到这个char *s=字符串的  D错。左边是没问题的。右边的问题在于，编译器会认为 t[4] 是数组t的第5个元素。一方面没声明数组t，另一方面就算声明了，也会让编译器以为你要把字符串赋值为数组t 的第五个元素


Question: LINUX下 char打印字符的问题

上面的是我写的各种测试，看现象的，谢谢大家  现在都明白了

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

引用 1 楼 u010158109 的回复:注意下我是在ubuntu，eclipse环境下运行的 这一句话就显得楼主特没水平，还特地强调！！！！  printf("data[] = %s\n", *data); 会在这句出错，%s表示打印字符串，你的data不是字符串

printf("data[] = %s\n", *data);  本句 printf 需要一个（合法的）字符串(char *) ，你提供了一个 char （ *data 是一个 char）。 自此程序的结果再也无法预知。  ==== 另外这里 memset(data2, 0, sizeof(data)); 后面应该是 data2 吧。

引用 2 楼 fefe82 的回复:请提供完整的程序    int main(void) { 	//puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */ //	unsigned char str[16] ; //	unsigned char str1[8] ; //	sprintf(str, "0fbc400200000000"); //    CharToHex( str1, str, 16); //    printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", str1[0],str1[1],str1[2],str1[3],str1[4],str1[5],str1[6],str1[7]); //	unsigned long a = 100; //	printf("0x%03x", a); // //	char a[100] = "yhx"; //	      printf("siziof = %d\n",sizeof(a)); //	      printf("strlen = %d\n",strlen(a)); 	unsigned int id; 	unsigned char data[8]; 	int i, j, k; 	char data2[200]; 	memset(data, 0, sizeof(data)); 	memset(data2, 0, sizeof(data)); 	srand((unsigned)time(NULL)); //	{0,0,0x702,"0",0,"1a 2a 3a 4a 5a 6a 7a 8a"}, 	for(i = 0; i < 10; i++) 	{ 		switch(rand()%3+1) 		{ 		case 1 : 				id = 0x701; 				break; 		case 2 : 				id = 0x201; 				break; 		case 3 : 				id = 0x702; 				break; 		} 		printf("0x%x,", id); 	} 	puts("\n"); 	for(j = 0; j < 8; j++) 	{ 		data[j] = 1; 	} //	int a = 15; 	char *aa = "abc"; 	char b = 'a'; //	b = (char)a; 	printf("b = %c\n", b);  	printf("data[] = %s\n", *data); 	for(i = 0; i < sizeof(data); i++) 	{ 		printf("data[%d] = %d\n", i, data[i]); 	} //		printf("%d\n", id); //		for(j = 0; j < 8; j++) //		{ //			data[i] = (unsigned char)(rand()%4); //			printf("%c\n", data[i]); //		} //		sprintf(data2,"{0,0,0x%03x,""0"",0,"" %02x %02x %02x %02x %02x %02x %02x %02x""}""",\ //				id,data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); //	} //		printf("%s\n", data2);  	return EXIT_SUCCESS; }

每天回帖即可获得10分可用分！  四楼、五楼正解， 再说如果楼主把j换成其它整数，搞不好会在data[j]里面放入了不可打印字符，输出的时候当然就可能看不到了。。。

请提供完整的程序

注意下我是在ubuntu，eclipse环境下运行的


Question: 哪里错了？该怎么改？

按我的写就对了 #include <stdio.h> #include <time.h>  int main() {   int i = 0, x, r, get = 0, lost = 0, number;   int t1 = 0, t2 = 0;   char option, go;    do {     i++;     srand(time(0));     x = rand() % 12 + 1;     printf("=======================================================\n");     printf("Guesses Choice:\n");     printf("O-Odd E-Even L-Low M-Medium H-High N-Number\n");     printf("=======================================================\n");     printf("Enter your choice: ");     scanf("%c", &option);     getchar();     printf("Point at risk: ");      scanf("%d", &r);          switch (option) {                   case 'O':       case 'o':         printf("Odd number\n");         if( (x % 2) == 1) get = r;           else lost = r;         break;       case 'E':       case 'e':         printf("Even number\n");         if( (x % 2) == 0) get = r;           else lost = r;         break;       case 'L':       case 'l':         printf("Low number\n");         if(x <= 4) get = 2 * r;           else lost = r;         break;       case 'M':       case 'm':         printf("Medium number\n");         if(x >= 5 && x <= 8) get = 2 * r;           else lost = r;         break;       case 'H':       case 'h':         printf("High number\n");         if(x >= 9) get = 2 * r;           else lost = r;         break;       case 'N':       case 'n':         printf("A number\n");         printf("Enter your number: \n");         scanf("%d", &number);         if(x == number) get = 12 * r;           else lost = r;         break;       default:         printf("Try again!\n www.xlongjt.com");     }      printf("The winning number is %d.\n", x);     if(get > 0) printf("You won %d points.\n", get);    	  else printf("You lost %d points.\n", lost);    	t1 += get;    	t2 += lost;     printf("Continue (Y/N)? ");     scanf("%c", &go);     getchar();   } while (go == 'Y' || go == 'y');   printf("Total number of guesses: %d\n", i);   printf("Your current point: %d\n", t1 - t2);   system("pause"); }

scanf( "%c", &r); 只是读入一个字符,而你在输入时实际上输入的是:某个字符+Enter,Enter 产生的'\n' 也会停留在输入缓冲区中,下次调用 scanf( "%c", &number);或者scanf("%c", &go);时就会直接读到 ‘\n’ 而不是等待你再次输入! 因此，在scanf("%d", &r); 和 scanf("%d", &number); 后加getchar(); 即可。

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

少了一个#include <stdlib.h> 然后再所有要输入，但是可能输入错误的地方再输入后，加上清空输入缓冲区fflush(stdin)   #include <stdio.h> #include <stdlib.h> #include <time.h>  int main() {   int ret;   int i = 0, x, r, get = 0, lost = 0, number;   int t1 = 0, t2 = 0;   char option, go;    do {   	//这里加一个    	fflush(stdin);     i++;     srand(time(0));     x = rand() % 12 + 1;     printf("=======================================================\n");     printf("Guesses Choice:\n");     printf("O-Odd E-Even L-Low M-Medium H-High N-Number\n");     printf("=======================================================\n");     printf("Enter your choice: "); 	scanf("%c", &option); 	 	//这里加一个 	fflush(stdin);	 	//getchar();      printf("Point at risk: ");      ret = scanf("%d", &r);          //如果输入的不是数字，就清除输入流缓冲      if (ret == 0)     { 		fflush(stdin); 	}          switch (option) {                   case 'O':       case 'o':         printf("Odd number\n");         if( (x % 2) == 1) get = r;           else lost = r;         break;       case 'E':       case 'e':         printf("Even number\n");         if( (x % 2) == 0) get = r;           else lost = r;         break;       case 'L':       case 'l':         printf("Low number\n");         if(x <= 4) get = 2 * r;           else lost = r;         break;       case 'M':       case 'm':         printf("Medium number\n");         if(x >= 5 && x <= 8) get = 2 * r;           else lost = r;         break;       case 'H':       case 'h':         printf("High number\n");         if(x >= 9) get = 2 * r;           else lost = r;         break;       case 'N':       case 'n':         printf("A number\n");         printf("Enter your number: \n");         scanf("%d", &number);         if(x == number) get = 12 * r;           else lost = r;         break;       default:         printf("Try again!\n");     }      printf("The winning number is %d.\n", x);     if(get > 0) printf("You won %d points.\n", get);    	  else printf("You lost %d points.\n", lost);    	t1 += get;    	t2 += lost;     printf("Continue (Y/N)? \n");     //getchar();     fflush(stdin); 	scanf("%c", &go);        } while (go == 'Y' || go == 'y');   printf("Total number of guesses: %d\n", i);   printf("Your current point: %d\n", t1 - t2);   system("pause"); }


Question: 基于RTP的前向纠错（FEC）功能的编码输出

http://blog.csdn.net/mediapro/article/details/50393685  使用FEC改善UDP（RTP）音视频传输效果 www.mediapro.cc

板块发错，太专业

看来真的是没有人回复了


Question: C语言综合程序设计 急！！！

平时都是直接用的输入重定向，第一次这么做不知道对不对   #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h>  // 宏 根据某个学生的专业名判断是否对应某个专业 #define IS_PROFESSIONAL_TX(A) (strncmp(A,"通信",strlen("通信")) == 0 ) #define IS_PROFESSIONAL_WL(A) (strncmp(A,"网络",strlen("网络")) == 0) #define IS_PROFESSIONAL_WLW(A) (strncmp(A,"物联网",strlen("物联网")) == 0)  // 学生信息结构体 struct student { 	char *name; 	char *professinal_name; 	short score_english; 	short score_liner_algebra; 	short score_c_language; 	short score_all; };   // 各专业平均总成绩，学生总人数数组，枚举变量代表专业序号 enum avr_index{tx_index,wl_index,wlw_index}; short avr_score[3] = {0}; int stu_all[3] = {0};  // 读取filename指示的文件，将学生的信息从文件内容初始化到内存 // 三级指针为一个二级指针的地址，该指针在main中定义 // 二级指针的指向一段连续的地址，连续存放了一堆指向学生信息的指针的指针 // 一级指针指向学生信息结构体 int ReadStudentInfo(const char *filename, 							struct student*** pStudent) { 	FILE *fp = fopen(filename,"r"); 	if(fp == NULL) 		return -1; 	char buf[256]; 	bzero(buf,256); 	int count = 0; 	while(fgets(buf,256,fp) != NULL) 	{ 		count++; 	} 	// printf("%d\n",count); 	int i = 0; 	(*pStudent) = (struct student **) malloc (sizeof(struct student *) * count); 	for(i = 0; i < count; i++) 		(*pStudent)[i] = (struct student *) malloc(sizeof(struct student));  	fseek(fp,0,SEEK_SET); 	bzero(buf,256); 	char *buf_temp = NULL; 	char *buf_t = NULL; 	char a_temp[16]; 	bzero(a_temp,16); 	i = 0; 	int len = 0; 	while(fgets(buf,256,fp) != NULL && i < count) 	{ 		buf_t = buf; 		 		while(isspace(*buf_t))   //读取一行数据的学生名 			++buf_t; 		buf_temp = buf_t; 		while(!isspace(*buf_t)) 			buf_t++; 		len = (buf_t - buf_temp) + 1; 		(*pStudent)[i]->name = (char *)malloc(sizeof(char) * len); 		bzero((*pStudent)[i]->name,len); 		strncpy((*pStudent)[i]->name,buf_temp,len); 		// printf("=== %s\n",*pStudent[i]->name);  		while(isspace(*buf_t))   //读取一行数据的专业名 			++buf_t; 		buf_temp = buf_t; 		while(!isspace(*buf_t)) 			buf_t++; 		len = (buf_t - buf_temp) + 1; 		(*pStudent)[i]->professinal_name = (char *)malloc(sizeof(char) * len); 		bzero((*pStudent)[i]->professinal_name,len); 		strncpy((*pStudent)[i]->professinal_name,buf_temp,len); 		// printf("=== %s\n",*pStudent[i]->professinal_name);  		while(isspace(*buf_t))   //读取一行数据的英语成绩 			++buf_t; 		buf_temp = buf_t; 		while(!isspace(*buf_t)) 			buf_t++; 		len = (buf_t - buf_temp) + 1; 		bzero(a_temp,16); 		strncpy(a_temp,buf_temp,len); 		(*pStudent)[i]->score_english = atoi(a_temp);  		while(isspace(*buf_t))   //读取一行数据的线代成绩 			++buf_t; 		buf_temp = buf_t; 		while(!isspace(*buf_t)) 			buf_t++; 		len = (buf_t - buf_temp) + 1; 		bzero(a_temp,16); 		strncpy(a_temp,buf_temp,len); 		(*pStudent)[i]->score_liner_algebra = atoi(a_temp); 		 		while(isspace(*buf_t))   //读取一行数据的C成绩 			++buf_t; 		buf_temp = buf_t; 		while(isdigit(*buf_t)) 			buf_t++; 		len = (buf_t - buf_temp) + 1; 		bzero(a_temp,16); 		strncpy(a_temp,buf_temp,len); 		(*pStudent)[i]->score_c_language = atoi(a_temp);  		bzero(buf,256); 		i++; 	}   	fclose(fp); 	return count; }  // 统计各专业学生的总人数，总平均成绩，计算学生总成绩 // 三级指针为一个二级指针的地址，该指针在main中定义 // 二级指针的指向一段连续的地址，连续存放了一堆指向学生信息的指针的指针 // 一级指针指向学生信息结构体 // num为指针可以找到的学生总人数 void Count(struct student ***pStudent,int num) { 	int i = 0; 	enum avr_index index; 	for(i = 0; i < num; i++) 	{ 		(*pStudent)[i]->score_all = (*pStudent)[i]->score_english + (*pStudent)[i]->score_liner_algebra  										+ (*pStudent)[i]->score_c_language;  		if(IS_PROFESSIONAL_TX((*pStudent)[i]->professinal_name)) 			index = tx_index; 		else if(IS_PROFESSIONAL_WL((*pStudent)[i]->professinal_name)) 			index = wl_index; 	 	else if(IS_PROFESSIONAL_WLW((*pStudent)[i]->professinal_name)) 			index = wlw_index; 		else 			continue;   		stu_all[index]++; 		if(avr_score[index] == 0) 				{ 					avr_score[index] = (*pStudent)[i]->score_all; 				} 		else 		{ 			avr_score[index] += (*pStudent)[i]->score_all; 			avr_score[index] /= 2; 		}  	} }  // 打印各个学生的信息和总的统计信息 // 三级指针为一个二级指针的地址，该指针在main中定义 // 二级指针的指向一段连续的地址，连续存放了一堆指向学生信息的指针的指针 // 一级指针指向学生信息结构体 // num为指针可以找到的学生总人数 void InfoPrint(struct student ***pStudent,int num) { 	puts("学生信息:"); 	puts("___________________________"); 	printf("序号\t姓名\t专业\t英语成绩 线代成绩 C成绩 总成绩\t\n"); 	int i; 	for(i = 0; i < num; i++) 	{ 		printf("%d\t",i+1); 		printf("%s\t",(*pStudent)[i]->name); 		printf("%s\t",(*pStudent)[i]->professinal_name); 		printf("%d\t",(*pStudent)[i]->score_english); 		printf("%d\t",(*pStudent)[i]->score_liner_algebra); 		printf("%d\t",(*pStudent)[i]->score_c_language); 		printf("%d",(*pStudent)[i]->score_all); 		printf("\n"); 	} 	puts("统计信息:"); 	puts("___________________________"); 	printf("序号\t专业名称  学生人数  平均成绩\n"); 	for(i = 0; i < 3; i++) 	{ 		printf("%d\t",i+1); 		if(i == 0) 		printf("通信"); 		else if(i == 1) 		printf("网络"); 		else if(i == 2) 		printf("物联网"); 		printf("\t"); 		printf("%d\t",stu_all[i]); 		printf("%d",avr_score[i]); 		printf("\n"); 	}  }  int main(void) { 	struct student **pStudent  = (struct student **) malloc(sizeof(struct student *)); 	int count = ReadStudentInfo("a.txt",&pStudent); 	Count(&pStudent,count); 	InfoPrint(&pStudent,count);  	for   	return 0; }

楼上正解，楼主也需要自己动动手咯。。  你看设计说明的后面还有个实验步骤呢。。。。

这是详细设计文档了，就剩转化代码了 这个应该不是很复杂，一个一个实现试试吧


Question: c语言中switch语句，随便怎么输入都是显示的没有资格= =菜鸟求解释

谢谢啦

switch(age)

switch(age）就可以了，不要放式子，你放个表达式相当于拿ture或者false去和下面的23456对比


Question: 请输入远程路经或文件名…………

工程建错了, 你建了库工程, 应该是win32 控制台应用程序工程


Question: 求学生管理系统代码，谢谢了

这个也不是很难啊，作业自己做嘛。

这样的作业好像很简单爱！新手入门都可以写出来！这么简单的作业也不思考下自己做做啊？

引用 1 楼 u010165006 的回复:自己动手，心里多轻松 把功课补补吧，还来得及，每天看几页书，敲点代码验证一下，贵在坚持，坚持一个月就习惯了 自己写了有问题再上论坛比较好 坚持一段时间逐渐会有get的感觉，心里会充实


Question: 六度空间，BFS广度搜索，错在哪

将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施”：//不带表头结点的单向链表 #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-> //   十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中


Question: C语言，帮忙看看哪错了！

#include<stdio.h>  char toup(char ch) { 	ch=ch+'A'-'a'; 	return ch; }  char tolow(char ch) { 	ch=ch+'a'-'A'; 	return ch; }  int main(){ 	int choice;  	for(;;) { 		printf("请选择：1.将小写转化为大写   2.将大写转化为小写   3.   退出程序\n"); 		scanf("%d",&choice); 		getchar();  		if (choice==1) { 			char ch = 0; 			printf("请输入：º\n");  			while (ch!='\n'){ 				ch=getchar(); 				if (ch<'a'||ch>'z') 					break; 				ch=toup(ch); 				putchar(ch); 			} 		}  		else if (choice==2) { 			char ch = 0;  			printf("请输入：\n");  			while (ch!='\n'){ 				ch=getchar(); 				if (ch<'A'||ch>'Z') 					break; 				ch=tolow(ch); 				putchar(ch); 			} 		} 		else if (choice==3) 			return 0;  		printf("输入错误，请重新输入\n\n"); 	}  }

引用 2 楼 qq_33176571 的回复:[quote=引用 1 楼 user-2 的回复:] 你在获取choice的值时，有一个enter留在缓存区中 ，被getchar（）得到，所以中断循环。我刚新手的时候也总是发生这种情况，等你学到输入输出函数，了解多些就能理解了  那该如何清除这个enter呢？[/quote]  我懂了，用这个char ch;while((ch = getchar()) != '\n' && ch != EOF); 谢谢

引用 1 楼 user-2 的回复:你在获取choice的值时，有一个enter留在缓存区中 ，被getchar（）得到，所以中断循环。我刚新手的时候也总是发生这种情况，等你学到输入输出函数，了解多些就能理解了  那该如何清除这个enter呢？


Question: 我是个新手啦，不太了解静态函数的作用

静态函数就是你这个函数只能在定义它的文件内使用，方便程序员查找，可以免得其它文件误调用


Question: C语言编写素数伴侣的问题！！

引用 1楼lm_whales 的回复:把数据分成奇偶两组，奇数只能找偶数，偶数只能找奇数 或者先求出。 素数，然后 拆分素数，去重分组很有必要，然后还是需要穷举？

引用 2楼user-2 的回复:这个规模并不大啊，穷举就好了。  一共才 100 个数，不到 5000 个组合。筛一个 60000 以内的素数表出来，逐个尝试就行。  关键问题在于如何求出最多的对数。假设奇偶各50个且各不相同，组合就有50！种组合，你说5000个是怎么计算的？

最大系数的拆分方案，包含了所有素数的拆分方案 你需要的是在这些拆分方案里面，找到其他所有素数的拆分方法。

每个素数，都可以拆分成比他小的奇数和一个偶数之和 这些奇数，包含比他小的素数。 我感觉这个关系，是可以利用的。 至于如何利用，只能耐心的分析了


Question: 测试时，出现的错误改不来，大神求帮助

for(int i=0,mid=0;i<3;i++) 这种把i定义在前面 int i,mid; for(i=0,mid=0;i<3;i++)

编译时加选项 -std=c99

#include<stdio.h> void Max(int a[3][4],int b[3]){     for(int i=0,mid=0;i<3;i++)     {         for(int j=1;j<4;j++)         {             if(a[i][j-1]>a[i][j])                 mid=a[i][j-1];             else mid=a[i][j];         }         printf("%d ",mid);      }  } int main() {     int a[3][4],b[3];     printf("请输入一个3*4的矩阵\n");     for(int i=0;i<3;i++)     for(int j=0;j<4;j++)     scanf("%d",&a[i][j]);     Max(a,b);     return 0; } 用C++

#include<stdio.h> void Max(int a[3][4],int b[3]) {     int i;     for(i=0;i<3;i++)     {         int j; 		b[i] = a[i][0];         for(j=1;j<4;j++)             if(a[i][j]>b[i])                 b[i] = a[i][j];     } } int main() {     int a[3][4],b[3];     int i;     printf("请输入一个3*4的矩阵\n");        for(i=0;i<3;i++)     {         int j;         for(j=0;j<4;j++)             scanf("%d",&a[i][j]);     }     Max(a,b); 	for(i=0;i<3;i++) 		printf("%d\n", b[i]);      return 0; }

引用'for' loop initial declarations are only allowed in C99 mode 仅C99模式下允许for循环的初值声明  标准C下，所有声明必须放在最前，把i和j的声明放到函数的最前面就行了。

把源文件的扩展名改为.cpp也行

C++下没有问题，可能C语言不允许，你把for语句中的变量放到外面定义   #include<stdio.h> void Max(int a[3][4],int b[3]) { 	int i, mid; 	for(i=0,mid=0;i<3;i++) 	{ 		int j; 		for(j=1;j<4;j++) 		{ 			if(a[i][j-1]>a[i][j]) 				mid=a[i][j-1]; 			else mid=a[i][j]; 		} 	} 	printf("%d",b); } int main() { 	int a[3][4],b[3]; 	int i = 0; 	printf("请输入一个3*4的矩阵\n");	 	for(i=0;i<3;i++) 	{ 		int j; 		for(j=0;j<4;j++) 			scanf("%d",&a[i][j]); 	} 	Max(a,b); 	return 0; }


Question: 这个哪里错了？应该怎么改？

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

第二个for循环内的复合语句打{}，否则执行到if语句的时候j=4了

if(k!=x)  //k已经为4

引用 1楼user-4 的回复:第一次执行if(a[j]<a[k]) 这句时 j = 5了，也就是说越界了第一次j不应该为1吗？

引用 2楼chehw_1 的回复:引用for(j=x+1;j<n;j++); 多了个“;”复制出错啦看看过程

引用for(j=x+1;j<n;j++); 多了个“;”

第一次执行if(a[j]<a[k]) 这句时 j = 5了，也就是说越界了


Question: 一道C语言的问题，，求大神帮忙解答。。。谢谢，帮帮忙吧

引用 5 楼 qq_26347849 的回复:[quote=引用 3 楼 baidu_33185996 的回复:] 测试时出现这个错误 D:\CB-Irellia\1.12\main.c:21:5: error: 'for' loop initial declarations are only allowed in C99 mode  这个错误怎么改啊？ 没见过这个错误的类型，他说你的for循环有问题。这个。。。[/quote] 楼主的编译器不支持C99语法，把i的定义单独些出来吧。

引用 3 楼 baidu_33185996 的回复:测试时出现这个错误 D:\CB-Irellia\1.12\main.c:21:5: error: 'for' loop initial declarations are only allowed in C99 mode  这个错误怎么改啊？ 没见过这个错误的类型，他说你的for循环有问题。这个。。。

http://bbs.csdn.net/topics/391866596  此贴处已帮你改好

你很急，我就在这里直接写的，没有调试。你自己再小修一下就好了

void Max(int a[3][],  int b[]){     for(int i=0,mid=0;i<3;i++){           for(int j=1;j<4;j++){                  if(a[i][j-1]>a[i][j])mid=a[i][j-1];                  else mid=a[i][j];            }            b[i]=mid;      }      printf("%d",b); }  int main() {     int a[3][4],b[3];     printf("请输入一个3*4的矩阵\n");     for(int i=0;i<3;i++)        for(int j=0;j<4;j++)             scanf("%d",&a[i][j]);     Max(a,b);     return 0; }


Question: 结构体成员又是结构体的问题。

已经解决啦。。

scanf("%d",&a.date.n);     scanf("%s",a.date.name);     scanf("%d",&a.date.age);

再加一句，重点是指针引用的方法为啥错。


Question: 求帮忙

楼主，按照下面的步骤应该没有问题           http://www.cnblogs.com/fnng/archive/2011/07/18/2110023.html

贴出错误信息


Question: C语言 问一个有关文件的问题

引用 6 楼 songxinjianqwe 的回复:[quote=引用 5 楼 paschen 的回复:] 你写文件时，结构体中是char name[10];  读的时候那个结构体变成了char name[20]; 恩改成一样的就可以了 请问是什么原因呢[/quote]  你怎么存的就要怎么读，不然就读错位了显示出来当然不对了。。你错写之后sizeof(struct Student)的值就不同了

引用 5 楼 paschen 的回复:你写文件时，结构体中是char name[10];  读的时候那个结构体变成了char name[20]; 恩改成一样的就可以了 请问是什么原因呢

目测楼主在控制台输入数据时格式有误

引用 2 楼 paschen 的回复:结构体中变量一个个保存 ...木有看懂

结构体中变量一个个保存

附上两张图


Question: 请教注册表操作

注册表有两份，一份是64位的，一份是32位的。


Question: 急！C语言的一个小问题，关于跳出循环

这是C,C++ 设计的一个bug 循环和switch 不应该共享这个关键字。

引用 4 楼 Jammg 的回复:if((check1==1&&check2==1)&&(check3==1&&check4==1)) break;  }       <----- 这里这个括号对应的是switch的，不会跳出for循环  。。。我好傻，太谢谢你了！！！

#include<stdio.h> #include<stdlib.h> #include<time.h>  #define ASPECT 4  int main() { 	char map[10][10]; 	int i,j,check1=0,check2=0,check3=0,check4=0; 	int direction; 	 	for(i=0;i<10;i++) 		for(j=0;j<10;j++) 			map[i][j]='.';  	i=0; 	j=0; 	map[i][j]='A'; 	 	srand((unsigned) time(NULL)); 	 	for(;;){	 		direction=rand() %ASPECT; 		switch (direction) { 			case 0:  			{ 				if (map[i-1][j]=='.'&&(1<=i&&i<=9)){ 					i-=1; 					map[i][j]=map[i+1][j]+'B'-'A'; 					check1=0; 					check2=0; 					check3=0; 					check4=0; 					} 				else 					check1=1;	 				break;		 			} 			case 1:  			{ 				if (map[i+1][j]=='.'&&(0<=i&&i<=8)){ 					i+=1; 					map[i][j]=map[i-1][j]+'B'-'A'; 					check1=0; 					check2=0; 					check3=0; 					check4=0; 					} 				else 					check2=1;	 				break;		 			} 			case 2:  			{ 				if (map[i][j-1]=='.'&&(1<=j&&j<=9)){ 					j-=1; 					map[i][j]=map[i][j+1]+'B'-'A'; 					check1=0; 					check2=0; 					check3=0; 					check4=0; 					} 				else 					check3=1;	 				break;		 			} 			case 3:  			{ 				if (map[i][j+1]=='.'&&(0<=j&&j<=8)){ 					j+=1; 					map[i][j]=map[i][j-1]+'B'-'A'; 					check1=0; 					check2=0; 					check3=0; 					check4=0; 					} 				else 					check4=1;	 				break;		 			}  			if(map[i][j]=='Z')  				break; 			 			if((check1==1&&check2==1)&&(check3==1&&check4==1)) 				break;	 		} 	} 			 	for(i=0;i<10;i++){ 		for(j=0;j<10;j++) 			printf("%c",map[i][j]); 		printf("\n"); 	} 	 	return 0;	 	 }  重发一下

引用 1 楼 HQ1356466973 的回复:看你写的代码我就蛋疼了，格式好乱啊  不好意思，c-free复制黏贴过来空格都没了，你主要看看 if(map[i][j]=='Z')  break;  if((check1==1&&check2==1)&&(check3==1&&check4==1)) break;	 这 为什么跳不出来，我调试出来的结果满足if的条件啊

看你写的代码我就蛋疼了，格式好乱啊


Question: C使用Socket类传输文件，怎么样知道传输的速度是多少呢？

自已计算用了多少时间，传输了多少大小数据得到


Question: 关于strcpy与二级指针的问题

必然错。二级指针你可以看成指针型的数组。你现在只给数组里面的指针自身分配了空间，但是指针全是野指针。

char **oldlist = (char **)malloc(sizeof(char *) * 1024);  你只是给指针分配了内存，但是并没有给指针指向的字符串分配空间，oldlist指针数组里全是野指针 并且strlen返回长度不包含'\0'，分配内存时需注意。  oldlist[n] = (char *)malloc(sizeof(char *) * (len + 1);

二维数组分配内存不是像你这样分配的吧：char **oldlist = (char **)malloc(sizeof(char **) * 1024);

59         int len = strlen(dir->d_name);  60         char *ptmp = (char *)malloc(sizeof(char *) * len);  61         strcpy(ptmp, dir->d_name);  62         *oldlist = (char *)malloc(sizeof(char *) * len);  63         strcpy(*(oldlist + n++), ptmp);  64     //  oldlist[n++] = ptmp;  依然出错

难道 二级指针取×号后，不能用strcpy 进行赋值吗。

以上不管如果 ，编译 都 是通过的。

上面复制的时候没注意，sizeof里应该是char，char *是另一回事了 oldlist[n] = (char *)malloc(sizeof(char) * (len + 1);


Question: C语言字符串求解

引用 3 楼 tnl159753 的回复:[quote=引用 1 楼 user-2的回复:]while(*--t != 'I')  用*t--来判断时会多减一次。 谢谢，我懂了，这个怎么给分，第一次用[/quote]  结帖可以给分

引用 1 楼 user-2的回复:while(*--t != 'I')  用*t--来判断时会多减一次。 谢谢，我懂了，这个怎么给分，第一次用

最后还会多减一次，可以最后给i的值加1

while(*--t != 'I')  用*t--来判断时会多减一次。


Question: 新手求助 c语言 选择排序问题

/* **选择排序 ,每轮循环，把最大值放在第一位，第二大值放在最后  */ #include <stdio.h>  void print_s(int *p,int n); void selectionsort(int *p,int n); int main() { 	//int arr[]={1,2,3,4,5,6};	 	int arr[] = {21,48,29,12,34};	 	int num = sizeof(arr)/sizeof(*arr); 	print_s(arr,num); 	selectionsort(arr,num); 	print_s(arr,num);	 	return 0;  }    void selectionsort(int *p,int n) { 	int i,j,tmp; 	int max,smax; 	for (i=0;i<n-1-i;i++) 	{ 		max = i; 		smax = n-1-i; 		//开始时，将第1位设为最大，最后1位设置为次最大。 		//如果smax大于max，则交换。  		if (p[smax]>p[max]) 		{ 			tmp = p[smax]; 			p[smax] = p[max]; 			p[max] = tmp; 		} 		for (j=i+1;j<=n-1-i;j++) 		{	 			//如果j大于max，先将max放在次最大smax上，再将j放到max上。  			if (p[j] > p[max]) 			{ 				tmp = p[smax]; 				p[smax] = p[max]; 				p[max] = tmp; 							 				tmp =p [max]; 				p[max] = p[j]; 				p[j] = tmp; 			}  			//如果j在max 和smax之间，则是为次最大，交换 j与smax即可  			else if (p[max] > p[j] && p[j] > p[smax]) 			{ 				tmp = p[smax]; 				p[smax] = p[j]; 				p[j] = tmp; 			} 		} 	}	 }   void print_s(int *p,int n) { 	int i; 	for (i = 0;i<n;i++) 	{ 		printf("%d ",*(p+i)); 	} 	printf("\n"); }

引用 1 楼 陈年风楼的回复:放一个i从0到n-1跑，放一个j从i+1到n-1跑，两层循环，非降序排的话，如果i指的元素大于j指的元素，就交换。输出自己加 抱歉看错问题╭(°A°`)╮（尴尬～


Question: 经过哈夫曼编码后的文章，如何控制每一个bit输出到二进制文件

可以移位 哈夫曼编码，第一步 把码表写入文件 接着才是文件的哈夫曼 编码 码表写入后，  读取原文，按表读取编码c和位数b。 剩余编码r，移位b 位， 把编码c 或到r上  够8bits 则取走8 bit  剩余位数保留在r上 哈夫曼编码是前缀码，每个原文代码（通常为一个字符），被编成一定位数的，一定编码的哈夫曼码。 所以可以用原文作索引，查找哈夫曼表，一一对译。 哈夫曼表的生成，才是哈夫曼编码，最精致，最核心，最关键的内容。 关系到压缩率的大小。

引用 5 楼 lm_whales 的回复:待编码数据 a[N]; 编码余项 r 逐次取a[i] 编码到r后面，r够 8Bits储存之不够继续下一轮处理 如此即可 最后剩下 r 补齐输出 我也想过这个方法，但是要读出原文，能一个一个bit读吗？ 还有，能不能麻烦给出实现这个操作bit的方法代码？谢谢

够8Bit就输出，不够就继续处理下一批数据， 最后一个数据，补齐即可

我的主要问题是如何控制bit的输出到文件中，比如二进制码是100，没有到8位，我也不想补齐8位成为char类型输出。就想只是输出二进制码100到二进制文件中。为的是节约内存空间（相当于压缩文件）。就这个怎么实现。求大神帮忙解决

你需要哪几个位上的值， 就让该数与 需要的位为1、其他位为0的一个数做AND运算，然后将结果移位后就是你需要的数了

查表就可以了


Question: openssl 验证证书的bug ?

BEGIN/END之外的不是证书的内容， 当注释就可以了， 之间的数据包含了你需要的所有东西， 如果你不乱改， 用之间的数据可以把这部分内容重新生成出来，大部分地方保存 PEM 证书也不保存 BEGIN/END 之外的东西。

引用 6 楼 mLee79 的回复:不是说了么， PEM格式的文件 只看 BEGIN/END 之间的数据， 其他的是给人看的， 随便改， 无意义。 这个文件里 BEGIN/END 间是 base64 编码的 der 格式的 X509 证书。   1.   Signature Algorithm: sha1WithRSAEncryption   这句话已经很明显，告知该 begin /end 之间的hash值（加密过的）   2.     Public Key Algorithm: rsaEncryption                 Public-Key: (2048 bit)                 Modulus:                     00:c5:a3:86:8d:7d:21:d8:c9:0b  这个  不就是用户证书的公钥吗？   用户证书 的目的—— 证明公钥的合法，公钥都被改了， 难道还不报错。   这才是我反复追问你的原因！！！！   好，如果我们按照你的逻辑，是不是可以说明， 发送方，只需要读取begin /end之间的内容，然后socket发送？  其他内容都不需要管了？   收方收到后，然后验证being/end之间的内容？    这毕竟不是小事，不能不追问？

up 起来

之间之间 你也把 BEGIN/END 带着啊， PEM就认这几个标志啊..

引用 9 楼 mLee79 的回复:交换证书的时候是对 BEGIN/END 间数据做 base64 解码后发送，发这种 b64编码后的数据也太浪费带宽了.. 你把 BEGIN/END 之间的数据存成个文件， 然后用 openssl x509 -in 1.pem -text  看看。  openssl verify 1.pem  unable to load certificate 140215703820104:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: TRUSTED CERTIFICATE

BEGIN/END 之间的是真正的证书数据， BASE64 编码的 DER格式的 X.509 证书， 之外的是给人看的， 随便改..

引用 1 楼 user-2 的回复:没加密的证书？  是啊  pem格式，就是典型的文本模式，  谁遇到， 最近要用， 用过的人，发个例子，

没加密的证书？


Question: 关于C语言结构体中的指针问题

谢谢你了！学习了！

if(tmp[i].name == NULL)	return -1; tmp[i].name = "hjs"; 字符串不能这么赋值，改成 strcpy 即可，并且要注意不要越界。 指针不带这么玩的，这么玩，分配的内存，丢失了，无从释放，标准的内存泄露 而 free 指向常量（串字面值） "hjs" 的指针tmp[i].name 是个错误，所以  if(stu[i].name != NULL){ free(stu[i].name); printf("%d\n", i);  }这段程序，会出错也很正常。


Question: 求救！！！编写程序对表达式求值（从左向右运算，不计符号优先级）

引用 2 楼 paschen 的回复:你处理过程写的是对的，关键是跳不出循环，帮你改成这样：   #include<stdio.h>  float arithmetic(float x,char ch,float y) { switch (ch) {     case '+' : return (x+y); break;   case '-' : return (x-y); break;     case '*' : return (x*y); break;    case '/' : return (x/y); break;    }  }  int main() { 	float a[20]; 	float n=1; 	char ch='*'; 	int i=0;   	printf("Enter an expression:");  	while (ch!='\n') { 		if (i==0) 			scanf("%f",&a[i]); 		else  		{ 			scanf("%c",&ch); 			if(ch=='\n') 				break; 			scanf("%f",&a[i]); 		}  		n=arithmetic(n,ch,a[i]);  		i++;  	}  	printf("Value of expression:%.1f",n);  	return 0;  } 建议把printf("Value of expression:%.1f",n);中的%.1f改成%g，这样不止一位小数的也能准确输出而且没有多余的0

楼上的n=1有点问题，只能算1开头的算式。。 改成这样就对了 #include<stdio.h> float cal(float x,char ch,float y){   switch (ch) {   case '+':return(x+y);break;   case'-':return(x-y);break;   case'*':return(x*y);break;   case'/':return(x/y);break; } }  int main() { 	float a[50]; 	float n; 	char ch; 	int i=0;  	printf("Enter an expression:");  	while (ch!='\n'){ 		if(i==0){ 			scanf("%f",&n); 			scanf("%c",&ch); 			scanf("%f",&a[i]); 			n=cal(n,ch,a[i]); 			i++; 		} 		else 		   scanf("%c",&ch); 			if(ch=='\n') 				break; 			scanf("%f",&a[i]); 			n=cal(n,ch,a[i]); 			i++; 		  	 	}  	printf("Value of expression:%.1f",n);  	return 0; }

引用 2 楼 paschen 的回复:你处理过程写的是对的，关键是跳不出循环，帮你改成这样：   #include<stdio.h>  float arithmetic(float x,char ch,float y) { switch (ch) {     case '+' : return (x+y); break;   case '-' : return (x-y); break;     case '*' : return (x*y); break;    case '/' : return (x/y); break;    }  }  int main() { 	float a[20]; 	float n=1; 	char ch='*'; 	int i=0;   	printf("Enter an expression:");  	while (ch!='\n') { 		if (i==0) 			scanf("%f",&a[i]); 		else  		{ 			scanf("%c",&ch); 			if(ch=='\n') 				break; 			scanf("%f",&a[i]); 		}  		n=arithmetic(n,ch,a[i]);  		i++;  	}  	printf("Value of expression:%.1f",n);  	return 0;  }   太感谢了！！！完美的解决了我的问题！！！

引用 1 楼 Gdreamlend 的回复:给下建议或者思路吧：  if (i==0)	这个判断可以换掉  1.先把整个表达式输入进来， 2.然后判断字符串中的每个字符是不是数字， 3.如果是数字赋值给a, 4.否则赋值给c, 5.然后如果是数字赋值给b  6.这时应该去调用你的计算函数，得到中间结果d 7.然后这时的a=d,  8如果输入的字符串并没有读完 循环上面的 5及后面步骤  虽然和我想的不一样，但提供了不一样的思路还是谢谢你！


Question: C语言闪之轨迹卡牌Blade游戏AI求教

c语言？醒醒吧，c语言你写个界面都麻烦的要死，还要先学习win APi编程，建议lz考虑别的编程语言

首先，我决定游戏里面那个ai感觉很一般啊，基本就是先手的话出最小的牌，然后你出稍大一点的他有雷就放雷，再大就镜子，基本达不到玩家的水平吧，不过感觉这游戏还是很靠手气的，毕竟到最后就是大牌的较量了

你这lab么。。。


Question: sed -i '1d' test3 | sed -i 's/"//g' test3 | wc - C语言 linux下写法

已完成 谢谢

sed --help


Question: 杨辉三角

不知道你是否记得这一道题  用for输出                                    *                                ***                              *****                            *******                              *****                                ***                                  *                          本质上基本一样在输出的时候再加一个for就行了

仅供参考：#include <stdio.h> #define MAXN 10 unsigned __int64 y[MAXN][MAXN]; int i,j; char s[60]; void main() {     printf("%30s\n","1  ");     printf("%33s\n","1     1  ");     y[1][0]=1ui64;y[1][1]=1ui64;     for (i=2;i<MAXN;i++) {         y[i][0]=1ui64;sprintf(s,"1  ");         for (j=1;j<=i-1;j++) {             y[i][j]=y[i-1][j-1]+y[i-1][j];             sprintf(s,"%s   %-3I64u",s,y[i][j]);         }         y[i][i]=1ui64;sprintf(s,"%s   1  ",s);         printf("%*s\n",30+i*3,s);     } } //                           1 //                        1     1 //                     1     2     1 //                  1     3     3     1 //               1     4     6     4     1 //            1     5     10    10    5     1 //         1     6     15    20    15    6     1 //      1     7     21    35    35    21    7     1 //   1     8     28    56    70    56    28    8     1 //1     9     36    84    126   126   84    36    9     1

把它当作4*7的矩阵,除数字部分,其余都为空格.

你首先要知道你会输出多少行，然后做一个for递减或者while递减的，从第一行开始打印空格就行了


Question: 为什么我这个数组越界的程序无法运行

引用 4 楼 caterpillarous 的回复:[quote=引用 3 楼 user-1 的回复:] [quote=引用 2 楼 caterpillarous 的回复:] [quote=引用 1 楼 user-1 的回复:] 去年/Gs（缓冲区溢出安全检查选项） 只有VS中有个这个选项吗。。其他编译器里我都搜不到。。VC++6.0可以关闭GS吗[/quote]  现在编译器一般默认会采取一些措施防止缓冲区溢出攻击，以下资料收集于网络：    对抗缓冲区溢出攻击： 栈随机化 为了在系统中插入攻击代码，攻击者不但要插入代码，还要插入指向这段代码的指针，这个指针也是攻击字符串的一部分。产生这个指针需要知道这个字符串放置的栈地址。在过去，程序的栈地址非常容易预测，在不同的机器之间，栈的位置是相当固定的。 栈随机化的思想使得栈的位置在程序每次运行时都有变化。因此，即使许多机器都运行相同的代码。它们的栈地址都是不同的。 实现的方式是：程序开始时，在栈上分配一段0--n字节之间的随机大小空间。程序不使用这段空间，但是它会导致程序每次执行时后续的栈位置发生了变化。 在Linux系统中，栈随机化已经变成了标准行为。（在linux上每次运行相同的程序，其同一局部变量的地址都不相同）  栈破坏检测 在C语言中，没有可靠的方法来防止对数组的越界写，但是，我们能够在发生了越界写的时候，在没有造成任何有害结果之前，尝试检测到它。 最近的GCC版本在产生的代码中加入了一种栈保护者机制，用来检测缓冲区越界，其思想是在栈中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀值。这个金丝雀值是在程序每次运行时随机产生的，因此，攻击者没有简单的办法知道它是什么。 在恢复寄存器状态和从函数返回之前，程序检查这个金丝雀值是否被该函数的某个操作或者函数调用的某个操作改变了。如果是，那么程序异常终止。  限制可执行代码区域 限制那些能够存放可执行代码的存储器区域。在典型的程序中，只有保存编译器产生的代码的那部分存储器才需要是可执行的，其他部分可以被限制为只允许读和写。 现在的64位处理器的内存保护引入了”NX”(不执行)位。有了这个特性，栈可以被标记为可读和可写，但是不可执行，检查页是否可执行由硬件来完成，效率上没有损失。[/quote] 你好 我还想请教一个问题 我写了一个C++程序 是先声明子函数然后声明主函数的 然后我看了一下函数的入口地址，主函数是在高地址的，我觉得是先声明先在内存中定义的啊，为什么是主函数先定义的呢 先谢过[/quote]  主函数在高地址是后定义不是先定义！

引用 3 楼 user-1 的回复:[quote=引用 2 楼 caterpillarous 的回复:] [quote=引用 1 楼 user-1 的回复:] 去年/Gs（缓冲区溢出安全检查选项） 只有VS中有个这个选项吗。。其他编译器里我都搜不到。。VC++6.0可以关闭GS吗[/quote]  现在编译器一般默认会采取一些措施防止缓冲区溢出攻击，以下资料收集于网络：    对抗缓冲区溢出攻击： 栈随机化 为了在系统中插入攻击代码，攻击者不但要插入代码，还要插入指向这段代码的指针，这个指针也是攻击字符串的一部分。产生这个指针需要知道这个字符串放置的栈地址。在过去，程序的栈地址非常容易预测，在不同的机器之间，栈的位置是相当固定的。 栈随机化的思想使得栈的位置在程序每次运行时都有变化。因此，即使许多机器都运行相同的代码。它们的栈地址都是不同的。 实现的方式是：程序开始时，在栈上分配一段0--n字节之间的随机大小空间。程序不使用这段空间，但是它会导致程序每次执行时后续的栈位置发生了变化。 在Linux系统中，栈随机化已经变成了标准行为。（在linux上每次运行相同的程序，其同一局部变量的地址都不相同）  栈破坏检测 在C语言中，没有可靠的方法来防止对数组的越界写，但是，我们能够在发生了越界写的时候，在没有造成任何有害结果之前，尝试检测到它。 最近的GCC版本在产生的代码中加入了一种栈保护者机制，用来检测缓冲区越界，其思想是在栈中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀值。这个金丝雀值是在程序每次运行时随机产生的，因此，攻击者没有简单的办法知道它是什么。 在恢复寄存器状态和从函数返回之前，程序检查这个金丝雀值是否被该函数的某个操作或者函数调用的某个操作改变了。如果是，那么程序异常终止。  限制可执行代码区域 限制那些能够存放可执行代码的存储器区域。在典型的程序中，只有保存编译器产生的代码的那部分存储器才需要是可执行的，其他部分可以被限制为只允许读和写。 现在的64位处理器的内存保护引入了”NX”(不执行)位。有了这个特性，栈可以被标记为可读和可写，但是不可执行，检查页是否可执行由硬件来完成，效率上没有损失。[/quote] 你好 我还想请教一个问题 我写了一个C++程序 是先声明子函数然后声明主函数的 然后我看了一下函数的入口地址，主函数是在高地址的，我觉得是先声明先在内存中定义的啊，为什么是主函数先定义的呢 先谢过

引用 2 楼 caterpillarous 的回复:[quote=引用 1 楼 user-1 的回复:] 去年/Gs（缓冲区溢出安全检查选项） 只有VS中有个这个选项吗。。其他编译器里我都搜不到。。VC++6.0可以关闭GS吗[/quote]  现在编译器一般默认会采取一些措施防止缓冲区溢出攻击，以下资料收集于网络：    对抗缓冲区溢出攻击： 栈随机化 为了在系统中插入攻击代码，攻击者不但要插入代码，还要插入指向这段代码的指针，这个指针也是攻击字符串的一部分。产生这个指针需要知道这个字符串放置的栈地址。在过去，程序的栈地址非常容易预测，在不同的机器之间，栈的位置是相当固定的。 栈随机化的思想使得栈的位置在程序每次运行时都有变化。因此，即使许多机器都运行相同的代码。它们的栈地址都是不同的。 实现的方式是：程序开始时，在栈上分配一段0--n字节之间的随机大小空间。程序不使用这段空间，但是它会导致程序每次执行时后续的栈位置发生了变化。 在Linux系统中，栈随机化已经变成了标准行为。（在linux上每次运行相同的程序，其同一局部变量的地址都不相同）  栈破坏检测 在C语言中，没有可靠的方法来防止对数组的越界写，但是，我们能够在发生了越界写的时候，在没有造成任何有害结果之前，尝试检测到它。 最近的GCC版本在产生的代码中加入了一种栈保护者机制，用来检测缓冲区越界，其思想是在栈中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀值。这个金丝雀值是在程序每次运行时随机产生的，因此，攻击者没有简单的办法知道它是什么。 在恢复寄存器状态和从函数返回之前，程序检查这个金丝雀值是否被该函数的某个操作或者函数调用的某个操作改变了。如果是，那么程序异常终止。  限制可执行代码区域 限制那些能够存放可执行代码的存储器区域。在典型的程序中，只有保存编译器产生的代码的那部分存储器才需要是可执行的，其他部分可以被限制为只允许读和写。 现在的64位处理器的内存保护引入了”NX”(不执行)位。有了这个特性，栈可以被标记为可读和可写，但是不可执行，检查页是否可执行由硬件来完成，效率上没有损失。

引用 1 楼 user-1 的回复:去年/Gs（缓冲区溢出安全检查选项） 只有VS中有个这个选项吗。。其他编译器里我都搜不到。。VC++6.0可以关闭GS吗

去年/Gs（缓冲区溢出安全检查选项）


Question: 初学指针，求助逆序输出字符串

懂了 谢谢!

while(*p)p++;   //这个循环后， p在字符串末尾 p--;   //往前一位，指向/0前面一位 while(p>=s)   //只要p在s后就循环（s是字符串首地址） { printf("%c",*p);  //输出p当前字符 p--;   //递减p         }  }

意思就是到最后一个字符后再倒叙输出直到第一个  但是s【】没有初始化你确定这个程序能正常运行么？ 超出输入字符数范围后能正确返回0或false么？


Question: C语言问题

有没有发现你的  c和 buf[BUFSIZE]都没初始化

你把一个float类型的数当字符操作。。


Question: 求解。。。为什么求不出鞍点

你的代码有点乱，使用的变量太多，变量名称也不易分辨含义。 稍微改写了一下（为了简化代码并便于测试，在示例中直接给a赋值）：   #include<stdio.h>  int main(int argc, char ** argv) { 	int a[3][3] = {	{2, 4, 1}, 				{3, 5, 7}, 				{1, 6, 9} 					}; 	 	int row, col, i; 	int max; 	int saddles_count = 0;  	row = 0; 	while(row < 3) 	{ 		max = a[row][0]; 		col = 0; 		 		// 找出当前行（row）中的最大值所在的列(col) 		for(i = 1; i < 3; i++) 		{ 			if(a[row][i] > max)  			{ 				max = a[row][i]; 				col = i; 			} 		} 		 		// 判断此值是否为该列上的最小值 		for(i = 0; i < 3; i++) 		{ 			if(a[i][col] < max) break;  		} 		 		// 不是最小值时，i 必小于3 		if(i == 3)  		{ 			saddles_count++; 			printf("saddle point @(%d, %d) = %d\n", row, col, a[row][col]); 		} 		row++; 	} 	 	printf("saddle points count = %d\n", saddles_count);	 	 	return 0; }

... max=a[i][0]; n = 0; //此处为新添加行 for(j=0;j<3;j++) ...   printf("鞍点数为%d",a[i][n]); // 把“j" 改为 "n"

所以我应该怎么修改呢，，，而且[3][n]是没有的，只有a[2][n]

z=1; for(k=0;k<3;k++){ if(max>a[k][n])         z=0;          }       你的结果跟你最后max和a［3］［n］有关系，跟之前的没关系。所以不出


Question: 八皇后的问题

不知道你的思路，代码很难看懂啊，这是以前学的时候写的，有循环和递归两个版本，你可以对照看一下，没有画图，只生成了结果数组 #include <iostream>  using namespace std;   bool place(int *x, int k) { 	for(int i=1;i<k;i++) 	{ 		if((x[i]==x[k]) || (abs(x[i]-x[k])==abs(i-k))) 			return false; 	} 	return true; }  void n_queens(int n) { 	int *x = new int[n+1]; 	for(int i=0;i<n+1;++i) x[i]=0;  	int k=1;//k表示当前搜索的行数，从第1行开始 	x[1]=0;//x[1]是解向量第一个元素，为跟以后的循环匹配，先赋值给0，其实是从1开始的 	while(k>0)//控制行，只要大于0，证明搜索在第0行以下进行 	{ 		//start 找到符合条件的列 		x[k]=x[k]+1;//从下一列开始，因为不能同列 		while((x[k]<=n)&&(!place(x,k)))//找到下一个满足条件的列 			x[k]=x[k]+1;//后移一列 		//end 找到符合条件的列 		if(x[k]<=n)//有符合条件的列 		{ 			if(k==n)break;//搜索完成，跳出循环 			else//搜索没有完成(得到的是部分解) 			{ 				k=k+1;//搜索下一行 				x[k]=0;//下一行的x[k]初始化为0 			} 		} 		else//没有符合条件的列了 		{ 			x[k]=0;//恢复x[k]为0 			k=k-1;//回溯到上一行 		}  	}  	for(int i=1;i<n+1;++i) 		cout<<x[i]<<" "; 	cout<<endl; 	delete[] x; } //每个函数的功能是处理一行，也就是填写x[i]，然后决定是继续填写x[i+1]还是 //回溯填写x[i-1] bool r_n_q(int* x,int i,int n) { 	if(i<1)return false;//回溯到根节点了，证明无解 	x[i]=x[i]+1;//因为上一个x[i]是死节点了，所以查询下一个 	while((x[i]<=n) && (!place(x,i))) 		x[i]=x[i]+1;//找到下一个满足条件的节点，或者扫描完整个行 	if(x[i]<=n)//找到符合条件的节点了 	{ 		if(i==n)return true;//已经是第n行了，也就是x数组填充成功了 		else//还没填充完，得到的是部分解，继续填写下一行 		{ 			x[i+1]=0;//下一行从0开始，因为后面要加1 			r_n_q(x,i+1,n);//调用函数填写第i+1行 		} 	} 	else//没有找到符合条件的节点，也就是这一行扫描完了，要回溯到上一行了 	{ 		r_n_q(x,i-1,n);//回溯，搜索上一行 	} } void recursive_n_queens(int n) { 	int *x = new int[n+1]; 	for(int i=0;i<n+1;++i) x[i]=0;  	if(r_n_q(x,1,n)) 	{ 		for(int i=1;i<n+1;++i) 			cout<<x[i]<<" "; 		cout<<endl; 	} 	else  		cout<<n<<"皇后问题无解！"<<endl; 	delete[] x; } int main() {  	for(int i=1;i<15;++i) 	{ 		n_queens(i); 		recursive_n_queens(i); 	} 	system("pause"); 	return 0; }


Question: 问一个很简单有关scanf的问题

简单的说，一般情况下scanf遇到空格符或回车符时自动跳过，但如果是要求输入一个字符型数据%c时，空格符或回车符都将作为一个字符被读入

其实，你需要了解一下计算机输入缓冲区的机制！自己查查资料，或许理解得深一些！

加了20分，可以解释的全给了...

看不懂 试了一下第一个代码 只有第二种好使 第二个代码 第一二中都好使  实在不明白为啥是这样 楼上发的英文实在看不懂 百度搜了一下  如果scanf中%d是连着写的如“%d%d%d”,在输入数据时，数据之间不可以加逗号，只能是空格或tab键或者回车键——“2 3 4” 或 “2（按tab）3（按tab）4（按tab）”。若是“%d，%d，%d”，则在输入数据时需要加“，”，如“2，3，4”.  其中没有包含之间有空格的，而有的时候连着写也是无法输入的

4 The fscanf function executes each directive of the format in turn. When all directives have been executed, or if a directive fails (as detailed below), the function returns. Failures are described as input failures (due to the occurrence of an encoding error or the unavailability of input characters), or matching failures (due to inappropriate input). 5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. The directive nev er fails. 6 A directive that is an ordinary multibyte character is executed by reading the next characters of the stream. If any of those characters differ from the ones composing the directive, the directive fails and the differing and subsequent characters remain unread. Similarly, if end-of-file, an encoding error, or a read error prevents a character from being read, the directive fails.


Question: C 语言 malloc问题

引用 5 楼 visp 的回复:你想申请几个int 就写几个  #include <stdio.h> #include <stdlib.h>  int main() { int *a; a = malloc(sizeof(int)*3); a[0] = 1; a[1] = 2; a[2] = 3; printf("%d\n%d\n%d\n",a[0],a[1],a[2]);  return 0; }  j是这样1用的~~~~ 对你的代码，可能会有未知的错误发生。但是不一定会发生，因为你的越界使用，数据不一定正确，且内存操作的地址不是每次都正确

引用 7 楼 yaojuntong77 的回复:哦，44行忘了个惊叹号。。。 应该改成：if  (!(array = (int *) malloc (arrsize * sizeof(int))))

哦，44行忘了个惊叹号。。。

楼主，你的代码用法不安全，我写个给你，看是不是你想表达的意思：  #include <stdio.h> #include <stdlib.h>  int *getmemory(int * restrict array, const int arrsize); void freememory(int * restrict array);  int main(void) { 	int  *array = NULL,  arrsize = 0,  i; 	 	printf("请输入你需要的数组元素个数（大于0的int型整数）: "); 	fflush(NULL); 	scanf("%d", &arrsize); 	if (NULL == getmemory(array, arrsize)) 	{ 		printf("内存元素个数指定错误：%d\n", arrsize); 		exit 1; 	}  	// 尝试给数组存入测试的值，然后打印输出： 	for(i=0; i<arrsize; i++) 	{ 		array[i] = i * 520 + 1; 	} 	printf("数组的当前值如下：\n"); 	for(i=0; i<arrsize; i++) 	{ 		printf("\tarray[%-2d] = %d\n", i, array[i]); 	}  	// 测试完以后，程序结束前，释放申请的动态内存 	freememory(array);  	return 0; }  int *getmemory(int * restrict array, const int arrsize) { 	if (0 >= arrsize) 	{ 		return NULL; 	}  	if (array = (int *) malloc (arrsize * sizeof(int))) 	{ 		return NULL; 	}  	return array; }  void freememory(int * restrict array) { 	if (array) 	{ 		free(array); 		array = NULL; 	} }

The malloc() and calloc() functions return a pointer to  the  allocated        memory  that  is  suitably aligned for any kind of variable.  On error,        these functions return NULL.  NULL may also be returned by a successful        call  to  malloc() with a size of zero, or by a successful call to cal‐        loc() with nmemb or size equal to zero.

这与系统底层实现有关，不同的系统可能会有不同结果。  malloc分配的内存并不完全等同于是你指定的大小（要考虑字节对齐的方式，以及保存一些信息使得调用free（）可以正确释放这个内存块）。  引用If size is 0, then malloc() returns either NULL, or a unique pointer value that can        later be successfully passed to free().  malloc(0)的结果可能为NULL，也可能是一个可以安全传递给free()的指针。  在后一种情况下，malloc(0)也会分配一定的空间（比如24字节或32字节）。  可以调用 size = malloc_usable_size(a)；看一下实际分配了多少字节。

越界了， 指针a指向malloc分配的有一定大小的空间 然后后面使用（初始化、赋值等）指针a指向的空间时，不能超过分配的空间 个人理解

你已经越界了，free(a)或许就出错了！ 不要总是天真以为没出错做法就是对的


Question: linux下C语言实现excel文件导入到数据库 动态库libxl.so用法

感谢楼上提示： [app_usr@jstest16 lib64]$ ldd -r libxl.so ldd: warning: you do not have execution permission for `./libxl.so' ./libxl.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./libxl.so) ./libxl.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./libxl.so)         libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002aee5f7eb000)  [app_usr@jstest16 ~]$ cd /settle/oracle_bak/11.2/client_1/lib/stubs/ [app_usr@jstest16 stubs]$ strings libstdc++.so.6 | grep "GLIBC" GLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 [app_usr@jstest16 stubs]$  解决方案 下载最新lib。 ps 现在思路是改一下功能实现的方式。

libxl-3.6.5.0库中有未定义符号 ldd -r libname


Question: 关于循环的问题

引用 4 楼 visp 的回复:如果你输入的就是3个字符，因为字符串会自动加一个\0，结果这个\0就加到num的地址上了，相当于把num设置成0了。 所以你看到的循环就只执行了一次。    #include<stdio.h> #include<stdlib.h> int main() {    	int num=0;    	scanf("%d",&num);    	getchar(); 	char arr[3]={0}; 	//num和arr的内存地址在一起，过了arr就是num的地址。  	printf("arr:%p\n",arr); 	printf("1_num:%p--%d\n",&num,num); 	while(num--) // 1: 循环 输入 ,问题是循环一次就结了, num的值被修改了.. 	{    		printf("2_num:%p--%d\n",&num,num); 		scanf("%s",arr); //问题出在这里吧。如果你输入的就是3个字符，因为字符串会自动加一个\0，结果这个\0就加到num的地址上了，相当于把num设置成0了。所以你看到的循环就只执行了一次。 		  		printf("3_num:%p--%d\n",&num,num);       		for(int j = 0;j < 3; j++) 			printf("%c ",arr[j]); 		printf("\n");    	} }    ++ 在编译器没做特殊安排的时候 变量是按照定义顺序编址的 自动变量顺序存储的话，由于堆栈是向下扩展的，先定义的在高地址处，后定义的在低地址处 当然，编译器未必这么安排 但很多时候都是这样的，尤其是发布版。

二楼说的对啊。你输入的长度很轻易的超过你的定义的字符串长度。第一次肯定能读取，但是越界，占用了字符串后面的内存。所以你第二次循环时，scanf函数对一个越界字符串有问题，所以循环终止。

scanf("%s",arr);  的时候出界了。  改成 scanf("%2s", arr) 吧。

arr先初始化为0   #include<stdio.h> #include<stdlib.h> int main() {    	int num;    	scanf("%d",&num);    	getchar(); 	char arr[3]={0}; 	while(num--) // 1: 循环 输入 ,问题是循环一次就结了, num的值被修改了.. 	{        		scanf("%s",arr);        		for(int j = 0;j < 3; j++) 			printf("%c ",arr[j]); 		printf("\n");    	} }


Question: 不用任何编程工具，只用text文本的情况下怎么手动编译执行C语言?

楼主估计是想问怎么用命令行编译执行c程序。

也许可以    引用 25 楼 u010165006 的回复:[quote=引用 24 楼 lm_whales 的回复:] .com 至少一些简单代码是不需要的重定位的 .com 一般是tiny 模式，不需要设置CS,DS,ES,SS 可以直接从第一个指令执行。 如果采用相对寻址指令，寄存器寻址指令，完全不需要考虑重定位。 我的意思是重定向： C:\>debug <p1.asm [/quote]

引用 24 楼 lm_whales 的回复:.com 至少一些简单代码是不需要的重定位的 .com 一般是tiny 模式，不需要设置CS,DS,ES,SS 可以直接从第一个指令执行。 如果采用相对寻址指令，寄存器寻址指令，完全不需要考虑重定位。 我的意思是重定向： C:\>debug <p1.asm

引用 19 楼 lm_whales 的回复:dos下的.com 比较适合手动编辑 不过，一般不用ed,notepad 等文本文件编辑器 可以用 debug 程序，编写 CCDOS 中文操作系统，是对英文DOS系统的扩展，其中许多程序，据说就是利用debug 编写的 编辑好以后重定向到debug，不是不容易出错和丢失

拿钱请人做事, 不要说text, 一句话就搞定

围观！

引用 17 楼 布拉格曼的回复:[quote=引用 6 楼 lm_whales 的回复:] 1）先把C语言手动变成汇编 2）把汇编变成二进制代码 3）根据目标平台的可执行文件格式，设定某些内容。如堆栈，数据段，代码段，启动地址，甚至中断，重定位表等等     其实就是设定一些数据结构，以便目标平台可以执行。  楼主可以把自己当成CPU、内存、总线、外设和硬盘，然后考虑你的每行代码需要在底层如何执行，接着把每句C写成汇编指令（不含伪指令），然后找到汇编指令转二进制指令译码表，把所有汇编语句改写成二进制01的文件，重写入txt文本（需要考虑系统平台类型和存储格式、CPU类型、核心数和支持的指令集、系统支持的文件系统格式、字节对齐格式、系统堆栈调用格式等等），然后改成.exe后缀（Windows平台）或者复制为无后缀名的副本（Linux平台），就变成可执行程序了，当然在linux下还有一步，需要修改可执行权限，使其能够执行[/quote]

可是等你完成这一系列过程，终于翻译完成一个小程序后，一个可爱的疯子就诞生了

引用 6 楼 lm_whales 的回复:1）先把C语言手动变成汇编 2）把汇编变成二进制代码 3）根据目标平台的可执行文件格式，设定某些内容。如堆栈，数据段，代码段，启动地址，甚至中断，重定位表等等     其实就是设定一些数据结构，以便目标平台可以执行。  楼主可以把自己当成CPU、内存、总线、外设和硬盘，然后考虑你的每行代码需要在底层如何执行，接着把每句C写成汇编指令（不含伪指令），然后找到汇编指令转二进制指令译码表，把所有汇编语句改写成二进制01的文件，重写入txt文本（需要考虑系统平台类型和存储格式、CPU类型、核心数和支持的指令集、系统支持的文件系统格式、字节对齐格式、系统堆栈调用格式等等），然后改成.exe后缀（Windows平台）或者复制为无后缀名的副本（Linux平台），就变成可执行程序了，当然在linux下还有一步，需要修改可执行权限，使其能够执行

在第一台计算机被制造出来之前，图灵机就已经存在了。

用记事本写好代码，文件后缀用.c，再使用gcc编译。如果不使用任何编译器不可能的。

这么神奇的事情一定要看看

牛！任何工具都不用也能写代码。

使用tcc用命令行方式就可以编译呀

楼主估计描述错了，应该是不用ide的情况下

如果连编译器都不用的话，问题就比较难了，起码我不会 如果可以用编译器的话，通过命令行，网上都能查到

。。。你为什么要这样

另外ALT+小键盘可以输入二进制代码的，虽然看不见，盲输入吧


Question: C# OpenPop.Mime 接收EMime 中文附件名过长乱码！

楼主稳步到C#版块提问啊，那边C#牛人多


Question: 求助，我做的课程设计，主要是最后几个链表的函数，拿出来单独跑的时候没问题， 放在整体里跑的时候说函数定义非法。并没有少大括号。求大神指点迷津。代码和错误如下

最前面加一句 void zhu();

提供完整的代码

这是有问题的那一部分，单独跑没问题。前面的函数段也没问题 。但只要放在一起就会报错 。。这错误实在看不懂为什么。


Question: 关于C语言方法参数，给C#调用的问题

[dllimport]  默认使用 __stdcall 调用约定  c api 默认使用 __cdecl 调用约定.  是不是这个导致的?

如果你需要传 NULL到非托管内存，使用 IntPtr，然后传递 IntPtr.Zero。

这是C的调用示例 #include “Custom_Interface.h” #include “GI_Datatype.h” #define   reciveID  “020000000008”//假设接收方ID为020000000008 #define   sendID  “020000000009”// 假设发送方ID为020000000009 void main() { CI_RV				 rv; unsigned long		 dataLen, encDataLen,newDataLen; unsigned char       data[1024]; //假设明文最大长度为1024个字节 unsigned char       encData[1024+16];//对应最大密文长度为1024+16个字节 unsigned char     newData[1024];//假设解密得到的新明文长度最大为1024个字节  dataLen = 563;//假设加密的数据长度为563个字节 //使用与实体0008共享的第3个对称加密密钥加密将要与实体0008共享的数据。 rv = CI_SymEncrypt( 3, reciveID, data, dataLen,  NULL, &encDataLen);        if(rv != GI_OK)        {             printf(“get cipher length error. Error code is [%08x]\n”,rv);         } }

unsigned  char 对应的是 byte。 char *和 wchar_t * 才是字符串。

我看MSN上面的 C函数对应C#数据类型 https://msdn.microsoft.com/zh-cn/library/ac7ay120.aspx unsigned char 好像应该使用 byte ？ 那C 语言 参数名后面*号，是什么意思，对应的是C# ref 参数吗 ？

我把代码改为下面的引用，返回的结果还是一样的     [DllImport(@"libeaspui.dll")] public static unsafe extern int CI_SymEncrypt(long nFunction, ref  StringBuilder pEntity, ref  StringBuilder pPlainData, UInt32 nPlainLength, ref StringBuilder pCipherData, ref  UInt32 pnCipherLength);

我现在情况是：方法调用正常，没有报错，但是根据方法返回的code 得到的含义是 指针参数为NULL！！！ 所以我想问一下 这个是因为C# 参数传递错误造成的么

2 3 5参数类型一样的,为啥到C#那边就不一样了呢?

仅供参考：using System.Runtime.InteropServices;  public class Win32 {      [DllImport("user32.dll", CharSet=CharSet.Auto)]      public static extern IntPtr MessageBox(int hWnd, String text,                       String caption, uint type); }  public class HelloWorld {     public static void Main() {        Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0);     } }         ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_fxinterop/html/ccb68ce7-b0e9-4ffb-839d-03b1cd2c1258.htm .NET Framework 开发人员指南  与非托管代码交互操作  发送反馈意见     Microsoft .NET Framework 将促进与 COM 组件、COM+ 服务、外部类型库和许多操作系统服务的互操作。在托管和非托管对象模型之间，数据类型、方法签名和错误处理机制都存在差异。为了简化 .NET Framework 组件和非托管代码之间的互用并便于进行移植，公共语言运行库将从客户端和服务器中隐藏这两种对象模型之间的差异。  在运行库的控制下执行的代码称作托管代码。相反，在运行库之外运行的代码称作非托管代码。COM 组件、ActiveX 接口和 Win32 API 函数都是非托管代码的示例。  本节内容 与非托管代码交互操作帮助主题  提供指向在有关与非托管代码进行互操作的概念性文档中找到的所有帮助主题的链接。  向 .NET Framework 公开 COM 组件  描述如何从基于 .NET 的应用程序使用 COM 组件。  向 COM 公开 .NET Framework 组件  描述如何从 COM 应用程序使用基于 .NET 的组件。  使用非托管 DLL 函数  描述如何使用平台调用来调用非托管的 DLL 函数。  互操作的设计注意事项  提供有关编写集成 COM 组件的提示。  互操作封送处理  描述如何对 COM Interop 和平台调用进行封送处理。  如何：映射 HRESULT 和异常  描述异常和 HRESULT 之间的映射。  使用泛型类型进行交互操作  描述泛型类型在用于 COM interop 时的行为。  相关章节 高级开发技术  提供指向关于 .NET Framework 中的高级开发任务和技术的更多信息的链接。   发送反馈意见，就此主题向 Microsoft 发送反馈意见。


Question: 大神看下这个二维数组   想求每一行中的最大值  输出来总是第一个数

for( k=0 ;k<3 ; k++)      printf("%d",a[k][0]);   这里a[k][0] 肯定就输出第一个数啊，[0][0],[1][0],[2][0]    二维数组 输出也得用2重循环输出！

printf("%d",a[k][0]);  你代码中不是每次都只输出第0个元素，也就是最前面那个啊

输出来总是每一行的第一个数。为什么啊？？

int& max = a[i][0];   这句话是什么意思  ，能不能告诉我一下   是不是就是把a[i][0]的地址值赋值给 max ,但是数组的形参可以改变实参的吗？

void max ( int a[3][4] ) {    int i , j , t ,k;      for( i=0 ; i<3 ; i++ )     {              int& max = a[i][0];         for( j=1 ;j<4 ; j++)          {    if( a[i][j]>max )               {                 t=max;                max=a[i][j];                a[i][j]=t;               }          }   printf("%d",a[i][0]);     }  } 改成这样就可以了。。。不然了解不了你到底要表达啥

不需要交换，重新命名一个数组来接每行最大的数组。输出地就是新数组啦。


Question: 对const的两点疑问

请给出完整的用于测试的程序，你用于测试的编译命令行及输出，以及你的编译器版本。

引用 17 楼 fefe82 的回复:c11 draft N1570 6.7.6.2 Array declarators 2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.  "对结构体成员数组定义使用 const int 作为长度是不允许的。" 是我解读过度了，抱歉。 变长数组只能出现在 block scope 或 function prototype scope 。你现在的这个例子是在 block scope 的。  作为全局的变量或 struct 的定义是不行的。  ============================== 4 If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope;143) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)  这里要求如果不是 VLA (variable length array) ，长度必须的 interger constant expression.  ============================= 6.6 Constant expressions 6 An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.  这里限定了 integer constant expression实在是太厉害了，您能这么快精准的锁定，是因为通篇看过吗？？？我明天仔细研究一下，很荣幸与您交流。。。

引用 17 楼 fefe82 的回复:c11 draft N1570 6.7.6.2 Array declarators 2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.  "对结构体成员数组定义使用 const int 作为长度是不允许的。" 是我解读过度了，抱歉。 变长数组只能出现在 block scope 或 function prototype scope 。你现在的这个例子是在 block scope 的。  作为全局的变量或 struct 的定义是不行的。  ============================== 4 If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope;143) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)  这里要求如果不是 VLA (variable length array) ，长度必须的 interger constant expression.  ============================= 6.6 Constant expressions 6 An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.  这里限定了 integer constant expression服了，只能膜拜一下了。最新的C标准。。。我以为这东西只有写编译器的人才看。。。待我仔细看一下。

我在VS2012下测试均能通过  不过const不是真正的常量 ，他在内存中仍是按变量存（可以取地址），只是编译器作检查，而#define是真常量

引用 16 楼 docterwg 的回复:[quote=引用 15 楼 fefe82 的回复:] 因为 C 不允许使用 const int 作为 integer constant expression 作为普通数组的长度定义。只有字面量（及 sizeof 等）是允许的。 同时，variable length array 只允许作为 局部变量。 对结构体成员数组定义使用 const int 作为长度是不允许的。 您说的这几个英文确实让我觉得您答在点子上。但您说const int 不能作为普通数组的长度定义，对结构体成员数组定义使用 const int 作为长度是不允许的。,我不这么认为，事实上，下面代码运行正确。 int main() {     const int length= 5;     int aa[length];     struct  {         int cc[length];     } bb;      printf( "%d %d\n", sizeof(aa) ,sizeof(bb.cc)); 	return 0; } 还有就是我手上只有K&R的书，没有其他参考书。想问问您，您的以上观点从哪获得？我下载了C99文档，可我的英文水平确实读它有些慢。。。[/quote]  c11 draft N1570 6.7.6.2 Array declarators 2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.  "对结构体成员数组定义使用 const int 作为长度是不允许的。" 是我解读过度了，抱歉。 变长数组只能出现在 block scope 或 function prototype scope 。你现在的这个例子是在 block scope 的。  作为全局的变量或 struct 的定义是不行的。  ============================== 4 If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope;143) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)  这里要求如果不是 VLA (variable length array) ，长度必须的 interger constant expression.  ============================= 6.6 Constant expressions 6 An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.  这里限定了 integer constant expression

引用 15 楼 fefe82 的回复:因为 C 不允许使用 const int 作为 integer constant expression 作为普通数组的长度定义。只有字面量（及 sizeof 等）是允许的。 同时，variable length array 只允许作为 局部变量。 对结构体成员数组定义使用 const int 作为长度是不允许的。 您说的这几个英文确实让我觉得您答在点子上。但您说const int 不能作为普通数组的长度定义，对结构体成员数组定义使用 const int 作为长度是不允许的。,我不这么认为，事实上，下面代码运行正确。 int main() {     const int length= 5;     int aa[length];     struct  {         int cc[length];     } bb;      printf( "%d %d\n", sizeof(aa) ,sizeof(bb.cc)); 	return 0; } 还有就是我手上只有K&R的书，没有其他参考书。想问问您，您的以上观点从哪获得？我下载了C99文档，可我的英文水平确实读它有些慢。。。

因为 C 不允许使用 const int 作为 integer constant expression 作为普通数组的长度定义。只有字面量（及 sizeof 等）是允许的。  同时，variable length array 只允许作为 局部变量。  对结构体成员数组定义使用 const int 作为长度是不允许的。  引用 12 楼 docterwg 的回复:[quote=引用 2 楼 fefe82 的回复:] 你不给程序，没有办法理解你的编译器输出啊。  我没理解你的意思，你要什么程序? 我说了main()里面没有东西，只有return 0; const int BlockSize = 20;//#define BlockSize 20 typedef struct _node {     int array[BlockSize];    struct _node* next;  } Node; int  main()  {return 0;} 程序编译不过去，我想知道为什么？ [/quote]

引用 10 楼 xmnathan 的回复:是因为你的编译器还没支持这个吧R U Sure?

引用 11 楼 ZiSheng 的回复:这个-std=c99在code：block中在哪添加？？？谢谢  Settings->Global compiler settings->Compiler settings->Other options->输入即可。伸手党要不要做的这么明显？

引用 2 楼 fefe82 的回复:你不给程序，没有办法理解你的编译器输出啊。  我没理解你的意思，你要什么程序? 我说了main()里面没有东西，只有return 0; const int BlockSize = 20;//#define BlockSize 20 typedef struct _node {     int array[BlockSize];    struct _node* next;  } Node; int  main()  {return 0;} 程序编译不过去，我想知道为什么？

引用 8 楼 docterwg 的回复:[quote=引用 7 楼 paschen 的回复:] [quote=引用 6 楼 docterwg 的回复:] [quote=引用 4 楼 user-6 的回复:] 和编译器有关系吧 这个在effective C++里面提到过 关于const 与#define  上述是C语言，不是C++，这两者对const处理不完全相同，好像C++更完善一些。[/quote]   在C语言中用const去修饰一个变量，表示这个变量是只读的，不可通过显式的调用a去修改a的值，并且此时a仍然是一个变量，不能等同于常量  const int n=5; int a[n];  这种方式在C语言中会报错，原因在于声明数组时数组的长度必须为一个constant，即常量，虽然n用const限定了，但n终究是一个变量，因此会报错;  但是在C++中不会报错，因为在C++中用const修饰过后，n就已经等同于一个常量了，因此可以通过。  摘自：http://www.cnblogs.com/dolphin0520/archive/2011/04/18/2020248.html[/quote]  版主可尝试一下，把你写的这个写在main()里面，看看编译能否通过。若通不过，加-std=c99，我的编译器可以编译过。[/quote]  这个-std=c99在code：block中在哪添加？？？谢谢

是因为你的编译器还没支持这个吧

引用 3 楼 docterwg 的回复:[quote=引用 2 楼 fefe82 的回复:] 请给出完整的用于测试的程序，你用于测试的编译命令行及输出，以及你的编译器版本。  main()函数里面什么也没有，只有return 0; ①②任意一个写在main()外都不行。  ---------------------------------------------------------------------针对①的----------------------------------------------------------------------------------------------------- 编译项目变更... -------- - 项目文件名: D:\C\项目1.dev - 编译器名: TDM-GCC 4.9.2 32-bit Release  生成 makefile... -------- - 文件名: D:\C\Makefile.win  正在处理makefile... -------- - makefile处理器: C:\Program Files (x86)\Dev-Cpp\MinGW64\bin\mingw32-make.exe - 命令: mingw32-make.exe -f "D:\C\Makefile.win" all  gcc.exe -c main.c -o main.o -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -m32 -std=gnu99  main.c:6:9: error: variably modified 'array' at file scope      int array[BlockSize];          ^  D:\C\Makefile.win:28: recipe for target 'main.o' failed  mingw32-make.exe: *** [main.o] Error 1   编译结果... -------- - 错误: 1 - 警告: 0 - 输出文件名: D:\C\项目1.exe - 输出大小: 101.6064453125 KiB - 编译时间: 0.45s --------------------------------------------------------------------针对②---------------------------------------------------------------------------------------------------- 编译项目变更... -------- - 项目文件名: D:\C\项目1.dev - 编译器名: TDM-GCC 4.9.2 32-bit Release  生成 makefile... -------- - 文件名: D:\C\Makefile.win  正在处理makefile... -------- - makefile处理器: C:\Program Files (x86)\Dev-Cpp\MinGW64\bin\mingw32-make.exe - 命令: mingw32-make.exe -f "D:\C\Makefile.win" all  gcc.exe -c main.c -o main.o -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -m32 -std=gnu99  main.c:5:1: error: initializer element is not constant  int g = gAll;   ^  D:\C\Makefile.win:28: recipe for target 'main.o' failed  mingw32-make.exe: *** [main.o] Error 1   编译结果... -------- - 错误: 1 - 警告: 0 - 输出文件名: D:\C\项目1.exe - 输出大小: 101.6064453125 KiB - 编译时间: 0.45s[/quote]  你不给程序，没有办法理解你的编译器输出啊。

引用 7 楼 paschen 的回复:[quote=引用 6 楼 docterwg 的回复:] [quote=引用 4 楼 user-6 的回复:] 和编译器有关系吧 这个在effective C++里面提到过 关于const 与#define  上述是C语言，不是C++，这两者对const处理不完全相同，好像C++更完善一些。[/quote]   在C语言中用const去修饰一个变量，表示这个变量是只读的，不可通过显式的调用a去修改a的值，并且此时a仍然是一个变量，不能等同于常量  const int n=5; int a[n];  这种方式在C语言中会报错，原因在于声明数组时数组的长度必须为一个constant，即常量，虽然n用const限定了，但n终究是一个变量，因此会报错;  但是在C++中不会报错，因为在C++中用const修饰过后，n就已经等同于一个常量了，因此可以通过。  摘自：http://www.cnblogs.com/dolphin0520/archive/2011/04/18/2020248.html[/quote]  版主可尝试一下，把你写的这个写在main()里面，看看编译能否通过。若通不过，加-std=c99，我的编译器可以编译过。

引用 6 楼 docterwg 的回复:[quote=引用 4 楼 user-6 的回复:] 和编译器有关系吧 这个在effective C++里面提到过 关于const 与#define  上述是C语言，不是C++，这两者对const处理不完全相同，好像C++更完善一些。[/quote]   在C语言中用const去修饰一个变量，表示这个变量是只读的，不可通过显式的调用a去修改a的值，并且此时a仍然是一个变量，不能等同于常量  const int n=5; int a[n];  这种方式在C语言中会报错，原因在于声明数组时数组的长度必须为一个constant，即常量，虽然n用const限定了，但n终究是一个变量，因此会报错;  但是在C++中不会报错，因为在C++中用const修饰过后，n就已经等同于一个常量了，因此可以通过。  摘自：http://www.cnblogs.com/dolphin0520/archive/2011/04/18/2020248.html

引用 4 楼 user-6 的回复:和编译器有关系吧 这个在effective C++里面提到过 关于const 与#define  上述是C语言，不是C++，这两者对const处理不完全相同，好像C++更完善一些。

赞同版主的看法！

引用 2 楼 fefe82 的回复:请给出完整的用于测试的程序，你用于测试的编译命令行及输出，以及你的编译器版本。  main()函数里面什么也没有，只有return 0; ①②任意一个写在main()外都不行。  ---------------------------------------------------------------------针对①的----------------------------------------------------------------------------------------------------- 编译项目变更... -------- - 项目文件名: D:\C\项目1.dev - 编译器名: TDM-GCC 4.9.2 32-bit Release  生成 makefile... -------- - 文件名: D:\C\Makefile.win  正在处理makefile... -------- - makefile处理器: C:\Program Files (x86)\Dev-Cpp\MinGW64\bin\mingw32-make.exe - 命令: mingw32-make.exe -f "D:\C\Makefile.win" all  gcc.exe -c main.c -o main.o -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -m32 -std=gnu99  main.c:6:9: error: variably modified 'array' at file scope      int array[BlockSize];          ^  D:\C\Makefile.win:28: recipe for target 'main.o' failed  mingw32-make.exe: *** [main.o] Error 1   编译结果... -------- - 错误: 1 - 警告: 0 - 输出文件名: D:\C\项目1.exe - 输出大小: 101.6064453125 KiB - 编译时间: 0.45s --------------------------------------------------------------------针对②---------------------------------------------------------------------------------------------------- 编译项目变更... -------- - 项目文件名: D:\C\项目1.dev - 编译器名: TDM-GCC 4.9.2 32-bit Release  生成 makefile... -------- - 文件名: D:\C\Makefile.win  正在处理makefile... -------- - makefile处理器: C:\Program Files (x86)\Dev-Cpp\MinGW64\bin\mingw32-make.exe - 命令: mingw32-make.exe -f "D:\C\Makefile.win" all  gcc.exe -c main.c -o main.o -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -m32 -std=gnu99  main.c:5:1: error: initializer element is not constant  int g = gAll;   ^  D:\C\Makefile.win:28: recipe for target 'main.o' failed  mingw32-make.exe: *** [main.o] Error 1   编译结果... -------- - 错误: 1 - 警告: 0 - 输出文件名: D:\C\项目1.exe - 输出大小: 101.6064453125 KiB - 编译时间: 0.45s


Question: 求推荐IOS版的c语言编程app

c for ios  自己去app store搜索，有一个是不用钱的


Question: 求教大神关于C语言顺序栈的问题

弱弱的问句，怎么给别人分数呢，我不会啊

引用 9 楼 qq_24647133 的回复:[quote=引用 6 楼 坚持奋斗的李洛克的回复:]#include "stdafx.h" #include<stdio.h> #include<stdlib.h> #define maxsize 100 struct SNode {     int ptr;     int *data;     int Maxsize; }; typedef struct SNode *Stack;   void initStack(Stack s) {     s->ptr=-1;     s->Maxsize=maxsize;     s->data=(int *)malloc (maxsize *sizeof(int));     printf("%d\n",s->ptr); }   void Push(Stack s,int x) {     if(s->ptr==maxsize-1)     {         printf("栈满");     }     else     {         s->ptr++;         s->data[s->ptr]=x;         printf("%d\n",s->data[s->ptr]);     } }   void pop(Stack s,int x) {     if(s->ptr==-1)     {         printf("栈空");     }     else     {         x=s->data[s->ptr];         s->ptr--;     } }     void main() {     struct SNode stack;     Stack s=&stack;     int x;     scanf("%d",&x);     initStack(s);     printf("%d\n",s->ptr);     Push(s,x);     printf("%d\t%d",s->data[s->ptr],s->ptr);   }  这样就可以啦！同意的话赏点分啊！ 那个int *data 和initStack 里的 malloc函数我其实并不明白什么意思。int *data不是定义一个指针变量吗？为什么后面分配内存后成为数组了？不太明白到底为什么这样用，希望不吝指教。明天用电脑给您分[/quote]  确的说不是数组类型，只是一个指针，malloc返回的是你分配内存的首地址，你可以把你分配的空间当作数组来使用

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

不听老人言，吃亏在眼前。

引用 6 楼 坚持奋斗的李洛克的回复:#include "stdafx.h" #include<stdio.h> #include<stdlib.h> #define maxsize 100 struct SNode {     int ptr;     int *data;     int Maxsize; }; typedef struct SNode *Stack;   void initStack(Stack s) {     s->ptr=-1;     s->Maxsize=maxsize;     s->data=(int *)malloc (maxsize *sizeof(int));     printf("%d\n",s->ptr); }   void Push(Stack s,int x) {     if(s->ptr==maxsize-1)     {         printf("栈满");     }     else     {         s->ptr++;         s->data[s->ptr]=x;         printf("%d\n",s->data[s->ptr]);     } }   void pop(Stack s,int x) {     if(s->ptr==-1)     {         printf("栈空");     }     else     {         x=s->data[s->ptr];         s->ptr--;     } }     void main() {     struct SNode stack;     Stack s=&stack;     int x;     scanf("%d",&x);     initStack(s);     printf("%d\n",s->ptr);     Push(s,x);     printf("%d\t%d",s->data[s->ptr],s->ptr);   }  这样就可以啦！同意的话赏点分啊！ 那个int *data 和initStack 里的 malloc函数我其实并不明白什么意思。int *data不是定义一个指针变量吗？为什么后面分配内存后成为数组了？不太明白到底为什么这样用，希望不吝指教。明天用电脑给您分

顺序栈：http://blog.csdn.net/zhangxiangdavaid/article/details/26819603

void initStack(Stack s)，你传入的s，在函数中已经在栈上给它分配内存了，不用在动态分配内存，在分配就会覆盖原内存，这个函数运行完毕，分配内存就会销毁，就又回到原内存上，所以其值是不变的。不用分配内存在。

引用 楼主 qq_24647133 的回复:#include<stdio.h> #include<stdlib.h> #define maxsize 100 typedef struct SNode *Stack; struct SNode { 	int ptr; 	int data[maxsize]; };  void initStack(Stack s) { 	s =(Stack ) malloc (sizeof (struct SNode)) ; 	s->ptr=-1; 	printf("%d\n",s->ptr); }  void Push(Stack s,int x) { 	if(s->ptr==maxsize-1) 	{ 		printf("栈满"); 	} 	else 	{ 		printf("%d\n",s->ptr); 		s->ptr++; 		printf("%d\n",s->ptr); 		s->data[s->ptr]=x; 	} }  void pop(Stack s,int x) { 	if(s->ptr==-1) 	{ 		printf("栈空"); 	} 	else 	{ 		x=s->data[s->ptr]; 		s->ptr--; 	} }   void main() { 	struct SNode stack; 	Stack s=&stack; 	int x; 	scanf("%d",&x); 	initStack(s); 	Push(s,x); 	printf("%d\t%d",s->data,s->ptr); 	pop(s,x); 	printf("%d",s->ptr); }  这个是我写得顺序栈，但是在主函数里我调用isitStack函数之后，将s->ptr设置为了-1，可是，在之后的程序运行中，我发现s->ptr为-280的值，也就是说isitStack函数并没有改变s->ptr的值，这是为什么呢?为什么s->ptr的值默认是-280呢？ 看了好几遍关于结构体的方面，都不明白是出现了什么问题，难道是调用函数不改变实参的值吗？可我用的是结构体指针，直接指向结构体变量的呀。 void initStack(Stack s) { s =(Stack ) malloc (sizeof (struct SNode)) ;    //去掉这一行    要不然主函数struct SNode stack;Stack s=&stack;传进来的值就没用了。 s->ptr=-1; printf("%d\n",s->ptr); }  printf("%d\t%d",s->data,s->ptr);  //改为：printf("%d\t%d",s->data[s->ptr],s->ptr);

#include<stdio.h> #include<stdlib.h> #define maxsize 100 struct SNode { 	int ptr; 	int *data; 	int Maxsize; }; typedef struct SNode *Stack;  void initStack(Stack s) { 	s->ptr=-1; 	s->Maxsize=maxsize; 	s->data=(int *)malloc (maxsize *sizeof(int)); 	printf("%d\n",s->ptr); }  void Push(Stack s,int x) { 	if(s->ptr==maxsize-1) 	{ 		printf("栈满"); 	} 	else 	{ 		s->ptr++; 		s->data[s->ptr]=x; 		printf("%d\n",s->data); 	} }  void pop(Stack s,int x) { 	if(s->ptr==-1) 	{ 		printf("栈空"); 	} 	else 	{ 		x=s->data[s->ptr]; 		s->ptr--; 	} }   void main() { 	struct SNode stack; 	Stack s=&stack; 	int x; 	scanf("%d",&x); 	initStack(s); 	printf("%d\n",s->ptr); 	Push(s,x); 	printf("%d\t%d",s->data,s->ptr);  }  我已经改成这样了，s->ptr是没问题了，但是s->data一直出错

引用 1 楼 赵4老师的回复:void initStack(Stack *s) { *s =(Stack ) malloc (sizeof (struct SNode)) ; (*s)->ptr=-1; printf("%d\n",(*s)->ptr); }   initStack(&s); 刚才我将initStack里的 malloc函数删除掉了，就已经好了可是s->data的数据却一直错误

引用 1 楼 赵4老师的回复:void initStack(Stack *s) { *s =(Stack ) malloc (sizeof (struct SNode)) ; (*s)->ptr=-1; printf("%d\n",(*s)->ptr); }   initStack(&s); 我之前已经  typedef struct SNode *Stack了  所以 Stack s中 s本身不就是指向结构体的指针吗，还是我理解错了


Question: 编写一个餐饮系统。各位大神，请支招

一步一步来，先把语法打好了一切都简单

不要用C语言，那就什么思路都有。

引用 4 楼 paschen的回复:一步一步来，先把语法打好了一切都简单 嗯嗯，明白了，就是感觉总有一些地方的思路打不通，怎么想都想不明白！

引用 1 楼 Gdreamlend的回复:思路最好还是先自己找找，遇到具体问题再问会比较好 嗯。好的，谢谢！现在正在思考中！

引用 3 楼 sdewenking的回复:不要用C语言，那就什么思路都有。 现在才刚刚学习C语言，其他的语言还没有学。所以只好求助咯！

先写一下你的思路吧，你需要什么功能，每个功能有哪些规则和需求，你自己先列出起来， 把你需要的数据什么的都先设计好，然后开始一步步开始慢慢开发吧， 你的餐饮系统是自己单机用，还是店内小范围，或者大范围的连锁用， 如果是店内用，服务员需不需要用点餐器帮助顾客点餐，还是只需要前台的电脑可以实用就行  比如，用户管理，菜单管理，进货什么的，好多的，看你需要什么

另外别拿c语言编啊，累死你了能

时间 时间 会给你答案。 你的餐饮系统时尚时尚最时尚

思路最好还是先自己找找，遇到具体问题再问会比较好


Question: b按表达式计算应该是11，为什么在c语言里会变成12了呢？

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

这种表达式具体运行结果，取决你的编译器，别纠结！

[C/C 板块推荐阅读] 关于C,C 表达式求值顺序.

未定义行为，+操作符两边的操作数哪个先执行由编译器决定，若先执行左操作数++a，则a变为6，再加a，则为12 若先执行右操作数，则读入a为5，再执行++a，左边为6，和为11

这涉及到顺序点问题  不要写这种表达式  具体搜索 《裘宗燕：C/C++ 语言中的表达式求值》 这篇文章看


Question: 新人小白求助……纠结一个问题整整一个晚上了。

ld是链接的程序，要把.o或者.obj链接起来成为一个程序，一般找不到需要的链接库会报这样的错误

具体不知道，楼主可以看下https://www.baidu.com/s?wd=Id+returned+1+exit+status&rsv_spt=1&rsv_iqid=0xbd980adb0002ab29&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=monline_3_dg

链接问题, 前面还有什么提示


Question: 汉诺塔V

用 unsigned long long

64个盘子,1号盘不是溢出了吗