在C语言中,地址也作为一种值,能被存储、比较、赋值,并称地址数据为指针类型,而称存储地址值的变量为指针变量,简称指针。C程序可用运算符&取变量的地址,如表达式&x
的值就是变量X的地址。程序除能按名引用变量外,也可利用变量的地址引用变量。按变量名引用变量称为直接引用,而将变量A的地址存于另一变量B中,借助于变量B引用变量A称为对A的间接引用。
指针的基本概念
为了区别内存的不同位置,内存被分成字节,内存的全部字节顺序地赋予一个称为地址的编号。程序中的变量将在内存中占据一定的内存字节,在这些字节中存储的数据信息称为变量的内容。一个变量占用连续的若干个内存字节时,最前面的一个字节的地址就作为该变量的地址。指针就是内存地址,是变量的地址,或函数的入口地址。变量的地址在程序执行时,起着非常重要的作用。当计算机在计算含有变量的表达式时,计算机按变量的地址取出其内容,并按变量的地址将计算结果存入到变量占据的内存中。如代码:
int x=l;
x=x+2;
其中语句“x=x+2;”中的第一个x涉及到变量x占据的内存,第二个 x是引用变量 x的内容。该语句的意义是“取X的内容,完成加上2的计算,并将计算结果存入变量X占据的内存中。”
字符串
称最后有字符率结束符'\0'的字符序列为字符串。字符数组中存储的字符序列本身并不要求最后一定要有字符'\0'.但当字符数组内存储的内容需要作为字符串时,就必须要有标记符'\'.当字符数组内存储的是字符串时,可用“%s”格式输出,若是普通的字符序列,则它不能用格式“%s”输出,而只能结合循环用格式“%c”输出。
指定元素个数的字符数组用字符串常量给它初始化时,其元素个数不能小于字符串常量的字符数,但数组的元素个数可以等于字符串常量的字符数。例如,
char ss[3]=“abc”;
则 ss[0]='a',ss[l]='b', ss[2]='c'.此时,字符数组ss中存储的是字符序列,不是字符串。
字符率结束标记符的代码是8位全0,称为空字符,程序用'\0'来标记。字符串的结束标记符紧接在字符串的有效字符列之后。例如,一个有8个有效字符的字符串,其长度为8个字符,但在它的第九个位置存有结束标记符'\0'.
请读者注意以下几点:
(l)字符率与存储字符串的字符数组有区别。字符率的有效字符是指从所指位置的第一个字符开始至字符串结束标记符之前的那些字符。格式符“%s”只输出字符串的有效字符,而不会再继续输出字符率结束标记符及其之后的字符。例如,
char str[50]=“Pas\0cal Cobol Fortran C”;
printf(“%s\n”,str) ;
将只输出:Pas
而实际上,数组str[]字符率结束符之后还存有其它许多字符。
(2)用“%s”格式输出字符串时,不包括字符串结束标记符。对应的输出项是字符串或字符串名。字符数组名可作为字符串名。对于上例,写成
printf(“%s”,s[0]);
是错误的。因s[0]是数组s的元素,是一个字符,不是字符串。
(3)在调用scanf()为字符数组输入字符串时,输入项是数组名,不要加地址运算符&.
(4)若用“%c”格式结合循环输入字符序列,若程序又想将输入的字符序列构成字符串,则程序必须用赋值语句在字符列之后存入字符串结束标记符,使其变成字符串。
程序经常要处理许许多多的字符串,如存储星期的名称。同时存储众多字符串的一个实现方法是定义一个二维字符数组,让二维数组的每一行存储一个字符串。这样做,要求数组每行元素个数应比可能最长的字符串字符个数还要多1个。如下面的示例所示:
char weekDay[][9]= {“Sunday”,“Monday”,“Tuesday”,“Wednesday”,
“Thursday”,“ Friday” ,“Saturday”};
在C程序中,存储多个字符串更好的方法是用指针数组。
常用字符串库函数
求字符串长度函数strlen()
函数调用 strlen(str)返回str中的有效字符(不包括'\0')的个数。
字符串拷贝函数strcpy()
函数调用Strcpy(strl,str2) 将字符串str2拷贝到字符数组strl.要求字符数组strl足够大,以便能容纳被拷贝的str2的全部内容。
限制字符数的字符串拷贝函数strncpy()
函数调用strncpy(strl,str2,n)的作用是将str2中的前n个字符拷贝到strl(并附加'\0')。其中n是整型表达式,指明欲拷贝的字符个数。如果str2中的字符个数不多于n,则函数调用
strncpy(strl,str2,n)等价于strcpy(strl,str2)。
字符串连接函数strcat()
函数调用strcat(strl,str2) 将str2内容拷贝接在字符数组strl中的字符串的后面。要求字符数组strl必须足够大,以便还能容纳str2的内容。该函数调用返回strl的开始地址。注意:字符串连接前,strl和str2都各自有'\0',连接后,strl中原来的'\0'在拷贝时被覆盖掉,而在新的字符率有效字符之后再保留一个'\0'.例如
char strl[30]=“Beijing”;
char str2[30]=“ Shanghai”;
函数调用
strcat(strl,str2);
printf(“%s \n”,strl);
将输出:
BeijingShanghai
字符串比较函数strcmp()
函数调用strcmp(strl,str2)批较两个字符串的大小,对两个字符串自左至右逐对字符相比较(按字符的 ASCII代码值的大小),直至出现不同的字符或遇到'\' 字符为止。如直至'\' 字符,全部字符都相同,则认为相等,函数返回0值;若出现不相同的字符,则以这第一对不相同的字符比较结果为准,若strl的那个不相同字符小于str2的相应字符,函数返回一个负整数;反之,返回一个正整数。
注意:对字符串不允许施行关系运算符比较两字符之间的大小关系,必须类似于本函数那样,通过逐个字符的比较来实现。
字符串输出函数puts( )
函数调用 puts(str) 将 str的字符串输出到终端,并将 str中的'\'以字符转换成换行符'\n'输出。即输出字符串内容后,并换行。所以,puts(str)相当于printf(“%s\n”,str)。
字符串输入函数gets( )
函数调用gets(str)从终端输入字符序列(包括空白符)到字符数组str,字符序列以回车符作为结束,并将输入时的回车符转换成'\'字符存储。该函数调用返回str的存储开始地址。调用get()函数与用“%s”格式调用格式输入函数scanf输入字符串不同,后者会自动跳过前导空白符,并以非空白符之后的空白符结束。前者用于输入一行内的全部字符,包括可能有的空白符,存放于字符数组str,并将最后读人的换行符转换成字符率结束标记存储在str中。