从题目入门指针和动态一二维数组的历程(萌新入门可参考)(上篇)

如果有问题求大佬指正…毕竟从百度学的
起因是做到c语言这本书5.13题是将两个字符串不用strcat函数连接起来。
本来这是个简单题目的,但收获MAX!!!!!!!!
居然写着写着把指针和动态数组搞懂了一点,还把没教的调用函数学了!
于是决定放出来让大家一起来快乐学下嘿嘿嘿(如果以后没听懂某杰讲的可以来康康我的这个鸭)[手动滑稽]
首先我们要写入两个字符串,以前都是规定长度比如str[100]什么的,但如果输入的字符串长度超过了100就会十分尴尬。如果str[100000000]那样占的内存又十分大,也不是很好。
于是就要采用动态数组的函数了,但指针没学!!!
于是就找了个动态数组定义字符串的例子,然后根据里面不懂的地方一个个百度去学习~~居然初步学懂了一点指针知识和调用函数的知识
例子在这里https://blog.csdn.net/qq_38967295/article/details/84851606
但是他没有任何一句解释,对萌新十分不友好,我决定一句句百度出来。
代码如下

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *p = NULL;
    p = (char *)malloc(sizeof(char));
    scanf("%s", p);
    int len = strlen(p);
    char str[len];
    for (int i = 0; i < len; i++)
    {
        str[i] = *p;
        p++;
    }
    printf("%c\n", str[2]);

    free(p);
    p = NULL;

    system("pause");
    return 0;
}

首先#include里多了没见过的stdlib.h函数
百度一下
在这里插入图片描述
是相关指针的函数
其中还有
在这里插入图片描述NULL是空指针常量
这样就不难理解代码中第一行char *p = NULL;就是定义一个空的指针
emmm,话说char *p是什么意思,百度一下(毕竟萌新没学指针hhh)
在这里插入图片描述
也就是说,char *p是定义p为字符串类型的指针,如果有指向的话应该是指向一个字符串地址中的首地址。而且从这里也知道普通的定义一个字符串比如char p[]
是给p分配了内存的,但是char *p并没有分配内存,按我的理解它就是一个记录别的字符串首地址的参数。所以第一句到这里已经很明了了,char *p = NULL就是定义p指针的值为空,没有任何指向,但接下来会指向字符串,因为定义的是char。
好!下一句!
p = (char *)malloc(sizeof(char));
咳咳,至少sizeof看懂了,计算char的长度。
然后百度malloc用法
在这里插入图片描述所以前面的(char *)是类型转换为字符型指针,然后赋值给p,这里懂了,后面就是开辟空间的意思吧?
继续下一句。
scanf("%s", p);
这p不是指针吗?为何还能赋字符串进去呢?
百度一下
在这里插入图片描述原来如此,并不是赋字符串给指针,而是创建一个字符串,然后把字符串的第一个 字符地址送给指针!orz懂了懂了!
然后 scanf("%s", p);和gets( p );应该是一样的,我就改成gets( p );好了
下一句 int len = strlen§; 计算p长度。等等,这是计算指针长度还是字符串长度呢?继续百度~
在这里插入图片描述
还真的可以,sizeof是获取指针长度, strlen是可以直接用指针获取字符串长度!(容我这么理解hhh)
继续下一句 char str[len]; 这一句其实已经解决了我最开始的问题,这样系统已经知道输入是多少个字节了,就不怕多定义了。那接下来的语句是干嘛用的呢?继续看下去。

for (int i = 0; i < len; i++) { str[i] = *p; p++; }
一开始没看懂(汗)然后百度发现
p前面加了*说明是这个地址中的值,也就是把这个地址中的值赋给了str[i]
而单单一个p则是代表指针,也就是地址。
那么,这就是一个循环语句,用指针遍历了一边,把地址中的值赋给了str[i]。
明白了…之前所有东西都存在指针指向的那个地址中,但我们不知道在哪里,所以要把那个地址中的字符串拿出来,到熟悉的str[i]方便运算。(虽然我觉得直接用指针运算也不是不行但可能那样有点麻烦hhhh)
继续!下面是 printf("%c\n", str[2]);
感觉没有实际作用啊。。。我的理解就是把第三个拿出来看看是否实际赋值成功,也就是检验前面的操作是否正常。
在这里插入图片描述
嘿嘿没错说明前面思路对的并且是可实现的,自信心+1

    free(p);
    p = NULL;

接下来就很魔幻…我的理解就是出来混总是要还的,你向系统内存借了空间用完了当然要还给他并且清空。然后我试了试借了不还会发生什么
结果发现删除没什么影响。
问下度娘,没弄到什么,然后就写自己的理解好了(不对见谅hhh)
如果不写free()看来没问题,但如果写的代码复杂一点估计很容易出事。
于是我就把free()和return 0;联系起来,return 0 不写也可以运行,但大家都写上,可能也是一种规范吧。

然后我又试了下只删除free(p)和把free(p);p=NULL一起删除,发现结果还是一模一样正常运行
那为什么还要来写个p=NULL呢,再问问度娘

在这里插入图片描述
get到野指针!原来free()释放的只是内存空间,但指针还在的,要把它归零。
要养成free()后加上指针归零的习惯hhh
最后一句 system(“pause”);让我很迷,这句真的不知道用来干什么…感觉没必要啊???(如果后期有学到我会补充上去,但去掉这一句感觉更顺畅的样子…求解释orz)

然后我就开始回归题目hhh,把这道不用strcat连接字符串的题目做了下。
然后想了下我要输入两个字符串,那么要写两边这个代码,那么麻烦!
于是就想能不能用调用函数的方法。

但是如果用调用函数会出现问题,因为我只有一个str,运行两遍的话str等于赋值两次,会覆盖掉,就没办法赋值到两个数组里连接在一起了。

于是

一开始想的解决方法是新建一个strA[]数组,加一个int i=0;i=i+1判断一下是第一次输入还是第二次输入,然后如果第一次赋值给str后再赋值给strA[],如果是第二次就只用直接赋值给str就好了,不执行赋值strA[]的。实现是可以实现,但感觉我好傻。

于是!重点来了
动态二维数组是不是就可以了??
开辟新大陆,打开百度,动态二维数组,搜索!
!!!发现居然要用到指针的指针!woc可!!!我可以!!!
来肝!
下篇再继续征程。
因为二维指针可能又要来一个例子慢慢分析了,于是分为两篇博客,一上一下hhh
真的是个巨坑啊,一道课本基础题居然可以无限挖到底,果然这是玄学!

PS:在学二维动态数组的时候忽然想到了一个致命点…我调用函数完了直接在函数外把函数返回值分别strcpy到str1和str2不就好了,用什么二维数组啊…
傻了傻了傻了傻了

猜你喜欢

转载自blog.csdn.net/zjjcxy_long/article/details/103093254
今日推荐