C语言复习 -- 指针,这篇够了

指针  --   地址

指针就是地址,地址就是指针

& -- 取地址运算符


* 取值运算符 (解引用)
得到地址 -- 要访问他的值 -- * 取值运算符 --  对地址解引用
a=*(&a)

----------------------------


指针变量  -- 存放指针的变量
 

初始化方式 -- int *p;


int a=10;
    int *p=&a;
    printf("%p\n",&a);
    printf("%d\n",*(&a));
    
        printf("%p\n",p);
    printf("%d\n",*(p));s


访问变量的两种方式:


1. 直接访问 -- 用变量名
2.间接访问 -- 将变量地址存放到一个指针变量中,再通过 * 取值间接访问变量


定义指针的时候要求变量类型要一致  --   int 类型的数据就要用 int * 类型的指针来存放  不然可能会出现数据丢失情况
such as: 使用char * 来存放打 int类型变量 的 地址 ,当用 * 取地址的时候 char -- 一个字节--8bit 位 取不完4字节32bit的数据
 
不同类型指针的增加步幅也不一样 -- int *pi; char *pc; 这里++pi的一次增加4bit的地址数据,而pc一次增加1bit的地址数据


//验证程序:
#include<stdio.h>


int main()
{
    
    int a=0x1234;
    int *p=&a;
    char *pc=&a;
    puts("& 和 * 的用法演示:");
    puts("使用a取地址和值:\n");
    printf("%p\n",&a);
    printf("%d\n",*(&a));
    
    puts("使用指针p取地址和值:\n");
    printf("%p\n",p);
    printf("%d\n",*(p));
    
    puts("不同类型指针的演示;");
    printf("int 地址-- %p\n",p);
    printf("char 地址-- %p\n",pc);
    printf("int -- 数值 0x%x\n",*p);
    printf("char -- 数值 0x%x\n",*pc);

    puts("自增差异");
    printf("int -- 0x%p\n",++p);
    printf("char -- 0x%p\n",++pc);
    
    return 0;
}

test1:实现 一个交换函数 -- 要求交换两个变量的值
#include<stdio.h>

void sswap(int *a,int *b)
{
    int t=*a;
    *a=*b;
    *b=t;
    
}


int main()
{
    int a=3;
    int b=4;
    printf("交换前\na= %d\nb= %d",a,b);
    sswap(&a,&b);
    printf("交换后\na= %d\nb= %d",a,b);
    
    return 0;
}
-------------------------------------------------------------------------


volatile对应的变量可能在你的程序本身不知道的情况下发生改变
比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量
你自己的程序,是无法判定何时这个变量会发生变化
还比如,他和一个外部设备的某个状态对应,当外部设备发生操作的时候,通过驱动程序和中断事件,系统改变了这个变量的数值,而你的程序并不知道。
对于volatile类型的变量,系统每次用到他的时候都是直接从对应的内存当中提取,**而不会利用cache当中的原有数值,**以适应它的未知何时会发生的变化,系统对这种变量的处理不会做优化——显然也是因为它的数值随时都可能变化的情况。


指针的第二个场景  -- 指向 固定的地址 -- 单片机 armbootloader -- 会用到
volatile unsigned int *p=(volatile unsigned int *)0x000000000061FE2B;    

test

-- 输入3个数,要求封装一个函数实现输出的时候他们是从大到小
#include<stdio.h>


void mySwap(int *a,int *b)
{
    int t=*a;
    *a=*b;
    *b=t;
}


void mySort(int *a,int *b,int *c) //使用指针排序后赋值回去
{
// ab ac bc  -- abc    
    
    
    if(*a<*b)mySwap(a,b);
    if(*a<*c)mySwap(a,c);
    if(*b<*c)mySwap(b,c);
    
}
int main()
{
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    mySort(&a,&b,&c);
    printf("%d %d %d\n",a,b,c);
    return 0;
}


通过指针引用数组 --  传参是  -- 数组首地址 

p=arr;
p=&arr[0];


指针的增量与数组的关系

#include<stdio.h>


int main()
{
    int arr[3]={1,2,3};
    int  *p;
    //p=arr;
    p=&arr[0];
    // printf("首元素:%d\n",*p);
    // printf("1元素:%d\n",*(p+1));
    // printf("2元素:%d\n",*(p+2));
    
    
    for(int i=0;i<3;++i)
    {
        printf("下标:%d 的元素为%d\n地址:0x%p\n",i,*(p+i),p+i);
    }
    
return 0;
}


访问数组的两种方式 :


1.常用 下标  优点 -- 可读性差
2. 指针  -- 优点: 高效

</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值