指针,c语言的灵魂

简介:

指针是一个值为内存地址的变量。

变量是一块内存空间,指针是变量,是用来存储内存地址的变量。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int num = 9;
    printf("num变量的地址为:%p\n",&num); // p表示指针占位符
    return 0;
}

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int num = 9;
    int * ptr_num = &num;
    printf("num变量的地址为:%p\n",ptr_num); // p表示指针占位符
    return 0;
}

根据地址,找到空间!然后操作空间!

变量地址也占用空间,只不过占用的不是内存空间,而是寄存器的存储空间。

内存地址实际上是一种偏移量,存储于段寄存器中。内存地址只是一种抽象,不是真正的物理内存地址,而是逻辑地址。由逻辑地址寻找到物理地址需要经过 逻辑地址->线性地址->物理地址 转换过程,而这些过程都是基于寄存器完成的。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int num = 9;
    int * ptr_num = &num;
    * ptr_num = 10;
    printf("* ptr_num的值为:%d\n",* ptr_num);
    printf("num的值为:%d\n",num); // p表示指针占位符
    return 0;
}

指针的类型,跟他所指向的数据结构有关。
基本类型的指针指向基本类型的数据结构。
比如:char * p; int p; float p; double *p;
分别指向的是char, int ,float, double 类型的变量。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int num1 = 1024;
    int num2 = 2048;
    int * ptr1;
    int * ptr2;
    ptr1 = &num1;
    ptr2 = &num2;
    printf("num1的值是%d\tnum1的地址是:%p\n",num1,ptr1);
    printf("num2的值是%d\tnum2的地址是:%p\n",num2,ptr2);

    // 将变量1的值赋给变量2
    num2 = num1;
    printf("num1的值是%d\tnum1的地址是:%p\n",num1,ptr1);
    printf("num2的值是%d\tnum2的地址是:%p\n",num2,ptr2);

    *ptr2 = *ptr1; // 等价于 num2 = num1
    printf("num1的值是%d\tnum1的地址是:%p\n",num1,ptr1);
    printf("num2的值是%d\tnum2的地址是:%p\n",num2,ptr2);

    // 地址变了,num1,num2不受影响
    ptr2 = ptr1;
    printf("num1的值是%d\tnum1的地址是:%p\n",num1,ptr1);
    printf("num2的值是%d\tnum2的地址是:%p\n",num2,ptr2);


    return 0;
}

一个变量就是一个内存空间,内存一定是有物理地址的!指针就是保存变量内存物理地址的变量!

指针与数组

数组是一个连续的内存空间,数组名就是它的首地址。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    double score[] = {98,87,65,43,76};
    printf("数组的首地址:%p\t 数组手元素的地址 :%p\n",score,&score[0]);

}

数组名就是数组元素的首地址。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    double score[5] = {98,87,65,43,76};
    double * ptr_score;
    ptr_score = score;
    for (i=0;i<5;i++) {
        printf("%.2lf\n",*ptr_score++); // 通过首地址取找数组元素的值
    }

    for (i=0;i<5;i++) {
        printf("%.2lf\n",score[i]);
    }

}

等价的!double类型的数据,每个数据移动了8个字节。物理地址是一个十六进制的数字。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int array[] = {15,20,25,30,35};
    int i;
    int * ptr_array = array;
    for (i = 0;i<5;i++) {
        printf("第%d个元素的值为%d,地址为%p\n",i,*ptr_array,ptr_array);
        ptr_array ++ ;
    }

    /*
    第0个元素的值为15,地址为0028FF0C
    第1个元素的值为20,地址为0028FF10
    第2个元素的值为25,地址为0028FF14
    第3个元素的值为30,地址为0028FF18
    第4个元素的值为35,地址为0028FF1C
    */
    return 0;
}

int型地址间隔4个字节。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 7

int main()
{
    int array[N] = {15,20,25,30,35,40,90};
    int i;
    int temp;
    // 实现数组的逆序
    // 数组的首尾元素进行交换
    for (i = 0;i<floor(N/2);i++) {
        temp = array[i];
        array[i] = array[N-i-1];
        array[N-i-1] = temp;
    }

    for (i = 0;i<N;i++) {
        printf("交换后第%d元素的值为:%d\n",i,*(array + i));
    }
    return 0;
}

逆序数组,找规律是写程序必备的技能!

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 7

int main()
{
    int array[N] = {15,20,25,30,35,40,90};
    int i;
    int temp;

    int * ptr_head;
    int * ptr_foot;
    ptr_head = &array[0];
    ptr_foot = &array[N-1];

    // 实现数组的逆序
    // 数组的首尾元素进行交换
    for (i = 0;i<floor(N/2);i++) {
        temp = * ptr_head;
        * ptr_head = * ptr_foot;
        * ptr_foot = temp;
        ptr_head ++;
        ptr_foot --;
    }

    for (i = 0;i<N;i++) {
        printf("交换后第%d元素的值为:%d\n",i,*(array + i));
    }
    return 0;
}

指针实现数组逆序!

二维数组与指针

首地址

&a[0][0]

有祥有略!有精有简!有的放矢有的取舍去学习!

何为二维数组,如何理解?由n个一维数组组成!

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int main()
{
    int i,j;
    double score[5][3] = {
        {55,56,57},
        {58,59,60},
        {61,62,63},
        {64,65,66},
        {67,68,69}
    };

    // 传统的访问方式
    for (i = 0;i < 5;i++) {
        for (j = 0;j <3 ;j++) {
            printf("%.2lf\t",score[i][j]);
        }

        printf("\n");
    }

    printf("=================================\n");

    // 指针的方式访问
    for (i = 0;i < 5;i++) {
        for (j = 0;j <3 ;j++) {
            // printf("%.2lf\t",*(score[i] + j));
            printf("%.2lf\t",*(*(score+i) + j));
        }

        printf("\n");
    }


    return 0;
}

*(*(score + i) + j) 获取二维数组的公式!



本文转自TBHacker博客园博客,原文链接:http://www.cnblogs.com/jiqing9006/p/8025510.html,如需转载请自行联系原作者

相关文章
|
2月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
56 0
|
20天前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
73 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
20天前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
44 9
|
20天前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
40 7
|
1月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
104 13
|
23天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
23天前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
75 3
|
24天前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
1月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
52 11
|
23天前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
35 1