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)是相同的。

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

相关文章
|
搜索推荐 数据库 C语言
C语言实现冒泡排序(超详细)
C语言实现冒泡排序(超详细)
690 1
|
XML 前端开发 JavaScript
视频弹幕设计网站02-----数据库设计与后端配置
视频弹幕设计网站02-----数据库设计与后端配置
|
设计模式 算法 Java
从入门到精通:一篇文章带你搞懂简单工厂模式
本文旨在通过深入浅出的方式,引导读者从入门到精通掌握简单工厂模式。文章首先介绍了简单工厂模式的基本概念和应用场景,阐述了其在软件开发中的重要性和实用性。接着,通过具体实例和详细解析,展示了简单工厂模式的实现方法和关键步骤,包括工厂类的设计、产品类的抽象与实现等。此外,文章还探讨了简单工厂模式的优缺点及适用场景,帮助读者更全面地理解该模式。最后,通过总结归纳,强调了简单工厂模式在提升代码可维护性、可扩展性和降低耦合度等方面的优势,鼓励读者在实际项目中积极应用。本文内容丰富、条理清晰,适合对简单工厂模式感兴趣的编程爱好者和软件开发者阅读参考。
375 1
|
数据采集 JavaScript 前端开发
常见的反爬虫策略有哪些?
常见的反爬虫策略有哪些?
899 1
|
人工智能 BI
区间问题之区间覆盖(看一遍就会系列)
区间问题之区间覆盖(看一遍就会系列)
|
开发框架 安全 搜索推荐
如何使用Python Flask发布web页面至公网并实现远程访问【内网穿透】
如何使用Python Flask发布web页面至公网并实现远程访问【内网穿透】
|
C语言
变量初始化和不初始化
变量初始化和不初始化。
462 1
|
XML 小程序 Java
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
373 0
阿里云企业邮箱价格表(标准版/尊享版/集团版)
2023阿里云企业邮箱价格表(标准版/尊享版/集团版),标准版企业邮箱原价600元一年、企业邮箱尊享版1400元一年、企业邮箱集团版9500元一年,目前收费版的企业邮箱可以享受9折或8折优惠
685 0
阿里云企业邮箱价格表(标准版/尊享版/集团版)