铁律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放在等号的右边取值(从内存获取值)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{ int c; int *p3 = 20; c = *p3;//读内存 printf("c:%d ", c); }
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 ", p); *(p + 2) = 'j'; // 常量区的不能修稿 printf("%s ", 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"); } |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 ", a); //20 printf("*p:%d ", *p); //20 { char *p = NULL; //分配4个字节的内存 栈区也叫临时区 p = (char *)malloc(100); //内存泄露概念 if (p != NULL) { free(p); } } system("pause"); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 ", p1); printf("%d ", p2); //指针变量和它所执行的内存空间变量是两个不同的概念 strcmp(p1, p2); system("pause"); }
训练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 ", p1); if (p1 != NULL) { free(p1); p1 = NULL; } // if (p1 != NULL) { free(p1); } printf("hello... "); 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... "); system("pause"); return ; } void main02() { //看提示的值 char *p1 = NULL; p1 = 0x00077; strcpy(p1, "abcdefg"); printf("hello... "); 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; }