指针,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,如需转载请自行联系原作者

相关文章
|
1月前
|
存储 C语言
【C语言篇】深入理解指针3(附转移表源码)
【C语言篇】深入理解指针3(附转移表源码)
36 1
|
19天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
44 0
|
18天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
13 2
|
18天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
18天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
25天前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
24天前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
25天前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
25天前
|
C语言
C语言指针(3)
C语言指针(3)
11 1
|
25天前
|
C语言
C语言指针(2)
C语言指针(2)
13 1