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语言中无法在被调用的函数中修改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};

在这里插入图片描述
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)是相同的。

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

相关文章
|
7月前
|
C语言 C++
深入理解指针
深入理解指针
69 2
|
程序员 C语言
C 指针
C 指针。
32 0
|
2月前
|
编译器
指针初步讲解(下)
指针初步讲解(下)
32 2
|
7月前
|
编译器
深入理解指针(2)
深入理解指针(2)
41 2
|
7月前
|
存储 C语言
深入理解指针(1)
深入理解指针(1)
46 2
|
7月前
|
存储 C++
|
7月前
|
程序员 C语言
C指针
C指针。
30 6
|
7月前
|
存储
浅谈指针(1)
浅谈指针(1)
|
存储 安全 C语言
C语言知识点之 指针1
C语言知识点之 指针1
62 0