指针函数的用法

  • Post author:
  • Post category:其他




指针函数

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
      



版权声明:本文为karry_hahaha原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。