指针函数
1、学习目标
- 掌握指针函数的用法
- 总结与思考
2、指针函数
-
指针函数是指一个函数的返回值为地址量的函数。
-
指针函数的定义,一般形式如下:
-
<数据类型> * <函数名称>( <参数说明>) {
语句序列;
}
-
-
下面程序是否有问题,若有问题,如何修改?
#include <stdio.h> char * mystring() { char str[20]; strcpy(str, "Hello"); return str; } int main() { printf("%s\n", mystring()); return 0; }
错误:1.strcpy();没有引用库函数<string.h>
2.“return str;”返回值str是局部变量,执行会出现乱码或段错误。
局部变量执行完就会立即清除,不会一直占用内存。
-
一种错误修改
#include <string.h> char * mystring(); int main() { / cahr * r; r = getstring(); printf("%s\n", mystring()); (*r)++; puts(r);/这样修改是不对的 return 0; } char * mystring() { char str[20]; strcpy(str, "Hello"); return str; }
程序中带*号的,这个程序内存有问题,执行结果是不确定的。
-
一种正确的修改方式
#include <stdio.h> #include <string.h> char * mystring(); int main() { char * r; r = mystring(); printf("%s\n", mystring()); (*r)++; puts(r); return 0; } char * mystring() { static char str[20];//static静态变量 strcpy(str, "Hello"); return str; }
-
一种不建议的修改方式
#include <stdio.h> #include <string.h> char * mystring(); int main() { char * r; r = mystring(); printf("%s\n", mystring()); // (*r)++; puts(r); return 0; } char * mystring() { // static char str[20]; char * str = "hello";//字符串常量 // strcpy(str, "Hello"); return str; }
使用字符串常量,变量无法修改。
-
有三种修改方式:返回值为:
- 全局变量的地址;
- static变量的地址;
- 字符串常量的地址;
-
3、例程
-
编写一个指针函数,删除一个字符串中的空格。
-
程序如下:
#include <stdio.h> #include <string.h> char * del_space(char * s); int main() { char * r; char str[] = " how are you "; printf("%s\n", str); r = del_space(str); printf("---%s---\n", r); puts(str);//printf和puts为两种打印方式 return 0; } char * del_space(char * s)//char * s = str; { char * r = s; char * p = s; //当指针s没有走到'\0'时 while (*s){ if (*s == ' ')//如果指针指向的是空格,指针++ s++; else{ *p = *s;//如果指针s指向的不是空格,进行赋值 s++; p++; } }//循环结束后执行*p = '\0' *p = '\0';//当指针p指向\0时结束 return r;//由于s和p都变化了,所以由r进行返回,将初始地址赋给r }
-
运行结果:
$ ./app how are you ---howareyou--- howareyou
-
拓展:什么使用指针函数进行回调?
#include <stdio.h> #include <string.h> char * del_space(char * s); int main() { // char * r; char str[] = " how are you "; char s1[50], s2[50]; printf("%s\n", str); strcpy(s2, strcpy(s1,del_space(str)));//多次拷贝赋值 puts(str);//不需要有return r 返回值 //下面两种打印需要有return r返回值 puts(s1); puts(s2); return 0; } char * del_space(char * s)//char * s = str; { char * r = s; char * p = s; while (*s){ if (*s == ' ') s++; else{ *p = *s; s++; p++; } } *p = '\0'; return r; }
运行结果:字符串连续赋值,验证字符串函数的使用及意义.
$ ./app how are you howareyou howareyou howareyou
-
-
编写一个指针函数,实现字符串连接。
-
程序如下:
#include <stdio.h> #include <string.h> char * mstrcat(char * dest, const char * src); int main() { // char * r; char dest[50] = "welcome "; char src[] = "makeru"; puts(mstrcat(dest, src)); puts(dest); return 0; } char * mstrcat(char * dest, const char * src) { char * r = dest; while (*dest){ dest++; } while (*src) { *dest = *src; dest++; src++; } *dest = '\0'; /*一种简化方式 while (*dest++);起始位置到了\0后面的位置 dest--;上面是++,所以此处要减下去 while (*src){ *dest++ = *src++; } *dest = '\0'; */ /* 另一种简化方式,不推荐 while (*dest++); dest--; while (*dest++ = *src++);先赋值再比较 *dest = '\0'; */ return r; }
运行结果:
./app welcome makeru welcome makeru
-
4、总结与思考
-
主要介绍了指针函数的概念以及指针函数的编写。
-
思考:
-
指针函数中可以返回什么样的指针?
返回值:全局变量的地址、static变量的地址、字符串常量的地址、堆的地址
-
编写一个指针函数,把整数123转化成字符串“123”。
程序如下:
#include <stdio.h> char * itoa(int n); int main() { int n; char * s; printf("input:"); scanf("%d", &n); s = itoa(n); puts(s); return 0; } char * itoa(int n)//itoa()自定义函数名称,整数转换成字符串 { int r, i, j; static char p[50]; while(n){ r = n % 10; n /= 10; p[i] = r + '0';//数字和字符的ASCII码相差48 i++; } p[i] = '\0'; j = i-1; i = 0; while(i < j){//数组反转,两个指针对位交换,从两边向中间走。 r = p[i]; p[i] = p[j]; p[j] = r; i++; j--; } return p; }
运行程序:
$ ./app input:1234 1234
另一种写法
#include <stdio.h> char * itoa(char * p, int n); int main() { int n; char s[50], *r;//给一个数组,可以利用数组的空间 // char * s; printf("input:"); scanf("%d", &n); r = itoa(s,n);//把输入的(n)放到数组(s)中 puts(r); puts(s); return 0; } char * itoa(char * p, int n) { int r, i = 0, j; // static char p[50];数组不用声明空间了,数组空间是上面传递来的 //不用再数组内部考虑空间大小 while(n){ r = n % 10; n /= 10; p[i] = r + '0'; i++; } p[i] = '\0'; j = i-1; i = 0; while(i < j){ r = p[i]; p[i] = p[j]; p[j] = r; i++; j--; } return p; }
运行结果:
./app input:1234 1234 1234
-