C语言学习-第八章 善于利用指针①

366 阅读6分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第24天,点击查看活动详情

指针是什么

为了说清楚什么是指针,必须先弄清楚数据在内存中是如何存储的,又是如何读取的。

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。

内存区的每一个字节有一个编号,这就是“地址”

由于通过地址能找到所需的变量单元,地址指向该变量单元。将地址形象化地称为“指针”, 通过它能找到以它为地址的内存单元。

C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是“带类型的地址”。

例如 &a:一般称它为“变量a的地址”,它是“整型变量a的地址”。

直接访问: 直接按变量名进行的访问

间接访问: 如将变量i的地址存放在另一变量中,然后通过该变量来找到变量i的地址,从而访问i变量

i_pointer = &i; // 将i的地址存放到 i_pointer 中
*i_pointer表示i_pointer指向的对象

为了将数值送到变量中,有两种方法:

  • 将数值直接送到变量i所标识的单元中,例如“i=3;”
  • 将数值送到变量i_pointer所指向的单元(即变量i的存储单元),例如:“*i_pointer = 3;” *i_pointer表示i_pointer指向的对象

由于通过地址能找到所需的变量单元,因此说,地址指向该变量单元。将地址形象化地称为“指针”。即通过它能找到以它为地震的内存单元。

如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”。如上面的i_pointer就是一个指针变量。指针变量就是地址变量,用来存放地址,指针变量的值就是地址(即指针)

指针是一个地址,而指针变量是存放地址的变量。

指针变量

使用指针变量的例子

#include <stdio.h>

int main() {
/**
 * 1. 通过指针变量访问整型变量.
 * 先定义2个整型变量,在定义2个指针变量,分别指向这两个整型变量,通过访问指针变量,可以找到它们所指向的变量,从而得到这些变量的值.
 * */
    int a = 100, b = 10; // 定义整型变量a,b,并初始化
    int *pointer_1, *pointer_2; // 定义指向整型数据的指针变量pointer_1,pointer_2
    pointer_1 = &a; // 把变量a的地址赋给指针变量pointer_1
    pointer_2 = &b; // 把变量b的地址赋给指针变量pointer_2
    printf("a=%d, b=%d\n",a,b); // 输出变量a和b的值
    printf("*pointer_1=%d, *pointer_2=%d\n", *pointer_1, *pointer_2); // 输出变量a和b的值


    return 0;
}

image.png

怎样定义指针变量

定义指针变量的一般形式为:类型名 *指针变量名;

// 类型名 *指针变量名;
int *pointer_1, *pointer_2;
// int是定义指针变量时必须指定的“基类型”

int是定义指针变量时必须指定的“基类型”。指针变量的基类型用来指定此指针变量可以指向的变量的类型

注意:

  • 指针变量前面的“*”表示该变量为指针变量
  • 在定义指针变量时必须指定基类型
    • 指向一个整型变量和指向一个实型变量,其物理上的含义是不同的
    • 从另一角度分享,指针变量是用来存放地址的,C的地址信息包括存储单元的位置(内存编号)和类型信息。指针变量的属性应与之匹配。
    int a, *p;
    p = &a;
    
    一个变量的指针的含义包括两个方面,一是以存储单元编号表示的纯地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如 int,char,float等)
    • 如何表示指针类型。指向整型数据的指针表示为“int *”,读作“指向int的指针”或简称“int指针”

怎样引用指针变量

引用指针变量时,可能有3种情况:

  • 给指针变量赋值
int a, *p;
p = &a; // 把a的地址赋给指针变量p

指针变量p的值是变量a的地址,p指向a。

  • 引用指针变量指向的变量
printf("%d", *p); // 以整数形式输出指针变量p所指向的变量的值,即变量a的值
*p = 1; // 相当于a=1. 将1赋给p所指向的变量
  • 引用指针变量的值
int a, *p;
p = &a;
printf("%o", p); // 以八进制数形式输出指针变量p的值,即输出的是a的地址,即&a

&:取地址运算符

*:指针运算符(或称”间接访问“运算符),*p代表指针变量p指向的对象

示例: 输入a和b两个整数,按先大后小的顺序输出a和b

/**
 * 2.输入a和b两个整数,按先大后小的顺序输出a和b
 * 不交换整型变量的值,而是交换两个指针变量的值
 * */
int *p1, *p2, *p, a, b; // p1,p2的类型是int*类型
printf("enter two integer numbers:");
scanf("%d,%d", &a, &b);
p1 = &a;
p2 = &b;
if (a < b) { // 如果a<b, p1与p2互换
    p = p1;
    p1 = p2;
    p2 = p;
}
printf("a = %d, b = %d\n", a, b);
printf("max = %d, min = %d\n", *p1, *p2);

image.png

指针变量作为函数参数

函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中。 示例:同上题。用函数处理,而且用指针类型的数据作函数参数

main函数:

/**
 * 3.输入a和b两个整数,按先大后小的顺序输出a和b. 用函数处理,而且用指针类型的数据作函数参数
 * 定义函数swap,将指向两个整型变量的指针变量所为实参传递给swap函数的形参指针变量,在函数中通过指针实现交换两个变量的值
 * */
    void swap(int *p1, int *p2);
    int *p1, *p2, *p, a, b; // p1,p2的类型是int*类型
    printf("enter two integer numbers:");
    scanf("%d,%d", &a, &b);
    p1 = &a;
    p2 = &b;
    if (a < b) swap(p1, p2);
    printf("a = %d, b = %d\n", a, b);
    printf("max = %d, min = %d\n", *p1, *p2);

定义函数:

// 定位swap函数,实现*p1和*p2互换
void swap(int *p1, int *p2) {
    int temp;
    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}

image.png


  • 指针是什么
  • 指针变量
  • 通过指针引用数组
  • 通过指针引用字符串
  • 指向函数的指针
  • 返回指针值的函数
  • 指针数组和多重指针
  • 动态内存分配与指向它的指针变量
  • 有关指针的小结