指针迭代和递归

对指针进行加法运算,及p+n,其结果依旧是一个指针,新的指针是在原来的地址值基础上加上n(sizeof(基类型))个字节。

当(*p)++,表达的是首先*p指的是啊a[0]的值然后进行++运算,此时数组变为22345.....当为*p++时先进行++运算表达式没有加但是值加了,再进行指针运算,最后指针会指向a[1]。

返回值为指针的函数也叫指针函数,可以返指针但不能返数组,空的话返回null。

在C++中,迭代器是一种泛化的指针,用于访问容器中的元素。在C语言中,指针可以模拟迭代器的功能,实现数组的遍历和操作。通过begin和end指针可以定义一个范围,遍历该范围内的所有元素。

int *p; p = a;在此代码中,指针变量可以++运算,a不是指针变量不可以++运算。

指针与指针不能求和,但可以做减法运算,最终代表两个地址之间差了几个基类型 ,但必须相互运算的类型一致。

如果数组指针为int型,则指针变量的基类型也为int型, p = &a[0], 把a[0]元素的地址赋给指针变量p,也就是使p指向a数组的第0号元素。(p = &a[0]; p = a;两句等价。)

如果指针变量p指向数组中的一个元素,则p+1指向同一数组下的一个元素,而不是将值简单的加一。

字符串函数的指针实现实现字符串函数(如puts、strlen)时,可以使用字符指针代替数组下标。puts函数通过循环打印字符指针指向的字符,直到遇到'\0'。strlen函数通过指针逐个递增,统计字符个数直到遇到'\0'。字符串常量可以作为函数参数传递,其本质是传递首字符的地址。

指针与数组的sizeof和strlen区别sizeof(s)返回数组s的总字节数,而strlen(s)返回字符串有效字符个数(不包括'\0')。对于字符指针p,sizeof(p)返回指针大小(通常为8字节),而strlen(p)返回字符串有效字符个数。比如char s[100] = "hello"; sizeof(p);  p = s;则sizeof(p) = 8,sizeof(s)= 100;strlen(s) = 5; 如果是strlen(p),传的是&s[0],所以还是5.

指针与数组的遍历

  • 可以通过定义两个指针(如begin和end)来实现数组的遍历。
  • 遍历时使用循环,条件为begin小于等于end,循环体内访问当前元素并移动指针。
  • 这种方式不需要下标变量,仅通过指针操作即可完成数组的遍历。
void printfarray(int *begin, int *end)
{

    //while(begin <= end)
    //{
        //printf("%d\n",*begin);
        //++begin;
    //}
    if(begin > end)
    {
        return ;
    }
    else
    {
        printf("%d\n", *begin);
        printfarray(begin + 1, end);
    }

}

这个函数 qSort 是实现快速排序,快速排序基于递归和指针操作,时间复杂度为O(N log N)。核心思想是选择一个基准数,将数组分为两部分,一部分比基准数小,另一部分比基准数大。通过左右指针从数组两端向中间扫描并交换元素,最终将基准数放到正确位置。递归处理左右两部分,直到整个数组有序。

void swap(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}

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

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

函数 server 实现了一个递归的两端扫描的交换操作,移动 begin 指针向后,end 指针向前,然后重复交换进行逆序操作。注释的是迭代操作,下面的是递归。第三个是常规逆序。

void server(int *begin, int *end)
{
    //while(begin < end)
    //{
        //swap(begin, end);
        //++begin;
        //--end;
    //}
    if(begin >= end)
    {
        return ;
    }

    else
    {
      
        swap(begin,end);
        server(begin + 1, end - 1);
    }
}

第一段代码是一个递归两数大小进行交换的代码,选择排序。在每轮循环找到范围最小的元素放在前面,swap(begin, p)在找到比*begin更小的元素时,交换它们。冒泡将未排序部分中的最大元素移动到末端。

void choicesort(int *begin,int *end)
{
    int *p;
    for(; begin < end; ++begin)
    {
        for(p = begin + 1; p <= end; ++p)
        {
            if(*begin > *p)
            {
                swap(begin,p);
            }
        }
    }
}
void maopasort(int *begin, int *end)
{
    int *p;
    int *q;
    for(p = end; p > begin; --p)
    {
        for(q = begin; q < p; ++q)
        {
            if(*q > *(q + 1))
            {
                swap(q, q + 1);
            }
        }
    }
}

两段实现 二分查找(Binary Search)的代码:binarfind 和 binary。它们的功能都是在有序数组中查找某个元素 n,但实现方式不同:一段是迭代版本,一段是递归版本。

int *binarfind(int *begin, int *end, int n)
{
   
    while(begin <= end)
    {
        int *mid = (end - begin) / 2 + begin;
        if(*mid > n)
        {
            end = mid - 1;
        }
        else if(*mid < n)
        {
            begin = mid + 1;
        }
        else
        {
            return mid;
        }
    }
        return NULL;
}

int *binary(int *begin,int *end,int n)
{
    if(begin > end)
    {
        return NULL;
    }
    int *mid = (end - begin) / 2 + begin;
    if(*mid > n)
    {
        end = mid - 1;
    }
    else if(*mid < n)
    {
        begin = mid + 1;
    }
    else
    {
        return mid;
    }
    binary(begin,end,n);
}

逐个字符地打印传入的字符串s,直到遇到字符串的结束符('\0')。每打印一个字符,就会将指针+1,移动到下一个字符。第二个函数用来计算字符串s的长度,也就是字符串中字符的个数(不包括字符串结束符'\0')。

void Puts(char *s)
{
    while(*s != '\0')
    {
        putchar(*s);
        ++s;
    }
    putchar('\n');
}

int Strlen(char *s)
{

    int counter = 0;
    while(*s)
    {
        ++s;
        ++counter;
    }
    return counter;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值