指针强化

铁律1:指针是一种数据类型

1)指针也是一种变量,占有内存空间,用来保存内存地址

测试指针变量占有内存空间大小

int a = 10;
    char *p1 = 100;  //分配4个字节的内存
    char ****p2 = 100;


    int *p3 = NULL;

    p3 = &a;

    *p3 = 20; //间接的修改a的值
    ////*就像一把钥匙 通过一个地址(&a),去修改a变量的标示的内存空间
  

 

2)*p操作内存

在指针声明时,*号表示所声明的变量为指针

在指针使用时,*号表示 操作 指针所指向的内存空间中的值

         *p相当于通过地址(p变量的值)找到一块内存;然后操作内存

         *p放在等号的左边赋值(给内存赋值) 

         *p放在等号的右边取值(从内存获取值)

    {
        int c;
        int *p3 = 20;
        c = *p3;//读内存
        printf("c:%d \n", c);

    }
View Code

3)指针变量和它指向的内存块是两个不同的概念

//含义1 给p赋值p=0x1111; 只会改变指针变量值,不会改变所指的内容;p = p +1; //p++

    {
     不断地给指针赋值,相当于不停地改变指针的指向
char *p4 = NULL; p4 = (char *)malloc(100); p4 = (char *)malloc(200); //0xcc11 }

                  

//含义2 给*p赋值*p='a'; 不会改变指针变量的值,只会改变所指的内存块的值  

  • 如果我们要修改指针所指向的内存空间数据的时候,我们要保证这个可以修改才行。
#define  _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void *getStr()
{
    char *p1 = NULL;
    p1 = "abcdefg";
    return p1;
}

void main()
{
    char *p;
    p = getStr();
    //printf("%s \n ", p);
    *(p + 2) = 'j'; // 常量区的不能修稿
    printf("%s \n", p);
}

//含义3 =左边*p 表示 给内存赋值, =右边*p 表示取值 含义不同切结!

//含义4 =左边char *p 

//含义5 保证所指的内存块能修改

 

4)指针是一种数据类型,是指它指向的内存空间的数据类型 

含义1:指针步长(p++),根据所致内存空间的数据类型来确定

p++=è(unsigned char )p+sizeof(a);

结论:指针的步长,根据所指内存空间类型来定。

        

注意:     建立指针指向谁,就把把谁的地址赋值给指针。图和代码和二为一。        

                   不断的给指针变量赋值,就是不断的改变指针变量(和所指向内存空间没有任何关系)。

 

 

/*

指针做函数参数的问题:
指针是一种数据类型,是指它指向的内存空间的数据类型 
int getABC1(char *p1); int getABC1(char* p1); int getABC2(char ** p2); int getABC2(char * *p2); int getABC2(char **p2); int getABC3(char ***p3); int getABC4(char (*p4)[30]); int getABC4(char (*p4) [30]); int getABC5(char p5[10][30]); int getABC5(char p5[10][30]); //指针做函数参数 形参有多级指针的时候, //站在编译器的角度 ,只需要分配4个字节的内存(32bit平台) //当我们使用内存的时候,我们才关心指针所指向的内存 是一维的还是二维的
*/

 练习题:

 

训练1划出内存四区

void main26()

{

       char buf[100];

       //byte b1 = new byte[100];

       int a = 10; //分配4个字节的内存 栈区也叫临时区

       int *p;//分配4个字节的内存

       p = &a; //cpu执行的代码,放在代码区

 

       *p = 20; //

 

       {

              char *p = NULL; //分配4个字节的内存 栈区也叫临时区

              p = (char *)malloc(100); //内存泄露概念

              if (p != NULL)

              {

                     free(p);

              }

       }

      

       system("pause");

}

 

 

 

全局区代码测试

char * getstring1()

{

       char *p1 = "abcde";

       return p1;

}

 

char * getstring2()

{

       char *p2 = "abcde";

       return p2;

}

 

 

void main()

{

       int i= 0;

 

       //指针指向谁就把谁的地址赋给指针变量。

       char *p1 = getstring1();

       char *p2 = getstring2();

       char *******    p3 = NULL; //p3 是个变量

 

       //指针变量和它所执行的内存空间变量是两个不同的概念

       strcmp(p1, p2);

 

       system("pause");

}

 

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

void main()
{
    char buf[100];
    //byte b1 = new byte[100];
    int a = 10; //分配4个字节的内存 栈区也叫临时区
    int *p;//分配4个字节的内存
    p = &a; //cpu执行的代码,放在代码区

    *p = 20; //
    printf("&a:%d \n", a);   //20
    printf("*p:%d \n", *p);  //20
    {
        char *p = NULL; //分配4个字节的内存 栈区也叫临时区
        p = (char *)malloc(100); //内存泄露概念
        if (p != NULL)
        {
            free(p);
        }
    }

    system("pause");
}
View Code

 

 

 

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//全局区代码测试
char * getstring1()
{
    char *p1 = "abcde";
    return p1;
}

char * getstring2()
{
    char *p2 = "abcde"; //编译器自动认为这两块内存块一样
    return p2;
}
void main()
{
    int i = 0;

    //指针指向谁就把谁的地址赋给指针变量。
    char *p1 = getstring1();
    char *p2 = getstring2();
    char *******    p3 = NULL; //p3 是个变量
    //*p1和*p2输出相同地址
    printf("%d\n", p1);
    printf("%d\n", p2);

    //指针变量和它所执行的内存空间变量是两个不同的概念
    strcmp(p1, p2);

    system("pause");
}
View Code

 

训练2 划出内存四区

void main01()

{

       char buf[100];

       //byte b1 = new byte[100];

       int a = 10; //分配4个字节的内存 栈区也叫临时区

       int *p;//分配4个字节的内存

       p = &a; //cpu执行的代码,放在代码区

 

       *p = 20; //

 

       {

              char *p2 = NULL; //分配4个字节的内存 栈区也叫临时区

              p2 = (char *)malloc(100); //内存泄露概念

              if (p2 != NULL)

              {

                     free(p2);

                     //p2 = NULL;  若不写,实验效果,分析原

 

 

              }

              if (p2 != NULL)

              {

                     free(p2);

              }

       }

 

       system("pause");

}

 

不加时候:

 

 

解决办法:

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

//野指针产生的原因
//指针变量和它所指向的内存空间变量是两个不同的概念
// 释放了指针所致的内存空间  但是指针变量本身没有重置成null
//造成释放的时候 通过if (p1 != NULL)

//避免方法: 1)定义指针的时候 初始化成nuLL 2)释放指针所指向的内存空间后,把指针重置成NULL。
void main11()
{

    char  *p1 = NULL;
    p1 = (char *)malloc(100);
    if (p1 == NULL)
    {
        return ;
    }
    strcpy(p1, "11112222");

    printf("p1:%s \n", p1);

    if (p1 != NULL)
    {
        free(p1);
        p1 = NULL;
    }

    //

    if (p1 != NULL)
    {
        free(p1);
    }

    printf("hello...\n");
    system("pause");
    return ;
}

 

 

 

 

 

指针的特殊 和共享内存块

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

void main()
{
    //指针第一个位置不能用
    char *p1 = NULL;

    strcpy(p1, "abcdefg");
    printf("hello...\n");
    system("pause");
    return ;
}

void main02()
{
    //看提示的值
    char *p1 = NULL;
    p1 = 0x00077;

    strcpy(p1, "abcdefg");
    printf("hello...\n");
    system("pause");
    return ;
}

 

画内存四区图 指针的精华(很像函数调用)

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



void main()
{
    char buff[128];
    int i;
    int j = 0;


    char *p2 = NULL;

    char *p1 = NULL;

    p1 = &buff[0];
    p1 = &buff[1];
    p1 = &buff[2];

    for ( i = 0; i < 10; i++)
    {
        p1 = buff[i];
    }

    p2 = (char *)malloc(100);
    strcpy(p2, "abcdrfg2e42989");

    for ( i = 0; i < 10; i++)
    {
        p1 = p2 + i;
        printf("%c ", *p1);
        printf("%c ", *p2);//p2 始终指向第一个元素
    }

    system("pause");
    return;
}

 

转载于:https://www.cnblogs.com/yaozhenhua/p/9296699.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值