C语言——数组和指针

C语言之我个人所知:

1.首先C语言是一个面向过程的编程语言是各位爷都知道的。

   那我们就要思考了,数组是啥吧(#`O′)?


那好我们来看一下简单的c语言程序是怎样编写数组的:

#include<stdio.h>//头文件包含

int  main() {
    //首先定义一个数组
    int name[] = { 1,2,3,4,5 };

    for (int i = 0; i < 5; i++) {//循环i在小于5的时候条件成立
        printf("&name[%d]= %p\n", i, &name[i]);
        printf("&%d[name]= %p\n", i,&i[name]);
        printf("\n");
    }
        return 0;
}


呀,为什么数组名在框框里面可以运行呢?为什么i=0,不等于1呢?好奇怪呀?

打印结果:

    &name[0]= 009AF920
    &0[name]= 009AF920

    &name[1]= 009AF924
    &1[name]= 009AF924

    &name[2]= 009AF928
    &2[name]= 009AF928

    &name[3]= 009AF92C
    &3[name]= 009AF92C

    &name[4]= 009AF930
    &4[name]= 009AF930

 



根据上述结果:那我们就先说一下为啥数组的下表是从零开始不是从1开始且&i[name]为什么可以运行的吧:
我们首先要明白数组名的二义性:

   首先数组是具有相同类型的若干变量有序的组织以便处理的元素集合!这元素也可以包括数组(*维数组),结构体

   说白了数组是一个具有相同类型且有序的构造类型

   数组名充当访问数据成员的首地址

#include<stdio.h>

int  main() {
    //首先定义一个数组
    int name[] = { 1,2,3,4,5 };
    printf("name:%p\n",name);
    return 0;
}


**打印结果**: 

 name:012FF810



这就说明数组名是数组的唯一标识符 !

   好,根据上述我们得知了数组名可以充当是首地址,那么我们又知道了数组是由若干个相同类型的元素组成的。我们大家把他们结合起来会得到什么呢?

 


 

  当name[0]时: 是不是可以这么想我们在name的基础上移动了0个呢?毕竟name本身就是第一个元素啊!以此类推是不是就很好解释了呢?5个元素,但是i<5;



进入下一个话题(&i[name]):

    首先咱要知道[ ]这对框框是啥?_?

    [ ]我们大家通常称为下标运算符。

可是他其实还有其他称呼哦(•ᴗ•)
那就是【**基址变址运算符**】

 



    简单点讲就是:i[name]根据name这个基址按照移动i个步长

基本的数据类型都是怎样创建和存储的

首先我们知道数据类型的定义是:类型+变量名
 但其实在函数内部的变量在类型前面还有一个叫做存储修饰符的
东东:auto
这个东西的作用是告诉计算机将该变量是存储在栈里面的。

    简单点说:就是在函数内部的变量是什么时候调用什么时候生成,调用完之后就自动销毁

这个看怎么感觉有点像内什么就不扯远了(ˉ▽ˉ;)…

    说完了函数内部的变量那咱就顺便说说全局变量吧:
    全局变量保存在内存的全局区中,占用静态的存储单元。说到静态的存储单元,这里还要提一下全局变量分为:全局变量和静态全局变量。

    简单点说:就是全局变量不管你调不调用一直都在!并且占用空间

指针的基本介绍

 什么是指针!

 
 我打个比方指针就像老王,他家里有你家钥匙,它可以通过钥匙去你家然后.⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄就不可描述了,请自行脑补!


 >二级指针
    通过上述我们就可以顺理成章的想到所谓的二级指针就是在老王的基础上增加了一个老李而已,也就是说老李家有老王家的钥匙,然后老李去老王家拿钥匙去你家

#include<stdio.h>

int  main() {
    int i = 0;
    int *p = &i;
    int **pp = &p;

    printf("i的地址为:%p\n", &i);        //取i的地址
    printf("p的地址为:%p\n", &p);        //取p的地址
    printf("pp里面的值:%p\n", &pp);    //取pp的地址
    printf("************************\n");
    printf("i里面的值:%p\n", i);        //取i里面的值
    printf("p里面的值:%p\n", p);        //取p里面的值
    printf("pp里面的值:%p\n", pp);        //取pp里面的值

    return 0;
}

   **打印结果**:

    i的地址为:00B3F7DC
    p的地址为:00B3F7D0
    pp里面的值:00B3F7C4

    i里面的值:00000000
    p里面的值:00B3F7DC
    pp里面的值:00B3F7D0


  从上述结果:我们发现了一个规律就是p里面保存的是i的地址,pp里面保存的是p的地址,我们可以通过号来取里面的值一个号是取本身的保存的值,俩*号可以取本身保存的值得下一个值。诶,就很神奇 !

好了,现在开始讲讲两个的联系吧

```c
int **p=NULL;
```
不管你信与不信,这可以说是一个二维数组,不信,用malloc理解下

```c
p = (int**)malloc(sizeof(int*)*(N));
for(int i = 0; i < N; i++){
    *p = (int*)malloc(sizeof(int)*(M));
}
```
**画图理解为:**

是不是很像二维数组呢?

*具体可以试试判断他们的地址是否一样。*

posted @ 2020-02-22 15:37  IT_Painter  阅读(157)  评论(0)    收藏  举报