C与指针——指针(二)

编程练习(续)

2.

请编写一个函数,删除一个字符串的一部分。函数的原型如下:

int del_substr(char *str,char const *substr)

函数首先应该判断substr是否出现在str中。如果它并未出现,函数就返回0;如果出现,函数应该把str中位于该子串后面的所有字符复制到该子串的位置,从而删除这个字串,然后函数返回1。如果substr多次出现在str中,函数只删除第1次出现的字串。函数的第2个参数绝对不会被修改。
举个例子,假定str指向ABCDEFG。如果substr指向FGH、CDF或XABC,函数应该返回0,str未作任何修改。但如果substr指向CDE,函数就把str修改为指向ABFG,方法是把F、G和结尾的NUL字节复制到C的位置,然后函数返回1。不论出现什么情况,函数的第2个参数都不应该被修改。
和上题的程序一样(上一题在我上一篇blog末尾):
a.你不应该使用任何用于操纵字符串的库函数(如strcpy,strcmp,等)。
b.函数中的任何地方都不应该使用下标引用。
一个值得注意的是,空字符串是每个字符串的一个子串,在字符串中删除一个空子串字符串不会产生变化。

程序如下:

#include<stdio.h>
int del_substr(char *str,char const *substr);
void main()
{
    char s[15]="ABCDEFG",t[3]="CDE";
    printf("str=%s\nsubstr=%s\n",s,t);
    del_substr(s,t);
    printf("The deleted string is: ");
    puts(s);
}
int del_substr(char *str,char const *substr)
{
   int flag=0,n;
   char *st=str; //将str的值赋给指向字符型指针的st 
   char *su=(char*)substr;
   char *st_r,*su_b;
   while(*st){     //当指针变量st所指向的对象存在,whlie(*st)等价于while(*st!=0) 
    if(*st==*su){ //st与su指向同一个地址单元,即字符C
      st_r=st; //st_r为CDEFG 
	  su_b=su; //su_b为CDE
	  n=0;
	  
      while(*st_r&&*su_b){ //当指针变量st_r与su_b所指向的对象存在 
       if(*st_r!=*su_b) break; //当st_r与su_b指向的字符不等时,即st_r为FG时,则跳出while循环 
       else{                   //当st_r与su_b都指向C时,各自加1 
          st_r++;su_b++;n++;   //n代表了st_r与su_b相等的字符数,即n=3 
        } 
     }    //这里的while语句主要为计算n
     
     if(!(*su_b)){ //如果此时以su_b变量内容为地址的那个变量不存在 
       st_r=st+n;  //令st_r赋值为st中位于相同字符串后面的所有字符,即FG 
        while(*st_r){  //当st_r所指向的对象为真,即FG存在 
         *(st_r-n)=*st_r;  //将FG赋值到(与su_b)相同字符串的位置,即将指向C变为指向F 
            st_r++;  //在这个例子中加到G即可 
        }
     } 
     *(st_r-n)='\0'; //此时执行完毕的字符串应以NUL结尾 
    }
     st++; //若st与su指向的地址单元不同,则继续比较下一个地址单元 
   }
   return 0;
}


运行结果:
在这里插入图片描述

flag不是c语言的关键字,其通常用来作为一个指示变化的变量的名称,C语言中一般设置一个变量flag,是一个来表示判断的变量,当做标志。
例如当一种情况的时候,置flag为1,当另外一种情况时,置flag为2。 变量名为flag,只是习惯问题,也可以取别的名字。

一个变量的指针的含义包含两个方面:
1.是以存储单元编号表示的地址(如编号为2000的字节);
2.是它指向的存储单元的数据类型(如int,char,float 等)。

指针变量中只能存放地址(指针),不可将一个整数赋给一个指针变量。
*p ——取出以p变量内容为地址的那个变量的值
若要通过函数改变某个变量的值,必须传入这个变量的地址然后用指针进行修改。

引用数组中各元素的值有3种方法:
(1)下标法,如a[i]形式;
(2)指针法,如*(a+i)或*(p+i)。其中a是数组名,p是指向数组元素的指针变量。

3.

编写函数reverse_string,它的原型如下:

void reverse_string(char *string);

函数把参数字符串中的字符反向排列。请使用指针而不是数组下标,不要使用任何C函数库中用于操纵字符串的函数。
提示: 不需要声明一个局部数组来临时存储参数字符串。

分析: 这个算法的关键是当两个指针相遇或擦肩而过时就停止。否则,这些字符将翻转两次,实际相当于没有任何效果。

程序如下:

//函数把参数字符串中的字符反向排列
#include<stdio.h>

void reverse_string(char *string);

int main(){
	char string[]="ABCDEFG";
	printf("The original string :%s\n",string);
	reverse_string(string);
	printf("The anti_string :%s",string);
	return 0;
}
/*翻转参数字符串*/ 
void reverse_string(char *string){
	char *last_char=string;
	//将last_char设置为指向字符串的最后一个字符 
	while(*last_char!='\0') 
	    last_char++; //while循环结束后,last_char指向NUL 
	 last_char--; //向前退一个单元,last_char指向字符串最后一个字符G 
	 
	 /*交换string和last_char指向的字符,string前进一步,
	 last_char后退一步,在两个函数擦肩而过之前重复此过程  */ 
	while(string<last_char){
		char temp=*string;  
		*string=*last_char;
		*last_char=temp; //string和last_char所指向的字符互换 
		string++;  //string前进一步,即接下来指向B 
	    last_char--;  //last_string后退一步,即指向F 
	}
}

运行结果:
在这里插入图片描述
关于字符串的翻转,还可以使用递归的方法:

#include<stdio.h>
int main(int argc)
{
    char c=getchar();
    if(c!='\n')
    {
        main(0);
        putchar(c);
    }
    if(argc) putchar('\n');
    return 0;
}

这一章节的有些程序会稍微牵扯到链表等数据结构
若提前有一定算法基础的,便不会花费太多时间了
关于《C程序设计》这本书,细节方面真的是很棒了
之前甚觉繁琐,而现今编程遇到问题时
才觉得繁(xiang)琐(xi)有多可贵


很多知识点只有在上手编程的过程中 才能深刻理解与掌握
指针先生,久仰大名,您可真是百闻不如一用呢

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值