> 文章列表 > C 中的指针

C 中的指针

C 中的指针

C 指针

学习 C 语言的指针既简单又有趣。通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的 C 程序员,学习指针是很有必要的。

正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址。

请看下面的实例,它将输出定义的变量地址:

举例:

#include <stdio.h>int main ()
{int var_runoob = 10;int *p;              // 定义指针变量p = &var_runoob;printf("var_runoob 变量的地址: %p\\n", p);return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

var_runoob 变量的地址: 0x7ffeeaae08d8

C 中的指针

当函数需要返回多个结果

由于C语言是使用传值的方式将参数值传递给被调用的函数,所以在C语言中无法在被调用的函数中修改main函数里的值,可以通过将main函数中变量的地址值传给被调用的函数,从而在被调用的函数中通过地址访问到变量的值,并且可以改变变量的值。

①交换函数值的例子

void swap(int a,int b){int temp;temp=a;a=b;b=temp;
} 

不使用指针变量,我们不能同时将改变后的a和b的值传回;这个时候我们就可以通过指针作为参数,通过地址访问变量的值,从而去实现。

#include<stdio.h>
void swap(int *a,int *b){int temp;temp=*a;*a=*b;*b=temp;
} 
int main(){int a=1;int b=3;swap(&a,&b);printf("a=%d b=%d",a,b);return 0;
}
运行结果:
a=3 b=1
--------------------------------
Process exited after 0.03594 seconds with return value 0
请按任意键继续. . .

可以看出,主函数里将变量的地址传入swap函数,我们在swap函数中直接通过指针访问到了主函数里变量的值,并交换了数值,同时在主函数里能打印出交换的值。

数组和指针

C语言中数组和指针有着很大的关联,具体的我们往下看:

①定义一个a数组

int a[5]={1,2,3,4,5};

C 中的指针
int类型的五个对象存在上述五块区域中;

②现在我们声明一个指针:int *p; 并且对指针赋值;p=&a[0];

#include<stdio.h>
int main(){int a[]={1,2,3,4,5};int i=0;int *p;       //声明了一个指针变量p=&a[0];      //给指针p赋了a[0]的地址值给指针for(i=0;i<5;i++){printf("%d ",a[i]); //通过for循环将数组里的值打印出来了}printf("\\n");for(i=0;i<5;i++){printf("%d ",*p);  //第一次循环的时候通过指针访问到了a[0]的值,并输出了p++;       //对地址加1。我们第一次对地址+1得到了a[1]的地址,第二次+1得到a[2]的地址.......}printf("\\n");return 0;
}
运行结果:
1 2 3 4 5
1 2 3 4 5
--------------------------------
Process exited after 0.04136 seconds with return value 0
请按任意键继续. . .

③升入探究一下,指针p储存的地址+1是怎么变成a[1]…的地址的

输出地址

#include<stdio.h>
int main(){int a[]={1,2,3,4,5};printf("%p\\n",&a[0]);printf("%p\\n",&a[1]);return 0;
}
运行结果:
000000000062FE00
000000000062FE04
--------------------------------
Process exited after 0.04234 seconds with return value 0
请按任意键继续. . .

我们得到了a[0]的地址空间是000000000062FE00;a[1]的地址空间是000000000062FE04;

我们发现a[0]和a[1]之间的地址值相差了4;那为什么一开始p指针储存的值是000000000062FE00,我们对其+1的时候不应该是000000000062FE01吗?而实际我们发现我们得到的是a[1]的地址000000000062FE04。

这是因为,p指针它指向的int类型的数组中的a[0];在进行p++的时候,我们+的一个sizeof(int)=4;所以*(p+1)指向的是a[1];那么如果是对于char类型的数组,指针p++的时候,才是真的是加了1;因为sizeof(char)=1;

总之无论数组是什么类型,指针加一都是意味着它指向了数组中的下一个对象;

④指针和数组关系

一般输出:

#include<stdio.h>
int main(){int a[]={1,2,3,4,5};int i=0;for(i=0;i<5;i++){printf("%d ",a[i]);}return 0;
}
运行结果:
1 2 3 4 5
--------------------------------
Process exited after 0.04031 seconds with return value 0
请按任意键继续. . .

指针输出:

#include<stdio.h>
int main(){int a[]={1,2,3,4,5};int i=0;for(i=0;i<5;i++){printf("%d ",*(a+i));}return 0;
}
运算结果:
1 2 3 4 5
--------------------------------
Process exited after 0.03991 seconds with return value 0
请按任意键继续. . .

通过对比我们发现 printf("%d “,a[i]); 和 printf(”%d ",(a+i)); 语句是完全等价的,即a[i]可以写成(a+i),可能比较难以理解,其实在C语言编译的时候,是先转化为*(a+i)的然后在进行运算的,其实我们还可换一个方面来理解,地址&a[i]和地址(a+i)是相同的。

现在我们发现其实数组和指针都是差不多的东西,但是值得我们注意的是,指针是一个变量,数组不是!而且当我们把一个数组传入函数的时候,其实我们实际传入的是数组中第一个元素的地址‘