呵呵哒!手把手教你什么是指针
1.地址和指针的概念
地址:一个变量的地址称为该变量的“指针”。
指针:指针是一个地址,而指针变量是存放地址的变量。
特别注意:只有整型变量的地址才能放到指向那个整型变量的指针变量中,以此类推。
2.指针变量的引用
有两个有关的运算符:
(1)& : 取地址运算符。
(2)* :指针运算符(或称为“间接访问”运算符),取指针所指向的对象的内容。
例如:&a为变量的a的地址,*p为指针变量p所指向的存储单元的内容(即p所指向的变量的值)
//通过指针变量的访问整型变量
#include <stdio.h>
void main(){
int a,b;
int *pointer_1,*pointer_2;
a=100;b=10;
pointer_1=&a;//把变量a的地址赋给pointer_1
pointer_2=&b;//把变量b的地址赋给pointer_2
printf("%d,%d\n",a,b);
printf("%d,%d\n",*pointer_1,*pointer_2);
}
知识点巧懂:
(1)&*pointer_1的含义是什么?
&和*这两个运算符的优先级级别相同,按照自右向左的方便结合,因此先进行*pointer_1的运算,它就是变量a,然后在执行&运算。也就是说:&*pointer_1=&a,即变量a的地址
(2)*&a的含义是什么?
先进行&a运算,得到a的地址,再进行*运算,也就是说:*&a=a。而且*&a和*pointer_1的作用也是一样的。
(3)(*pointer_1)++相当于a++
由于&和*这两个运算符的优先级级别相同,按照自右向左的方便结合,括号是必要的。
3.指针变量运用
(1)算法实现:不交换整型变量的值,而是交换两个指针变量的值(即a和b的地址)。
#include <stdio.h>
void main(){
int *p1,*p2,*p,a,b;
scanf("%d%d",&a,&b);
p1=&a;
p2=&b;
if(a<b){
p1=&b;
p2=&a;
}
printf("a=%d,b=%d\n\n",a,b);
printf("max=%d,min=%d\n",*p1,*p2);
}
(2)算法实现:不交换两个指针变量的值,而是交换整型变量的值 (即a和b)。
#include <stdio.h>
void main(){
void swap(int *p1,int *p2);
int a,b;
int *pointer_1,*pointer_2;
scanf("%d%d",&a,&b);
pointer_1=&a;
pointer_2=&b;
if(a<b){
swap(pointer_1,pointer_2);
}
printf("%d %d\n",a,b);
}
void swap(int *p1,int *p2){
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
(3)输入a,b,c这3个整数,按照大小顺序输出
#include <stdio.h>
void main(){
void exchange(int *q1,int *q2,int *q3);
int a,b,c,*q1,*q2,*q3;
scanf("%d%d%d",&a,&b,&c);
q1=&a;
q2=&b;
q3=&c;
exchange(q1,q2,q3);
printf("%d%d%d",a,b,c);
}
void exchange(int *q1,int *q2,int *q3){
void swap(int *q1,int *q2);
if(*q1<*q2) swap(q1,q2);
if(*q1<*q3) swap(q1,q3);
if(*q2<*q3) swap(q2,q3);
}
void swap(int *q1,int *q2){
int temp;
temp=*q1;
*q1=*q2;
*q2=temp;
}
4.通用指针引用数组元素
按照C语言的规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,而不是p的值(地址)简单的加1。例如,数组元素是float型,每个元素占4个字节,则p+1意味着使p的值(是地址)加4个字节,以使指向下一个元素。(Visual C++6.0中,对int,long和float型,d=4,对char型)
(1)p+i和a+i就是a[[i]的地址,或者说,它们指向a数组的第i个元素。
(2)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素。即a[i]。
(3)指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价
5.输出数组中的全部元素
(1)下标法
#include <stdio.h>
void main(){
int a[10];
int i;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
for(i=0;i<10;i++){
printf("%d",a[i]);
}
printf("\n");
}
(2)通过数组名计算数组元素地址,找出元素的值
#include <stdio.h>
void main(){
int a[10];
int i;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
for(i=0;i<10;i++){
printf("%d",*(a+i));
}
printf("\n");
}
(3)用指针变量指向数组元素
#include <stdio.h>
void main(){
int a[10];
int *p;
int i;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
for(p=a;p<(a+10);p++){
printf("%d",*p);
}
printf("\n");
}
也可以简写成为如下
#include <stdio.h>
void main(){
int a[10];
int *p;
int i;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
for(p=a;p<(a+10);){
printf("%d",*p++);
}
printf("\n");
}
但是不可以写成如下
for(p=a;a<(p+10);a++)
这样是不行的,因为数组名a代表数组首元素的地址,它是一个指针常量,它的值在程序运行期间是固定不变的,既然a是常量,所以a++是无法实现的。
6.通过指针变量输出a数组的10个元素
常见错误代码:
#include <stdio.h>
void main(){
int a[10];
int *p;
int i;
p=a;
for(i=0;i<10;i++){
scanf("%d",p++);
}
for(i=0;i<10;i++,p++){
printf("%d",*p);
}
printf("\n");
}
纠正代码
#include <stdio.h>
void main(){
int a[10];
int *p;
int i;
p=a;
for(i=0;i<10;i++){
scanf("%d",p++);
}
p=a;//添加这条语句,可以使得指针回到首地址
for(i=0;i<10;i++,p++){
printf("%d",*p);
}
printf("\n");
}
知识点巧懂
(1)*p++,由于++和*同优先级,结合方向为自右向左,因此它等价于*(p++)。作用是先得到p指向的变量的值,然后再p+1=p。
(2)*(p++)和*(++p)作用不同。
(3)*(p—)相当于a[i—],先对p进行”*“运算,然后p自减。
(4)*(++p)相当于a[i—],先对p自加,然后p进行”*“运算。
7.用选择法对10个整数按照由小到大顺序排序
(1)逐个取出数组的元素进行数字的排序
#include <stdio.h>
void main(){
void sort(int x[],int n);
int *p,i,a[10];
p=a;
for(i=0;i<10;i++){
scanf("%d",p++);
}
p=a;
sort(p,10);
p=a;
for(i=0;i<10;i++){
printf("%d",*p++);
}
}
void sort(int x[],int n){
int i,j,k,t;
for(i=0;i<n-1;i++){
k=i;
for(j=i+1;j<n;j++)
if(x[j]>x[k]){
k=j;
}
if(k!=i){
t=x[i];
x[i]=x[k];
x[k]=t;
}
}
}
(2)用指针的方法进行数字的排序
#include <stdio.h>
void main(){
void sort(int *x,int n);
int *p,i,a[10];
p=a;
for(i=0;i<10;i++){
scanf("%d",p++);
}
p=a;
sort(p,10);
p=a;
for(i=0;i<10;i++){
printf("%d",*p++);
}
}
void sort(int *x,int n){
int i,j,k,t;
for(i=0;i<n-1;i++){
k=i;
for(j=i+1;j<n;j++)
if(*(x+j)>*(x+k)){
k=j;
}
if(k!=i){
t=*(x+i);
*(x+i)=*(x+k);
*(x+k)=t;
}
}
}
8.多维数组和指针
int a[3][4]={ {1,2,3,4},{5,6,7,8},{9,10,11,12}};
知识点巧懂
(1)从二维数组的角度来看,a代表二维数组首元素的地址。例如a[0]在二维数组中代表一维数组a[0]中第0列元素的地址。即&a[0][0]。
(2)考虑1行0列元素的地址如何表示?a[0]为一维数组名,此时”a[0]+1”的地址为&a[0][1]。
(3)用指针变量输出二维数组元素的值。
#include <stdio.h>
void main(){
int a[3][4]={
{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *p;
for(p=a[0];p<a[0]+12;p++){
if((p-a[0])%4==0)
printf("\n");
printf("%4d",*p);
}
printf("\n");
}
(4)输出二维数组任一行任一列元素的值。
#include <stdio.h>
void main(){
int a[3][4]={
{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*p)[4],i,j;
p=a;
scanf("%d%d",&i,&j);
printf("a[%d,%d]=%d\n",i,j,*(*(p+i)+j));
}
(5)用指向数组的指针作函数参数。
#include <stdio.h>
void main(){
void average(float *p,int n);
void search(float(*p)[4],int n);
float score[3][4]={
{65,67,70,60},{80,87,90,81},{90,99,100,98}};
//average(score[0],12);
//*score=score[0]
average(*score,12);
//指定找出某一行
search(score,2);
}
void average(float *p,int n){
float sum=0;
float *p_end;
p_end=p+n;
for(;p<p_end;p++)
sum=sum+(*p);
printf("average=%f\n",sum/n);
}
void search(float(*p)[4],int n){
int i;
for(i=0;i<4;i++){
printf("%5.2f\t",*(*(p+n)+i));
}
printf("\n");
}
9.字符串与指针
(1)定义一个字符数组,对它初始化,然后输出该字符串。
#include <stdio.h>
void main(){
char string[]="I love China!";
printf("%s\n",string);
}
(2)用字符指针指向一个字符串。
#include <stdio.h>
void main(){
char *string="I love China!";
printf("%s\n",string);
}
(3)用指针变量将字符串a复制为字符串b。
#include <stdio.h>
void main(){
char a[]="I am a boy",b[20],*p1,*p2;
int i;
p1=a;
p2=b;
for(;*p1!='\0';p1++,p2++){
*p2=*p1;
}
*p2='\0';
for(i=0;b[i]!='\0';i++){
printf("%c",b[i]);
}
printf("\n");
}
(4)改变指针变量的值。
#include <stdio.h>
void main(){
char *a="I love China!";
a=a+7;
printf("%s\n",a);
}
9.指向函数的指针
(1)用函数指针变量调用函数
数据类型 (* 指针变量名)(函数参数表列)
这是一般方法程序
#include <stdio.h>
void main(){
int max(int,int);
int a,b,c;
scanf("%d%d",&a,&b);
c=max(a,b);
printf("max=%d",c);
}
int max(int x,int y){
int z;
if(x>y)z=x;
else z=y;
return (z);
}
用函数指针变量调用函数
#include <stdio.h>
void main(){
int max(int,int);
int (*p)(int,int);
int a,b,c;
scanf("%d%d",&a,&b);
p=max;
c=(*p)(a,b);
printf("max=%d",c);
}
int max(int x,int y){
int z;
if(x>y)z=x;
else z=y;
return (z);
}
(2)设一个函数process,在调用它的时候,每次实现不同的功能。
#include <stdio.h>
void main(){
int max(int,int);
int min(int,int);
int add(int,int);
int process(int,int,int(*fun)(int,int));
int a,b;
printf("enter a and b:");
scanf("%d%d",&a,&b);
printf("max = %d\n",process(a,b,max));
printf("min = %d\n",process(a,b,min));
printf("add = %d\n",process(a,b,add));
}
int process(int x,int y,int(*fun)(int,int)){
int result;
result=(*fun)(x,y);
return result;
}
int max(int x,int y){
int max;
max=x>y?x:y;
return max;
}
int min(int x,int y){
int min;
min=x<y?x:y;
return min;
}
int add(int x,int y){
int add;
add=x+y;
return add;
}
10.返回指针值的函数
(1)若干个学生的成绩(每个学生有四门课程),输入学生序号可以查询该学生的全部成绩。
#include <stdio.h>
void main(){
float score[][4]={
{20,30,40,50},{1,2,3,4},{5,6,7,8}};
float *search(float (*score_pointer)[4],int n);
float *p;
int i,m;
scanf("%d",&m);
p=search(score,m);
for(i=0;i<4;i++){
printf("%5.2f\t",*(p+i));
}
printf("\n");
}
float *search(float (*score_pointer)[4],int n){
float *pt;
//score_pointer等于score首地址,*(score_pointer+n)意思是得到第n第0列的地址
pt=*(score_pointer+n);
return pt;
}
(2)找出其中不及格课程的学生以及学生号。
#include <stdio.h>
void main(){
float score[][4]={
{60,70,80,90},{56,89,67,88},{34,78,90,66}};
float *search(float(*pointer)[4]);
float *p;
int i,j;
for(i=0;i<3;i++){
p=search(score+i);
if(p==*(score+i)){
printf("No.%d scores:",i);
for(j=0;j<4;j++){
printf("%5.2f",*(p+j));
}
printf("\n");
}
printf("\n");
}
}
float *search(float(*pointer)[4]){
int i;
float *pt;
pt=*(pointer+1);
for(i=0;i<4;i++){
if(*(*pointer+i)<60)
pt=*pointer;
}
return pt;
}
11.指针数组和指向指针的指针
(1)将若干个字符按照字母顺序(从小到大)输出。
#include <stdio.h>
#include <string.h>
void main(){
void sort(char *name[],int n);
void print(char *name[],int n);
char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer design"};
int n=5;
sort(name,n);
print(name,n);
}
void sort(char *name[],int n){
char *temp;
int i,j,k;
for(i=0;i<n-1;i++){
k=i;
for(j=i+1;j<n;j++){
if(strcmp(name[k],name[j])>0)
k=j;
}
if(k!=i){
temp=name[i];
name[i]=name[k];
name[k]=temp;
}
}
}
void print(char * name[],int n){
int i;
for(i=0;i<n;i++){
printf("%s\n",name[i]);
}
}
(2)指向指针的指针
#include <stdio.h>
void main(){
char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer design"};
//printf("%s\n",name[0]);
char **p;
int i;
for(i=0;i<5;i++){
p=name+i;
printf("%s\n",*p);
}
}
(3)指针数组的元素指向整型数据
#include <stdio.h>
void main(){
int a[5]={1,3,5,7,9};
int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};
int **p,i;
//num其实是&a[0]的地址 然后 p=num 所以 *p找到了&a[0],然后**p则*&a[0]=a[0]
p=num;
//printf("%d\n",&a[0]);
//printf("%d\n",num[0]);
for(i=0;i<5;i++){
printf("%d",**p);
p++;
}
printf("\n");
}
还没有评论,来说两句吧...