应该能看懂吧,需要了解的是ASCII码中48的值对应着’0’的值。
接下来就是gets和puts函数了。我个人还是比较喜欢着两个函数的,因为功能比较强大,如果是自己用scanf写一个读取字符的函数,不但费事,有些功能还做不到。
gets()函数是需要一个参数的,参数类型为字符串指针。指针这个概念后续会讲到,只要知道指针本质是个地址,用*实现指向地址所对应的数据就行了。而函数的返回值也是一个字符型指针,但是却不能用字符型的字符串首地址去承接,原因在于字符串名虽然也是指针,但是却不能够改写,比如这个语句:
char a[10],b[10]; b=gets(a);
这样的语句就不会报错,因为b作为b[10]的首地址,可使用,但不可改写。 但是下面这个小程序却可以其当地使用puts()函数,示例如下:
这里就是用gets先读取了这个字符串的首地址,然后给字符串赋值,最后再把字符串的地址返回给指针b。就是这样,很简单的。
而puts函数使用起来更简单一些,如果你需要输出一个字符串,只要把字符串名扔到参数列表里就可以了,示例程序如下:
可以看到,puts函数和gets函数的参数和返回值都是指针。需要注意的是puts()函数会在输出的时候自动换行,使用时要注意以下。其实指针还是挺简单的,如果学不好指针,根本谈不上学好C
语言,因为指针是C的精华所在。
至于puts的返回值你可以不用关心,这个在应用中比较少。补充一下,scanf的返回值是成功读取数据的个数,演示如下:
另外如果你想用scanf()读取含有空格的字符串,scanf会遗失信息,空格后面都不能读取,演示如下:
你可以发现这里scanf()在遇到空格的时候就终止了,没有继续读下去。这就是因为scanf在设计之初就只能读取到空格,这是函数设计之初就定好的,空格的值为32,而’\\0’的值为0,就是NULL的意思。而为什么scanf没读取完的字符”asd fgh”会被gets继续读取,涉及到一个输入缓冲区的概念,如果有兴趣,可以问我,就不在这里给你讲了,因为这个东西强哥的书上根本就没提。
另外还有时间函数,和时间有关的函数主要有time和rand函数了。time函数主要是返回当前的系统时间,返回类型是time_t,一个在time.h的函数中定义的量。其实如果你上机的话可以找一下这个定义,其实结果相当让人吐血,所谓的一个time_t就是一个long变量,就是通过那个typedef实现的定义。所以time函数返回的就是一个相当大的整数,这个经过处理可以转为当前时间,包括年月日时分秒,而其依据的的标准貌似是从197?年到现在所经历的秒数,具体时间记不清了。而rand函数则是返回一个随即数,是整数啊。而这个函数需要一个初始化函数,而这个初始化函数需要一个种子变量,所以就有了下面的语句:
srand((int)time(0));
这里time函数的参数不具体介绍了,是个指针,而0表示指针为空==NULL。这样rand函数就实现了初始化,不然你每次调用rand函数返回值都是一样的,那会让人很崩溃。
下面简单介绍一下rand函数的使用技巧:
rand函数返回的是一个很大的整数值,在使用的时候可以通过求余运算获取所需的随机数,比如从0到9十个数,可以通过如下的代码实现:
a=rand();
这样就能产生
0——9
的随机数了,以下是演示程序:
这样就生成了100个随机数,其实还有一个更好玩的方法,就是把代码中循环模块里那个i=10;去掉,然后就是这个效果了:
怎么样,挺有意思的吧。适当修改一下属性,就可以有黑客帝国的效果了…… 这个程序的代码:
#include
int temp,rand_num[10],i=10; srand((int)time(0)); for(int j=0;j<=9;j++) {
while(i--) {
rand_num[i]=rand(); printf(\ }
putchar('\\n'); }
system(\ return(0); }
可以自己运行一下,挺有意思的。
常用函数先介绍到这里,关于字符串的函数我会在下面的数组中专门讲解。
数组和指针
(假前的不完全版,后面有假期写的)
这部分的内容我打算把指针和数组结合起来讲,因为指针和数组在使用的时候基本是不分开的,规模稍微大一些的程序或函数基本都需要依靠指针完成数组的传递使用。那么接下来先讲数组。
一维数组
数组的内存中存在形式是一个数组在内存中统一占用一整块空间,是连续不可断开的。这样既有好处又有不足。好处是在你想寻址的时候,可以简单的依靠数组的顺序去进行处理,如果是而且在空间的使用上相对占用少。不过不足的地方就是在于整块空间的使用上,对存储空间相对挑剔。而且存储内容相对单一,比如说你创建了一个int a[10],那么这块空间除了整数的信息外不能包含其它的信息。如果你想存储一个人的信息,简单的包含姓名 年龄 性别,那么数组就无能为力了。而链表的好处在于可以随意使用存储空间,不需要连续的内存块。因为链表单元的内部存有地址变量,这样就通过这个地址变量(指针)把各个模块串联起来,使用的时候自己写的函数处理就可以了。另外就是存储的内容比较丰富,基本上是什么都有吧。不过数组结构小巧,在使用比较简单的数据时有很大优势,而结构体在存储某一类信息时又很好用。总的来讲是各有千秋吧,择优而用。
数组的声明形式:
数据类型 数组名[数字];
这里数组的大小主要由数组元素的数量和种类决定的,目前在计算机下的编程基本不需要考虑大小问题,基本上能实现目标就可以,而在一些微型计算系统上就需要好好的考虑了,比如C8051单片机的内存只有128B,占用空间大了内存是装不下的。
数组的种类:
数组基本分为三类,分别是整数型数组,字符串数组,浮点型数组。这里整数型数组和浮点型数组基本可以分为一类,因为这二者在使用方法上基本一致,而字符串数组的特殊之处就在于其首地址的使用上。
另外需要注意的是,数组的元素是从[0]号开始的,如果你声明了一个元素个数为N的数组,那么这个数组元素的最后一个元素位[N-1]。
另外一个注意事项是,数组的越界保护。需要说明的是,数组是没有越界保护机制的,这点完全依赖程序员自己了。比如说你声明了一个a[10],那么编译器给你提供的只有a[0]—>a[10]的10个元素。这些你能够随便使用而且不会出错的单位。而如果你现在使用a[10],那么你就是使用a[9],也就是第10个元素后面的那个元素。那个这个元素的值是什么?谁也不知道。根据我编程的经验,