四六级成绩批量查询器

软件已更新。。请下载最新突破限制版

四级准考证号忘学校了。。。。只能一个一个试。。网站上试的太慢了。。还得等十五秒。。就做了一个批量查询器。终于把成绩给查出来了。。没有过!有点太笨了哦。。高兴呢?还是悲伤呢?呵呵

422,417,419!希望下次成绩可以突破425

四六级成绩批量查询器(突破宿舍99限制最新版)

通过调整查询时间间隔来突破限制。测试间隔100ms查询一次可以正常查询,软件新加调整时间间隔功能,方便使用!

下载地址:

http://u.xunzai.com/fileview_105042.html

学习之余看个高智商故事,也许会对你的做事方式有启发(转载)

一位优秀的商人杰克,有一天告诉他的儿子。

杰克:我已经决定好了一个女孩子,我要您娶她。

儿子:我自己要娶的新娘我自己会决定。

杰克:但我说的这女孩可是比尔?盖茨的女儿喔。

儿子:哇!那这样的话……

在一个聚会中,杰克走向比尔?盖茨。

杰克:我来帮您女儿介绍个好丈夫。

比尔:我女儿还没想嫁人呢。

杰克:但我说的这年轻人可是世界银行的副总裁喔。

比尔:哇!那这样的话……

接着,杰克去见世界银行总裁。

杰克:我想介绍一位年轻人来当贵行的副总裁。

总裁:我们已经有很多位副总裁,够多了。

杰克:但我说的这年轻人可是比尔?盖茨的女婿喔。

总裁:哇!那这样的话……

最后,杰克的儿子娶了比尔-盖茨的女儿,又当上世界银行的副总裁。  

这就是整合创业的力量。

scanf详解[good]

1.scanf函数的一般形式

scanf(格式控制,地址表列)

int scanf(char *format[,argument,…]);

“格式控制”的含义同printf函数;“地址表列”是由若干个地址组成的表列,可以是变量的地址,或字符串首地址。

scanf()函数返回成功赋值的数据项数,出错时则返回EOF。
例题 scanf函数输入数据。

#include<stdio.h>

void main(){

int a,b,c;

printf(“input a,b,cn”);

scanf(“%d%d%d”,&a,&b,&c);

printf(“a=%d,b=%d,c=%d”,a,b,c);

}

格式字符 说明

%a 读入一个浮点值(仅C99有效)

%A 同上

%c 读入一个字符

%d 读入十进制整数

%i 读入十进制,八进制,十六进制整数

%o 读入八进制整数

%x 读入十六进制整数

%X 同上

%c 读入一个字符

%s 读入一个字符串

%f 读入一个浮点数

%F 同上

%e 同上

%E 同上

%g 同上

%G 同上

%p 读入一个指针

%u 读入一个无符号十进制整数

%n 至此已读入值的等价字符数

%[] 扫描字符集合

%% 读%符号

附加格式说明字符表修饰符 说明L/l 长度修饰符 输入”长”数据

h 长度修饰符 输入”短”数据

W 整型常数 指定输入数据所占宽度

* 星号 空读一个数据

hh,ll同上h,l但仅对C99有效。

(B) 空白字符空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符,空白符可以是space,tab,newline等等,直到第一个非 空白符出现为止。(C) 非空白字符一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。

注:scanf()控制串知识就介绍到这里(应该比较齐全了^_^),如有遗漏下次补上。下面将结合实际例程,一一阐述.三、 scanf()函数的控制串的使用例1.#include “stdio.h”

int main(void)

{

int a,b,c;

scanf(“%d%d%d”,&a,&b,&c);

printf(“%d,%d,%dn”,a,b,c);return 0;

} 运行时按如下方式输入三个值:3□4□5 

三个简单的C程序分析

例1

#include <stdio.h>

main()

{int i;int b;

scanf(“%d”,&i);

getchar();

}

为什么只输入一个数字或字母都会退出?

答:当输入为一个数字时,scanf可以正确读取,getchar()为接收一个’n’字符,所以就退出了

当输入为一个字母时,scanf不能正确读取缓冲区中一个字母而跳过,getchar正常接收缓冲区的字母,同样退出。


例2

#include <stdio.h>

main()

{int i;int b;

scanf(“%d”,&i);

scanf(“%d”,&b);

}

为什么输入一个数字不会退出,输入一个字母会退出?

答:当输入为一个数字时,scanf正常接收缓冲区中的数字,而执行第二个scanf(此时缓冲区中无内容)。所以不会退出

当输入为一个字母时,scanf不能正常接收缓冲区中的数字,则跳过,第二个scanf同样不能接收保留在缓冲区中的数字,跳过,接着程序就退出了.



例3

#include <stdio.h>

main()

{int i;int b;

scanf(“%d”,&i);

getch();

}

为什么输入一个数字或者字母都不会退出?

答:当输入为一个数字时,scanf正常接收缓冲区中的数字,执行完后,缓冲区中无内容;接着执行getch(),所以不会退出。

当输入为一个字母时,scanf执行出错,不会理会缓冲区中的字母,但此时getch()是不会到缓冲区中读取内容的,而是等待键盘输入。输入完毕后退出.

三个看似简简单单的程序。。。。其实不简单。很容易忽略的细节。

缓冲区及清除缓冲区中的内容[转]

getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,也就是说,如果stdin有数据的话不用输入它就可以直接读取了。

getch()和getche()是conio.h中的库函数,它的作用是从键盘接收字符。getchar带有显示。

    与前面两个函数的区别在于: getchar()函数等待输入直到按回车才结束(前提是缓冲区没有数据),回车前的所有输入字符都会逐个显示在屏幕上。但只有第一个字符作为函数的返回值。

#include<stdio.h>

#include<conio.h> /*我在gcc里没找到这个头文件,可能改名或者取消了吧,以后找到再说.*/

void main()

{

    char c;

    c=getchar(); /*从键盘读入字符直到回车结束*/

           //getchar()在这里它只返回你输入字符串的第一个字符,并把返回值赋值给c

    putchar(c); /*显示输入的第一个字符*/

    printf(“nn”);

}

这个程序你运行一下,相信你又会有疑问了。这个就是从缓冲区中读取了例子。第一次getchar()时,确实需要人工的输入,但是如果你输了多个字符,以后的getchar()再执行时就会直接从缓冲区中读取了。

#include<stdio.h>

#include<conio.h>

void main()

{

    char c;

    while ((c=getchar())!=’n’) /*每个getchar()依次读入一个字符*/

        printf(“%c”,c); /*按照原样输出*/

    printf(“nn”);

}

程序运行时,首先停下来,等你输入一串字符串,输入完毕后,它把你输入的整个字符串都输出来了,咦,你不是说getchar()只返回第一个字符么,这里怎么?

因为我们输入的字符串并不是取了第一个字符就把剩下的字符串丢掉了,它还在我们的内存中,好比,开闸放水,我们把水放到闸里去以后,开一次闸就放掉一点,开一次就放掉一点,直到放光了为止,这里开闸动作就相当于调用一次getchar()。我们输入的字符串也是这么一回事,首先我们输入的字符串是放在内存的缓冲区中的,我们调用一次getchar()就把缓冲区中里出口最近的一个字符输出,也就是最前面的一个字符输出,输出后,就把它释放掉了,但后面还有字符串,所以我们就用循环把最前面的一个字符一个个的在内存中释放掉,直到不满足循环条件退出为止。

例子中循环条件里的’n’实际上就是你输入字符串后的回车符,所以意思就是说,直到遇到回车符才结束循环,而getchar()函数就是等待输入(或缓冲区中的数据)直到按回车才结束,所以实现了整个字符串的输出。当然,我们也可以把循环条件改一下,比如while ((c=getchar())!=’a’),什么意思呢,意思就是遇到字符’a’就停止循环,当然意思是如果你输入“12345a213123n”那么只会输出到a,结果是12345a。

再次注意:用getchar()它是从“流”中间去读取,所以第一个getchar()接受的是刚刚中断的流队列中即将出列的第一个字符(不限于回车符,上面举过例子了),如果流队列不为空,执行getchar()就继续放水,直到把回车符也放空为止,空了之后再在执行getchar()就停下等待你的输入了;我们用getch()为什么每次都是等待用户的输入呢?因为getch()是从键盘接收,即时的接收,并不是从stdin流中去读取数据。

    补充:按键盘上的回车产生了2个字符:回车符(‘r’)和换行符(‘n’)。回车符’r'(CR:carriage return:倒车)使光标回到这行的首部,换行符(‘n’)(new line)然后再换行。

    所以当输入字符’w’,并按下回车键以后。首先得到回车符。那个getchar函数结束了。 但是还存在一个换行符。所以如果用getchar()来做判断的时候。最好再写一次getchar()清除缓冲区的’n’.

如何清空输入缓冲区的内容?

    如果我想让getchar()每次都能够等待用户输入的话就要清空缓冲区,下面就介绍方法(不同平台)

       C标准规定 fflush()函数是用来刷新输出(stdout)缓存的。对于输入(stdin),它是没有定义的。但是有些编译器也定义了 fflush( stdin )的实现,比如微软的VC。其它编译器是否也定义了 fflush( stdin )的实现应当查找它的手册。GCC编译器没有定义它的实现,所以不能使用 fflush( stdin )来刷新输入缓存。

       对于没有定义 fflush( stdin )的编译器,可以使用 fgets()函数来代替它(比用 getchar()、scanf()等函数通用性好)。可以这样忽略输入流中留下的回车等其它输入,从而使下一次的输入总保持一个“干净”的状态。(这个是任何平台下都可以的)

char sbuf[1024];

// …

fgets( sbuf, 1024, stdin );

// …

在windows 的vc下面就可以这样了:

for(int i=0;i<10;++i)

{

       char ch=getchar();

       fflush(stdin); //每次都会有等待状态了

}

这里说到gcc编译器没有定义fflush的实现,我们一般用getchar();来清除缓冲区.

下面是我的讨论:

先来一段code:

#include <stdio.h>

main()

{

    char c;

    for(;(c=getchar())!=’a';)

    printf(“%c”,c);

    getchar();

    c=getchar();

    printf(“%c”,c);

}

输入:

ssss回车

得到:

ssss

光标处(等待输入)

说明:此时程序没有结束,进行到for循环,因为并没有字符a出现,所以还没跳出for循环.键入回车后,getchar

依次从缓冲区内取出(for循环):’s”s”s”s”n’

如果我们输入:

ssssa回车

得到:

ssss光标处(等待输入)

说明:程序已经跳出for循环,但是由于我们用getchar();清除了换行’n’,后面第7句c=getchar();需要你输入一个字符(因为ssssa后面并没有新的字符),所以程序仍然没有结束.如果我们注释掉getchar();这一句,那么得到:

ssss

光标处(程序结束)

这个输入ssssa是的回车中的换行符’n’就被c=getchar();这一句读取并输出了。

总结:

键盘输入的字符都存到缓冲区内,一旦键入回车,getchar就进入缓冲区读取字符,一次只返回第一个字符作为getchar函数的值,如果有循环或足够多的getchar语句,就会依次读出缓冲区内的所有字符直到’n’.要理解这一点,之所以你输入的一系列字符被依次读出来,是因为循环的作用使得反复利用getchar在缓冲区里读取字符,而不是getchar可以读取多个字符,事实上getchar每次只能读取一个字符.如果需要取消’n’的影响,可以用getchar();来清除,这里getchar();只是取得了’n’但是并没有赋给任何字符变量,所以不会有影响,相当于清除了这个字符.还要注意的是这里你在键盘上输入ssss看到的回显正是来自于getchar的作用,如果用getch就看不到你输入了什么



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/weinixugeyuan/archive/2009/03/11/3980498.aspx

理解C语言的输入缓冲区[转]

1.机理

你键盘输入了东西,而此时你又没有用程序去getchar她,请问这个时候你按的键的状态保存在何处?为什么你一会儿去getchar的时候能得到呢

(例子好举,你先做一个1分钟延迟,然后再getchar,会发现一分钟前按的东西会显示出来)

实际上是 输入设备->内存缓冲区->程序getchar

你按的键是放进缓冲区了,然后供程序getchar

你有没有试过按住很多键然后等一会儿会滴滴滴滴响,就是缓冲区满了,你后头按的键没有存进缓冲区.

2.getchar()和getch()

然后就可以给你讲了

getchar是回车以后才进缓冲区

getch是每次都进缓冲区

用你的程序来说(我怎么觉得应该是n不是/n)

其实你输入computer,没按回车之前, 运行都停止在

getchar()里头,根本没有进入循环,自然也没有运行printf

当你一按回车,才从getchar出来,然后以后因为键盘缓冲区里头有东西,就一个一个字符getchar出来了

想立刻回显,用getch就好了

2.scanf

scanf这个库函数比较奇怪,而且存在一定的缺陷,所以很多人都不用了,这里还是要简单介绍一下.

scanf输入字符串,整型,实型等数据判断的方式都一样,回车,空格,tab键都认为是一个数据的结束,当然字符的话,一个字符就是结束了,回车,空格等都有对应的ascii码,所以用scanf输入字符时要小心这些东东被当成字符输进去,而输入字符串和整型,实型等数据时这些都被当成分隔符而不会被输入到字符数组或变量里.当然如果输入格式不是”%s%s”而是”%s,%s”分隔符就是逗号了,这个讲到输入输出函数时再说.

说了这么多举几个例子:

#include <stdio.h>

int main()

{

char n1[10];

char n2[10];

scanf(“%s”,n1);

scanf(“%s”,n2);

printf(“n1=%s,n2=%s”,n1,n2);

}

输入:

hello回车

world回车

得到:

n1=hello,n2=wolrd光标处(程序结束)

这里hello后面就是输入再多个回车,空格也不会被赋值到n2中的,因为他们只是分隔符.

如果输入:

hello回车

光标处(等待输入)

说明回车被认成分隔符,所以程序还要你输入一个字符串来赋给n2.

其实这时缓冲区里是有一个’n’被留下来的,程序改成这样:

#include <stdio.h>

int main()

{

char n1[10];

char n2[10];

char n3,n4;

scanf(“%s”,n1);

scanf(“%s”,n2);

printf(“n1=%s,n2=%s”,n1,n2);

n3=getchar();

printf(“%c”,n3);

//n4=getchar();

//printf(“%c”,n4);

}

输入:

hello回车

world回车

得到:

hello

world

n1=hello,n2=wolrd

光标处(程序结束)

如果取消最后两行的注释,同样的输入得到:

hello

world

n1=hello,n2=wolrd

光标处(等待输入)

说明此时缓冲区内只有一个’n’,第二个getchar就需要你再输入一个字符了,缓冲区内已经没有字符了.

scanf不会把回车空格赋给字符串但是会赋给字符,就如同getchar一样,这时就要考虑’n’的存在了.

比如:

#include <stdio.h>

int main()

{

char n1[10];

char n2;

scanf(“%s”,n1);

scanf(“%c”,&n2);

printf(“n1=%s,n2=%d”,n1,n2);

}

输入:

hello回车

得到:

n1=hello,n2=10光标处(程序结束) //10是’n’的ascii码.

如果输入:

hello 空格回车(一定要有回车,因为scanf也是要等回车,准确说是’r’才会去读缓冲区的.)

得到:

n1=hello,n2=32光标处(程序结束) //32是空格的ascii码.

再罗嗦一下,如果最后一句输入n2=%d改成n2=%c,则输入:

hello回车

得到:

n1=hello,n2=

光标处(程序结束)

是不是和getchar一样可以把’n’读出来呢,呵呵.

总结一下就是:

如果scanf输入的不是字符,那么分隔符为回车,空格,tab键时,两个数据之间的分隔符只是起区别两个数据的作用,把分隔好的两个数据分别赋值到各自定义好的变量或数组中去,两个数据之间的分隔符被从缓冲区读出但是不起任何作用,当然最后一个’n’会被留在缓冲区内,除非用getchar();或scanf(“%c”,&c);把它读出来.

回车是一定要有的,不管getchar还是scanf只要是通过缓冲区输入数据的函数都是等待回车键’r’出现才进入缓冲区的.再来个整型数据,字符串,字符的混合例子:

#include <stdio.h>

int main()

{

int a,b,c;

char n1[10];

char n2,n3;

scanf(“%d%d”,&a,&b);

scanf(“%c”,&n2);

scanf(“%d”,&c);

scanf(“%s”,n1);

scanf(“%c”,&n3);

printf(“a=%d,b=%d,n2=%c,c=%d,n1=%s,n3=%c”,a,b,n2,c,n1,n3);

}

输入:

12(若干空格或回车就不影响结果,这里用了回车)

34(这里还要求输入,因为scanf只得到了一个整型数据,而缓冲区内没有整型数据了。要有回车或空格表示这个数据结束了,留下来的空格或回车被下个%c接受,这里用了回车,可以试一下空格)

45 jfdkjfa(回车)

得到:

a=12,b=34,n2=

,c=45,n1=jfdkjfa,n3=

光标处(程序结束)

这里说明一下过程:在前两个整型数据输入时,两个数据之间无论是回车还是若干空格都被scanf当做分隔符,好了,scanf读到分隔符(回车或空格)时,把第一个整型数据送到变量a中,缓冲区中留下分隔符和下面的整型数据,这时scanf再读当然先读分隔符,但是要求输入的还是整型数据(%d),所以分隔符被忽略,如果这时要求输入字符%c(不是字符串%s),那么分隔符将以一个字节的形式送到字符变量里,就如同这里的n2.同理可以知道c和n1的保存过程,最后的n3正是接收了输入时的最后一个回车.

好了如果看到这里你都理解了那么看最后一个例子:

#include <stdio.h>

main(){

int a;

char ch;

scanf(“%d”,&a);

ch=getchar();

printf(“%d,%c”,a,ch);

}

输入:

95回车

得到:

95,

光标处(程序结束)

很明显这是由于分隔符(回车)被getchar读取并输出了,如果加入一句:getchar();

#include <stdio.h>

main(){

int a;

char ch;

scanf(“%d”,&a);

getchar();

ch=getchar();

printf(“%d,%c”,a,ch);

}

输入:

95回车

c回车

得到:

95,c光标处(程序结束)

信令

在网络中传输着各种信号,其中一部分是我们需要的(例如打电话的语音,上网的数据包等等),而另外一部分是我们不需要的(只能说不是直接需要)它用来专门控制电路的,这一类型的信号我们就称之为信令,信令的传输需要一个信令网。

  信令的分类:

  最传统的信令是中国一号信令,过去电话用的多,现在基本用的最多的是七号信令(电话和网络传输都用到)。

  通讯设备之间任何实际应用信息的传送总是伴随着一些控制信息的传递,它们按照既定的通讯协议工作,将应用信息安全、可靠、高效地传送到目的地。这些信息在计算机网络中叫做协议控制信息,而在电信网中叫做信令(Signal)。英文资料还经常使用”Signalling”(信令过程)一词,但大部分中文技术资料只使用”信令”一词,即”信令”既包括”Signal”又包括”Signalling”两重含义。

  信令按其用途分为用户信令和局间信令两类。

  用户信令作用于用户终端设备(如电话机)和电话局的交换机之间,后者作用于两个用中继线连接的交换机之间。

  局间信令分类主要有随路信令和共路信令,随路信令就是说信令网就附在计算机网络或是电话网络上,不需要重新建一个网络,而共路信令则是需要重新建设一个信令网(主要是在局端之间),例如打电话:当我们开始打电话的时候,拿起电话机时就有信号传到当地的电信局端,一系列交换后,本局端就先在网络上发送信令,等对端收到信令后回应一个信令同意通话,此时网络上传输信令功能就算完成了,开始传输语音信号,就可以通话了。等电话结束的时候,同样需要通过信令来控制电路拆除。

  总之,信令实际上就是一种用于控制的信号。

数组名在编译器中是如何实现的?

C专家编程里解释的很好:


经典的错误:在一个文件定义了数组,却在另外一个文件声明其为指针。代码如下:
/*File name: main.c*/

extern int* array; /*声明指针*/

int main(void)

{

array[0]=1; /*用指针访问数据*/

return 0;

}

/*File name: def.c*/

int array[5]={0}; /*定义的却是数组*/


1。编译器对数组名和指针变量的处理方式

编译器在编译时会产生一个符号表,记录了符号名和它的地址。对于指针变量,这显然很好理解。而数组名就不那么明显了,它仅仅是一个符号而已,何来地址?编译器是这样处理的,它记录了array[0]的地址;这和我们通常的理解也是一样的。

2。带下标形式的数组和指针寻址方式

(1)数组情形

char a[9]=”abcdefgh”;



c=a[i];

在编译期,会在符号表中创建这样一条记录:

name:a address:9980

要获取a[i]的值分两个步骤:

step 1:取得i的值并和9980相加

step 2:在内存地址(9980+i)处取其内容


(2)指针情形

char* p=”abcdefgh”;



c=p[i];

在编译期,会在符号表中创建这样一条记录:

name:p address:4624

要获取p[i]的值分三个步骤:

step 1:在内存地址4624处取其内容,比如说“5081”

step 2:取得i的值并和5081相加

step 3:在内存地址(5081+i)取其内容


现在有了这些知识,前面出现的错误就很好解决了。在def.c中定义array是一个int型数组,在符号表中就会有把array和array[0]的地址关联起来。而在main.c中却把把array看作是一个int型指针,于是乎按照上面介绍的指针寻址方式,把符号表中array的地址(即&array[0])中的内容当作指针来寻址,这显然是不对的。

C词法分析中的“贪心”法[转]

本章探讨的是符号和组成符号的字符之间的关系,以及有关符号含义的一些常见的误解。

   当我们阅读一个句子时,我们并不去考虑组成这个句子的单词中单个字母的含义,而是把单词作为一个整体来理解。确实,字母本身并没有什么意义,我们总是将字母组成单词,然后给单词赋予一定的意义。对于C语言或其他语言编写的程序,道理也是一样的。

   编译器中负责将程序分解为一个一个符号的那部分,一般称为”词法分析器”,在C语言中符号之间的空白将被忽略,包括空格符,制表符和换行符。


=和==


   一般而言,更为常用的操作用更为简短的表达,以节省大家的时间。故符号=作为赋值,符号==作为比较运算,因为赋值比使用的更为频繁。

   =的左边的操作数为左值(lvalue),右边的为右值(rvalue),关于lvalue和rvalue,详情请参阅《The C programming Language》(K&R/TCPL)的附录A.5和A.7。

   潜在的问题代码:
   if (x = y)
           foo();

   程序员的本意是判断(x == y)还是直接的赋值(x = y)呢?现在的gcc编译器在发现形如e1 = e2的表达式出现在条件判断的部分时,会给出相关的警告信息,如果编译的时候把警告打开的话。

   比如下面这段代码:

   #include <stdio.h>

   #include <stdlib.h>

  

   int main(int argc, char **argv)

   {

           int x = 1;

           int y = 1;

           if ( x = y)

               printf(“x = y is truen”);

           exit(0);

   }

   不打开警告的编译方法和打开警告的编译方法分别为:

   gcc -o prog prog.c

   gcc -Wall -o prog prog.c

   则可以看到如果打开警告,编译器会有提示”warning: suggest parentheses around assignment used as truth value”,如果不打开警告的话,就没有任何警告提示了。

   作为一种解决方法和一种良好的编程习惯,作者建议写作显式比较的形式:

   if ((x = y) != 0)

           foo();

   既能去除警告,也使得代码的意图一目了然,只是多了几个字符,何乐而不为!

C语言的某些符号,例如/、* 和=,只有一个字符长,称为单字符符号。而C语言中的其他符号,例如/*和==,以及标识符,包括了多个字符,称为多字符符号,当C编译器读入一个字符‘/’后又跟了一个字符’*’,那么编译器就必须做出判断:是将其作为两个分别的符号对待,还是合起来作为一个符号对待。C语言对问题的解决方案可以归纳为一个很简单的规则:每一个符号应该包含尽可能多的字符。也就是说,编译器将程序分解成符号的方法是,从左到右一个字符一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一下字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。这个处理策略有时候被称为“贪心法”,或者,更口语化一点,称为“大嘴法”。Kernighan与Ritchie对这个方法的表述如下:“如果(编译器的)输入流截止到某个字符之前都已经被分解为一个个符号,那么下一个符号将包括从该 字符之后可能组成一个符号的最长字符串”。


     根据上述说法,我们可以将下述表达式正确解析:

    ab <====> a b

    而下述表达式写得时候也应该注意:

     y =x/*p (错误写法)

     y =x/ *p (正解写法)

     y =x/(*p)(正解写法)

   那么表达式 “a+++++b” 该如何解析呢?

   根据贪心法,我觉得应该这样解析“(a++)++ + b ”,在GCC 4.1里面测试了下,发现该表达式根本就是错误的,下面是我的测试程序的截图:

字符与字符串
    这个相对容易理解多了,单引号和双引号嘛。下面说说两者的实质的区别:
    单引号:单引号字符本质上是代表一个整数,其值对应于该字符在编译器采用的字符集中的序列值。对于普通的采用ASCII字符集的编译器,如gcc,’a’就是97或0141(八进制)。
    双引号:双引号的字符串代表的是一个指向无名数组起始字符的指针,该数组被双引号之间的字符以及一个额外的二进制值为零的字符’’初始化。
   
   下面的语句:
    printf(“Hello worldn”);
   
    char hello[] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘ ‘, ‘w’, ‘o’, ‘r’, ‘l’, ‘d’, ‘n’, ‘’}
    printf(hello);
    两者是等价的。

    这个很好理解,用一种形而上学的理解记忆,一个串相当N多字符的组合,要放在一起使用,当然只能用数组的形式了,也就是说串就是字符的无名数组形式了,既然无名,就只能使用指针来引用了,串就是这个指针。而这个数组最后的’’代表串的结束(总得有一个东西来代表结束吧)。
    关于这个结束字符串的东西,在《Expert C Programming: Deep C Secrets》(《C 专家编程》)中的第二章的2.1小节的小启发中说是NUL,而NULL代表空指针,表示什么也不指向,而NULLL则说明需要检查一下是不是拼写错误了。这里的NUL其实ASCII码表0值的char字面意思,NUL并没有在标准C中定义,当然如果自己想用的话,#define一下也不错。
    一句话总结就是,单引号的字符代表一个整数,双引号的则代表一个指针,混用的话编译器的类型检查功能会检测到这样的错误的,gcc就可以。