当前位置 博文首页 > 谷哥的小弟:C语言自学完备手册(27)——指针(1)
自定义View系列教程00–推翻自己和过往,重学自定义View
自定义View系列教程01–常用工具介绍
自定义View系列教程02–onMeasure源码详尽分析
自定义View系列教程03–onLayout源码详尽分析
自定义View系列教程04–Draw源码分析及其实践
自定义View系列教程05–示例分析
自定义View系列教程06–详解View的Touch事件处理
自定义View系列教程07–详解ViewGroup分发Touch事件
自定义View系列教程08–滑动冲突的产生及其处理
探索Android软键盘的疑难杂症
深入探讨Android异步精髓Handler
详解Android主流框架不可或缺的基石
站在源码的肩膀上全解Scroller工作机制
Android多分辨率适配框架(1)— 核心基础
Android多分辨率适配框架(2)— 原理剖析
Android多分辨率适配框架(3)— 使用指南
讲给Android程序员看的前端系列教程(图文版)
讲给Android程序员看的前端系列教程(视频版)
Android程序员C语言自学完备手册
从本小结开始学习指针。
利用&
可以获取变量(有时也泛称对象)在内存中的地址。请看如下示例:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x;
double y;
int z[3];
printf("x的地址是%p\n",&x);
printf("y的地址是%p\n",&y);
printf("z的地址是%p\n",&z);
return 0;
}
结果如下:
x的地址是0060FF0C
y的地址是0060FF00
z的地址是0060FEF4
在该示例中通过了&
获取了各变量在内存中的地址。更确切地说:&
获取了变量在内存中的首地址!还有一个小细节需要留意:在printf( )函数中使用的是%p来表示打印变量地址,p是单词pointer的缩写。
单纯地使用&
获取变量在内存中的地址没有太大的实际意义,更多的是将其与指针联合在一起使用。
指针(pointer)堪称C语言的灵魂,由此开始,我们正式进入指针的学习。
在C语言中利用*
声明指针。例如:
int *p;
该语句有以下几重含义:
核心小结:
1 指针的声明如下:Type *指针名,该指针的类型是Type*型;或者说该指针是Type*型指针
2 一般来说,Type*型指针不会指向Type型以外的对象。
3 指针指向的是对象在内存中的首地址!
接下来初始化该指针:
int *p;
int number=9527;
p=&number;
好了,有了刚才的基础知识,我们来看一个简单的示例,代码如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p;
int number=9527;
p=&number;
printf("p在内存中的地址是%p\n",&p);
printf("number在内存中的地址是%p\n",&number);
printf("number在内存中的地址是%p\n",p);
printf("number=%d\n",number);
printf("number=%d\n",*p);
puts("----------------");
number=999;
printf("number=%d\n",number);
printf("number=%d\n",*p);
puts("----------------");
*p=888;
printf("number=%d\n",number);
printf("number=%d\n",*p);
return 0;
}
在该示例中指针p指向了int类型的变量number。所以,p中所存的正是变量number在内存中的地址。故,可以通过&number和p这两种方式得到number在内存中的地址。我们若想获取或者修改number的值,可通过number和*p两种方式进行。也可以通俗地理解为:*p是number的别名,两者指向了同一个内存区域。
结果如下:
示例小结
在本示例中存在以下对等关系
需求很简单,实现代码如下:
#include <stdio.h>
#include <stdlib.h>
void changeNumber(int number){
if(number>=0&&number<=100){
number=number*2;
}
}
int main()
{
int number=17;
printf("修改前number=%d\n",number);
changeNumber(number);
printf("修改后number=%d\n",number);
return 0;
}
结果如下:
修改前number=17
修改后number=17
在该示例中并没有成功的改变number的值。因为这种传递方式是值传递,实参和形参彼此独立,不能够相互影响。所以,我们可以用指针来解决该问题。
#include <stdio.h>
#include <stdlib.h>
void changeNumber(int *p){
if(*p>=0&&*p<=100){
*p=*p*2;
}
}
int main()
{
int number=17;
printf("修改前number=%d\n",number);
int *q=&number;
changeNumber(q);
printf("修改后number=%d\n",number);
return 0;
}
在该示例中将指针作为参数传递。修改指针的值就等同于修改原来的值,即代码第6行。这样就避免了在值传递过程中带来的不便。
结果如下:
修改前number=17
修改后number=34
在这儿,我们初步领略了指针的魅力,继续我们的练习。
#include <stdio.h>
#include <stdlib.h>
void getSumAndDiff(int a,int b,int *sum,int *diff){
*sum=a+b;
if(a>b){
*diff=a-b;
}else{
*diff=b-a;
}
}
int main()
{
int a;
int b;
int sum=0;
int diff=0;
int *s=∑
int *d=&diff;
puts("请您输入两个整数");
printf("请输入第一个整数:");
scanf("%d",&a);
printf("请输入第二个整数:");
scanf("%d",&b);
getSumAndDiff(a,b,s,d);
printf("两个数的和=%d,两个数的差=%d",sum,diff);
return 0;
}
结果如下:
请您输入两个整数
请输入第一个整数:5
请输入第二个整数:8
两个数的和=13,两个数的差=3
Process returned 0 (0x0) execution time : 5.529 s
Press any key to continue.
#include <stdio.h>
#include <stdlib.h>
void swapNumber(int *a,int *b){
int temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int a=4;
int b=9;
int *p=&a;
int *q=&b;
printf("交换前a=%d,b=%d\n",a,b);
swapNumber(p,q);
printf("交换后a=%d,b=%d\n",a,b);
return 0;
}
结果如下:
交换前a=4,b=9
交换后a=9,b=4
在刚才的示例中创建了两个指针p和q并将两者作为swapNumber( )方法的输入参数。其实,我们也可以不定义这两个指针,直接将&a和&b作为swapNumber( )方法的输入参数;代码如下:
#include <stdio.h>
#include <stdlib.h>
void swapNumber(int *a,int *b){
int temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int a=4;
int b=9;
printf("交换前a=%d,b=%d\n",a,b);
swapNumber(&a,&b);
printf("交换后a=%d,b=%d\n",a,b);
return 0;
}
空指针(null pointer)是一种非常特殊的指针,它表示“什么也不指向”的指针
我们通常在使用scanf( )函数时都会在变量名前加上一个特殊符号&,例如:
int no;
scanf("%d",&no);
该代码片段表示:接收键盘输入的整数值,并将该值赋给变量i。
类似的代码已经写过很多次了,我们可能不禁要问:为什么通常在使用scanf( )函数时会在变量名前加上一个符号&?因为scanf( )函数要往变量里写入数值,所以它必须知道该变量的在内存中的地址。至于该变量里是否已经存在值,存的是什么值,scanf( )是不管的,它只管把键盘输入的值存入该变量!
顺便地我们再回过头来看看printf( )函数,该函数的作用是输出变量里的数值。所以它只关注变量的值是多少,至于该变量在内存的地址它是不理会的。
从本质上而言:scanf( )函数用于写数据,printf( )函数用于读数据。