当前位置: 首页 > news >正文

【时时三省】(C语言基础)字符指针作函数参数

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省

如果想把一个字符串从一个函数“传递”到另一个函数,可以用地址传递的办法,即用字符数组名作参数,也可以用字符指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以引用改变后的字符串。

例题1

用函数调用实现字符串的复制。

解题思路:

定义一个函数copy_string用来实现字符串复制的功能,在主函数中调用此函数,函数的形参和实参可以分别用字符数组名或字符指针变量。分别编程,以供分析比较。

编写程序:

( 1 )用字符数组名作为函数参数

运行结果:

程序分析:

a和b是字符数组。copy string函数的作用是将from [ i ]赋给to [ i ],直到from [ i ]的值等于' \0 '为将from [ i ]赋给to [ i ],直到from [ i ]的值等于' \0 '为止。在调用copy string函数时,将a和b第1个字符的地址分别传递给形参数组名from和to。因此from [ i ]和a [ i ]是同一个单元,to[ i ]和b [ i ]是同一个单元。由于b数组原来的长度大于a数组,因此在将a数组复制到b数组后,未能全部覆盖b数组原有内容。b数组最后3个元素仍保留原状。在输出b时由于按%s(字符串)输出,遇' \0’即告结束,因此第一个' \0 '后的字符不输出。如果不采取% s格式输出而用% c逐个字符输出是可以输出后面这些字符的。

( 2 )用字符型指针变量作实参copy_string函数不变,在main函数中定义字符指针变量from和to,分别指向两个字符数组a,b。

运行结果与程序(1)相同。

程序分析:

指针变量from的值是a数组首元素的地址,指针变量to的值是b数组首元素的地址。它们作为实参,把a数组首元素的地址和b数组首元素的地址传递给形参数组名from和to(它们实质上也是指针变量)。其他与程序(1)相同。

( 3 )用字符指针变量作形参和实参

运行结果同上。

程序分析 

形参改用char*型变量(即字符指针变量)。在程序(1)和( 2 )中copy_string函数的形参用字符数组名,其实编译系统是把字符数组名按指针变量处理的,只是表示形式不同。copy_string函数中不是用下标法引用数组元素,而是通过移动指针变量的指向,找到并引用数组元素。

main函数中的a是字符指针变量,指向字符串“I am a teacher .”的首字符。b是字符数组,在其中存放了字符串“You are a student .”。p是字符指针变量,它的值是b数组第一个元素的地址,因此也指向字符串" You are a student .”的首字符。copy string函数的形参from和to是字符指针变量。在调用copy string时,将数组a首元素的地址传给from,把指针变量p的值(即数组b首元素的地址)传给to。因此from指向a串的第一个字符a[0],to指向b [ 0 ]。在for循环中,先检查from当前所指向的字符是否为' \0 ',如果不是,表示需要复制此字符,就执行“* to = *from”,每次将* from的值赋给* to,第1次就是将a串中第1个字符赋给b数组的第1个字符。每次循环中都执行“from ++”和“to ++”,使from和to分别指向a串和b数组的下一个元素。下次再执行“* to = * from”时,就将a串中第2个字符赋给b [ 1 ]…最后将' \0 '赋给* to,注意此时to指向哪个单元。

程序改进:

对copy_string函数还可以改写得更精练一些,可以作以下一些改动:

( 1 )将copy_string函数改写为

void copy string ( char * from , char * to )

{while ( (*to = *from ) ! =' \0 ' )

 { to + +;from + +;}

}

请与上面程序对比。在本程序中将“* to = * from”的操作放在while语句括号内的表达式中,而且把赋值运算和判断是否为' \0 '的运算放在一个表达式中,先赋值后判断。在循环体中使to和form增值,指向下一个元素……直到*from的值为' \0 '为止。

( 2 ) copy_string函数的函数体还可改为

{while ( ( * to + + = * from++ ) ! =' \0 ');}

把上面程序的to + +和from++运算与* to = *from合并,它的执行过程是,先将* from赋给* to,然后使to和from增值。显然这又简化了。

( 3 ) copy_string函数的函数体还可写成

{ while ( * from ! = \0 ' )

     *to++ = *from++;

  *to='\0';

}

当* from不等于0时,将* from赋给xto,然后使to和from增值。

( 4 )由于字符可以用其ASCII码来代替(例如,“ch = ' a '”可用“ch = 97”代替,“while ( ch ! = ' a ' )”可以用“while ( ch ! = 97 )”代替)。因此,“while ( * from ! = ' \0 ' )”可以用“while ( * from ! = 0 )”代替( ' \0 '的ASCII代码为0 )。而关系表达式“* from ! = 0”又可简化为“* from”,这是因为若* from的值不等于0,则表达式“* from”为真,同时“* from ! = 0”也为真。因此“while ( * from ! = 0 )”和“while ( * from )”是等价的。所以函数体可简化为

{while ( * from )

to + + = * from + +;

* to =' \0 ' ;

}

( 5 )上面的while语句还可以进一步简化为下面的while语句:

while ( * to + + = * from++ );

它与下面语句等价:

while ( ( * to + + = * from++ ) ! =' \0 ' );

将* from赋给*to,如果赋值后的*to值等于'\0 ',则循环终止( '\0 '已赋给* to )。

( 6 )函数体中也可以改为只用一个for语句:

for (;( * to + + = * from++ ) ! = 0;););

for (;*to + + = * from++;);

( 7 )也可以用字符数组名作函数形参,在函数中另定义两个指针变量pl,p2。函数copy_string可写为

void copy_string ( char from[] , char to [] )

{char * pl , * p2 ;

pl = from ; p2 = to ;

while ( ( * p2 + + = *p1++ ) ! =' \0 ');

}

 

http://www.dtcms.com/a/289642.html

相关文章:

  • 如何系统性备考网络规划师
  • TCL --- 列表_part1
  • 第459场周赛
  • 开源社区贡献指南:如何通过Three.js插件开发提升企业技术影响力?
  • 【JS逆向基础】数据库之mysql
  • Python,GPU编程新范式:CuPy与JAX在大规模科学计算中的对比
  • 【企业架构】TOGAF概念之一
  • Linux基础命令详解:从入门到精通
  • 详解Mysql解决深分页方案
  • 试用SAP BTP 05A:AI服务-Document Information Extraction
  • Python桌面版数独(二版)-增加4X4、6X6
  • 小型支付项目3-5:检测未接收到或未正确处理的支付回调通知
  • 论文笔记:Seed: Bridging Sequence and Diffusion Models for RoadTrajectory Generation
  • LLM指纹底层技术——KV缓存压缩
  • 嵌入式通信DQ单总线协议及UART(一)
  • 是否可以将“进化”应用到软件系统的设计中?
  • 049_List接口(ArrayList / LinkedList / Vector)
  • Three.js + WebGL 深空星波粒子动画特效制作详解
  • 30天打牢数模基础-模拟退火算法讲解
  • 零基础100天CNN实战计划:用Python从入门到图像识别高手
  • k8s:离线添加集群节点
  • Java中的ScopeValue 使用详解
  • 深入解析业务代表模式:解耦表示层与业务层的利器
  • 列空间与零空间,秩—零化度定理
  • ( LeetCode 面试经典 150 题 ) 202. 快乐数 (快慢指针)
  • [simdjson] `error_code` | .get() | 异常 | is_fatal() | current_location() | 链式处理
  • 限流算法与实现
  • MySQL锁(一) 概述与分类
  • CMSIS-RTOS线程创建osThreadNew
  • JAVA国际版任务悬赏+接单系统源码支持IOS+Android+H5