指针(new)

指针

一、指针概述

  1. 内存以1个字节为单位分配内存。

  2. 每个字节的内存都有标号,这个标号就是地址,也叫指针。

  3. 地址需要存储,32位编译器用32位(4字节)存此地址,64位编译器用64位(8字节)存此地址。

&a是指取a的首地址。

1.内存

(1)内存含义
  • 存储器:计算机的组成中,用来存储程序和数据,辅助CPU经行运算处理的重要部分。
  • 内存:内部存储器,暂存程序/数据——掉电丢失SRAM、DRAM、DDR、DDR2、DDR3。
  • 外存:外部存储器,长时间保存程序/数据——掉电丢失ROM、ERRROM、FLASH(NAND、NOR)、硬盘、光盘。
(2)内存是沟通CPU与硬盘的桥梁
  • 暂存放CPU中的运算数据
  • 暂存与硬盘等外部存储器交换的数据

2.指针和指针变量

  • 内存区的每一个字节都有一个编号,这就是"地址"。
  • 如果在程序中定义了一个变量,在对程序进行编译或运行时,系统就会给这个变量分配内存单元,并确定它的内存地址(编号)。
  • 指针的实质就是内存"地址",指针就是地址,地址就是指针。
  • 指针是内存单元的编号,指针变量是存放地址的变量。

二、指针的定义和使用

#include <stdio.h>

int main(int argc,char *argv[])
{
    //指针也是一种数据类型
    //p是一个变量,p的类型是int *
    int *p;
    p=123;
    printf("%d\n",p);
    
    //指针指向谁,就把谁的地址赋给指针
    int a=10;
    p=&a;//p保存了a的地址
    //%p打印地址,是以16进制的方式打印
    printf("%p,%p\n",p,&a);
    
    //直接操作指针变量本身没有意义
    p=345;
    printf("p=%d\n",p);//345
    
    //需操作*p,操作指针所指向的内存
    *p=100;//*p相当于a
    printf("%d %d\n",*p,a)//100 100
    
}
(1)指针变量和指针所指向的内存
#include <stdio.h>

int main(int argc,char *argv[])
{
    int a=10;
    //有2层含义
    //定义变量时,*代表类型,它是指针类型int *
    int *p;
    p=&a;
    *p=100;
    printf("a=%d\n",a);
    
    int b=11;
    p=&b;
    *p=200;
    printf("a=%d,b=%d\n",a,b);
}
(2)野指针

这个指针变量保存了一个没有意义(非法)的地址

#include <stdio.h>
//只有定义后的变量,此变量的地址才是合法地址
//野指针就是保存没有意义地址的指针变量
//操作野指针变量本身不会有任何问题
//操作野指针所指向的内存才导致段错误
int main(int argc,char *argv[])
{
    int *p;
    p=0x1234;
    printf("p=%d\n",p);
    *p=100;
    
    return 0;
}
(3)空指针
#include <stdio.h>

int main(int argc,char *argv[])
{
    //空指针,给指针变量赋值为NULL
    //NULL就是数字0
    int * p=NULL;
    
    
    int a=11;
    p=&a;
    if(p!=NULL)
    {
        *p=100}
    
}

三、指针大小

#include <stdio.h>

int main(int argc,char &argv[])
{
    //32位编译器用32位大小(4字节)保存地址
    //64位编译器用64位大小(8字节)保存地址
    
    int a=sizeof(int *)
    int b=sizeof(char *)
    double *p;
    int c=sizeof(p);
    printf("a=%d,b=%d,c=%d",a,b,c);
       
}

四、多级指针

#include <stdio.h>

int main(int argc,char *argv[])
{
    //如果定义一个合适类型的变量保存另一个变量的地址
    //在需要保存变量地址的基础上加一个*
    int a=10;
    int *p=&a;
    int **q=&p;
    int ***t=&q;
    int ****m=&t;
}

五、万能指针和指针步长

(1)万能指针
#include <stdiio.h>

int main(int argc,char *argv[])
{
    //不可以定义void类型的普通变量
    //void a;//err
    //可以定义void *变量,void*指针也叫万能指针
    //void *可以指向任何类型的变量
    
    void *p=NULL;
    
    int a=10;
    p=&a;
    
    *((int *)p)=222;
    printf("*p=%d\n",*((int*)p));
 
    return 0;
}
(2)指针步长
#inlcude <stdio.h>
//指针的加法,不是传统的加法
//步长由指针指向的数据类型决定
int main(int argc,char *argv[])\
{
    int a;
    int *p=&a;
    
    printf("p:%d,p+1:%d\n",p,p+1);
    
    char b;
    char *p=&b;
    printf("q:%d,q+1:%d\n",q,q+1);
    
    printf("\n");
    system("pause");
    return 0;
    //p:163816 p+1:163820
    //q:1637795 q+1:1637796
}

六、const修饰的指针变量

#include <Stdio.h>

int main(int argc,char *argv[])
{
    int a=10;
    int *p1=&a;
    *p1=100;//等价于操作啊,*p1操作指针所指向的空间
    p1=NULL//操作指针变量
        
    //const修饰*,代表指针所指向的内存是只读
    const int *p2=&a;
   //*p2=100;//err
    p2=NULL;//ok
    
    //const修饰*,代表指针所指向的内存是只读
    int const *p3=&a;
    //*p3=100;//err
    p=NULL;//ok
    
    //const修饰指针变量,代表指针变量的值是只读
    int * const p4=&a;
    *p4=100;//ok
    //p4=NULL;//err
    
    const int * const p5=&a;
}

七、数组名

#include <stdio.h>
int main(int argc,char *argv[])
{
    int a[10];
    //数组名是数组首元素地址
    printf("a=%p,&a[0]=%p\n",a,&a[0]);
    
    //数组名是常量,不允许修改
}

(1)指向数组首元素的指针

#include <stdio.h>

int main(int argc,char *argv[])
{
    int a[10]={1,2,3,4,5,6,7,8,9,10};
    
    int *p=NULL;
    //p指针变量指向首元素
    p=&a[0];
    //或者
    p=a;
    
    int i=0;
    for(i=0;i<10;i++)
    {
        //printf("%d,",a[i]);
        printf("%d,",*(p+i));
        //p[i]等价于*(p+i),操作都是指针所指向的内存
        printf("%d,",p[i]);
    }
    printf("\n");
    
    
}

(2)通过指针加减访问数组元素

#include <stdio.h>

int main()
{
    int a[10]={1,2,3,4,5,6.7,8,9,10};
    
    //定义一个指针,指向首元素
    int *p=a;
    p=&a[0];
    
    int n=sizeof(a)/sizeof(*a);//a为数组大小,*a为首元素大小
    int i=0;
    
    for(i=0;i<n;i++)
    {
        printf("%d,",*p);
        p++;
    }
    printf("\n");
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值