鱼C论坛

 找回密码
 立即注册
查看: 3678|回复: 10

指针数组

[复制链接]
发表于 2016-8-28 21:01:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
实参传递值给形参, 函数中的量用完之后就释放了,这个排序函数void paixu(char *a[],int n)只改变了本函数中地址的排序,执行完之后,最后为什么没有释放地址,为什么最后还能输出正常的排序??求大神指点
#include <stdio.h>
#include <string.h>
void main()
{
        void paixu(char *a[],int n);
        void shuchu(char *a[],int n);
        char *b[]={"whit s fox","i am a boy","you are","i am a cat","you are a girl"};
    int x=5;
        paixu(b,x);
        shuchu(b,x);
}
void paixu(char *a[],int n)
{
        char *t;
        int i,j;
        for(i=0;i<n-1;i++)
                for(j=i+1;j<n;j++)
                        if(strcmp(a[i],a[j])>0)
                        {
                                t=a[i];a[i]=a[j];a[j]=t;
                        }
}
void shuchu(char *a[],int n)
{
        int i;
        for(i=0;i<n;i++)
                printf("%s\n",a[i]);
}
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-8-28 21:28:49 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <string.h>
  3. void main()
  4. {
  5.         void paixu(char a[][30],int n);
  6.         void shuchu(char a[][30],int n);
  7.         char b[5][30]={"whit s fox","i am a boy","you are","i am a cat","you are a girl"};
  8.         int x=5;
  9.         paixu(&b[0],5);
  10.         shuchu(&b[0],5);
  11.        
  12. }
  13. void paixu(char a[][30],int n)
  14. {
  15.         char t;
  16.         int i,j;

  17.         //a是一个数组 数组里的元素是char*类型  所以 a[i] 其实是一个char*类型 a[0] 指向"whit s fox"
  18.        
  19.         for (int k = 0;k<n;k++)
  20.         {
  21.                 char *p = &a[k][0];   //这样就循环指向 "whit s fox","i am a boy","you are","i am a cat","you are a girl"了
  22.                 int len = strlen(p);
  23.                 for(i=0;i<len-1;i++)

  24.                         for(j=i+1;j<len;j++)
  25.                                 if(strcmp(&a[k][i],&a[k][j])>0)
  26.                                 {
  27.                                         t=p[i];p[i]=p[j];p[j]=t;
  28.                                 }
  29.         }


  30. }
  31. void shuchu(char a[][30],int n)
  32. {
  33.         int i;
  34.         for(i=0;i<n;i++)
  35.                 printf("%s\n",&a[i][0]);
  36. }
复制代码


  1. t=a[i];a[i]=a[j];a[j]=t;
复制代码

上面的5个字符串是存在常量区的这样修改是错误的

所以我用了个二维数组

还有char *a[] 是个数组 数组里的元素是个指针
所以你a[j]其实就是换到其它字符串了 没操作到字符串里的字符
自己看代码吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-8-29 13:23:18 | 显示全部楼层
楼主对指针的理解还不是很清晰;建议楼主在看有关指针的代码时可以使用画板画下指针的指向;那样会好理解很多

先上我画的图;大概画的;个人理解,有错误欢迎指正
捕获.PNG
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-29 13:50:15 | 显示全部楼层
本帖最后由 18813974736 于 2016-8-29 13:58 编辑
  1. #include <stdio.h>
  2. #include <string.h>

  3. //两个函数的声明
  4. void paixu(char *a[],int n);
  5. void shuchu(char *a[],int n);


  6. void main()
  7. {
  8.    //定义一个指针数组并初始化
  9.     char *b[]={"whit s fox","i am a boy","you are","i am a cat","you are a girl"};
  10.         //首先指针数组是一个数组,它的每一个元素都是一个指针(即地址);
  11.         //也就是说我们初始化指针数组的时候其实传给它每个元素的是字符串的首地址;
  12.         //字符串是存储在文字常量区(内存的data段),它的生命周期跟程序一样(即程序结束它才释放);
  13.        
  14.     int x=5;
  15.         paixu(b,x);//b是数组名,代表数组首元素地址
  16.         shuchu(b,x);//b是数组名,代表数组首元素地址
  17. }


  18. void paixu(char *a[],int n)//这里的指针变量a存储的是指针数组b的首元素地址
  19. {
  20.         char *t;
  21.         int i,j;
  22.         for(i=0;i<n-1;i++)
  23.         {       for(j=i+1;j<n;j++)
  24.                 {
  25.                                 if(strcmp(a[i],a[j])//比较两个字符串的ASCII大小(即比较相同编号的字符的ASCII的大小)
  26.                         {                                   //如 whit s fox 和 i am a boy(先 w 和 i 比较ASCII码的大小,只要不是等于就不会再往下比较)
  27.                                                         //楼主可以自己查看下 strcmp 函数;传的是字符串首地址,
  28.                                                         //比较的却是这个地址所指向的内存里存储的字符串
  29.                                                                
  30.                                                                
  31.                                 t=a[i];     //交换的是地址(因为指针数组里每个元素存储的都是指针(即地址))
  32.                                 a[i]=a[j];
  33.                                 a[j]=t;
  34.                         }                                       
  35.                  }
  36.         }
  37. }


  38. void shuchu(char *a[],int n)
  39. {
  40.         int i;
  41.         for(i=0;i<n;i++)
  42.                 printf("%s\n",a[i]);
  43. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-29 14:13:03 | 显示全部楼层
上面的代码传了之后好乱 截个图发吧; 我用了那个<>发的,不能看,还是上图
1.PNG
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-8-29 17:50:58 | 显示全部楼层
我补充一点点。数组名是指向数组首元素的指针。所以数组名作为参数传递时,相当于传递了数组指针。
void paixu(char *a[],int n)内部访问原始数组,修改了每个字符指针的指向间接达到排序目的。
(数组标记实质上是一种变相使用指针的形式。编译器对数组的访问方式是按照指针索引的。)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-29 20:13:37 | 显示全部楼层
mingcxx 发表于 2016-8-29 17:50
我补充一点点。数组名是指向数组首元素的指针。所以数组名作为参数传递时,相当于传递了数组指针。
void p ...

void paixu(char *a[],int n)内部访问原始数组,修改了每个字符指针的指向,但是这个void paixu(char *a[],int n)执行完之后,指向不是都释放了吗?实参b把自己的值传递给形参a,(a[i]也指向每个字符串),然后修改了每个a[i]的指向,但是paixu函数执行完之后,形参不是都释放了吗?(也就是修改后的a的指向都释放了),为什么下一个void shuchu(char *a[],int n)函数  还能利用a正常输出 结果呢???

指向是这样的吗?
C:\Users\ding\Desktop\IMG_20160829_195924.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-29 20:24:06 | 显示全部楼层
18813974736 发表于 2016-8-29 14:13
上面的代码传了之后好乱 截个图发吧; 我用了那个发的,不能看,还是上图

谢谢大神指点,但是我有一点还是不明白
实参b把自己的值传递给形参a,(a也指向每个字符串),然后修改了每个a的指向,但是paixu函数执行完之后,形参不是都释放了吗?(也就是修改后的a的指向都释放了,a不在指向b中存放的地址了),为什么下一个void shuchu(char *a[],int n)函数  还能利用a正常输出 结果呢???
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-29 23:42:17 | 显示全部楼层
xiaoshuai666 发表于 2016-8-29 20:24
谢谢大神指点,但是我有一点还是不明白
实参b把自己的值传递给形参a,(a也指向每个字符串),然后修改了 ...

我觉得你把其他知识点杂糅了进来,本来是帮助理解的,却造成了理解上的障碍。a释放不释放并不影响理解,它也不是这个问题的重点。
最重要就一个,数组名是指向数组(或其首元素)的指针,所以————————数组作为参数传递给被调函时数,实质上在函数内被编译器以指针的方式访问了数组。被调函数内所有对数组的操作都会直接修改原始数组。
所以paixu()调用结束后a销毁了,b则被修改了。
别被实参b、形参a、a销毁、指向消失的说法混淆,从内存的角度理解。
粗暴但不是很准确地说:a释放了就释放了呗,指向不指向的说法也就没了。反正它释放前我用它修改完了原始数组char *b[],我的目的达到了,就行了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-8-30 08:37:40 | 显示全部楼层
xiaoshuai666 发表于 2016-8-29 20:24
谢谢大神指点,但是我有一点还是不明白
实参b把自己的值传递给形参a,(a也指向每个字符串),然后修改了 ...

void paixu(char *a[],int n)//这个函数的变量a在调用完函数后是释放了
但是 void shuchu(char *a[],int n) 这个函数它也定义了一个变量a啊;
void shuchu(char *a[],int n)
{
    int i;
    for(i=0;i<n;i++)
        {
                printf("%s\n",a[i]);//变量a是这个函数自己定义的形参a
                                         //所以并没有冲突啊
        }
      
}
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-30 08:44:03 | 显示全部楼层
mingcxx 发表于 2016-8-29 23:42
我觉得你把其他知识点杂糅了进来,本来是帮助理解的,却造成了理解上的障碍。a释放不释放并不影响理解, ...

好的,谢谢啦
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-12 21:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表