一、交换两个整数
方法一:通过函数交换两个数
void exchange(int a,int b){
int temp = a;
a = b;
b = temp;
printf("a=%d , b=%d\n",a,b);
printf("a=%p , b=%p\n",&a,&b);
}
int main(void){
int a = 5;
int b = 6;
exchange(a,b);
printf("a=%d , b=%d\n",a,b);
printf("a=%p , b=%p\n",&a,&b);
return 0;
}
运行结果:
函数内的结果:
a=6 , b=5
a=000000000061fdf0 , b=000000000061fdf8
函数外的结果:
a=5 , b=6
a=000000000061fe1c , b=000000000061fe18
这种方法显然是达不到预期结果的,实参的地址与形参地址不同,也就是说实参与形参不是一个变量。函数内仅仅交换了形参,函数运行完空间释放,实参a和b的值还是原来的值。
方法二:通过地址去改变
void exchange_2(int *q,int *p){ //q,p存放着a,b的地址
int temp = *q; //*q,*p就是实参a,b
*q = *p;
*p = temp;
printf("q=%d , p=%d\n",*q,*p);
printf("q=%p , p=%p\n",&q,&p);
}
int main(void){
int a = 5;
int b = 6;
//exchange_1(a,b);
exchange_2(&a,&b); //传入a,b的地址
printf("a=%d , b=%d\n",a,b);
printf("a=%p , b=%p\n",&a,&b);
return 0;
}
运行结果:
函数内:
q=6 , p=5
q=000000000061fdf0 , p=000000000061fdf8
函数外:
a=6 , b=5
a=000000000061fe1c , b=000000000061fe18
传入了a,b的地址,q和p中存放着a,b的地址,*q就是实参a,*p就是实参b,交换*q和*p就等于交换了a和b。换句话说,就是通过地址去找到a和b然后改他们的值。
方法三:别名
void exchange_3(int &n,int &m){ //通过取别名的方式改变数据位置
int temp = n;
n = m;
m = temp;
printf("n=%d , m=%d\n",n,m);
printf("n=%p , m=%p\n",&n,&m);
}
int main(void){
int a = 5;
int b = 6;
//exchange_1(a,b);
//exchange_2(&a,&b);
exchange_3(a,b);
printf("a=%d , b=%d\n",a,b);
printf("a=%p , b=%p\n",&a,&b);
return 0;
}
运行结果:
函数内:
n=6 , m=5
n=000000000061fe1c , m=000000000061fe18
函数外:
a=6 , b=5
a=000000000061fe1c , b=000000000061fe18
这种方式可以看出实参和形参的地址是一致的,别名是个这个变量取得“小名”,“小名”和“大名”都是指向的同一变量。
二、交换数组中的数据
数组元素逆置:
#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;
#define COUNT 8
//逆序函数
void reversed_order(int a[],int n){
//为什么是 n/2 ,其实遍历数组的一半就可以实现整个数组元素逆置
for (int i = 0; i < n/2; i++)
{
int temp = a[n-i-1];
a[n-i-1] = a[i];
a[i] = temp;
}
cout<<"输入数据逆序显示为:";
for (int j = 0; j < n; j++)
{
cout<<a[j]<<" ";
}
}
int main(void){
int arr[COUNT];
//int len = sizeof(arr)/sizeof(arr[0]);
//cout<<"len = "<<len<<endl;
cout<<"请输入一组数:";
//输入数据
for (int i = 0; i < COUNT; i++)
{
cin>>arr[i];
}
cout<<"输入数据初始显示为:";
//遍历数据
for (int j = 0; j < COUNT; j++)
{
cout<<arr[j]<<" ";
}
cout<<endl;
reversed_order(arr,COUNT);
return 0;
}
运行结果:
请输入一组数:1 2 3 4 5 6 7 8
输入数据初始显示为:1 2 3 4 5 6 7 8
输入数据逆序显示为:8 7 6 5 4 3 2 1
在这里交换数组元素还可以使用while循环:
int p = 0;
int q = n - 1 - p;
while (p<q)
{
int temp = a[p];
a[p++] = a[q]; // 相当于a[p] = a[q],p++;
a[q--] = temp; //
}
//可以用上面的代码替换下面的代码效果一样但是循环的次数不一样
//为什么是 n/2 ,其实遍历数组的一半就可以实现整个数组元素逆置
for (int i = 0; i < n/2; i++)
{
int temp = a[n-i-1];
a[n-i-1] = a[i];
a[i] = temp;
}
冒泡排序,实现数组元素由小到大:
#include <iostream>
#define NUMBER 6
using namespace std;
//使用数组函数实现冒泡排序
void dataSorting(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n; j++)
{
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
//使用指针实现数组数据冒泡排序
void pointerSorting(int *p,int n){
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n; j++)
{
if (*(p + i) > *(p + j)) //*p,解引用->就是p指向地址存放的数据
{
int temp = *(p + i);
*(p + i) = *(p + j);
*(p + j) = temp;
}
}
}
}
int main(void)
{
int arr[NUMBER];
int *p;
p = arr; //指针p指向arr[NUMBER]的首地址
cout << "please enter the data:";
for (int i = 0; i < NUMBER; i++)
{
cin >> arr[i];
}
cout << "the first time display:";
for (int j = 0; j < NUMBER; j++)
{
cout << arr[j] << " ";
}
//dataSorting(arr, NUMBER);
pointerSorting(p,NUMBER);
cout << endl;
cout << "the second time display:";
for (int k = 0; k < NUMBER; k++)
{
cout << arr[k] << " ";
}
return 0;
}
运行结果:
please enter the data:3 2 1 7 5 6
the first time display:3 2 1 7 5 6
the second time display:1 2 3 5 6 7
冒泡排序使用指针怎么实现的呢:用指针指向数组的首地址即可。
三、字符串逆转
方法一:使用string.h中的strrev函数
方法二:使用algorithm中的reverse函数
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int main(void){
//方法一
//char arr[] = "hello";
//strrev(arr);
//方法二
string arr = "hello";
reverse(arr.begin(),arr.end());
cout<<arr<<endl;
return 0;
}
方法三:自己写函数
#include <iostream>
using namespace std;
void Reverse(char *s,int n){
for(int i=0,j=n-1;i<j;i++,j--){
char c=s[i];
s[i]=s[j];
s[j]=c;
}
}
int main()
{
char s[]="hello";
Reverse(s,5);
cout<<s<<endl;
return 0;
}
四、带中文的字符串实现逆转
常见到的是ASCII字符串逆序,ASCII编程字符串逆序比较简单,一个字母、数字或者符号只占用一个字节,因此逆序也相对较容易。然而汉字太多一个字节不够编码,因此一个汉字占用两个字节,其采用GBK编码方法。同时GBK为了兼容ASCII编码,规定汉字的每一个字节第八位为1(ASCII编码方式共用了七位)。如果知道了上述这些也就比较容易写出含有中文字符串的逆序。
原文链接:https://blog.csdn.net/huangshanchun/article/details/49928047
#include<iostream>
#include<string.h>
using namespace std;
void dataRev(unsigned char * s){
int len = strlen((char*)s); //用strlen函数获取s的长度-字节数
unsigned char temp[1024]; //定义一个临时的数组用来存储数据
unsigned char * p1 = s; //指针p指向s的首地址
unsigned char * p2 = temp + len; //指针q指向temp数组的第len位
*p2-- = 0; //先将0赋值给p2,然后地址到了p2-1;
while(*p1){
if(*p1 < 0x80){ //ASCII码 汉字大于127
*p2-- = *p1++; //先赋值,再加加减减
}else{
*(p2-1) = *p1++;
*p2 = *p1++;
p2 -= 2;
}
}
for (int i = 0; i < len; i++)
{
s[i] = temp[i];
}
}
int main(void){
unsigned char ch[] = "我是小萌新";
cout<<ch<<endl;
dataRev(ch);
cout<<ch<<endl;
return 0;
}