声明:本文参照了C primer Plus中文版、翁凯C语言课程数组和指针章节
公司专注于为企业提供成都网站设计、网站建设、微信公众号开发、电子商务商城网站建设,小程序开发,软件按需网站策划等一站式互联网企业服务。凭借多年丰富的经验,我们会仔细了解各客户的需求而做出多方面的分析、设计、整合,为客户设计出具风格及创意性的商业解决方案,成都创新互联公司更提供一系列网站制作和网站推广的服务。目录
指针概念
访问地址变量*
两数交换
找到数组中的大值和最小值
指针最常见的错误
指针与数组
数组变量是特殊的指针
指针运算
*p++
指针类型
作为参数的指针:
void f(int *p)
int i=0; f(&i);
下面看一个例子:
#includevoid f(int *p);
int main(){
int i=6;
printf("&i=%p\n",&i);
f(&i);
return 0;
}
void f(int *p){
printf(" p=%p\n",p);
}
从运行结果可以知道,i的地址是000000000062FE1C,通过f函数将地址取出来然后赋给了p指针,于是可以说p是一个指向i变量的指针。
访问地址变量*#includevoid f(int *p);
void g(int k);
int main(){
int i=6;
printf("&i=%p\n",&i);
f(&i);
g(i);
return 0;
}
void f(int *p){
printf(" p=%p\n",p);
printf("*p=%d\n",*p);
}
void g(int k){
printf("k=%d\n",k);
}
void f(int *p){
printf(" p=%p\n",p);
printf("*p=%d\n",*p);
*p=26;
}
传进来的是i的地址,对*p进行修改实际上是对i的值进行修改,p是i的地址,*p用来访问p指针所代表的值。
两数交换#includevoid swap2(int a,int b);
int main(){
int a=5,b=6;
swap2(a,b);
printf("a=%d,b=%d\n",a,b);
return 0;
}
void swap2(int a,int b){
int t = a;
a = b;
b = t;
}
先分析一下这个程序能够交换a,b两数的值吗?很明显是不能交换成功的,我们只是在swap中重新定义了两个值a和b,这里的a和b地址和主函数中的地址是不一样的,对其进行交换的话也不能改变主函数中a和b的地址,地址不变的话,其值更不会改变。
#includevoid swap(int *pa,int *pb);
void swap2(int a,int b);
int main(){
int a=5,b=6;
swap2(a,b);
printf("a=%d,b=%d\n",a,b);
swap(&a,&b);
printf("a=%d,b=%d\n",a,b);
return 0;
}
void swap(int *pa,int *pb){
int t = *pa;
*pa = *pb;
*pb = t;
}
void swap2(int a,int b){
int t = a;
a = b;
b = t;
}
所以需要在函数中对其做到修改需要对地址进行修改。
找到数组中的大值和最小值#includevoid minmax(int a[],int len,int *max,int *min);
int main(){
int a[] = {1,2,3,4,5,6,7,8,9,12,13,14,16,17,47,24,55,89};
int min,max;
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
printf("min=%d,max=%d\n",min,max);
return 0;
}
void minmax(int a[],int len,int *min,int *max){
int i;
*min = *max = a[0];
for(i=1;i*max){
*max=a[i];
}
}
}
指针最常见的错误定义了指针变量,还未指向任何变量就直接开始使用。
p指向的地址可能恰好是不能赋值的地方,这时候可能就会报错。
指针与数组在不同的系统中,C语言指针的大小是不同的。
在32位系统(即x86)中,指针的大小为4字节。
在64位系统(即x64)中,指针的大小为8字节。
#includevoid minmax(int a[],int len,int *max,int *min);
int main(){
int a[] = {1,2,3,4,5,6,7,8,9,12,13,14,16,17,47,24,55,89};
int min,max;
printf("main sizeof(a)=%lu\n",sizeof(a));
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
printf("min=%d,max=%d\n",min,max);
return 0;
}
void minmax(int a[],int len,int *min,int *max){
int i;
printf("minmax sizeof(a)=%lu\n",sizeof(a));
*min = *max = a[0];
for(i=1;i*max){
*max=a[i];
}
}
}
可以看到在minmax中a的大小恰好等于一个指针的大小,
#includevoid minmax(int a[],int len,int *max,int *min);
int main(){
int a[] = {1,2,3,4,5,6,7,8,9,12,13,14,16,17,47,24,55,89};
int min,max;
printf("main sizeof(a)=%lu\n",sizeof(a));
printf("main a=%p\n",a);
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
printf("min=%d,max=%d\n",min,max);
return 0;
}
void minmax(int a[],int len,int *min,int *max){
int i;
printf("minmax sizeof(a)=%lu\n",sizeof(a));
printf("minmax a=%p\n",a);
*min = *max = a[0];
for(i=1;i*max){
*max=a[i];
}
}
}
#includevoid minmax(int a[],int len,int *max,int *min);
int main(){
int a[] = {1,2,3,4,5,6,7,8,9,12,13,14,16,17,47,24,55,89};
int min,max;
printf("main sizeof(a)=%lu\n",sizeof(a));
printf("main a=%p\n",a);
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
printf("min=%d,max=%d\n",min,max);
return 0;
}
void minmax(int a[],int len,int *min,int *max){
int i;
printf("minmax sizeof(a)=%lu\n",sizeof(a));
printf("minmax a=%p\n",a);
a[0]=1000;
*min = *max = a[0];
for(i=1;i*max){
*max=a[i];
}
}
}
在maxmin中将a[0]改写成1000,这个发现大值最小值都发生了变化,此时最小值为2,大值为1000,那么1000是怎么来的呢,很明显是刚刚修改a数组后得到的。这时候也说明了函数参数中a[]表示的是一个指针。
既然是一个指针,那么写成指针的形式肯定也没有什么区别,将a[]修改成*a再进行编译,发现没有区别。
#includevoid minmax(int *a,int len,int *max,int *min);
int main(){
int a[] = {1,2,3,4,5,6,7,8,9,12,13,14,16,17,47,24,55,89};
int min,max;
printf("main sizeof(a)=%lu\n",sizeof(a));
printf("main a=%p\n",a);
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
printf("min=%d,max=%d\n",min,max);
return 0;
}
void minmax(int *a,int len,int *min,int *max){
int i;
printf("minmax sizeof(a)=%lu\n",sizeof(a));
printf("minmax a=%p\n",a);
a[0]=1000;
*min = *max = a[0];
for(i=1;i*max){
*max=a[i];
}
}
}
数组变量本身表达地址,所以
[ ]运算符可以对数组做,也可以对指针做:
*运算符可以对指针做,也可以对数组做:
数组变量是const指针,所以不能被赋值
#includeint main(){
int a[] = {1,2,3,4,5,6,7,8,9,12,13,14,16,17,47,24,55,89};
int *p = a;
printf("*p=%d\n",*p);
printf("p[0]=%d\n",p[0]);
printf("p[5]=%d\n",p[5]);
return 0;
}
对着个代码运行的结果可以这样理解:p指针指向的是数组a,p[0]是指将所指的地方当做一个数组,取该数组的第1个元素,p[5]表示取数组a的第6个元素。
指针运算#includeint main(){
char ac[] = {0,1,2,3,4,5,6,7,8,9};
char *p = ac;
printf("p =%p \n",p);
printf("p+1=%p \n",p+1);
int ai[] = {0,1,2,3,4,5,6,7,8,9};
int *q = ai;
printf("q =%p \n",q);
printf("q+1=%p \n",q+1);
return 0;
}
地址变化:sizeof(char)=1,sizeof(int)=4.当我们给一个指针+1的时候,我们的地址变化并不是在地址值上+1,而是在地址值上加一个sizeof(数据类型)。
这些算术运算可以对指针做:
两个指针相减的结果是什么?通过以下程序可以很清楚的了解到。
这里也并不是直接的通过地址值相减,而是减完后除以了sizeof(数据类型),得到的是这两个指针之间有多少个这样的地址,或者能放几个这样的地址。
*p++你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧