当传递给函数的是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 请按任意键继续. . .