1.野指针(也叫悬摆指针,迷失指针)
野指针是导致BUG的罪魁祸首之一。对指针调用Delete后(释放掉了它指向的内存,野指针还是指向原来的地址),如果没有重新赋值就使用它,将导致难以预料的后果。因为此时操作野指针,它指向的内存地址可能已经分配给其他变量在使用了。
所以指针在Delete之后,如果不再使用,一定要赋值Nullptr。
2.const指针之一:指针本身是常量 or 指向的对象是常量
int iValOne = 111, iValTwo = 222, iValThree = 333;
//示例1.指针指向的内容是常量
const int *pValOne = &iValOne;
//*pValOne = iValTwo; //错误,不能修改指针指向的内容:iValOne值不能被修改
pValOne = &iValTwo; //正确,可以修改指针本身的地址:iValTwo的地址赋值给指针
//示例2.指针本身是常量
int * const pValTwo = &iValTwo;
*pValTwo = iValThree; //正确,可以修改指针指向的内容:iValTwo的值修改为iValThree的值
//pValTwo = &iValThree; //错误,不可以修改指针本身的地址:pValTwo的地址只能是iValTwo的地址
//示例3.指针本身及其所指向的内容都是常量
const int * const pValThree = &iValThree;
//*pValThree = iValOne; //错误,不能修改指针指向的内容:iValThree值不能被修改
//pValThree = &iValOne; //错误,不可以修改指针本身的地址:pValThree的地址只能是iValThree的地址
常量指针,指针常量容易搞混淆,有一个比较好的办法,在星号(*)右边画一条竖线,
const在竖线左边:不能修改内容(内容为常量),如以上代码中示例1
const在竖线右边:不能修改指针本身(指针本身为常量),如以上代码中示例2
const在竖线两边:不能修改指针本身及其指向的内容,如以上代码中示例3
3.指针和数组
3.1指针和一维数组
int a[10];
for (int i = 0; i < 10; i++)
{
a[i] = i;
}
int *p = a;//同:int *p = &a[0];
for (int i = 0; i < 10; i++)
{
cout << *p << endl;
p++;
}
数组地址与指针
int a[10];
for (int i = 0; i < 10; i++)
{
a[i] = i;
}
int *p;
p = &a[0];
cout << *(a + 1) << endl;//输出1
cout << *(p + 2) << endl;//输出2
3.2指针与二维数组
二维数组的内存地址是连续的,可以将二位数组看做一维数组。
int iArrayOfTwoDim[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
//输出二维数组
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 4; j++)
{
cout << setw(5)<< iArrayOfTwoDim[i][j];
<span style="white-space:pre"> </span>//同:<span style="font-family: Arial, Helvetica, sans-serif;">cout << setw(5)<< </span><span style="font-family: Arial, Helvetica, sans-serif;">*(*(iArrayOfTwoDim + i) + j)</span><span style="font-family: Arial, Helvetica, sans-serif;">;</span>
}
cout << endl;
}
//转换为一维数组
int iArrayOneDim[12];
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 4; j++)
{
iArrayOneDim[i * 4 + j] = iArrayOfTwoDim[i][j];
}
}
for (size_t i = 0; i < 12; i++)
{
cout << setw(3) << iArrayOneDim[i] << endl;
}
输出:
1 2 3 4
5 6 7 8
9 10 11 12
1
2
3
4
5
6
7
8
9
10
11
12
请按任意键继续. . .
二维数组通过指针访问地址输出,验证结果:二维数组在内存中是连续的
int iArrayOfTwoDim[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
int *pVal = iArrayOfTwoDim[0];//同:int *pVal = &iArrayOfTwoDim[0][0];
//输出二维数组
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 4; j++)
{
cout << "Value(Address " << pVal << "): " << *pVal++ << endl;
}
cout << endl;
}
输出:
Value(Address 002EFBEC): 1
Value(Address 002EFBF0): 2
Value(Address 002EFBF4): 3
Value(Address 002EFBF8): 4
Value(Address 002EFBFC): 5
Value(Address 002EFC00): 6
Value(Address 002EFC04): 7
Value(Address 002EFC08): 8
Value(Address 002EFC0C): 9
Value(Address 002EFC10): 10
Value(Address 002EFC14): 11
Value(Address 002EFC18): 12
请按任意键继续. . .
4.指针与字符串
//连接两个字符串
char cArrayOne[50], cArrayTwo[50];
cout << sizeof(cArrayOne) << endl;
char *pStr1 = cArrayOne, *pStr2 = cArrayTwo;
cout << sizeof(pStr1) << endl;
cout << "Please input str1:";
gets_s(cArrayOne);
cout << "Please input pStr2:";
gets_s(cArrayTwo);
while (*pStr1 != '\0')
pStr1++;
while (*pStr2 != '\0')
*pStr1++ = *pStr2++;
*pStr1 = '\0';
cout << "str1 + str2:";
pStr1 = cArrayOne;//将pStr1重新指向cArrayOne
puts(pStr1);//同:puts(cArrayOne);
输出:
50
4
Please input str1:I am
Please input pStr2:fond of Cplusplus!
str1 + str2:I am fond of Cplusplus!
请按任意键继续. . .
Char*与Char[]的区别
char*指向常量时,内容不能修改;char[]可以修改;
char *pStr = "I love c++!";
pStr[0] = 'U';//编译时没问题,运行时error
cout << pStr << endl;
用char[]
char cArray[50] = "I love c++!";
char *pStr = cArray;
pStr[0] = 'U';//Ok
cout << pStr << endl;