指针草稿

旧时模样 提交于 2020-03-03 17:29:40

指针

  1. 内存,以一个字节为单位来分配内存
  2. 每个字节的内存都有标号,这个标号就是指针
  3. 指针需要存储,32位的编译器用32位(4字节)存储此地址,64位的用64位的(8字节)存储此地址
  • 编码:为每个物理存储单元(一个字节)分配一个号码
  • 寻址:根据分配的号码找到相应的存储单元,完成数据读写

char:占一个字节,分配一个地址

int:占四个字节,分配四个地址 定义一个变量,在程序编译或运行时,系统给这个变量分配内存的单元,并且确定他的内存地址

指针是内存的单元的编号,指针变量是存放地址的变量;我们通常把指针变量和指针都叫做指针;

	int a = 10;
	int* p = &a;	//取出a的地址,赋值给p
	printf("%p\n%p\n",p,&a); 	//%p是打印地址,以十六进制的方式 
	printf("结束");	//&a和p的值相同
	int b = *p;
	printf("%d\n",b);		//*p是访问p位置的值,这里打印出a的值10 
	*p = 200;
	printf("%d\n",b);		//b的值是10 
	printf("%d\n",a);		//a的值是200 

int a =10;分配一个空间给a,a的地址编号是0X123456,把10存放到a的空间;

int *p = &a;分配一个空间给p,把a的地址编号0x123456存放到p的空间;


野指针

段错误就是指访问的内存超出了系统所给这个程序的内存空间;在编程中以下几类做法容易导致段错误,基本上是错误地使用指针引起的。 1)访问系统数据区,尤其是往系统保护的内存地址写数据最常见就是给一个指针以0地址。 2)内存越界(数组越界,变量类型不一致等): 访问到不属于你的内存区域。

野指针就是指向了一个非法的位置,例如你直接写了int* p = 0x12345;这就是非法的,若使用就会发生段错误;


//*p等价于*(p+0),同时等价于p[0];
//p[1]就是越界了,操作野指针指向的内存,等价于*(p+1)

万能指针

//不可以定义void类型的变量
//void a;	不知道分配多大空间
//可以定义void*,这种指针叫万能指针
//void*可以指向任何类型
int a = 10;
void* p = &a;
//*p = 20;报错,因为使用指针操作内存,但是不知道分配多大空间
//把万能指针转换成确定的类型
* ((int*)p) = 20;
printf("%d",* ((int*)p));

int a = 10;
int* p = &a;	//取出a的内存首地址,如果是万能指针,就不知道走多久是结束;
//这叫不知道指针步长

指针步长

 	int a = 10;
 	char c = 'c';
 	
 	int* p = &a;
 	char* q = &c;
 	//指针的加法不是传统的加法
	//加的1个单位是1个步长
	//步长是指针指向的数据类型决定的,int的步长是4个字节,char的步长是1个字节
	printf("%p,%p\n",p,p+1);	//p和p+1相差4个字节  0X...3C,0X...40
	printf("%p,%p\n",q,q+1);	//q和q+1相差1个字节  0X...3B,0X...3C
 

const修饰指针

 int a = 10;
 int* p1 = &a;
 *p1 = 20;	//修改a的值,OK
 p1= null;	//修改指针的值,OK
 //------------------
 const int* p2 = &a;	//const修饰*,代表指针指向的内存只读
 *p2 = 20;	//error
 p2 = null;	//OK
 //------------------
 int const *p3 = &a;	//const修饰*,代表指针指向的内存只读
 *p3 = 20;	//error
  p3 = null;	//OK
 //------------------
  int* const p4 = &a;	//const修饰指针变量,代表指针变量的值是只读 
 *p4 = 20;	//OK 
  p4 = null;	//error 
  //------------------
  const int* const p5 = &a;	//都修饰,指针变量和指向的内存都是只读 
 int a[10];
 //数组名是数组元素的首地址,a = &a[0]
 printf("%p,%p",a,&a[0]);
 //数组名是常量,不允许修改。类似于int* const p;
 //a=10;	//error 

指针和数组

 int a[10] = {0,1,2,3,4,5,6,7,8,9};
 printf("%d\n",a[4]);	//打印第五个元素,输出4
 int* p = a;	//等价于p = &a[0] 
 printf("%d\n",p[4]);	//打印第五个元素,输出4;	p[i]等价于a[i] 
 printf("%d\n",*(p+4) );//打印第五个元素,输出4;	*(p+4)是首地址加四个步长,取出第五个元素 
 int a[10] = {0,1,2,3,4,5,6,7,8,9};
 int* p = a;
 int len = sizeof(a) / sizeof(*a);	//*a访问首地址存放的0,等价于a[0],*p
 for(int i=0;i<len;i++)
 {
 	printf("%d, ",*p);
 	p++;	//不可以写a++,因为数组名是常量,不可变 
 }
 
 int a[10] = {0,1,2,3,4,5,6,7,8,9};
 int len = sizeof(a) / sizeof(*a);	//*a访问首地址存放的0,等价于a[0],*p
  int* p = a+len-1;
 for(int i=0;i<len;i++)
 {
 	printf("%d, ",*p);
 	p--;	//使用指针,从最后一个向前访问 
 }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!