一、知识点
1.字符串和字符指针
·如果定义一个字符指针接收字符串常量的值,该指针就指向字符串的首字符。这样,字符数组和字符指针都可以用来处理字符串。例如:
Char sa []=”array”;
Char *sp=”point”;
Printf(“%s”,sa);
Printf(“%s”,sp);
Printf(“%s ”,”string”);
输出:
Array point string
调用printf(函数),以%s的格式输出字符串时,作为输出参数,数组名sa、指针sp和字符串“string”的值都是地址,从该地址所指定的单元开始连续输出其中的内容(字符),直至遇到‘ ’为止。
·定义字符指针后,如果没有对它赋值,指针的值是不确定的,不能明确它指向的内存单元。
·为了尽量避免引用未赋值的指针所造成的危害,在定义指针时,可先将它的初值置为空。 如:char *s=NULL。
2.常用的字符串处理函数
·字符串的输入和输出:函数scanf()和gets()可用来输入字符串,而printf()和puts()输出字符串。它们在系统文件stdio.h中定义。
①scanf:格式控制字符串中使用格式控制说明%s,输入参数必须是字符型组名。该函数遇回车或空格输入结束,并自动将输入的数据和字符串结束符‘ ’送入数组中。
例如:scanf(“%s”,s);
②printf:格式控制字符串中相应的格式控制说明用%s,输出参数可以是字符数组名或字符串常量。输出‘ ’结束。例如:printf(“%s”,s);
③字符串输入函数gets(s):参数s是字符数组名。函数从输入得到一个字符串,遇回车输入结束,自动将输入的数据和‘ ’送入数组中。采用函数gets()输入的字符串允许带空格。实际上函数gets()有返回值,如果输入成功则返回值是字符串第一个字符的地址,如果输入失败则返回NULL。但一般情况下使用gets()主要是为了输入字符串,而不关心它的返回值。
④字符串输出函数puts(s):参数s可以是字符数组名或字符串常量。输出时遇‘ ’自动将其转换为‘ ’,即输出字符串后换行。同样函数puts()也有返回值,如果成功执行了输出字符串的操作,则返回换行符号‘ ’,否则返回EOF。
字符串A
#include<stdio.h>int main()
{
char str[80];
scanf("%s",str);
printf("%s",str);
printf("%s","Hello");
return 0;
}
字符串B
#include<stdio.h>int main()
{
char str[80];
gets(str);
puts(str);
puts("Hello");
return 0;
}
·字符串的复制、连接和比较及字符串长度:字符串复制、连接和比较及计算字符串长度的函数,在系统头文件string.h中被定义。
①字符串复制函数char *strcpy(char *s1,char *s2):该函数把字串符s2复制到s1,直到遇到s2中的‘ ’为止。s1要有足够的空间容纳s2,且s1中的内容被覆盖,函数返回的是S1。同样可以简化以上函数的表达形式为:strcpy(s1,s2);参数s1必须是字符型数组基地址,参数s2可以是字符数组名或字符串常量。例如:
Int i;
Char s1[80],s2[80]=”happy”;
Strcpy(str1,from);
Strcpy(str2,”key”);
第三条语句调用了函数strcpy()把from中的字符串复制给str1;第四条语句把字符串常量“key”复制给str2后,数组str1中存放了“happy”,数组str2中存放了“key”。
②字符串连接函数strcat(s1,s2)
参数s1必须是字符数组基地址,参数s2可以是字符数组名或字符串常量。strcat()函数将字符串s2接到字符串s1的后面,此时,s1中原有的结束符‘ ’被放置在连接后的结束位置上。数组s1的长度要足够大,以便存放连接后的新字符串。例如:
Char str1[80]=”hello”,str2[80],t[80]=”world”;
Strcat(str1,t);
Strcpy(str2,str1);
Strcat(str2,”!”);
先调用函数strcat()连接strl和t,结果放在strl中,再调用函数strcpy()将strl中的字符串赋给str2,最后调用函数strcat()连接str2和字符串常量“!”后,str2中存放了“Hello world!”。
③字符串比较函数strcmp(s1,s2)
和函数strcpy()中对参数的要求不同,函数strcmp()中的参数s1和s2可以是字符数组名或字符串常量。函数strcmp()返回一个整数,给出字符串s1和s2的比较结果:
若s1和s2相等,返回0。
若s1大于s2,返回一个正数。
若s1小于s2,则返回一个负数。
设str1和str2都是字符串,在C语言中,str1=str2、str1>str2和str1<=str2比较的是两个字符串的起始地址,而strcmp(str1,str2)==0、strcmp(str1,str2)>0和strcmp(str1,str2)<=0比较两个字符串的内容。
·字符串比较的规则:从两个字符串的首字符开始,依次比较相应的字符(比较字符的ASCII码),直到出现不同的字符或遇‘ ’为止。如果所有的字符都相同,返回0;否则,以第一个不相同字符的比较结果为准,返回这两个字符的差,即第一个字符串中的字符减去第二个字符串中的字符得到的差。例如:
Strcmp(“sea”,“sea”)的值是0,说明“sea”与“sea”相等。
Strcmp(“compute”,“compute”)的值(‘u’-‘a’)是个正数,说明“compute”大于“compyte”。
Strcmp(“happy”,“z”)的值(‘h’-‘z’)是个负数,说明“happy”小于“z”。
Strcmp(“sea”,“seat”)的值(‘ ’-‘t’)是个负数,说明“sea”小于“seat”。
④字符串长度函数strlen(s1):参数s1可以是字符数组名或字符串常量。函数strlen()返回字符串s1的‘ ’之前的字符个数。即字符串有效字符的个数(不包括字符结束符“ ”)。
例如:strlen(“happy”)的值是5,strlen(“A”)的值是1。
·如果使用C语言标准库中的字符、字符串函数,应在程序开始的预处理定义部分加上这些库函数所在的头文件名。
3.用指针实现内存动态分配
·动态内存分配的步骤:
①了解需要多少内存空间。
②利用C语言提供的动态分配函数来分配所需要的储存空间。
③是指针指向获得的内存空间,以便用指针在该空间内实施运算或操作。
④当使用完毕内存后,释放这一空间。
·动态内存分配函数:
①动态存储分配函数malloc()
函数原型:
Void *malloc(unsigned size)
注:虽然这里存储块是动态分配的,但它的大小在分配后也是确定的。不用越界使用,尤其不能越界赋值,否则可能引起非常严重的错误。
②计数动态存储分配函数calloc()
函数原型:
Void *calloc(unsigned n,unsigned size)
注:malloc()对所分配的存储块不做任何事情,calloc()对整个区域进行初始化。
③动态存储释放函数free()
函数原型:
Void free(void *ptr)
注:释放后不允许再通过该指针去访问已经释放的块,否则也可能引起灾难性错误。
④分配调整函数realloc()
函数原型:
Void *realloc(void *ptr,unsigned size)
4.结构的概念与定义
·结构是C语言中一种新的构造数据类型,它能够把有内在联系的不同类型的数据汇聚成一个整体,使它们相互关联;同时,结构又是一个变量的集合,可以按照对基本数据类型的操作方法单独使用其成员变量。
·结构类型定义的一般形式为:
struct 结构名{
类型名 结构成员名1;
类型名 结构成员名2;
...
类型名 结构成员名3;
};
·关键字struct和它后面的结构名一起组成一个新的数据类型名。结构的定义以分号“;”结束。
5.结构的嵌套定义
·在定义嵌套的结构类型时,必须先定义成员的结构类型,再定义主结构类型。
6.结构变量的定义和初始化
三种定义结构变量的方式:
①单独定义:先定义结构类型,再定义具有这种结构类型的变量;
struct friends_list{
char name[10];
int age;
char telephone[13];
};
struct friends_list friend1,friend2;
②混合定义:在定义结构类型的同时定义结构体变量;
struct friends_list{
char name[10];
int age;
char telephone[13];
}friend1,friend2;
③无类型名定义:在定义结构体变量时省略结构体名;
struct{
char name[10];
int age;
char telephone[13];
}friend1,friend2;
7.结构变量的使用
①结构变量成员的引用
格式为:结构变量名.结构成员名
②结构变量的整体赋值
·如果两个结构变量具有相同的类型,则允许将一个结构变量的值直接赋给另一个结构变量。例如:s1=s2。
注:只有相同结构类型的变量之间才可以直接赋值。
③结构变量作为函数参数
·如果程序中含有结构类型的数据,就有可能需要用结构变量作为函数的参数或返回值,以便在函数间传递数据。
·结构变量的特点:可以传递多个数据且参数形式较简单。但是,对于成员较多的大型结构,参数传递时所进行的结构数据复制使得效率较低。
二、实验过程中遇到的问题及解决方法
1.在使用字符串复制函数strcpy时要注意(s1,s2)的位置,跌倒了就会导致程序错误。(多加深理解,多尝试练习)
2.把函数对应的函数类型使用错误,使程序错误。
(在使用函数定义的同时要注意变量的类型,要做到准确对应。)
三、实验心得体会
本次作业的综合性更强了,需要我们严谨小心的去完成,对于字符串的应用不熟练,理解不透彻,第二题用字符串部分新知识暂时完成不了,需要跟老师请教后再进一步完成,程序难度在不断增加,需要我们更多的时间和精力去学习理解,加强练习。