C3-C语言练习:二级指针理解

代码:此理解基于一级指针的理解之上(了解p、*p、p++,*p++,(*p++)含义

#include <stdio.h>
#include <string.h>
//总结:如果想在函数中改变变量的值,形参必须定义为一级指针
//如果想在函数中改变一级指针的值,形参必须定义为二级指针
void swap(char** a, char** b)
{
    while (*a < *b) {
        **a ^= **b;
        **b ^= **a;
        **a ^= **b;
        (*a)++;
        (*b)--;
    }
}

//相当于当于将数组的首地址传递到函数中了,并不是
//将整个数组的成员传递过来
void change_word_position(char arr[1])
{
    printf("sizeofarr=%zd\n",sizeof(arr)); //结果是8字节
    char* p, * q;
    p = arr;        //指向首地址
    q = arr + strlen(arr) - 1;        //指向末地址

    printf("p = %p,q = %p\n", p, q);
    swap(&p, &q);
    printf("p = %p,q = %p\n", p, q);
}

int main(int argc, const char* argv[])
{
    char arr[100] = { 0 };

    printf("input string > ");
    gets_s(arr);

    change_word_position(arr);

    printf("%s\n", arr);
    return 0;
}

数组首地址作为实参:change_word_position(arr);

长度为1的字符串数组作为形参:void change_word_position(char arr[1]);

打印的是首地址大小,而不是类型char的大小:printf("sizeofarr=%ld\n",sizeof(arr));

本质理解:**a => *p;* a=> p;a=> &p,p=> arr;关于b这个二级指针也是如此去理解;

所以根据a=>&p,声明形参:void swap(char** a, char** b)的实参调用:swap(&p, &q);  不要疑惑char**这部分,因为它是定义类型,不要和**q混淆;

根据*a=>p,while (*a < *b)相当于while (p < q);

根据**a => *p,**a ^= **b;相当于*p^=*q;

**a 表示指针 a 所指向的字符,即 *a 所指向的值或变量;同理,表示指针 b 所指向的字符,即 *b 所指向的值或变量。所以 **a ^= **b 的意思是:让指针 a 所指向的字符与指针 b 所指向的字符进行异或操作,完成字符的交换。具体来说,即将字符 *a 和字符 *b 进行异或操作后的结果赋给 *a,然后再将字符 *a 和字符 *b 再进行异或操作后的结果赋给 *b,这样就完成了两个字符的位置交换。

程序是如何实现字符串倒过来排序的?

可查阅文章讲解为什么三次异或操作可以交换两个数http://t.csdnimg.cn/lHZsZ

while (*a < *b) {

//值交换,地址不变
        **a ^= **b;
        **b ^= **a;
        **a ^= **b;

//更新地址,用于下次循环进行值交换
        (*a)++;
        (*b)--;
    }

字符的异或运算是按照字符的 ASCII 码进行的。在 C 语言中,字符在内存中以 ASCII 码的形式存储。ASCII 码是一种字符编码标准,为每个字符分配一个唯一的整数值。

在进行字符的异或运算时,实际上是对字符的 ASCII 码进行异或运算。异或运算的规则如下:

  • 如果两个对应位置的比特位相同(都是0或都是1),则结果为0;
  • 如果两个对应位置的比特位不同,则结果为1。

          例如,字符 'A' 的 ASCII 码为 65(二进制表示为 01000001),字符 'B' 的 ASCII 码为 66(二进制表示为 01000010)。执行 'A' ^ 'B' 的异或运算,具体过程如下:

  1. 指针 a 和 b 已经储存了字符串的起始和末尾位置。

  2. 在 while 循环中,通过比较 *a 和 *b,即比较 a 和 b 所指向的字符,来确定字符的顺序是否需要交换。

  3. 字符的异或运算是按照字符的 ASCII 码进行的。在 C 语言中,字符在内存中以 ASCII 码的形式存储。ASCII 码是一种字符编码标准,为每个字符分配一个唯一的整数值。

    在进行字符的异或运算时,实际上是对字符的 ASCII 码进行异或运算。异或运算的规则如下:  如果两个对应位置的比特位相同(都是0或都是1),则结果为0;如果两个对应位置的比特位不同,则结果为1。

    01000001  ('A')
XOR 01000010  ('B')
------------
    00000011  ('C')




确保指针不空不野---
      **a ^= **b;
      **b ^= **a;
      **a ^= **b;
------------本质是
**a等于**b的值,**b等于**a的值;
值互换需要这么写, 如果  **a = **b; **b = **a;
无法实现互换;




------------
假设输入字符串ABCDE
结果EDCBA

------------

A    B    C    D    E
a                   b
...............循环逻辑:值交换,但地址不变

E    B    C    D    A
     a         b
...............再次循环


扩展:值互换
    char *temp = *a;
    *a = *b;
    *b = temp;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值