【C】指针

目录

定义

声明指针

地址运算符和取值运算符

初始化指针

使用指针

指针的算术操作

空指针和野指针

指针与数组

指针运算

指针与整数的加减

指针间的减法

指针比较


在C语言中,指针是一个非常重要的概念,它直接关联到内存管理和数据访问的效率。

定义

指针是内存中一个最小单元的编号,也就是地址,指针=地址

指针变量是一个用来存放内存地址的变量,通常情况下我们说指针都是指指针变量

指针变量是一个变量,其值为另一个变量的地址。换句话说,指针“指向”内存中的某个位置。在C语言中,指针通过星号(*)来声明。

声明指针

声明一个指针变量,你需要指定它将指向的数据类型。以下是声明指针的一些例子:

int *intPtr;    // 声明一个指向整数的指针
char *charPtr;  // 声明一个指向字符的指针
float *floatPtr;// 声明一个指向浮点数的指针

地址运算符和取值运算符

  • 地址运算符(&:用于获取一个变量的地址。

        在scanf函数中,&+变量 就是获取变量所存储的第一位地址,然后读取内容

  • 取值运算符(*:用于获取指针指向地址的值。
int a=7;
int* pi=a;
*pi++;    //*+指针变量可以获取指针变量所对应的变量的值

初始化指针

你可以通过地址运算符来初始化指针,使其指向一个具体的变量。

int var = 5;
int *ptr = &var; // ptr 现在指向 var 的地址

使用指针

指针可以用于访问或修改它所指向的变量的值。

printf("Value of var: %d\n", var);     // 直接访问变量
printf("Value of var via ptr: %d\n", *ptr); // 通过指针访问变量

*ptr = 10; // 通过指针修改 var 的值
printf("New value of var: %d\n", var); // 输出 10

指针的算术操作

指针可以进行一些算术操作,如增加或减少其所存储的地址值。以下是一些指针算术操作:

  • ptr++ 或 ptr += sizeof(type):将指针向前移动到下一个相同类型的数据的地址。
  • ptr-- 或 ptr -= sizeof(type):将指针向后移动到上一个相同类型的数据的地址。

空指针和野指针

  • 空指针:一个没有被初始化的指针,通常用 NULL 来初始化,表示它不指向任何地址。
int* pi=NULL;
  • 野指针:一个没有被正确初始化的指针,可能指向内存中的任意位置,使用野指针可能导致不可预测的行为甚至程序崩溃。

野指针的出现可能有三种情况:

int* p;

第一种情况:没有给定所要储存地址的变量,会随机给p分配一个地址,地址随机对应一个变量,这是定义时出现的一种错误,需要避免,因为不会有报错。

int a[5]={0};
int* p = a;
int i=0;
for(;i<=5;i++){
    *p=i;
    p++;
}

第二种情况:数组中越界,这种情况相比第一种就属于更加高级一点的错误,相对来说更隐蔽一些,需要把握好数组界限这一规则,作为写代码的注意点。

第三种情况:指针对应的变量在内存中释放了,常见于用函数返回地址给指针变量,后面函数内部内存释放(相当于是把这个内存空间的使用权限还给了操作系统,可能这个地方的值并没有发生变化)

int* test(){
    int a=10;
    return &a;
}
int main(){
    int* p = test();//test函数使用之后a就被释放了
    return 0;
}

指针与数组

指针和数组紧密相关。数组名在大多数情况下可以作为指向数组首元素的指针使用。

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // 数组名 arr 可以看作指向首元素的指针

for (int i = 0; i < 5; i++) {
    printf("Value at arr[%d] = %d\n", i, *(ptr + i)); // 通过指针访问数组元素
}

指针运算

  1. 指针与整数的加减:可以将一个整数值加到指针上或从指针中减去一个整数值。这会导致指针移动到它当前指向的类型的前一个或后一个实例的位置。

  2. 指针间的减法:两个指向同一数组内元素的指针可以进行减法运算,结果是两个指针之间的元素数量。

  3. 指针比较:可以比较两个指针的值,通常用于确定一个指针是否在另一个指针之前或之后。

以下是一些具体的指针运算示例:

指针与整数的加减

int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // ptr 指向数组 arr 的第一个元素

ptr = ptr + 2; // ptr 现在指向 arr[2],即 30
printf("%d\n", *ptr); // 输出 30

ptr = ptr - 1; // ptr 现在指向 arr[1],即 20
printf("%d\n", *ptr); // 输出 20

指针间的减法

int *ptr1 = &arr[3];
int *ptr2 = &arr[0];

int diff = ptr1 - ptr2; // diff 现在是 3,因为 ptr1 比 ptr2 靠后 3 个整型元素
printf("Difference: %d\n", diff);

指针比较

if (ptr1 > ptr2) {
    printf("ptr1 is after ptr2 in memory\n");
} else {
    printf("ptr2 is after ptr1 in memory\n");
}

以下是关于指针运算的一些重要规则和注意事项:

  • 同一数组内的指针运算:只有当指针指向同一数组内的元素时,指针运算才是有意义的。

  • 指针类型:指针的类型决定了指针运算时移动的步长。例如,一个指向 int 类型的指针每次增加1,实际上会增加 sizeof(int) 字节。

  • 空指针和未初始化指针:对空指针(NULL)或未初始化的指针进行运算会导致未定义行为。

  • 越界访问:超出数组范围的指针运算可能会导致越界访问,这是危险的,并且可能导致程序崩溃。

  • 指针减法限制:只有当两个指针都指向同一数组内的元素时,指针间的减法才是有意义的。

  • 指针比较限制:只有当两个指针都指向同一数组内的元素时,指针的比较才是有意义的。

指针运算是C语言中一个非常强大但也容易出错的功能,因此在使用时需要格外小心。

指针也是C语言中很重要的概念,需要多去复习巩固

在写代码的时候由于基础不扎实我掉入了一个关于单双引号不同含义的坑里面

这个是我最开始写的代码,用于创建一个自己的字符统计函数(里面涉及到知识点包括字符串变量最后会有一个'\0'的字符表示终结,'\0'会占用内存;字符串传参的话传过去的实际上是第一个字符的地址,所以接受时需要用指针变量来接收),我出现的问题就是单引号实际上是表示引号里面是字符,双引号是字符串,上面的代码运行的时候它一直跟我说指针变量和一个整型不能比较,这样一个小小的问题我也是花了一点时间去检查的,把*str != "\0"中的双引号改成单引号就行了,可见基础十分重要

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值