ghosTzone
main(_){return _} && echo $? /* Keep It Simple Stupid | 本博客所有文章皆为原创 转载请注明 - ghosTM55 */

scanf函数返回值 3

2008年11月26日 17:08 in C/C++ tags:

  我们在写C程序时一直使用的scanf()也有返回值,它的返回值是读入的值的个数。请看这段代码:

#include<stdio.h>
int main(void)
{
        printf("test programme:\n");
        int a,b,value;
        value=scanf("%d %d",&a,&b);
        printf("%d,%d,%d\n",value,a,b);
        return 0;
}

  编译,执行:

ghosTM55:test> gcc test.c
ghosTM55:test> ./a.out
test programme:
10
20
2,10,20
 

ghosTM55:~> date
Wed Nov 26 09:10:30 CST 2008


随机数的生成与使用技巧 0

2008年11月22日 02:00 in C/C++ tags:

  在C语言中,rand()函数能够帮助用户生成一个从0到RAND_MAX之间的任意数,它们的定义包含在stdlib.h的头文件中。

  这段代码展示了一些使用随机数的一些技巧:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
        int chose=0;
        for(;chose-1!=0;)
        { 
                srand(time(NULL));
                chose=1+rand()%20; /* 限制随机数的范围: 1~20 */
                printf("%d\n",chose);
        } 
        return 0;
}

  rand()函数在使用之前需要一个seed,而通过srand()与time()函数能够帮助用户产生随机的 rand()函数seed。time()所返回的值是从1970年1月1日至今所经过的秒数,所以,这个程序在执行的时候,可以看到每经过一秒,就会产生一个新的随机数,直到随机数为1时退出循环。

txi@ghosTunix:~$ date
2008年 05月 17日 星期六 07:37:11 CST


循环条件的使用问题 0

2008年11月22日 01:59 in C/C++ tags:

#include<stdio.h>
int main(void)
{
        float t=2.0,i=0.0;
        for(;i!=t;i+=0.2);
        printf("terminated\n");
        return 0;
}

txi@ghosTunix:~$ date
2008年 05月 17日 星期六 07:47:27 CST


让C程序暂停一秒 0

2008年11月22日 01:57 in C/C++ tags:

  在C语言中,time.h头文件中包含了clock()函数,它负责返回程序开始运行后的时间,以时钟周期为单位。同时,在time.h中定义了CLOCKS_PER_SEC的常量,即1秒的时钟周期数。利用这两个特性,可以实现C语言中的程序暂停1秒的功能。

#include<stdio.h>
#include<time.h>
int main(void)
{
        int now=clock();
        printf("%d\n",now);     /* 显示0 */
        for(;clock()-now<CLOCKS_PER_SEC;);
        printf("1\n");          /* 一秒后显示1 */
        now=clock();
        for(;clock()-now<CLOCKS_PER_SEC;);
        printf("2\n");          /* 再过一秒后显示2 */
        return 0;
}



清除输入缓存 0

2008年11月22日 01:53 in C/C++ tags:

  我们熟知的scanf()函数事实上并不是从键盘直接接受输入,而是检查键盘缓存。所以,初学者常常会对一些奇怪的输入问题感到困惑。先来看下面这段代码:

#include<stdio.h>
int main(void)
{
        int c='y';
        while(c=='y')
        {
                printf("y/n:");
                scanf("%c",&c);
        }
        return 0;
}

  无论程序执行者是循规蹈矩地输入一个y然后按下回车,或者是输入yes后按下回车,程序都不会按照表面看起来那样让执行者进行下一次循环:

txi@ghosTunix:~/programming/c/test$ ./a.out
y/n:y
y/n:txi@ghosTunix:~/programming/c/test$

  可以看到,在按下y+回车后,下一个循环直接跳过,并为执行。这是因为在第二个循环中,程序将回车,也就是"\n"赋值给了变量c,由于"\n"!='y',所以跳出了循环。通过清楚输入缓存,能够很好的解决这个问题:

#include<stdio.h>
int main(void)
{
        int c='y',flush;
        while(c=='y')
        {
                printf("y/n:");
                scanf("%c",&c);
                while((flush=getchar()) != '\n' && flush != EOF); /* 清除缓存 */
        }
        return 0;
}

  清楚输入缓存并没有官方的方法,通过执行一个空while语句,可以将输入缓存“消耗”掉。

  参考资料:http://www.c-faq.com,Question 12.26[ab]

txi@ghosTunix:~$ date
2008年 05月 18日 星期日 08:50:31 CST


正确使用strlen计算字符数组长度 0

2008年11月22日 01:51 in C/C++ tags:

#include<stdio.h>
#include<string.h>
/*#include<stddef.h>*/
int main(void)
{
        char str[]="helloworld!!!";
        size_t length=strlen(str);
        printf("%d\n",length);
        return 0;
}
 

  由于strlen()函数返回的值其实是size_t类型的,所以,采用size_t来声明一个记录数组长度的变量能够达到更好的移植性。数据类型 size_t是在stddef.h头文件中定义的,由于在stdio.h头文件中预处理了stddef.h,所以能够直接使用。

txi@ghosTunix:~$ date
2008年 05月 18日 星期日 21:14:45 CST


判断是否正确分配内存 0

2008年11月22日 01:49 in C/C++ tags:

  在使用malloc进行内存分配时,由于一些原因(比如内存不够)而导致内存分配失败后,malloc函数将返回一个值为NULL的指针。所以,在每次分配完内存后,对其成功性进行验证非常有必要:

#include<stdio.h>
#include<stdlib.h>
int main(void)
{
    long *pArray=(long *)malloc(1000000*sizeof(long));
    if(pArray==NULL)
    {
        printf("Memory allocation failure :(\n");
        exit(1);
    }
    else
    {
        printf("Memory allocation success :),%u\n",pArray);
        free(pArray);
        exit(0);
    }
}

  运行结果:
Memory allocation success :),3082084360

  如果再多分配一些内存,就会失败:
Memory allocation failure :(

  可是,当我这样分配内存时,它却成功了:
long *pArray=(long *)malloc(1000000000000000000000000000*sizeof(long));

  至于为什么以及如何改进,就留给大家自己思考了。

txi@ghosTunix.org:~> date
2008年 07月 08日 星期二 16:35:38 CST


C语言误区之void main() 0

2008年11月22日 01:45 in C/C++ tags:

  大学开学一个月了,看到了很多胡扯的老师和学生,具体的没必要浪费时间进行愤怒的驳斥了。先说说C语言的一个非常大的误区,在很多教材上都没有提到,甚至引用了这种错误的代码写法,就是著名的void main()问题。

  先来看一下这段看似正确的代码:

#include<stdio.h>
void main()
{
    printf("helloworld\n");
}

  然后使用gcc编译器进行编译,会提示警告:

txi@ghosTunix.org:test> gcc helloworld.c
helloworld.c: In function ‘main’:
helloworld.c:3: warning: return type of ‘main’ is not ‘int’

  不过没关系,程序照样能执行:

txi@ghosTunix.org:test> ./a.out
helloworld

  运行完全正确,但我们查看该程序的返回值会发现系统接受到了一个错误的返回值11:

txi@ghosTunix.org:test> echo $?
11

  可见,void main()其实根本就是一个错误的写法,系统在执行完这样一段程序后,得到的程序返回值是一个错误的返回值。

  在C语言的标准中,从来没有定义过void main()这样的写法,标准的main函数调用形式如下

#include<stdio.h>
int main(void)
{
    printf("helloworld\n");
    return 0;
}

  有了确切的返回值,程序能够在像用户需要的情况那样运行时,还能让系统很好的了解到程序已经成功或者错误地执行了。

txi@ghosTunix.org:~> date
Wed Oct 15 20:47:08 CST 2008