int a = 4;
cout << &a << endl;
cout << *(&a) << endl; //& :取址符,可以获取变量的内存地址, * :解引用 ,表示地址里面的值
*(&a) = 5;
cout << a << endl;
名词解释:
指针:一个地址.知道了一个地址就知道了一个方向,相当于一个指向这个方向的指针
指针变量:一个存放地址的变量
指针与一维数组的关系
#include <iostream>
using namespace std;
int main()
{
int a[5] = { 1,2,3,4,5 };
cout << a << " " << &a[0] << endl;//都表示第一个元素的地址
int* p = &a[0];
cout << p << " " << p + 2 << " " << &a[0] << " " << &a[2] << endl;
cout << a << " " << a + 1 << " " << a + 2 << " " << a + 3 << " " << a + 4 << endl;
cout << *a << " " << *(a + 1) << " " << *(a + 2) << " " << *(a + 3) << " " << *(a + 4) << endl;
cout << &a << " " << &a + 1 << endl;
int(*p2)[5] = &a; //p2是数组的指针,指向一个含有5个int型元素的数组的指针
cout << p2 << endl;
return 0;
}
数组名a,表示数组的起始地址,作为指针指向的对象是数组的元素,+1,就向后偏移一个所指向对象的长度
要想搞清楚指针要知道:1.它的值 2.它所指向的对象
练习:颠倒数组存放顺序
题目:利用指针,将数组a中的整数按相反的顺序存放。
样例输入:
1 3 2 4 6 5
5 6 4 2 3 1
q p
样例输出:
5 6 4 2 3 1
#include <iostream>
using namespace std;
void Swap(int *a,int n)
{
for(int *p = a, *q = a + n - 1; p < q; p++, q--)
{
swap(*p, *q);
}
}
int main()
{
int a[6] = { 1,3,2,4,6,5 };
Swap(a, 6);
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
return 0;
}
二维数组与指针的关系
#include <iostream>
using namespace std;
int main()
{
int a[4][5] = { {11,12,13,14,15},
{21,22,23,24,25},
{31,32,33,34,35},
{41,42,43,44,45} };
cout << a << " " << &a[0][0] << " " << a+1 << endl; //行指针
int(*p)[5] = a;
cout << *a << " " << *p <<" "<<*a+1<<" "<<*p+1<< endl;//列指针
cout << **a << " " << **p << " " << *(*a + 1) << " " << *(*p + 1) << endl; //元素值
cout << &(*a) << " " << &(*a)+1 << endl; //列指针变成行指针
return 0;
}
二维数组的数组名是一个地址,是数组的起始地址,最为指针指向该数组的第一行,+1,指向下一行.所以是一个行指针,对它加个*,则指向第一行的第一列,则由行指针变成列指针, +1,则指向第一行的下一列,
列指针前面加&则变成行指针
指针与字符串的关系
1).用英文双引号括起来的任意字符序列
例:”boy”
注意:
字符串常量是存储在数据区里的常量区,所以它的值不能被改变,体现常量特性,本身代表地址,它在常量区中的存储地址,作为指针是一个指向它第一个字符的指针
#include <iostream>
using namespace std;
int main()
{
//char a[]="abcdedf";
//a[0] = 'x';
//cout << a << endl;
//
const char* p = "abcd";
//
*p = 'x';
cout << p << endl;
while(*p)
{
cout << *p << endl;
p++;//p=p+1
}
return 0;
}
练习:利用指针将一个字符串逆序输出
样例输入:
advbf
样例输出:
fbvda
#include <iostream>
using namespace std;
void Reverse(char *str)
{
if (*str == '\0')
return;
Reverse(str + 1);//递归的原理,因为输出的数据从a到k一直堆积没有释放,最后达到条件释放的时候就从k开始释放,导致结果顺序是反过来的
cout << *str;
}
int main()
{
char str[] = "asdfghjk";
Reverse(str);
return 0;
}
指针与函数的关系
指针函数:返回指针的函数
函数指针:指向函数的指针
指向函数起始地址的指针
函数指针定义:
函数返回类型名(指针变量名)(函数形参类型列表);
`int (a)(int,int)<br />**函数指针的使用**<br />指针变量名 = 被指向的函数名;
a = func或
a = &func;<br />函数调用:指针变量名(函数调用时的实际参数);
a (10,20)或
(a) (10,20)`
*例如
#include <iostream>
using namespace std;
void func1()
{
cout << "void func1 called!" << endl;
}
int func2(int a)
{
cout << "int func2(int a) called a=" << a << endl;
return a;
}
int main()
{
//定义一个指针,指向没有返回值,没有参数的函数的指针
void (*p1)();
//指向func1;
//p1 = &func1;
p1 = func1;
//通过指针调用函数
// (*p1)();
// p1();
//定义一个指针p2,指向返回值类型为int,有一个int形参的函数
int (*p2)(int);
//p2指向func2
//p2 = func2;
p2 = &func2;
//通过指针调用函数
// p2(10);
(*p2)(10);
return 0;
}
#include <iostream>
using namespace std;
void func1()
{
cout << "void func1 called!" << endl;
}
void func2()
{
cout << "void func2 called!" << endl;
}
void func3()
{
cout << "void func2 called!" << endl;
}
int main()
{
// int a[3];
// int(*a)[3];
void (*a[3])()={func1,func2,func3};
void(*(*p)[3])() = &a; //p是一个指向含有3个元素,每个元素都是指向一个没有返回值没有形参的函数的数组的指针
(**p)();
(*(*p + 1))();
return 0;
}
练习:破解密码
主任交给小樱一项任务,解密抗战时期被加密过的一些伤员的名单。
经过研究,小英发现了如下加密规律(括号中是一个“原文 -> 密文”的例子)
- 原文中所有的字符都在字母表中被循环左移了三个位置(dec -> abz)
- 逆序存储(abcd -> dcba )
- 大小写反转(abXY -> ABxy)
【输入】
一个加密的字符串。(长度小于50且只包含大小写字母)
【输出】
输出解密后的字符串。
【输入样例】
GSOOWFASOq
【输出样例】
Trvdizrrvj
#include <iostream>
using namespace std;
int main()
{
char s[100]={'\0'};
cin >> s;
for(int i=0;i<strlen(s);i++)
{
if (s[i] + 3 > 'z')
{
s[i] = (s[i] + 3) % 122 + 96 - 32;
}
else if (s[i] + 3 > 'Z' && s[i] < 'a')
s[i] = (s[i] + 3) % 90 + 64 + 32;
else
{
if (s[i] > 'a')
s[i] = s[i] + 3 - 32;
else
s[i] = s[i] + 3 + 32;
}
}
for (int i = strlen(s) - 1; i >= 0; i--)
cout << s[i];
return 0;
}