| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 990 人关注过本帖
标题:关于指针的问题(问题应该出在指针吧)
只看楼主 加入收藏
perfectc
Rank: 1
等 级:新手上路
帖 子:15
专家分:1
注 册:2009-12-16
收藏
 问题点数:0 回复次数:15 
关于指针的问题(问题应该出在指针吧)
#include <stdio.h>
#define N 3
struct student
{
    char name[10];
    float chinese;
    float math;
    float english;
    float total;
};
struct student *sum()
{
    struct student score[N],*ptr;
    int i;
    for(i=0;i<N;i++)
    {
        printf("请输入第%d位学生姓名:",i+1);
        scanf("%s",score[i].name);
        printf("%s请输入该生的语文 数学 英语成绩:",score[i].name);
        fflush(stdin);
        scanf("%f%f%f",&score[i].chinese,&score[i].math,&score[i].english);
        score[i].total=score[i].chinese+score[i].math+score[i].english;
    }
    ptr=&score[0];
    return (ptr);
}
void main()
{
    int i;
    struct student *ptr;
    ptr=sum();
    for(i=0;i<N;i++)
    {
        printf("%s的成绩为:%.2f\n",ptr->name,ptr->total);
        ptr++;
    }
}


运行后名字为乱码···第二 三个成绩算不出·····
求解~~谢谢啦
搜索更多相关主题的帖子: 指针 
2009-12-16 23:16
sidooh
Rank: 4
等 级:业余侠客
帖 子:121
专家分:265
注 册:2009-6-26
收藏
得分:0 
将struct student score[N]放在函数外声明

放在函数内的话,运行完sum()之后,为他分配的内存就释放了,他们的地址也就不是连续的了
放在函数外,就是全局性的,数组始终存在,他们的地址也是始终连续的

测试通过
2009-12-17 11:37
perfectc
Rank: 1
等 级:新手上路
帖 子:15
专家分:1
注 册:2009-12-16
收藏
得分:0 
   确实如此~~把 struct student score[N],*ptr;这句改为 static struct student score[N],*ptr; 既把score改为静态变量  也可以得出正确答案~~

2009-12-17 12:44
perfectc
Rank: 1
等 级:新手上路
帖 子:15
专家分:1
注 册:2009-12-16
收藏
得分:0 
   但有
#include <stdio.h>
#define N 3
struct student
{
    char name[10];
    float chinese;
    float math;
    float english;
    float total;
};
void sum(struct student score[])
{
    int i;
    for(i=0;i<N;i++)
    {
        printf("请输入第%d位学生姓名:",i+1);
        scanf("%s",score[i].name);
        printf("%s同学的语文 数学 英语成绩:",score[i].name);
        fflush(stdin);
        scanf("%f%f%f",&score[i].chinese,&score[i].math,&score[i].english);
        score[i].total=score[i].chinese+score[i].math+score[i].english;
    }
}
void main()
{
    int i;
    struct student *ptr,b[N];
    ptr=b;
    sum(ptr);
    for(i=0;i<N;i++)
    {
        printf("%s的成绩为:%.2f\n",ptr->name,ptr->total);
        ptr++;
    }
}

  这个也通过···这是因为数组b通过函数改变了自身对吗?
   还有没有别的方法不定义全局变量(老师说不要用太多全局变量)···来做这题呢?
2009-12-17 13:04
perfectc
Rank: 1
等 级:新手上路
帖 子:15
专家分:1
注 册:2009-12-16
收藏
得分:0 
还有这题
#include <stdio.h>
char *m_month(int);    //原形说明
main()
{
    int x;
    char *ptr;
    printf("Please enter a number:");
    scanf("%d",&x);
    ptr=m_month(x);
    printf("It's %s\n",ptr);
}
char *m_month (int k)
{
    char *name[]={"illegal month","January","February","March","April","May","June","July","August","September","October","November","December"};
    if(k<1||k>12)
        return (name[0]);
    else
        return (name[k]);
}


它指针数组也是在函数中定义··为什么它可以得到正确结果呢?
2009-12-17 13:22
sidooh
Rank: 4
等 级:业余侠客
帖 子:121
专家分:265
注 册:2009-6-26
收藏
得分:0 
我认为用static比较好


这是因为数组b通过函数改变了自身对吗?

因为数组b的占用的内存直到程序结束时(main函数返回时)释放,程序结束之前数组b相邻元素的地址是连续的


下面的ptr保存了字符串的地址,所以可以输出正确结果
但name数组在调用完m_month函数之后,相邻元素的地址就不连续了,在main函数中对通过ptr进行数值运算来输出下个月或上个月应该就不行了,和第一个程序差不多,只能输出返回的保存下来的student数组的第一个元素,而通过对ptr进行数值运算来输出下一个学生就不行了


我是这么理解的,不知道对不对
2009-12-17 18:19
perfectc
Rank: 1
等 级:新手上路
帖 子:15
专家分:1
注 册:2009-12-16
收藏
得分:0 
在main函数中对通过ptr进行数值运算来输出下个月或上个月应该就不行了
   
确实不行
程序结束之前数组b相邻元素的地址是连续的
   
  内存分配数组地址时是连续的··为什么在调用完后就不连续了?地址不是固定的吗?(偶小白一个)
        还有调用完后内存释放··那么如果此时又有函数对刚释放的内存进行写入(程序本身··或电脑的其它软件?)那么还能显示正确的月份吗?

很感激你的热心回答~~谢谢
2009-12-17 21:47
sidooh
Rank: 4
等 级:业余侠客
帖 子:121
专家分:265
注 册:2009-6-26
收藏
得分:0 
调用完后内存释放,这些地址就可能放入其他的变量,数组相邻元素的地址就不连续了



那么如果此时又有函数对刚释放的内存进行写入(程序本身··或电脑的其它软件?)那么还能显示正确的月份吗?

我错了,第一个程序的输出的第一行就有可能输出不正确的结果,因为他占用用的内存可能会被其他变量占用,第一行的输出就是未定义行为
程序代码:
    for(i=0;i<N;i++)
    {
        printf("请输入第%d位学生姓名:",i+1);
        scanf("%s",score[i].name);
        printf("%s请输入该生的语文 数学 英语成绩:",score[i].name);
        fflush(stdin);
        scanf("%f%f%f",&score[i].chinese,&score[i].math,&score[i].english);
        score[i].total=score[i].chinese+score[i].math+score[i].english;
    }
改为
程序代码:
    int j;
    for(i=0;i<N;i++)
    {
        for(j=0;j<10;j++)
            score[i].name[j] = 'a';
        printf("%s请输入该生的语文 数学 英语成绩:",score[i].name);
        fflush(stdin);
        scanf("%f%f%f",&score[i].chinese,&score[i].math,&score[i].english);
        score[i].total=score[i].chinese+score[i].math+score[i].english;
    }
我运行之后,第一行的名字不是aaaaaaaaaa,而是乱码,应该是name数组所占用的内存被其他变量占用了,大概可以证明第一行是未定义行为了,但未定义行为表现了正常的结果(分数)...


显示月份的那个程序,我认为会输出正常的结果,因为m_month()函数返回的是字符串的地址,字符串在内存中是静态存储的,所占用的内存不会被其他变量占用

这是我看了别人的讨论得出的,个人理解,不知道对不对

(10:44:51 PM) TheNovice: when i write char *ptr = "HELLO" where is storage for hello allocated
(10:45:45 PM) ramok: TheNovice: in static data segment
(10:46:06 PM) TheNovice: so if i return ptr from a function
(10:46:29 PM) TheNovice: will this "HELLO" be retained in memory and legally used in other functions
(10:47:19 PM) Zhivago: The: The question is not about the pointer -- it is about what it points into.
(10:47:48 PM) Zhivago: The: "HELLO" is a string literal. String literals have static storage, so they do not get deallocated.
(10:48:00 PM) Zhivago: The: This means that you may safely point into them at all times.



[ 本帖最后由 sidooh 于 2009-12-18 13:10 编辑 ]
2009-12-18 13:06
perfectc
Rank: 1
等 级:新手上路
帖 子:15
专家分:1
注 册:2009-12-16
收藏
得分:0 
for(j=0;j<10;j++)
            score[i].name[j] = 'a';
        printf("%s请输入该生的语文 数学 英语成绩:",score[i].name);

   是这句在输出时%s为乱码吗?一个个赋值name[i]最后得到的应该不是字符串;把它改为
for(j=0;j<10;j++)
            score[i].name[j] = 'a';
        score[i].name[9]='\0';
        printf("%s请输入该生的语文 数学 英语成绩:",score[i].name);
   
就可以输出了。
2009-12-18 14:47
perfectc
Rank: 1
等 级:新手上路
帖 子:15
专家分:1
注 册:2009-12-16
收藏
得分:0 
   在1楼的student函数中
   scanf("%s",score[i].name);
     
   这句输入的字符串也是静态存储的?在函数student结束后,结构数组score所占内存被释放,所以不能通过数组score的名字访问依然存在的字符串name对吗?


(感觉好晕
2009-12-18 15:02
快速回复:关于指针的问题(问题应该出在指针吧)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017913 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved