指针

指针的定义

  • 取址符&:每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址。
  • 指针的定义:指针也就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。
  • 指针变量的声明的一般形式:type *var_name
  • 注意:此时指针的数据类型是 type* 而不是 type
  • 例子:int *ip; // 这是一个整型的指针
  • 所有实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数。
  • 不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
  • int *ip = &val,那么 ip 是地址,*ip 是一个整数
  • int *ip = &valint *ip; *ip = val 等价
  • 使用 printf 输出地址时用 %p 作为占位符

NULL 指针

  • 空指针:在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针

指针的算术运算

  • 指针的每一次递增,它其实会指向下一个元素的存储单元。
  • 指针的每一次递减,它都会指向前一个元素的存储单元。
  • 指针在递增和递减时跳跃的字节数取决于指针所指向变量数据类型长度,比如 int 就是 4 个字节。

递增一个指针

递增一个指针意味着让指针指向下一个内存位置。

指针的递增操作会根据指针所指向的数据类型进行适当的内存偏移。

使用指针代替数组

这很方便,因为变量指针可以递增,而数组不能递增,数组可以看成一个指针常量。

#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   // 定义一个整数数组
   int var[] = {10, 100, 200};
   // 定义一个整数变量 i 和一个整数指针 ptr
   int i, *ptr;
 
   // 将指针 ptr 指向数组 var 的起始地址
   ptr = var;
   // 循环遍历数组
   for ( i = 0; i < MAX; i++)
   {
      // 打印当前指针 ptr 所指向的地址
      printf("存储地址:var[%d] = %p\n", i, ptr );
      // 打印当前指针 ptr 所指向地址的值
      printf("存储值:var[%d] = %d\n", i, *ptr );
 
      // 将指针 ptr 移动到下一个数组元素的位置
      ptr++;
   }
   return 0;
}

递增字符指针

#include <stdio.h>

int main() {
    char str[] = "Hello";
    char *ptr = str;  // 指针指向字符串的第一个字符

    printf("初始字符: %c\n", *ptr);  // 输出 H

    ptr++;  // 递增指针,使其指向下一个字符
    printf("递增后字符: %c\n", *ptr);  // 输出 e

    return 0;
}

在这个示例中,ptr++ 使指针从 str[0] 指向 str[1]。因为 ptr 是一个 char 类型指针,所以它递增时会移动 sizeof(char) 个字节,即 1 个字节。

递增结构体指针

#include <stdio.h>

struct Point {
    int x;
    int y;
};

int main() {
    struct Point points[] = {{1, 2}, {3, 4}, {5, 6}};
    struct Point *ptr = points;  // 指针指向结构体数组的第一个元素

    printf("初始点: (%d, %d)\n", ptr->x, ptr->y);  // 输出 (1, 2)

    ptr++;  // 递增指针,使其指向下一个结构体
    printf("递增后点: (%d, %d)\n", ptr->x, ptr->y);  // 输出 (3, 4)

    return 0;
}

在这个示例中,ptr++ 使指针从 points[0] 指向 points[1]。因为 ptr 是一个 struct Point 类型指针,所以它递增时会移动 sizeof(struct Point) 个字节。

递减一个指针

递减一个指针意味着让指针指向前一个内存位置。和递增指针类似,指针的递减操作也会根据指针所指向的数据类型进行适当的内存偏移。

递减数组指针

#include <stdio.h>
 
int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = &arr[4];  // 指针指向数组的最后一个元素
 
    printf("初始值: %d\n", *ptr);  // 输出 50
 
    ptr--;  // 递减指针,使其指向前一个整数元素
    printf("递减后值: %d\n", *ptr);  // 输出 40
 
    ptr--;  // 再次递减指针
    printf("再次递减后值: %d\n", *ptr);  // 输出 30
 
    return 0;
}

递减字符指针

#include <stdio.h>

int main() {
    char str[] = "Hello";
    char *ptr = &str[4];  // 指针指向字符串的最后一个字符 'o'

    printf("初始字符: %c\n", *ptr);  // 输出 o

    ptr--;  // 递减指针,使其指向前一个字符
    printf("递减后字符: %c\n", *ptr);  // 输出 l

    ptr--;  // 再次递减指针
    printf("再次递减后字符: %c\n", *ptr);  // 输出 l

    return 0;
}

递减结构体指针

#include <stdio.h>

struct Point {
    int x;
    int y;
};

int main() {
    struct Point points[] = {{1, 2}, {3, 4}, {5, 6}};
    struct Point *ptr = &points[2];  // 指针指向结构体数组的最后一个元素

    printf("初始点: (%d, %d)\n", ptr->x, ptr->y);  // 输出 (5, 6)

    ptr--;  // 递减指针,使其指向前一个结构体
    printf("递减后点: (%d, %d)\n", ptr->x, ptr->y);  // 输出 (3, 4)

    ptr--;  // 再次递减指针
    printf("再次递减后点: (%d, %d)\n", ptr->x, ptr->y);  // 输出 (1, 2)

    return 0;
}

指针的比较

  • 相等比较 (==!=): 用于判断两个指针是否指向相同的内存位置。
  • 大小比较 (<, >, <=, >=): 通常用于指针遍历数组或内存块时,判断一个指针是否在另一个指针之前或之后。

例子 1

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr1 = &arr[1];  // 指向 arr[1],值为 20
    int *ptr2 = &arr[3];  // 指向 arr[3],值为 40

    if (ptr1 < ptr2) {
        printf("ptr1 在 ptr2 之前\n");  // 这行会被输出
    } else {
        printf("ptr1 在 ptr2 之后或相同位置\n");
    }

    if (ptr1 > ptr2) {
        printf("ptr1 在 ptr2 之后\n");
    } else {
        printf("ptr1 在 ptr2 之前或相同位置\n");  // 这行会被输出
    }

    return 0;
}

例子 2

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *start = arr;           // 指向数组的第一个元素
    int *end = &arr[4];         // 指向数组的最后一个元素
    int *ptr;

    for (ptr = start; ptr <= end; ptr++) {
        printf("当前指针指向的值: %d\n", *ptr);
    }

    return 0;
}

指针数组

  • 指针数组是一个数组,其中的每个元素都是指向某种数据类型的指针。
  • 指针数组存储了一组指针,每个指针可以指向不同的数据对象。
  • 指针数组通常用于处理多个数据对象,例如字符串数组或其他复杂数据结构的数组。
  • 指针数组的声明:type *ptr[MAX];
    • 在这里,把 ptr 声明为一个数组,由 MAX 个整数指针组成。因此,ptr 中的每个元素,都是一个指向 int 值的指针。

例子 1

#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};
   int i, *ptr[MAX];
 
   for ( i = 0; i < MAX; i++)
   {
      ptr[i] = &var[i]; /* 赋值为整数的地址 */
   }
   for ( i = 0; i < MAX; i++)
   {
      printf("Value of var[%d] = %d\n", i, *ptr[i] );
   }
   return 0;
}

例子 2

#include <stdio.h>
 
const int MAX = 4;
 
int main ()
{
   const char *names[] = {
                   "Zara Ali",
                   "Hina Ali",
                   "Nuha Ali",
                   "Sara Ali",
   };
   int i = 0;
 
   for ( i = 0; i < MAX; i++)
   {
      printf("Value of names[%d] = %s\n", i, names[i] );
   }
   return 0;
}

例子 3

#include <stdio.h>
 
int main() {
    int num1 = 10, num2 = 20, num3 = 30;
    
    // 声明一个整数指针数组,包含三个指针
    int *ptrArray[3];
    
    // 将指针指向不同的整数变量
    ptrArray[0] = &num1;
    ptrArray[1] = &num2;
    ptrArray[2] = &num3;
    
    // 使用指针数组访问这些整数变量的值
    printf("Value at index 0: %d\n", *ptrArray[0]);
    printf("Value at index 1: %d\n", *ptrArray[1]);
    printf("Value at index 2: %d\n", *ptrArray[2]);
    
    return 0;
}
posted @ 2025-04-09 21:55  LittleMoMol  阅读(38)  评论(1)    收藏  举报
*/