• 1. 随机整数生成
    int chosen=0;
    srand(time(NULL));
    chosen=rand();
    注:用stdlib.h中的rand()函数可以生成伪随机数,范围是0到RAND_MAX(已在stdlib.h中定义)。而rand()对于相同种子生成的随机数是相同的,可以用srand()函数的参数向rand()提供种子(srand()在stdlib.h头文件中)。为了每次生成不同的种子,可以使用time.h头文件中的time()函数,此函数返回从1970年1月1日到现在的秒数,用整型表示,time()的参数为NULL。
    若要限定随机数的范围:
    0到limit:chosen=rand()%limit;
    1到limit:chosen=1+rand()%limit;

     

    2. 转义字符\a输出铃声

     

    3. 用%p可以输出变量的地址,用十六进制表示,例如,printf("%p",&a);&必不可少。

     

    4. 计算累加可以用以下算法:
    for(i=1;i<=count;sum+=i++);或者for(i=count;i>=1;sum+=i--);
    而这些循环其实都不必要,直接用公式sum=n*(n+1)/2效率会高得多。

     

    5. sizeof()的参数可以是变量,数据类型,数组名,数组元素。

     

    6. 确定边界:头文件limits.h定义了有符号整数类型的上下边界信息,如INT_MAX,对于无符号的,下界总是0。头文件float.h则定义了浮点类型的边界信息,如FLT_MAX。

     

    7. 分数值或小数值通常没有确切的浮点形式表示法,因此依靠等式作为判断结束循环的条件不太明智:
    double x=0.0;
    for(;x!=2.0;x+=0.2)
       printf("\nx=%.2lf",x);
    由于0.2没有精确的二进制浮点值表示形式,所以x永远也不会等于2.0,此循环不会结束。

     

    8. 二维数组board[][]中,要用board来获取第一个元素的值,需要使用两个间接运算符,即**board。
    void main()
    {  char board[3][3]={{'1','2','3'},{'4','5','6'},{'7','8','9'}};
    printf("value of board[0][0]:%c\n",board[0][0]);
    printf("value of board[0]   :%c\n",board*[0]);
    printf("value of board      :%c\n",**board);
    }
    结果:
    value of board[0][0]:1
    value of board[0]    :1
    value of board        :1

     

    9. 动态内存分配:malloc()函数的使用
    首先需要加入头文件stdlib.h,函数返回所分配的第一个字节的地址,所以,最好用指针保存返回值。
    int *pNumber=(int*)malloc(100);表示分配100个字节的内存,将其地址赋予pNumber,因为int类型占2字节,所以可以存50个int值。
    int *pNumber=(int*)malloc(100*sizeof(int));直接申请100个int类型的空间。
    由于malloc()是个通用函数,可以分配任何数据内型的数据,所以它的真正返回值是void型指针(void*),void没有明确类型可以执行任何类型的数据,而void型指针所指的值却不能被提取,所以必须加(int*)转换其类型。
    如果malloc()由于某种原因分配内存失败,将返回NULL值,所以在使用函数后,用if(pNumber==NULL)来检验是个好习惯。

     

    10. getchar循环方式输入:
    char buffer[100];
    char* pBuffer=buffer;
    while((*pBuffer++=getchar())!='\n');
    *pBuffer='\0';      /* 用'\0'覆盖了'\n',表示字符串结束 */

     

    11. 可变参数的函数:
    #include "stdio.h"
    #include "stdarg.h"
    double average(double a1,double a2,...)
    {
       va_list parg;
       double sum=a1+a2;
       double value=0;
       int count=2;
       va_start(parg,a2);
       while((value=va_arg(parg,double))!=0.0)
       {
          sum+=value;
          count++;
       }
       va_end(parg);
       return sum/count;
    }

    main()
    {
       printf("%lf",average(3.0,9.0,12.0,0.0));
       getch();
    }
    解释:va_start()需要两个参数,第一个是va_list型指针parg,第二个是要编写的函数指定的最后一个固定形参的名字,函数作用是把变量parg设置为调用该函数时传递给它的第一个可变参数。
    va_arg()第一个参数是通过调用va_start()初始化的变量parg,第二个变量是说明了希望找到的参数的类型。函数返回的是parg指定的当前参数的值,该值存在value中。它还会更新parg,根据函数调用中指定的参数类型,使它指向列表中的下一个参数。但指定类型不正确的话就不能正确获得下一参数。但得到的值未标示结束的值时(此处是0.0),循环将结束。
    va_end()把parg重置为NULL,该函数不可缺少。

    变长参数列表的基本规则:
    1。在接受参数个数可变的函数中,至少有一个固定参数。
    2。必须调用va_start()函数初始化函数中的可变参数列表指针的值。还要把该指针声明为va_list型的。
    3。需要有一种方法决定每个参数的类型。最好全部参数同一类型。
    4。必须安排某种方式确定参数列表的结尾。
    5。对于参数类型应有一定限制,如不要使用char,unsigned char或float。可以用int代替char,用double代替float。
    6。退出参数可变函数时,一定要调用va_end()。
    7。以上所有操作只适用ANSI C,UNIX的实现于这些有很大区别。

    注:在win-tc上运行正常,在visual studio2008上运行出错:找不到表示符va_list等,while((value=va_arg(parg,double))!=0.0)语句出错。

     

    12. void main(int argc,char *argv[])的两个参数:
    第一个参数是int型,表示在执行main()函数的命令行中要输入的实参的个数,其中包括程序名自身,argc值至少为1。第二个参数是一个字符串指针数组,第一个指针指向程序名,其后顺序指向main()命令行中要输入的实参。
    main(int argc,char *argv[])
    {  int i=0;
       printf("%s\n",argv[0]);
       for(i=1;i<argc;i++)
         printf("%d: %s",i,argv[i]);
       getch();
    }

     

    13. 格式化输入:
       double a;
       char str[]="%lf";
       scanf(str,&a);
       printf("%lf",a);

       double a;
       scanf("%lf",&a);
       printf("%lf",a);
    效果一样。

    char a[10],b[10];
    scanf("%[aeiou]%[^o]",a,b);
    printf("%s,%s",a,b);
    注:%[aeiou]表示只读入方括号内的值,输入中第一个不属于的值标志这个输入结束,%[^o]表示除了o以外字符都接受。

     

    14. scanf返回的是读入输入值的个数k=scanf("%s%s",a,b);k=2。

     

    15. int siblings(struct family *member1,struct family *member2)
    最原始形式,指针所指的内容可以被改变。
    int siblings(struct family const *member1,struct family const *member2)
    把形参声明为指向常量family结构的指针,即传递给函数的指针所指的结构在函数内部将被作为常量处理,起到保护数据的作用。
    int siblings(struct family *const member1,struct family *const member2)
    形参是指向family型结构的常量指针,所指的结构可以改变,指针本身不能改变,保护的是指针,而不是所指的内容。

     

    16. 预处理器指示必须是一个逻辑行,不过并不妨碍使用语句继续字符\,你可以编写以下代码:
    #define min(x,y) \
                    ((x)<(y)?(x):(y))
    注意,\必须是一行的最后一个字符,紧接在按下Enter键之前。

     

    17. 想在一个宏中生成两个结果,把它们连接起来,中间没有空格
    #define join(a,b) ab 这个宏不能实现此效果,宏扩展定义会把它解释成ab
    我们可以通过分隔参数符##来实现
    #define join(a,b) a##b
    例如:
    strlen(join(var,123));将生成下面语句strlen(var123);

     

    18. 宏__DATE__提供了日期字符串的表示,格式为mmm dd yyyy
    printf("%s\n%s",__TIME__,__DATE__) ;
    宏__TIME__存放的是时间值得字符串,格式是hh:mm:ss

     

    19. 关于assert()宏
    assert()的参数是一个值为整数的表达式,如果表达式为0,它将用一条诊断消息中断程序。它定义在assert.h头文件中。
    宏assert()的功能有开关控制,#undef NDEBUG时,宏起作用;想禁用断言时,可以#define NDEBUG。
    如:
    #undef NDEBUG
    #include "stdio.h"
    #include "assert.h"

    main()
    {  int a=1,b=0;
       assert(a==b);
       printf("ok") ;
       getch();
    }

  • Ubuntu的中文法 - [About Linux]

    2008-08-03

    Tag:Ubuntu

    首先要添加中文包,然后在语言支持中选中汉语,最后在SCIM输入法设置里添加中文的输入法,ok。不过安装超慢,我一于训教唔理,早上起身就装好了。以前遇网不淑,教人输入一大堆狗屎垃圾,结果得个橘,原来方法其实好简单。

    中文包方法
    sudo apt-get install language-support-zh language-pack-zh

    当然有时候会出现“无法找到软件包 language-support-zh”的情况,呢个大概系源的问题,如果是在已连接网络的情况下安装ubuntu,可能不会出现这个问题,解决方法是更新,不嫌麻烦的话可以换源之后再更新。

    更新在终端输入:sudo apt-get update

    完毕之后再装中文包应该就可以了。

    请参考以下链接:http://wiki.ubuntu.org.cn/%E5%BF%AB%E9%80%9F%E8%AE%BE%E7%BD%AE%E6%8C%87%E5%8D%97/GutsyGibbon#.E5.AE.89.E8.A3.85.E8.AF.AD.E8.A8.80.E5.8C.85