指针(20180303)
指针:可用来引用数组,对象或任何变量的地址。为的是在运行时动态分配和释放内存,这可通过指针实现。
指针用来保存内存地址,即指针变量的值是内存地址。
通常一个变量包含一个数据值,(整数,浮点数,字符串),而指针包含的是另一个变量的内存地址。
*作用
1)乘法运算符
2)用于声明指针变量,如
int *pCount = &count
3) 作为解引用运算符
(*pCount)++
解引用一个指针时候,得到了该指针变量存储的地址处的值
#include "stdafx.h" #include <iostream> #include <ctime> #include <string> using namespace std; int main() { int count = 5; int *pCount = &count; cout << "The value of count is " << count << endl; cout << "The address of count is " << &count << endl;//当&放在一个变量之前,为地址运算符,会返回变量的地址 &count是count的地址 cout << "The address of count is " << pCount << endl; //pCount 的数值为变量count的内存地址 cout << "The value of count is " << * pCount << endl; //*pCount 为地址pCount指向的变量 }
用typedef 定义同义类型
typedef existingType newType;
例如:
typedef int integer; //就可以使用integer 来声明int型变量: integer value = 40; typedef int* intPointer; intPointer value2 = 50;
常量指针
#include "stdafx.h" #include <iostream> #include <ctime> #include <string> using namespace std; int main() { double radius = 5; double *const p = &radius; //p是常量指针,p不可变 double length = 5; *p = 6;//OK 指针指向的数据不是常量,是可变的 //p = &length; wrong 因为指针是常量 const double *p1= &radius; //指针不是常量的,但指针指向的数据是常量 //*p1 = 6; wrong p1 = &length; // 指针可变 const double * const p2 = &radius; //指针及其指向的数据是常量 //*p2 = 6; wrong //p2 = length; wrong }
假设list指向数组的起始位置,假定此地址为1000.那么list+1 为 1000+sizeof( int )
在windows系统中,int类型的大小为4.list+1 指向第二个元素;list+2 指向第三个元素;
为什么数组下标从0开始:数组名是一个指针,list+0 指向数组
第一个元素,即为list[0]
#include "stdafx.h" #include <iostream> #include <ctime> #include <string> using namespace std; int main() { int list[6] = { 11,12,13,14,15,16 }; int *p = list; for (int i = 0; i < 6; i++) { cout << "address: " << (list + i) << " value: " << *(list + i) << " " << " value: " << list[i] << " " << //数组访问 " value: " << *(p + i) << " " <<//指针访问 " value: " << p[i] << endl; } }
结果:
address: 00DCFB24 value: 11 value: 11 value: 11 value: 11address: 00DCFB28 value: 12 value: 12 value: 12 value: 12
address: 00DCFB2C value: 13 value: 13 value: 13 value: 13
address: 00DCFB30 value: 14 value: 14 value: 14 value: 14
address: 00DCFB34 value: 15 value: 15 value: 15 value: 15
address: 00DCFB38 value: 16 value: 16 value: 16 value: 16
将数组的地址赋予一个指针不需要使用地址运算符(&)的,因为数组名已经表示数组的起始地址
int *p = list; 等价于 int *p = &list [0];
#include "stdafx.h" #include <iostream> #include <ctime> #include <string> using namespace std; int main() { const char* pCity = "Dallas"; // C/C++ 规定字符串类型为“常量”,所以指针指向的数据必须为常量 cout << pCity << endl; cout << *pCity << endl; cout << *(pCity + 1) << endl; cout << *(pCity + 2) << endl; cout << *(pCity + 3) << endl; const char * cities[] = { "Dallas","Alanta","Houston" }; cout << cities[0] << endl; cout<<cities[0][0]<<endl; }
#include "stdafx.h" #include <iostream> #include <ctime> #include <string> using namespace std; void swap1(int n1, int n2) { int temp = n1; n1 = n2; n2 = temp; } void swap2(int &n1, int &n2) { int temp = n1; n1 = n2; n2 = temp; } //值传递 如若使用指针q1,q2调用函数,则q1,q2通过传值方式传给n1,n2,当*q1改变的时候,*n1也会改变,但q1改变时,n1不改变。 //即两者地址其实是不同的 void swap3(int *p1, int *p2) { int temp = *p1; *p1 = *p2; *p2 = temp; } //引用传递,传入值和p1的地址以及地址指向的数值是等价的 void swap4(int *&p1, int *&p2) { int* temp = p1; p1 = p2; p2 = temp; } int main() { int num1 = 1; int num2 = 2; cout << "Before invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl; swap1(num1, num2); cout << "After invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl; cout << "Before invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl; swap2(num1, num2); cout << "After invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl; cout << "Before invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl; swap3(&num1, &num2);//交换的是指针 cout << "After invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl; int * p1 = &num1; int * p2 = &num2; cout << "Before invoking the swap function,num1 is " << p1 << " and num2 is " << p2 << endl; swap4(p1,p2); cout << "After invoking the swap function,num1 is " << p1 << " and num2 is " << p2 << endl; }
结果
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <string>
using namespace std;
void swap1(int n1, int n2)
{
int temp = n1;
n1 = n2;
n2 = temp;
}
void swap2(int &n1, int &n2)
{
int temp = n1;
n1 = n2;
n2 = temp;
}
//值传递 如若使用指针q1,q2调用函数,则q1,q2通过传值方式传给n1,n2,当*q1改变的时候,*n1也会改变,但q1改变时,n1不改变。
//即两者地址其实是不同的
void swap3(int *p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
//引用传递,传入值和p1的地址以及地址指向的数值是等价的
void swap4(int *&p1, int *&p2)
{
int* temp = p1;
p1 = p2;
p2 = temp;
}
int main()
{
int num1 = 1;
int num2 = 2;
cout << "Before invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl;
swap1(num1, num2);
cout << "After invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl;
cout << "Before invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl;
swap2(num1, num2);
cout << "After invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl;
cout << "Before invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl;
swap3(&num1, &num2);//交换的是指针
cout << "After invoking the swap function,num1 is " << num1 << " and num2 is " << num2 << endl;
int * p1 = &num1;
int * p2 = &num2;
cout << "Before invoking the swap function,num1 is " << p1 << " and num2 is " << p2 << endl;
swap4(p1,p2);
cout << "After invoking the swap function,num1 is " << p1 << " and num2 is " << p2 << endl;
}
分清通过指针传递值 以及 传递地址的区别
void f1(int x, int &y, int*z) //第二个参数表示通过指针传递数值,第三个参数要传入一个地址 { x++; y++; (*z)++; //指针z指向的值加1 } int main() { int i=1, j=1, k = 1; f1(i, j, &k); cout << "i is " << i << endl; cout << "j is " << j << endl; cout << "k is " << k << endl; }
i is 1 j is 2 k is 2
有用的数组函数
调用<algorithm> max_element,min_element,sort,random_shuffle,find 返回的都是指针
#include "stdafx.h" #include <iostream> #include <algorithm> using namespace std; void printArray(const int* list, int size) { for (int i = 0; i < 6; i++) cout << list[i] << " "; cout << endl; } int main() { int list[] = { 4,2,3,6,5,1 }; printArray(list, 6); int *min = min_element(list, list + 6);//返回的是指针,min是指针,*min是数值 int *max = max_element(list, list + 6); cout << "The min value is " << *min << " at index " << (min - list) << endl; cout << "The max value is " << *max << " at index " << (max - list) << endl; //list是第一个元素的索引 random_shuffle(list, list + 6); printArray(list, 6); sort(list, list + 6); printArray(list, 6); int key = 4; int *p = find(list, list + 6, key); if (p != list + 6) { cout << "The value " << *p << " is found at position " << (p - list) << endl; } else { cout << "The value " << *p << "is not found" << endl; } return 0; }
#include "stdafx.h" #include <iostream> #include <algorithm> using namespace std; int main() { int list[] = { 3,4,2,5,6,1 }; cout << *min_element(list, list + 2) << endl;//左闭右开 cout << *max_element(list, list + 2) << endl;//左闭右开 cout << *find(list, list + 6, 2) << endl; cout << find(list, list + 6, 20) << endl; sort(list, list + 6); cout << list[5] << endl; }
结果:
3
4
2
00BFFE18
6
//20180303更新
内存单元的直接访问和间接访问:
直接访问:使用变量名直接访问内存的数据;
间接访问:通过变量的地址也可以间接访问内存中的数据;
int a = 5, *pta = &a;
等价于
int a, *pta;
a = 5;pta = &a;
void swap(int *xp, int *yp)//形参为指针变量 { int t; t = *xp; *xp = *yp; *yp = t; //注意要交换地址 } swap(&x, &y); //实参注意为指针
cout << &a << endl; //a的地址,是指针常量 cout << a << endl; //a的值 cout << &p << endl; //p的地址,指针变量的地址 cout << p << endl; //p的值,a的地址 cout << *p << endl; //p所指变量的值,就是等于a的值 //*p 与*(&a)等价,就是a。 // p是一个指针变量,而&a是一个指针常数。
也可以利用指针参数带回函数的多个值
//利用指针返回多个值 double faver(int s[], int n, int *max, int *min); //桩函数 int main() { int list[5] = { 80,89,67,76,98 }, max, min; double aver; aver= faver(list, 5, &max, &min); cout << "max is " << max << " min is " << min<<endl; cout << "average is " << aver << endl; } double faver(int s[], int n, int *max, int *min) { double aver = s[0]; *max = *min = s[0]; for (int i = 1; i < n; i++) { aver += s[i]; if (s[i] > *max) { *max = s[i]; } if (s[i] < *min) { *min = s[i]; } } return aver/n; }
函数返回指针的时候,指针指向主调函数的变量
const char *noBlank(const char* string) { while (*string == " ") { string++; } return string; } int main() { const char *s1 = " using namespace std;" , *s2; s2 = noBlank(s1); cout << s2 << endl; return 0; }
若在函数中直接定义使用,返回多个值,只传递地址,提高运行效率。
- 上一篇:没有了
- 下一篇:没有了