C语言基础(12)字符指针 万能指针 和动态分配内存

一、字符指针

        字符指针可以定义为

                char *p

并可以指向单个字符或字符串。通过 *p 可以访问指针 p 所指向的字符,而 p = &c 可以让指针 p 指向字符变量 c 的地址。

        指向字符串时,如 char str[] = "Hello, world!"; char *p = str;,指针 p 指向字符串的第一个字符,即存储第一个字符的地址。

        字符指针可以用于遍历和修改字符串,通过指针运算(如 p++p += 7)可以移动指针访问数组中的其他元素。

        在遍历字符串时,通常通过 while (*p != '\0') 进行,直到遇到字符串的终止符 '\0'。修改字符串内容时,可以直接通过指针进行。

        指向常量字符串的指针(如 const char *p = "Hello, world!";不允许通过指针修改字符串内容。

        const修饰普通变量时,表示此变量不可以通过直接访问的形式进行修改,但是可以通过指针间接访问进行修改其内容。

        const修饰指针时,作用的不是指针本身,而是指针指向的数据

二、万能指针

        万能指针是一种特殊类型的指针,可以指向任何数据类型。

万能指针被定义为

                                                        void *

        它可以指向不同类型的数据,例如 `int`、`float` 或 `char` 等。

        万能指针需要通过类型转换才能指向的数据,例如将 `void *ptr` 转换为 `int *` 类型后再进行指针运算。

        在函数中,万能指针常用于处理不同类型的参数,通过额外的类型标志参数区分数据类型。

        使用万能指针时需特别注意以下几点:万能指针不支持指针运算,因为它没有类型信息;类型转换时必须确保转换后的类型与实际数据类型匹配,否则可能导致未定义行为。

        在实际编程中,万能指针可以提高代码的灵活性和通用性,但使用时需要谨慎,确保类型安全

        快速排序:其基本思想是通过一个“分区”过程,将待排序的数组分成两个子数组,其中一个子数组中的所有元素都比另一个子数组中的所有元素小。然后递归地对这两个子数组进行排序,从而达到整个数组有序的效果。

        步骤:

  • 选择基准: 选择数组中的一个元素作为基准。例如,如果选择第一个元素作为基准。

  • 分区过程

    • 使用两个指针,一个从数组的开始位置向右移动(i),另一个从数组的结束位置向左移动(j)。
    • 移动指针找到左边比基准大的元素和右边比基准小的元素,然后交换它们。
    • 当两个指针相遇时,基准元素与当前指针相遇的元素交换,使基准元素处于其最终位置。
  • 递归排序

    • 将分区后的左右两个子数组分别递归地进行快速排序。

示例代码:

void qSort(int *begin, int *end)
{
    if(begin >= end)
    {
        return ;
    }
    int t = *begin;
    int *p = begin,*q = end;
    while(p < q)
    {
        while(p < q && *q >= t)
        {
            --q;
        }
        while(p < q && *p <= t)
        {
            ++p;
        }
        swap(p,q);
    }
    swap(begin,p);
    qSort(begin, p - 1);
    qSort(p + 1,end);
}

三、动态分配内存

        动态内存分配是指在程序运行时根据需要分配和释放内存,提供了更灵活的内存管理方式。

1.malloc函数:从堆区划分出指定大小的连续内存,并返回分配好的堆区空间 的首地址。,分配失败,则返回NULL;

void *malloc(size_t size);

2.calloc函数:分配指定数量的内存块,并将它们初始化为零

void *calloc(size_t num, size_t size);

  3.realloc函数:调整先前分配的内存块的大小,可以扩大或缩小内存块。如果扩大内存块,新分配的内存内容不确定、

void *realloc(void *ptr, size_t size);

4.free函数  :释放先前分配的内存块

void free(void *ptr);

        使用 `malloc` 和 `calloc` 需要检查返回的指针是否为 `NULL` 以确保内存分配成功。

        `malloc` 用于分配指定大小的内存块,例如 `int *arr = (int *)malloc(5 * sizeof(int));`,

         `calloc` 分配的内存初始化为零,例如 `int *arr = (int *)calloc(5, sizeof(int));`。

        `realloc` 用于调整已经分配的内存大小,例如 `arr = (int *)realloc(arr, 10 * sizeof(int));`,

        如果重新分配失败,原内存块仍然需要释放。

        使用完动态分配的内存后,必须使用 `free` 函数释放内存以避免内存泄漏,例如 `free(arr);`。

        动态内存分配的过程中要注意避免内存泄漏、检查空指针、防止使用已释放的指针。

        通过动态分配内存 的方式 存储斐波那契数列的前十项:

#include<stdio.h>
#include <stdlib.h>
int main(void)
{
    int n = 10;
    int  *p = malloc(n * sizeof(int)); //申请内存
    if(p == NULL)
    {
        return -1;
    }
    else
    {
        for(int i = 0 ; i < n ; ++i)
        {
            if( i == 0 || i == 1)
            {
                *(p + i ) = 1;
            }
            else
            {
                *(p + i) = *(p + i - 2) + *(p + i - 1);
            }
        }
    }
    for(int i = 0 ; i < n ; ++i)
    {
        printf("%d ", *( p + i));
    }
    puts("");
    free(p); //释放内存
    p = NULL;//检查指针
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值