代码:此理解基于一级指针的理解之上(了解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'
的异或运算,具体过程如下:
-
指针
a
和b
已经储存了字符串的起始和末尾位置。 -
在
while
循环中,通过比较*a
和*b
,即比较a
和b
所指向的字符,来确定字符的顺序是否需要交换。 -
字符的异或运算是按照字符的 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;