<C> 指针01 - 2017/11/22

  上一节的内容:

      改多字节   图形库

 

  指针01

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

void increment(void);
int main()
{
#if 0  // 1.指针定义和意义
    /**
    *    数据:内存都有地址   变量名修改值    或者变量地址
    *    指针变量 -> 存放地址变量
    *    
    *    1.什么指针       2.存放什么类型的变量地址   3.它指向哪个位置
    *    
    *   【指针定义】:
    *          类型 *指针变量名;   // point
    *
    *          一个变量  同时只能存放一个值
    *
    *          p  存放一个int变量的地址  指向x   指向int类型的地址  类型int*
    *
    *          int *p;
    *          指针p的类型              --> 指针存放的地址的类型
    *          指针指向数据的类型       --> 指针指向的变量类型   <int类型的指针>
    * 
    *          类型*指针名  指针指向的数据的类型
    *          double *q;   指向数据的类型:双精度类型
    *          q的类型 -> double*
    *
    *          类型  变量名 -> double* q;
    *          类型  *变量名 -> double *q;  q指向的数据类型
    *
    *          %x打印整型16进制    浮点型  --> 转换
    */
    int x;
    x = 50;
    int *p = &x;  // 定义一个指针变量并给赋值
    //p = &x;     // 把x的地址赋值给它
    float y = 3.14f;
    //scanf_s("%d", &x);
    //printf_s("%x", y);
    printf_s("%x", *(int*)&y);


#elif 0 // 2.指针的使用 * &
    /**
    *    & 取变量地址 -> 可以用变量地址给指针赋值   类型不一样不能直接赋值
    *    * 取值  ->  可以直接通过地址修改
    *    
    *    变量定义到结束周期 x存在并且地址不会变化
    */
    int *p;  // 定义一个指针变量
    float y = 3.14f;
    double *q;   // 定义一个双精度指针
    double z = 3.1415;
    q = &z;
    //z = 4.5;
    *q = 4.5;
    printf_s("%lf\n", *q);
    //printf_s("%d", *(int*)&y);
    p = (int*)&y;  // 强转
    printf_s("%x", *p);   // 得到这地址存放的二进制的16进制形式
    /**
    *   分解:&y -> 取变量地址   float* (int*)强转  *计算机当作一个int 
    *
    *   地址  (int)y --> 类型转换 -> 会丢失精度
    *
    *    16进制 或者8进制或者2进制或者10进制 全是用来表示数据的
    */

#elif 0  // 3.指针的加法和减法
    /**
    *    指针加法 和整数相加 地址  相加没有意义
    *    指针加上数字  p+1  地址偏移量   相当于  指针指向的数据类型大小
    *    ==> 用于数组
    *    
    *    指针加法:只能和整数相加
    *
    *    指针可以减去一个整数
    *    指针减去指针  --> 如:int *p,*q;  int arr[10]
    *    p = &arr[0];   q = p + 3; --> 指向:arr[3]
    *    q - p // 指针相减:只能是相同类型指针 
    */
    /*char ch;
    int *p;
    double *q;
    //printf_s("%d %d", sizeof(p), sizeof(q));  // 指针大小一样大
    printf_s("%d %d", sizeof(*p), sizeof(*q));

    for (int i = 0; i < 10; i++)
    {
        printf_s("%p\n", p + i);  // 打印地址
    }*/

    char cArr[10];
    char *pch = &cArr[0];  // 取第一个元素的地址
    /* 用循环给赋值 */
    for(int i=0;i<10;i++)
    {
        *pch = 'A';
        //cArr[i] = 'A';
        pch++;
    }
    /* 循环之后  pch &cArr[10] */
    pch--;
    *pch = '\0';  // pch -> 指向的是:cArr[9]
    puts(cArr);

#elif 0  // 4.内存四区
     /**
     *     C语言 -> 内存划分四个区域:
     *      代码区                 存放代码二进制
     *      全局数据静态常量区     存放全局数据  静态数据  常量
     *      栈区                   在函数  main定义的普通变量  自动分配 自动回收 (缺点:内存小)
     *            2M  -> int iArr[1000][1000];
     *      堆区                   需要自己申请 自己释放  ( 2G ) <申请之后一定要释放(内存泄漏)>
     *
     *       #include <stdlib.h>
     *       malloc         分配堆内存  需要指针接受地址
     *       realloc        重新分配内存     将一个已经分配内存的区域重新分配大小
     *       free           释放内存
     */
     // 申请堆内存  存放一个int
    int *p = (int*)malloc(sizeof(int));  // 里面申请的内存大小
    /**
    *   1.用指针接收
    *   2.强制转换
    *   3.大小 sizeof(用字节做单位)
    *
    *   malloc 返回值 void*
    */
    *p = 4;  // 赋值
    printf_s("%d", *p);
    free(p);   // 释放内存

    /**
    *   不释放 内存泄漏
    *   申请内存   会申请失败  申请失败得到的值是:NULL
    */
    

#elif 1  // 数组和指针
/**
*        数组名  数组首地址  可以看成指针
*        *(arr+i)  arr[i]
*        *(p+i)    p[i]
*        *p   --> *(p+0)->p[0]
*        
*        数组名不能修改指向 数组名能++或者--  但是指针可以
*        arr++;  不行
*/

    int arr[10];
    for (int i = 0; i < 10; i++)
        printf_s("%p %p\n", arr + i, &arr[i]);

    /**
    *    申请 之后发现不够用 ->重新申请
    */
    int *p;
    p = (int*)realloc(p, 50);
    /**
    *    p 重新申请一块  p已经指向一块内存  50是重新申请的空间大小
    *    之前的空间  数据  数据会保留到新的内存中
    *    地址 不一定一样  如果和原地址不一样  原地址自动释放
    */
    getchar();


#endif
    getchar();
    return 0;
}

 

posted @ 2017-12-22 10:51  让优秀成为一种习惯  阅读(141)  评论(0编辑  收藏  举报