C语言指针 初探(上)

本文详细介绍了C语言中指针的定义、使用、运算、与数组的关系,以及注意事项,包括野指针、空指针、内存泄漏和指针类型的影响。指针是C语言的核心概念,但正确使用至关重要。
摘要由CSDN通过智能技术生成

目录

一.什么是指针

二.指针的定义和使用

三.指针的运算

四.指针与数组

五.注意事项

六.指针变量的大小

七.总结


指针是C语言中的重要的概念,它允许我们我们直接访问和操作内存地址。掌握指针对于深入理解C语言的底层机制以及编写的高效性。

一.什么是指针

指针是一个变量,它存储着另一个变量的地址,而不是值,我们可以间接地访问和操作它所指向的地址。

二.指针的定义和使用

在C语言中,我们可以通过定义一个指针变量

int x=10;
int *p=&x;

在这里,*p表示p是一个指针,int*表示p指向的一个整型变量。*p存储的是x的地址。

6b0423bc04224f02b26b15dcf666484c.png

可以看到输出的结果为x的值。

三.指针的运算

指针可以进行一些基本的运算,如加法,减法等。这些运算实际上改变指针所指向的地址。

int arr[5]={1,2,3,4,5};
int *ptr=arr;
for(int i=0;i<5;i++)
{
   printf("%d ",*(ptr+i));
}
输出结果为:1 2 3 4 5

四.指针与数组

在C语言中,数组名在被当作指向第一个元素的地址。

int arr[5] = {1, 2, 3, 4, 5};  
int *p = arr; // p现在指向arr的第一个元素  
printf("%d\n", *(p + 2)); // 输出3,因为p+2指向arr的第三个元素

五.注意事项

1.野指针:野指针是一个常见的编程错误,它指的是没有被初始化或者已经被释放的内存地址的指针。尝试对野指针进行赋值或者访问其指向的内存是非常危险的,可能会导致运行时错误,甚至程序崩溃。未初始化或已被释放的指针。避免野指针的方法是总是初始化指针,并在不需要时将其置为NULL。

int *p = NULL; // 初始化指针为NULL  
// ... 其他代码 ...  
free(p); // 释放指针指向的内存  
p = NULL; // 将指针置为NULL,防止成为野指针

2.空指针:在C语言中,可以使用 NULL 或 0 来初始化一个指针,使其成为一个空指针,表示它不指向任何有效的内存地址。

int *p = NULL; // p是一个空指针

3.内存泄漏:当使用 malloc、calloc 或 realloc 等函数动态分配内存后,如果忘记使用 free 函数释放这些内存,就会导致内存泄漏。正确的做法:

int *p = malloc(sizeof(int)); // 动态分配内存  
if (p != NULL) 
{  
    *p = 10; // 使用内存  
    free(p); // 释放内存  
    p = NULL; // 防止野指针  
}

4.指针的解引用:在解引用指针之前,必须确保指针不是空指针,并且指向的内存是有效的。

if (p != NULL) 
{  
    printf("%d\n", *p); // 安全地解引用指针  
}

5.指针的类型:指针的类型决定了它所指向的数据的类型以及指针运算的步长。例如,int* 和 char* 类型的指针在加法运算时,步长是不同的。

#include <stdio.h>  

int main() {
    int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
    char b[10] = { 'A' };
    int* pa = &a;
    char* pb = &b;
    printf("%p\n", a);
    printf("%p\n",pa+1);
    printf("%p\n",b);
    printf("%p\n",pb+1);

    return 0;
}
a1=C1DBDFFA68
pa=C1DBDFFA6C
b= C1DBDFFAA8
pb=C1DBDFFAA9

因此不同类型的指针在进行算术运算(如加法和减法)时,步长是不同的。步长取决于指针所指向的数据类型的大小。例如,char* 类型的指针每次加1时,地址会增加1个字节;而 int* 类型的指针(假设 int 是4字节)每次加1时,地址会增加4个字节。这是因为指针运算实际上是在调整指向的内存地址,调整的量等于它所指向数据类型的大小。


六.指针变量的大小

指针变量的大小与计算机体系结构和操作系统相关。在大多数现代计算机体系结构中,指针变量的大小通常为4字节或8字节,具体取决于操作系统的位数。

在32位操作系统上,由于地址总线宽度为32位,因此一个指针变量需要4字节来存储地址。这是因为32位系统最多可以寻址2^32个内存单元,每个内存单元的地址可以由一个32位的数来表示,即4个字节。无论指针变量指向的是何种数据类型,其大小均为4字节。

然而,在64位操作系统上,地址总线宽度为64位,因此一个指针变量需要8字节来存储地址。64位系统可以寻址的内存空间更大,为2^64个内存单元,每个内存单元的地址需要一个64位的数来表示,即8个字节。

#include <stdio.h>  

int main()
{
    // 定义不同类型的指针变量  
    int* int_ptr;
    char* char_ptr;
    float* float_ptr;
    double* double_ptr;
    void* void_ptr;
    // 使用sizeof运算符获取指针变量的大小,并打印结果  
    printf("%zu \n", sizeof(int_ptr));
    printf("%zu \n", sizeof(char_ptr));
    printf("%zu \n", sizeof(float_ptr));
    printf("%zu\n", sizeof(double_ptr));
    printf("%zu\n", sizeof(void_ptr));
    return 0;
}

32位机器输出:4 4 4 4 4 

64位机器输出:8 8 8 8 8


七.总结

指针是C语言中至关重要的概念,它作为存储内存地址的变量,能够实现对内存数据的间接访问和操作,从而赋予程序员强大的内存管理能力。指针的灵活性和高效性使其成为编写高效、紧凑代码的关键工具。然而,指针的使用也伴随着潜在的风险,如野指针、内存泄漏等问题,要求程序员在使用时务必谨慎,确保指针的初始化和释放,避免引发程序错误和安全隐患。因此,深入理解和掌握指针的概念和用法,对于提升C语言编程能力和写出高质量代码具有重要意义。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值