指针,总结


指针

例子

int是整型类型,存放一个数字的,例如1,2,3,4,5这些数字,而 int*就是一个整型的指针类型,是存放一个地址,但是这个地址指向整型的地址。

int *q;   

代码如下(示例):

#include<stdio.h>
int main()
{ 
	int *q;//q是指针变量, (int *)表示该q变量只能存放int类型的地址 
	int i = 10;
	q = &i;
	printf("%d\n",*q);
	printf("%d\n",q);
	return 0;
}

结果

结果

解释

代码如下(示例):

*q 就代表指针指向i的地址,显示i的地址所存数据(10)
q 存储的是i的地址,因此输出数据为i的地址

指针:一个变量的地址称之为指针。2000H
指针变量:一个变量专门用来存放灵感一个变量的地址(指针),则他称之为指针变量。p
空指针:指针变量为零时,称为空指针(记为:NULL)。
注:参照指针指向的内容前,必须保证指针不是空指针,否则会引起系统死机,重启等重大问题。因此访问指针前的内容务必判断指针是否为空。

解释


举个例子:

#include<stdio.h>
int main()
{ 
	int a;                 //定义int形变量a
	int *pa = &a;          //&a是取a变量所在的地址,*pa:pa指向a的地址
	a = 10;                //设置a存储的值为10   
	printf("a:%d\n",a);      //a的值:10
	printf("*pa:%d\n",*pa);  //取pa所指地址的值为10  pa指向a的地址
	printf("&a:%x(hex)\n",&a); //a的地址为
	printf("pa:%x(hex))\n",pa); //pa所存的值:pa里存的是a的地址
	printf("&pa:%x(hex)\n",&pa);//pa的地址
	return 0;                   //注:(hex)十六进制
	                               
}

结果:
key
图表示 :
key

辨析:*p++ *++p ++*p

前期知识:

#include<stdio.h>
int main()
{		
			int a[]= {0,1};
			int *p = a;
						
			printf("a[0]:%d\n",a[0]);
			printf("a[0]地址:%d\n",&a[0]);
			printf("a[1]:%d\n",a[1]);
			printf("a[1]地址:%d\n",&a[1]);
			printf("一个数组元素大小:%d\n",sizeof(a[0]));
			printf("*p:%d\n",*p);
			printf("*p+1:%d\n",*p+1);
			printf("p:%d\n",p);
			printf("p+1:%d\n",p+1);
}

可以看出 指针p +1 是增加一个int大小的长度,即4个子节(Byte)
key
优先级:

  • ++为后置运算符 > ++为前置运算符和*运算符&运算符
  • ++为前置运算符和 *运算符,& 运算符 的优先级相同

*p++

++此时为 指针p 的后置运算符,++为后置运算符的优先级 > * 运算符 &运算符。先将指针p +1后取出指针p存储的地址所指的元素。
式子根据 i++,显示的是递增前的数值 即*p递增前的数值。(表达式的值是 *p 递增前的值)
*p此时增加1,*p指向了a[2],p存储a[2]的地址

*++p

++对于p来说是前置运算符,++为前置运算符优先级和*运算符&运算符相同,计算*运算,*取的值是++p所存储的地址所指的值。
式子根据++i,显示的是递增后的数值 即p递增后的数值。(表达式的值是p递增后的值)
*p此时增加1,*p指向了a[2],p存储a[2]的地址

++*p

++此时为前置运算符,++为前置运算符优先级 和*运算符&运算符相同,
先取*p的值后+1
式子根据++i,显示的是递增后的数值 即*p递增后的数值。(表达式的值是*p递增后的值) *p所代表指向的位置不变。

#include<stdio.h>

void show(int x[]){           //依次输出数组元素
	int i;
	for(i = 0;i<5;i++){
		printf("x[%d]:%d\n",i,x[i]);
	}
	
}
void dzshow(int x[]){         //依次输出数组元素地址
	int i;
	for(i = 0;i<5;i++){
		printf("x[%d]:%d\n",i,&x[i]);
	}
}
void pzshow(int *p){          //输出 *p 
	printf("*p:%d\n",*p);
}

void pshow(int *p){           //输出指针p中存储的值
	printf("p:%d\n",p);
}

void pz2show(int *p){         //输出*p++ 
	printf("*p++:%d\n",*p++);
	printf("p:%d\n",p);
	printf("*p:%d\n",*p);
}

void pz3show(int *p){         //输出*++p
	printf("*++p:%d\n",*++p);
	printf("p:%d\n",p);
	printf("*p:%d\n",*p);
}

void pz4show(int *p){         //输出++*p
	printf("++*p:%d\n",++*p);
	printf("p:%d\n",p);
	printf("*p:%d\n",*p);
}

int main()
{ 
    int a[5] = {10,20,30,40,50};         //定义int类型数组 
    int *p;                              //定义int类型指针p 
	p = &a[1];                           //指针p指向a[1] 
	int length = sizeof(a)/sizeof(a[0]); //计算数组长度 
    printf("个数:%d个\n",length);        
	
	show(a,length);                      //数组元素分别输出 
	printf("<====================>\n");
	dzshow(a);                           //数组元素地址输出 
	pzshow(p);                           //指针p所指对象输出  即a[1] 
	printf("*p:%d\n",*p);
	pshow(p);                            //指针p存的值输出 
	printf("p:%d\n",p); 
	   
	printf("====================\n");                 
    printf("优先级:++为后置运算符 > ++为前置运算符和*运算符&运算符, ++为前置运算符和*运算符&运算符优先级相同 \n");         
	printf("====================\n");      
	printf("*P++\n");   
	show(a,length);                      //用来显示数组a是否发生变化 
	pz2show(p);       //先执行*p(把p指的元素取出来)再执行++。//根据i++,显示的是递增前的数值 即*p递增前的数值。(表达式的值是*p递增前的值)  *p此时增加1,*p指向了a[2],p存储a[2]的地址 
    show(a,length);                      //用来显示数组a是否发生变化
    
    printf("====================\n");
	printf("*++P\n");   
	show(a,length);                      //用来显示数组a是否发生变化
	pz3show(p);       //先指针p进行+1,再取出内容。//根据++i,显示的是递增后的数值 即*p递增后的数值。(表达式的值是*p递增后的值) *p此时增加1,*p指向了a[2],p存储a[2]的地址
    show(a,length);                      //用来显示数组a是否发生变化
    
    printf("====================\n");
	printf("++*P\n");
	show(a,length);                      //用来显示数组a是否发生变化
	pz4show(p);       //先*运算取出指针p的值,*p=20 之后+1,*p=21 ,根据++i,显示的是递增后的数值 即*p递增后的数值。(表达式的值是*p递增后的值) *p所代表指向的位置不变。 
    show(a,length);                      //用来显示数组a是否发生变化  数组a[]已经变化了     

	return 0;
}

key
key
key
key

字符串

字符串内部实现:
string
\0 为字符串结束标记


C语言实现

代码如下(示例):

#include <stdio.h>
#include <string.h> 
#include <stdlib.h>
int main()
{
	char *p;   
	p = (char *)malloc(20*sizeof(char)); //动态分配10个连续的字符空间      malloc函数由<stdlib.h>头文件提供 
	strcpy(p,"hello world");             //字符串处理所需的库函数(例:strcpy)由<string.h>头文件提供
  将hello world存放到p所指向的空间中 
	printf("%c\n",*p);  //输出字符h                   
	printf("%s\n",p);   //输出字符串hello world
	free(p);            //释放p指向的空间
	return 0;
} 

解释

过程解释:

  1. 先分配空间叫指针p
  2. 在主存里面分配20个连续的字符空间
  3. 将连续空间的首地址存储到指针p中
  4. strcpy将 hello world(常量) 存储到空间中去
  5. 输出字符c(因为输出的类型是char类型,因此只能输出一个字符,即h)
  6. 输出字符串hello world(依次从空间的首地址开始,依次输出,直到遇到 \0符 停止)
  7. 最后释放p指向的空间。(不是释放p)
    string

结果:
string


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值