指针如何赋值?关于指针的理解

数据结构文章推荐:
👉 顺序表和链表实现图书管理系统
👉 多种方式实现英文单词词频统计和检索系统
👉 深度优先搜索判断有向图路径是否存在
👉 待更新

——关于指针的一个问题

       今天班上的一位学霸在学习数据结构的字符串的时候遇到了一个问题,这个问题就是他在写代码的时候,不管怎么样主函数里就是不能够给指针赋值,就算赋值了好像指针里啥都没有,更别说使用其他函数了。
       首先声明一下:这个问题其实并不难,个人认为这个问题只要简单的认识两个点——指针到底是什么?指针到底怎么用?就可以搞懂这个问题了!接下来我会用我认为最简单的思路为有疑惑的同学一步步的讲解,希望各位有耐心的看完,谢谢!!!
       话不多说,我模拟了一下当时重要部分的代码,具体如下:

void output(char *chars){
    int i = 0;
    while(chars[i]!='\0'){
        printf("%c",chars[i]);
        i++;
    }
}
int main(){
    //char chars[] = "abcdefg";
    char *chars;
    int i = 0;
    while(scanf("%c",&chars[i++])!='\0'){}
    output(chars);
    return 0;
}

代码分析

       1、从上述代码可以看出,output中的一个参数是char的指针,output这个函数目的就是简单的输出一下指针里的东西。
       2、主函数中定义了一个名字为chars的字符串指针,并且主函数中试图利用循环对指针进行赋值
       3、主函数对名为chars的指针赋值完毕之后,最后调用output函数将指针的值输出。
       没错,你没有看错,就是这么简单的代码!好了,最上述代码的具体功能分析已经结束。


问题分析 & 问题解决

       我们再看一下问题:主函数不能给chars这个指针赋值,在运行的时候就是输入一串字符之后就中止进程了,就像这样?:
问题的错误情况
       那么这种问题为什么会出现?其实仔细看代码,其他地方实际上都没有写错,就是这个chars怎么看都不顺眼(实际上当时不是while循环是for循环,当时for循环也有一点小问题,所以这里写成了while)
       当时是指针的错误,但是我没有急着说,我在想什么同学会这样写——主函数中有一个chars的指针,output函数中的参数也为chars指针。没错,许多人都有个习惯,那就是认为主函数中要调用自定义函数,那么传过去东西的也必须是和自定义函数一样的(都是指针)!这是我的同学犯错的原因之一。
       不急着矫正错误,如果顺着其思路走下去,其实想法是没错的。因为在学数据结构的时候有个顺序表,顺序表中有个内容是这样的?:

第一部分
//顺序表数据结构
typedef struct SqList{
    Book *elem;   //储存空间的基地址
    int length;   //数据结构的长度
};

第二部分:
//初始化顺序表基本算法
Status InitList(SqList &BookSystem){
    //构造一个空的顺序表BookSystem
    BookSystem.elem =  new Book[maxsize];   //分配内存空间
    if(!BookSystem.elem)exit(-1);   //存储分配失败
    BookSystem.length = 0;  //当前长度为0
    return OK;
}

第三部分:
//添加6本图书
void insertBook(SqList &BookSystem){
    int i = 0;  //循环变量
    for(i;i<6;i++){
    	int index = i;
        Book newBook;
        scanf("%s %s %s %s %s %f",&newBook.isbn,&newBook.authorName,
                  &newBook.bookName,&newBook.publisher,
                  &newBook.publishYear,&newBook.price);
        BookSystem.elem[index] = newBook;
    }
}

       当时他说有个地方搞不清,就是结构体中的elem也是个指针,在insertBook函数中也可以用下标形式给指针赋值,所以就按照这个思路写了他的代码。
       乍一看好像也对,但仔细看看就不对了,我相信我的同学没有仔细揣摩为什么要有第二部分,而是直接照着第一部分第三部分写了代码。没有理解到初始化指针的作用,这也是我的同学犯错的原因之二。


问题解决之指针到底是什么?指针的作用方式?

       知道了错误之后,就要纠正错误,纠正错误就从两点搞起:1、指针到底是个啥?2、指针到底咋个用?——接下来就以我自己的想法和大家说一说,也许就能解决大家的疑惑了!
       首先,指针是个啥?我们都知道指针这东西很重要,这东西就想骇客手里的工具一样,“指”到你的设备,就能入侵你的设备并且还能扒取并修改你设备里的信息,但如果不去“指”,这个工具就缺少了入侵别人设备的途径,也就不能对别人的设备为所欲为了。
       上面已经说了指针必须得指到一个东西才能改那个东西。那么看上面代码可以知道,光定义了一个指针,但是没把任何东西的地址给那个指针,那还怎么能给那个指针赋值呢?这就是犯错的第二个原因,没有初始化指针!
       这里继续强调一下第二个代码示例中的第二部分,第二部分中将Book数组的首元素地址给了elem指针,所以才能执行第三部分的添加图书的操作的?

BookSystem.elem =  new Book[maxsize];   //分配内存空间

       好了,到了这里肯定有人会认为:给主函数里的那个指针一个被指的东西不就好了?就像这样?:

int main(){
	char shuzu[] = "abcdefg";
    char *chars = shuzu;
    int i = 0;
    while(scanf("%c",&chars[i++])!='\0'){}
    output(chars);
    return 0;
}

       确实,给一个字符数组让指针去指,就可以通过指针给数组赋值了。但还是有一个问题——主函数中调用output函数时传的是指针吗?显而易见,肯定不是,与上面所说的一样,指针通过指向某个值之后再去获取或修改那个值。再看下面的代码?:

void output(char *chars){
    //输出数组内容...
}
int main(){
	//代码略...
    output(chars);
    return 0;
}

       主函数传了个指针chars给output函数,output函数接收到chars之后,chars指向了chars然后执行输出操作,两者都是指针。听着是不是很乱?还记得我说的犯错的原因之一是什么吗?就是取了相同的名字所以容易让人混淆!
       我们将主函数中的chars改个名?:

void output(char *chars){
    //输出数组内容...
}
int main(){
	char shuzu[] = "abcdefg";
    char *c = shuzu;
    int i = 0;
    while(scanf("%c",&c[i++])!='\0'){}
    output(c);
    return 0;
}

       output函数接收到c之后,chars指向了c,如果说chars要取数组的内容那么是这样的:指针chars去找指针c中所指的数组的元素。不管怎么样,这样也太麻烦了。我们直接传数组过去让chars指不就好了吗?这样的话主函数就不用再写什么指针,老老实实写个数组再传就OK了!

int main(){
	char shuzu[] = "abcdefg";
    scanf("%s",&shuzu);
    output(shuzu);
    return 0;
}

       OK,问题解决!

问题总结

       我当时看到这个问题的时候,第一眼看过去好像还真是那么回事,从上述的代码分析也可以看出,其实这些代码要干什么我们都懂,但我的那位同学就是遇到了这个‘简单’的问题。
       为什么说这个问题是个‘简单’的问题?还是文章开头所说:这个问题其实并不难,个人认为这个问题只要简单的认识指针到底是什么?指针到底怎么用?就可以搞懂这个问题了!
       本人水平有限,我认为写一些能给大家帮助的文章非常有必要,同时巩固自己的思想,我认为逻辑思考能力十分重要,希望一些平时有很多疑惑的朋友务必要有思考的精神!
       最后,如果大家觉得本文有帮助,记得支持一下哦!大二菜鸟欢迎交流!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hillain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值