美文网首页
C语言- 指针用法

C语言- 指针用法

作者: 我阿郑 | 来源:发表于2021-12-11 12:25 被阅读0次

如何表示地址?

地址是整数,是否可以用int?
理论上可以,但是为了强调它是个内存地址,提出一些新的类型:

char* :表示一个char类型变量的地址
short* :表示一个short类型变量的地址
int* :表示一个int类型变量的地址
float* :表示一个float类型变量的地址
double* :表示一个double类型变量的地址
unsigned char* :表示一个unsigned char类型变量的地址
XXX* : 表示XXX类型变量的地址

上面的指针都是基本数据类型的指针
基本类型指针就是指:存放基本数据类型地址的指针

int *p;
int i = 3;
p = &i;

int j;
j = *p;

  • int *p; 中p是变量的名字,p是一个指针变量
  • int * 可以理解为是数据类型;int * 表示变量p存放的是int类型变量的【地址】
  • &i 表示取i的地址,然后赋值给指针变量p,所以变量p保存了i的地址,因此p指向了i,所以通过指针变量p就可以找到i;
  • *p就完全等同于i (或理解为:在所有出现*p的地方都可以替换成i,在所有出现i的地方都可以替换成*p
  • pi是两个不同的变量,并且他们的数据类型也不一样

关于指针

  • 1- 不同类型的指针,不能互相赋值
int a = 10;
int* pa = &a; 
double* pd = pa; // Error ❌ 左侧double* ,右侧int* , 不能互相赋值

char a = 78;
float* p = &a; // Error ❌ 左侧float* ,右侧cahr* , 不能互相赋值
  • 2- 星号*的位置

以下几种方式均可以,没有区别, 看个人习惯

int* p;
int * p;
int *p;

星号操作:按地址访问

有一个指针变量p, 则p用于访问p指向的变量*(p指向的内存)。

int a = 0x123;
int *p = &a; // p指向a所在的内存
*p += 2;

int b = *p;  // 取得p指向内存的值
int c = *p + 2;

指针作为函数的参数

可以把指针作为函数的参数

void test(int *p) {
    // 能把指针干什么呢?
    // 使用星号操作*p,来读写内存
    *p = 10;
}

int main() {
    int a = 0;
    test(&a);
    print("a=%d",a); // 打印10
}

使用指针作为参数,可以实现两种功能:

  • 可以读取上一层函数中变量的值 *p
  • 可以修改上一层函数中变量的值 *p (普通的参数无法实现)
例: 交换两个变量的值
void swap(int* a, int* b)
{
    int t = *a;
    *a = *b;
    *b = t;
}
int main()
{
    int a=10, b=11;
    swap(&a, &b);
    return 0;
}

传递数组作为参数

之前说过数组名,实质就是指针类型,传递数组,就是传递指针

int test(int *p, int length) {
    int sum = 0;
    for(int i=0; i<length; i++) {
        sum += p[i];
    }
    return sum;
}

int main() {
    int arr[] = {1, 2, 3, 4};
    int ret;
    
    ret = test(arr,4); // 从arr[0] 到 arr[3] 结果sum=10
    ret = test(arr,3); // 从arr[0] 到 arr[2] 结果sum=6
    ret = test(arr + 1,3); // 从arr[1] 到 arr[3] 结果sum=9
    
}

❤️ 对于test函数来说,不关心传进来的是不是数组;在它眼里,它只是接收到一个内存地址而已

  • 以下两种方法完全等价
int test(int *p, int length)
和
int test(int p[], int length)
  • 传递数组时,总是要传递长度信息,不能只把手地址传递给函数,这样是不够的

传指针有什么作用?

把一个指针传给函数,有什么作用?

  • 返回多个参数: return只能返回一个值,如果一个函数要返回多个值,必须使用指针参数(输出参数)
  • 效率问题: 传值和传地址,后者一般效率更高

如何安全的使用指针 ?

指针不可乱用,安全的使用指针,需要对指针有足够清晰的认识。
在使用指针之前,一定要弄清楚两个问题:

  • 这个指针指向了哪儿?
  • 这个指针指向的那个地方是否有效?(即:是否能够访问)

指针指向了哪儿?

  • 指向了变量、数组、结构体
  • 指向0

指向0的情况:(空指针

int* p = 0; // 空指针

空指针

值为0的指针,称为空指针

int* p = 0;

当指针为空时,不能使用星号操作。
int* p = 0;
printf(“%d \n”, *p); // 不能这么干❌

但空指针是程序员可以接受的一种情况,只需加一个if判断就能解决!
if(p) {
    printf(“%d \n”, *p);
} 

空指针:应用

某些参数可以省,当不想传入时就传一个空指针

void max_min(const int* arr, int len,
                int* pmax, int* pmin)
{
    ...
    if(pmax) *pmax = _max;
    if(pmin) *pin = _min;
}
// 调用时
int _max;
// 表示只需要得到最大值
max_min(arr,4, &_max, 0); 

危险的情况

int* p;
printf("%d", *p); // 立即crash

这个指针指向哪了? 当一个指针未赋值时,其值为随机值,此时指向了一个随机的内存地址,称为“野指针”

安全使用指针

1-杜绝野指针

一个好习惯:初始化为空指针 : int * p = 0;

考虑:为什么传递一个空指针是允许的?而传一个野指针是不允许的? (空指针也会崩溃)

int *  p = 0;
printf(“ %d  \n”, *p); // 空指针也会崩溃 ❌

传递空指针:函数内部是有办法处理,判断一下就行。
传递野指针:函数内无法判断出来你是个野指针!!

void test(int* p)
{
  // 在使用指针前判断
    if( p != 0)
    {
         printf(“%d \n”, *p);
    }
}

2-严防数组越界

当指针指向数组时,要注意不要越界访问

int arr[4];
int* p = arr;

p += 4;
*p = 12; // 已经越界!但不容易察觉!

3-变量是否已经失效?

如果指向的目标的生命期已经终结(失效),则该指针也失效

int main()
{
    int* p = 0;
    if(1)
    {
        int a = 10; // a生效
        p = &a; // p指向a
    } // a已失效

    *p = 11; // p指向了一个无效的位置⚠️
    return 0;
}

所以,指向全局变量的指针,安全性相对较高。因为它的生命期是永恒的,这一块内存总是有效。

相关文章

  • 02-C语言的指针

    02-C语言的指针 目标 C语言指针释义 指针用法 指针与数组 指针与函数的参数 二级指针 函数指针 指针在C中很...

  • C语言- 指针用法

    如何表示地址? 地址是整数,是否可以用int?理论上可以,但是为了强调它是个内存地址,提出一些新的类型: 上面的指...

  • go语言指针类型的使用

    go语言的指针类型 简单地说go语言的指针类型和C/C++的指针类型用法是一样的,除了出去安全性的考虑,go语言增...

  • 2-Linux C语言指针与内存-学习笔记

    Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标...

  • 《C和指针》——C语言补漏(基本用法篇)

    title: "《C和指针》——C语言补漏(基本用法篇)"date: 2014-05-14 19:06:57cat...

  • C语言05- 指针

    C语言05- 指针 13:指针 指针是C语言中的精华,也是C语言程序的重点和难点。 13.1:指针定义与使用 指针...

  • C语言指针总结大学霸IT达人

    C语言指针总结大学霸IT达人 C语言的指针是C语言区别其它语言的最主要的特定之一。有了指针,C语言就可以抛开所有束...

  • 带小白学C语言指针

    C语言里指针才是C语言的开始和指针;C语言里基本所有东西都是由指针演变而成; 指针是指向地址的变量,类型就是指针...

  • 在Swift中使用C语言的指针

    在Swift中使用C语言的指针 在Swift中使用C语言的指针

  • C语言中指针和结构体和向该文件操作

    学习目的: 在C语言中熟练掌握指针的定义、用法和与数组的区别,以及结构体的定义和使用 相关技术,及其使用 指针:为...

网友评论

      本文标题:C语言- 指针用法

      本文链接:https://www.haomeiwen.com/subject/szxhfrtx.html