跳至主要內容

04-地址与指针

黑静美原创...大约 4 分钟编程CcppC井

什么是指针

一个指针是一个变量,它包含了另一变量的地址

C语言中的指针:

pointer_type *identifier

pointer_type: 指针将指向数据类型。实际的指针的数据类型是一个16进制的数字,必须指出它将指出什么类型的数据。 星号*声明为一个指针,应该出现在用于指针变量的标识符旁边。

identifier: 指针名称

如:指向整型的指针p

int *p = NULL; //初始化声明为NULL
  • 指针应该初始化为NULL,直到它被分配到一个有效位置。
垃圾值

:::dangerC 语言中 int *n(未指定初始值),其值是不确定的,通常被称为“垃圾值”。这意味着指针有可能指向内存任何地址。 试图在初始化前使用这样的指针(例如解引用)是危险的,并且可能导致未定义行为。 :::

引用与解引用

举例

#include <stdio.h>

int main() {
    int j = 63;
    int *p = NULL; 
    p = &j;  //指针引用地址
    printf("The address of j is %x\n", &j);
    printf("p contains address %x\n", p);
    printf("The value of j is %d\n", j);
    printf("p is pointing to the value %d\n", *p);//todo 取消p
    return 0;
}

输出:

相关信息

要看一个指针指向什么,再使用*,如给p赋值,再打印*p。这种情况下,*被称为间接或取消引用运算符。该过程称为解引用

**P

⚠️注意 一些算法使用指向指针的指针。这种类型的变量声明使用 **,并且可以分配另一个指针的地址,如下所示:

int x = 12;
int *p = NULL;
int **ptr = NULL;
p = &x;
ptr = &p;
垃圾值

警告

C 语言中 int *n; 这样声明的指针 n 默认是什么? 在C语言中,当你声明一个指针变量如 int *n;它并没有被自动初始化为特定的某个值。其值是不确定的,通常被称为“垃圾值”。这意味着指针有可能指向内存任何地址。 试图在初始化前使用这样的指针(例如解引用)是危险的,并且可能导致未定义行为。

如果你试图让指针有一个初始值,你可以初始化它为NULL,这是一个特定值,表示指针不指向任何有效地址:

int *n = null;

使用 NULL 初始化指针是一个好习惯,因为你可以容易地检查一个指针是否已被赋值:

if (n == NULL) {
    // 指针还没有被赋值
}

总之,未初始化的指针在 C 中是危险的,并且在使用它们之前,你应始终确保它们被赋予一个合适的值。

表达式中的指针

指针可以在表达式中使用,就像任何变量一样,算术运算符可用于指针所指向的任何对象 例如:

#include <stdio.h>

int main() {
    int x = 5;
    int y;
    int *p = NULL;
    p = &x;

    y = *p + 2; //y被赋予7
    y += *p; //y被赋予12
    *p = y; // todo x 被赋予12
    (*p)++; // x增加到13
    ++(*p); // x增加到14

    printf("p的指向值 %d\n", *p);
    printf("x的值 %d\n", x);

    return 0;
}

⚠️注意 ++运算符需要()括号才能增加所指向的值。使用--运算符时也是如此。

指针和数组

指针在数组中特别有用。

声明一个数组后就为其元素保留了一个连续的内存地址块。通过指针,可以指向数组第一个元素,然后使用地址运算来遍历数组。

  • +向前移动到一个内存位置
  • -向后移动到一个内存位置

请看下面的程序:

#include <stdio.h>

int main() {
    int a[] = {22, 33, 44, 55, 66};
    int *ptr = NULL;

    ptr = a;
    for (int i = 0; i < 5; i++) {
        printf("%d ", *(ptr + i));
    }
    printf("\n");
    return 0;
}

:::tips 程序输出值为: 22 33 44 55 66 :::

数组的一个重要概念是:数组的一个重要的概念是:数组名作为一个指针已经指向了数组的第一个元素。 因此,

语句int *ptr = a等价于int *ptr = &a[0]
语句printf("&d", *a)将打印数组的第一个元素

下面代码运行输出是?

int a[5] = {22, 33, 44, 55, 66};
int *ptr = a;
int res = *(ptr + 2);
printf("%d", res);
上次编辑于:
贡献者: Heijingmei
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3