(九十五)函数与C-风格字符串

当传递给函数的是C-风格字符串时,和将数组传递给函数类似。

但传递C-风格字符串给函数时,首先是代码:

char a[10] = "abcdef";

char *b = a;

函数原型:char abc(char* a,int m);
//m是字符串长度,非必须

这个时候,将字符串传递给函数的时候,

参数有三种形式:

①abc(a); //这种方式是将字符串作为参数

②abc(b); //这种方式是将指向字符串的指针作为参数

③abc("abcdef"); //这种方式是将字符串常量作为参数

 

①和②优点,是可以通过指针或字符串(此时字符串是地址)作为参数,然后直接修改字符串内容。

③的优点,是直接传递的常量(注意,这个时候传递的不是字符串a)。

 

其中①和②是可以修改的,③是不能修改字符串的。假如要禁止字符串的修改,那么在函数原型和函数头加上const关键字,并相应在其他地方加上const关键字。

 

字符串作为地址时,实际上是字符串第一个字符的内存地址。

 

如代码:

#include<iostream>
using namespace std;
char abc(char* a);		//函数abc,返回值为char类型

int main()
{
	char a[10] = "abcdef";	//创建字符串a
	char *b = a;	//创建指针b指向数组a
	char c=abc(b);	//调用函数b,实参为指针b,返回值赋值给char变量c
	cout << a << endl;	//打印字符串a
	cout << c << endl;	//打印字符c(是abc函数返回值)
	system("pause");
	return 0;
}

char abc(char* a)
{
	for (; *a!=0;a++)	//指针不断偏移,直到遇见空字符0。也可以写为*a !='\0'
		*a = 'h';	//给指针指向的地址赋值字符h
	a--;	//因为这个时候指针指向的是空字符,所以往回偏移一个char距离
	return *a;
}

输出:

hhhhhh
h
请按任意键继续. . .

字符串和char数组的区别:

字符串和char数组的最大区别是,字符串的最后有结束字符(“\0”,ASCII值为0),而不以其为结尾的,则是char数组。

 

假如不写完,就容易导致有问题,例如:输出字符串的时候,输出的是烫(貌似烫是因为乱码)。

 

用函数返回字符串:

用函数返回字符串的方法,是将函数制作为指针函数。

例如函数头:char *abc(int*m,int n);

这个时候,abc是函数名,int*m是实参传递的字符串地址,int n是字符串的宽度。如代码:

#include<iostream>
using namespace std;

char *hanshu(char*m, const int n);

int main()
{
	char m[4] = "mab";
	char *f = hanshu(m, 4);	//调用函数hanshu,参数分别为字符串m的第一个字符的地址,和字符串长度4
	cout << m << endl;	//输出第一个字符串
	cout << f << endl;	//输出第二个字符串
	system("pause");
	return 0;
}

char *hanshu(char*m, const int n)	//char指针函数
{
	char *x = new char[n];	//new一个字符串x,长度为传递的参数n
	char a = m[0];	//字符a为传递的地址m所指向地址(char类型)的值,是参数指向地址(字符串mab)的第一个字符,即m
	for (int i = 0;i < n - 1;x++,i++)
		*x = a;	//偏移指针,并赋值为字符变量a的值(m)
	*x = '\0';	//最后一个位置填上'\0'字符
	x = x - n + 1;	//再把指针移回去
	return x;	//返回指针位置,即字符串第一个字符的位置
}

输出:

mab
mmm
请按任意键继续. . .

总结:

①函数可以返回地址(像声明指针那样)。

 

②函数不能在返回地址的时候同时返回字符串的长度(但可以通过给字符串指定位置赋值'\0'字符)

 

③也可以在new字符串之后,不能忘记字符串的结尾是\0,否则会出问题。

可以这样,如代码:

char *hanshu(char*m, int n)	//char指针函数
{
	char c = *m;
	char *a = new char[n+1];	//+1是空字符,不然下面的都要相应-1
	a[n] = '\0';	//n=4时,n+1=5个成员,a[4]是第五个成员,是空字符
	while (n-- >0)
		a[n] = c;	//这里是上面已经n-1之后的值,例如上面n=1时,n-->0,然后n=0,于是a[n]是a[0]
	return a;	//返回指针位置,即字符串第一个字符的位置
}

函数与字符串总结:

①字符串的结尾是" \0 "

 

②假如是void 变量名(char*指针, int 字符串长度);

传递的参数是指针,不能直接通过指针修改字符串,只能通过例如:指针名[0]这样,逐个修改字符。

如代码:

char word[4] = "mab";
hanshu(word);
void hanshu(char*m)	//char指针函数
{
	m[0] = 'c';
	m[1] = 'c';
	m[2] = 'c';
}

这样来修改字符串。或者使用wihle或者for循环,循环更新使用例如m++这样来移动指针。

因为需要逐个修改字符,所以有必要引入字符串长度,正如②的第一行那么写。在函数内,可以像以上代码那样逐个修改,也可以使用循环for或者while进行修改。

至于为什么需要逐个修改字符,不能一次直接修改,不知道……猜测是因为指针类型是char*,所以不能一次修改。

 

③假如是有返回值的字符串变量,返回值通常为指针地址——非指针地址情况参照(4);

注意,字符串应以空字符结尾。

有几种情况:

(1)在函数内使用char 变量名[字符串长度]

由于字符串长度要求是常量,即使函数头传递的参数被const所限定,也是不能使用的,只能直接输入数字。所以这个办法——×

 

(2)在函数内使用char *指针名 = new char[字符串长度]

这种情况下,字符串长度可以为函数头传递的参数,并且,不需要一定使用const进行限定。如函数头:char *指针名(int 变量名) 这样的。当然,也可以是char *指针名(const int 变量名)  这样的,这个办法——√

 

④函数头:void开头——无返回值;

char *开头,有返回值,返回值为 指针 或 函数内被static限定的字符串名;

 

⑤函数头传递的参数:

通常有(1)int类型的字符串长度;(2)char*类型的指针名/字符串名等;

 

需要函数读取传递的参数(如字符,或者指针),来作为新字符串的字符的话,在函数头使用 指针、字符串名、或者字符 作为参数。

如:char *指针名( char 变量名, int 字符串长度) ;

也可以将char 变量名改为char*指针名 或 char 字符串名[] 等。

 

⑥返回值,有以下几种情况:

无返回值——函数头使用void,函数往往是通过传递的指针地址来修改字符串。

有返回值——函数头使用char*字符串(传递的参数),返回值为指针名 或 被static限定的字符串名。通过返回值的地址,来修改字符串。

 

⑦函数本身:

修改原有字符串:需要让指针/字符串名作为传递的参数,然后逐个修改字符串的每个成员。

创建新字符串:需要传递字符串长度(除非默认字符串长度为固定值),返回值为指针名(因为函数头不能为字符串名,即char 字符串名[字符串长度](传递的参数)——应该吧),因此,函数内部也不能把字符串名作为返回值(因为函数执行完后,临时变量会被删除,而new指针指向的地址不会被删除)。

——但是若用static关键字 限定 字符串名,则可以用字符串名作为新字符串的返回值。如代码:

#include<iostream>
using namespace std;

char *abc(int);

int main()
{
	int a = 5;
	char *b = abc(a);
	cout << b << endl;
	system("pause");
	return 0;
}

char *abc(int m)
{
	char *a = new char[m];
	a[--m] = '\0';
	while (m-- > 0)
		a[m] = 'a';
	static char c[4];
	for (int i = 0;i < 3;i++)
		c[i] = a[i];
	c[3] = '\0';
	return c;
}

输出:

aaa
请按任意键继续. . .
时间: 2024-09-21 23:00:14

(九十五)函数与C-风格字符串的相关文章

在主函数中输入一个字符串str1,调用函数。

问题描述 在主函数中输入一个字符串str1,调用函数. 在主函数中输入一个字符串str1,调用函数chage(str1,N);将str1 中的小标为奇数的字符取出构成一个新的字符串放入字符串str2中.然后在主函数中输出字符串str2.运用到数组的引用. #include #define N 10 using namespace std; void chage(char str2[],int n); int main() { char str1[N]; for(int i=0;i cin>>s

C 风格字符串,C++string类,MFC,CString类的区别。

字符串,顾名思义是由字符组成的字符串,在标准C,标准C++,MFC中 字符串这一功能的实现是不相同的,C++完全兼容了C. 1.  标准C中的字符串    在标准C中没有string这样的数据类型,C中的字符串是有char类型的字符数组或者char类型的字符指针来实现的.例如:      char   name[26]="This is a C-style string"; 或者      char  *name="This is a C-style string"

C风格字符串

尽管C++支持C风格字符串,但在C++程序中最好还是不要使用它们.这是因为C风格字符串不仅使用起来不太方便,而且极易引发程序漏洞,是诸多安全问题的根本原因. 字符串字面值是一种通用结构的实例,这种结构即是C++由C继承而来的C风格字符串.C风格字符串不是一种类型,而是为了表达和使用字符串而形成的一种约定俗成的写法.按此习惯书写的字符串存放在字符数组中并以空字符串结束.以空字符结束的意思是在字符串最后一个字符后面跟着一个空字符('\0').一般利用指针来操作这些字符串. C标准库String函数

c c++-写一个函数判断输入的字符串是否是一个点分十进制格式的IP地址

问题描述 写一个函数判断输入的字符串是否是一个点分十进制格式的IP地址 写一个函数判断输入的字符串是否是一个点分十进制格式的IP地址 解决方案 #include ""winsock2.h""#pragma comment(libws2_32.lib"")BOOL CheckIsValidIP(const char* sIP){ unsigned long ulAddress = inet_addr(sIP); if (INADDR_NONE ==

Viusla Basic 6..0 语言编写一个函数,把uncode字符串转换为utf-8字符串

问题描述 Viusla Basic 6..0 语言编写一个函数,把uncode字符串转换为utf-8字符串 Viusla Basic 6..0 语言编写一个函数,把uncode字符串转换为utf-8字符串 解决方案 dim e as object Set?e=CreateObject("MSScriptControl.ScriptControl") e.Language?=?"javascript" dim d as stringd=?e.Eval("en

asp.net-C#中params的使用,为什么在调用函数时会出现输入字符串的格式不正确的问题

问题描述 C#中params的使用,为什么在调用函数时会出现输入字符串的格式不正确的问题 第一张是我写的函数, 第二张是调用出错 请问该怎么改,我需要传递到函数中的参数是不定个整形参数 解决方案 s.getinfo();//这个括号里你放个int型数组,然后将你的数给这个数组应该就可以了,你试试:要不然括号里的你要加花括号的,因为是一个数组: 如果回答对你有帮助,请采纳 解决方案二: params的用法没有错,可以试试这个,用法是一样的 using System; namespace Conso

DockOne微信分享( 九十五):树莓派上的Docker集群管理

本文讲的是DockOne微信分享( 九十五):树莓派上的Docker集群管理[编者的话]随着IOT市场的火热发展,Docker天然的轻量级以及帮助业务快速重构的特性,将会在IOT领域迎来巨大发展潜力,甚至有可能会比它在云端的潜力更大.本文将致力于构建一个利用Rancher&RancherOS来管理运行在树莓派上的容器集群. 目前业界主流基本都是在x86架构上使用Docker,除了因为Intel在服务器领域的绝对领导地位之外,x86 CPU的确在性能上有着卓越的表现.但是近些年来,随着云计算的迅猛

c++中使用equal 比较两个C风格字符串vector的问题

问题描述 c++中使用equal 比较两个C风格字符串vector的问题 c++primer(第5版)中的一个练习题 P339 T10.5 如果两个容器中保存的是c风格字符串 list<const char *> ,运用equal 比较两个容器会出现什么样的结果? #include <list> #include <iostream> #include <algorithm> #include <numeric> using std::list;

php使用字符串截取函数从结尾删除字符串

修复了一个获取控制器名称方法的bug 控制器的名称都是使用act结尾,使用过程中要删除act. 1.原来的方法 //使用替换act的方法获取控制器名称,很显然当控制器的名称出现act三个字符的时候都会被替换掉产生bug $actName = str_replace( 'act', '', 'ad_client_contactact'); 控制器名称 ad_client_cont 2.修复后的方法 //从结尾删除三个字符串 $actName = substr('ad_client_contacta