C语言_指针1

指针一

一.指针的概念

1.为了方便访问内存中的内容,给每一个内存单元编号,我们称这个编号为地址,也就是指针

地址即是指针

2.指针也是一种数据类型,所以指针有自己的内存,存储的是地址(编号)

四要素

int a=10

int* p=&a;===>int*就是指针本身的类型,p就是指针名,int就是指针指向的类型

1.指针本身的类型

除去指针名,剩下的就是指针本身的类型

2.指针指向的类型

除去指针名和一个*,剩下的就是指针指向的类型

3.指针本身的内存

用来存储指向内容的地址(指针里面,只存编号)(四个字节-32位编译器)

4.指针指向的内存

可以是各种类型

二指针的定义

1.运算符

定义时,表示定义的是一个指针,其他时候表示解析引用(取内容)

&:取首地址符

定义

定义一个指针,指针也是一种数据类型

指针类型==》指针名

1.除去指针名,剩下的就是指针类型

2.除去指针名和一个*,剩下的就是指针指向的类型 

int* p;//野指针
//定义了一个int*类型的指针,叫做p
//p这个指针,本身的类型是int*
//p这个指针,指向的类型是int

三指针的内存

指针也是一种数据类型,所以指针有自己的内存,存储的是地址(编号)

编号是一个数字==》十六进制数

1.所有的指针,不论类型,在内存中都只占4个字节的内存

要看具体的编译器

    int* a;
    short* b;
    char* c;
    float* d;
    double* e;
    printf("%d\n",sizeof(a));
    printf("%d\n",sizeof(b));
    printf("%d\n",sizeof(c));
    printf("%d\n",sizeof(d));
    printf("%d\n",sizeof(e));
//都是四个字节,

四 指针的初始化和赋值

1.用对应类型变量的地址赋值

int num=10;
int* p=#//初始化
//必须是对应的类型,可以强转
​
short sh=20;
short* p1;
p1=&sh; //赋值

2.用相同类型的指针直接给值

int num=10;
int* p=#
int* p1;
p1=p;
int* p1=p;
 

3.直接用地址给值

int* p=(int*)0x36;
//(int*)==>强制转换类型

4.用数组名给值

//数组名就是数组的首地址!!!
int arr[5]={1,2,3,5,6};
int* p=arr;
//*p取的是数组里的第一个内容,1

5.用字符串给值

char arr[10]="abcd";
char* p=arr;
char* p="abcd";
printf("%x",p);//打印的是一个十六进制的数,是p的地址
printf("%s",p);//打印的是abcd
cout<<p<<endl<<;//打印的是abcd
​
//char*类型的指针,可以直接输出整个字符串,直到遇见'\0'停止

6.置空

1,有时候,指针定义了,还没有指向,

2,或者是,指针用完了,没有指向了

此时不知道指向哪里

此时的指针很危险==》(野指针)

所以,这些情况下的指针,我们给他们一个固定的指向

指向0地址

int* p1=NULL;
int* p2=nullptr;
int* p3=(int*)0x0;
char* p4=(char*)0x0;

7.多级指针

int a=10;

int* p=&a;

*p指的是:取出p指向的内存里面所存的东西

而p指向的是a,a里面存的是10

所以打印的*p的值为10

int a = 10;
    cout << "a=" << a << endl;
//a=10
    cout << "&a=" << &a << endl << endl;
//地址
    
​
    int* a1 = &a;
    cout << "a1=" << a1 << endl;
//a1是一个指针,打印的是地址
    cout << "&a1=" << &a1 << endl;
//取a1的首地址
    cout << "*a1=" << *a1 << endl << endl;
//*a1是int整型,*a1=10
​
    int** a2 = &a1;
    cout << "a2=" <<a2<< endl;
    cout << "&a2=" << &a2 << endl;
    cout << "*a2=" << *a2 << endl << endl;
​
    int*** a3 = &a2;
    cout << "a3=" << a3 << endl;
    cout << "&a3=" << &a3 << endl;
    cout << "*a3=" << *a3 << endl <<;
    cout<<"***a3="<<***a3<<endl;
​
/*打印的结果
a=10
&a=00F7FA44
​
a1=00F7FA44
&a1=00F7FA38
*a1=10
​
a2=00F7FA38
&a2=00F7FA2C
*a2=00F7FA44
​
a3=00F7FA2C
&a3=00F7FA20
*a2=00F7FA38
***a3=10
*/

一个例题

    short sh = 10;
​
    short* psh1 = &sh;
    short* psh2 = psh1;
​
    short** ppsh1 = &psh2;
    short** ppsh2 = ppsh1;
​
    short*** pppsh = &ppsh2;
​
    ***pppsh = 9;
    cout << "sh=" << sh << endl;
//最后输出的sh=9,***pppsh是直接取指sh里的内容,可以直接修改

五.指针的加减法

核心:指针本身的值(指向)有没有变化

指针的偏移

不改变指针的指向

1.指针可以加上或者减去一个整数

2.指针加上或减去一个整数后,实际上是进行了偏移

偏移的范围是加上或者减去的整数个单位

单位:指针指向的类型在内存中所占的字节数

偏移:指针指向不变,但是根据偏移量取内容

    int num = 10;
​
    int* p = &num;
    cout << p << endl;              //004FF728
    cout << "*p="<< *p << endl;     //*p = 10
    cout << p + 1 << endl << endl;  //004FF72C  加了4
​
    short sh = 20;
    short* psh = &sh;
    cout << psh << endl;            //004FF710
    cout << psh + 1 << endl;        //004FF712  加了2

六.指针的自增自减

自增自减,会改变指向

++:表示指针向后移动一个单位

--:表示指针向前移动一个单位

单位:指针指向的类型在内存中所占的字节数

七.指针与一维数组

通过指针遍历一维数组

    int arr[5] = { 1,2,3,6,5 };
    int* p = arr;
    cout << *p << endl;//打印1
    for (int i = 0; i < 5; i++)
    {
        cout << arr[i] << endl;
    }
    int* parr = arr;
    for (int i = 0; i < 5; i++)
    {
        cout << parr[i] << endl;
    }
    printf("\n");
    //输出的效果都是一样的
    //parr和arr是一样的
    //但是arr是一个常量
    cout << *(parr+0) << endl;
    cout << *(parr + 1) << endl;
​
    /*
    *(parr+0) <==> parr[0]
    *(parr+1) <==> parr[1]
    *(parr+2) <==> parr[2]
    结论:
    *(p+n)等价于p[n]
    */


通过指针遍历二维数组

int arr[3][4] = {
    {1,5,3},
    {6,3,2},
    {5,6,9}
    };
    /*
    int* p = &(arr[0][0]);
    *(p+n) <==> p[n]
    arr[0][0]  ==>  *(arr[0]+0) ==> *(*(arr+0)+0) ==> *(*(arr))  
    &(*(*(arr)))==>(*(arr))==>*(arr)==>arr[0]
    */
    int* p = arr[0];
    for (int i = 0; i < 12; i++)
    {
        cout << p[i] << endl;
    }
//可以将这个二维数组打印出来

存储模式

1.小端模式(vs)

存储:低字节存数据的低位

读取:从高位向低位读取(逻辑习惯)

一位十六进制对应四位二进制

两位十六进制对应一个字节

2.大端模式

存储:低字节存数据的高位

读取:从低向高读取(阅读习惯)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值