左值和右值的区别:
左值就是在赋值中可以放在赋值操作符两边的值,比如:
int a = 1;
double b = 2.0
a = b;
b = a;
这里a和b都是左值,一切变量都是左值,但const量是例外。
而右值则是只可以放在赋值操作符右边的值,比如:
int a = 0;
char *b = "hello";
3 = a; // ERROR
"howdy" = b // ERROR
这里3和"howdy"都是右值,所以不能放在赋值操作符左边,一切常数、字符和字符串都是右值。
指针变量的声明与初始化
1.指针包含的是包含特定值的变量内存地址,变量名直接引用数值,而指针是在间接引用数值。
2.值为0或null的指针称为空指针。
3.声明方式为:int *Ptr;
4.指针运算符为&:
int y=5; int *yPtr; yPtr=&y;
以上语句表示,将变量y的地址赋值给指针yPtr,或者也可以说让指针yPtr指向变量y
5.运算符的应用:
#include<iostream>
using namespace std;
int main(){
int a;
int *aPtr;
a=7;
aPtr=&a;
cout<<"The address of a is "<<&a<<endl;
cout<<"The value of aPtr is "<<aPtr<<endl;
cout<<endl;
cout<<"The value of a is "<<a<<endl;
cout<<"The value of *aPtr is "<<*aPtr<<endl;
cout<<endl;
cout<<"Showing that * and & are inverses of each other."<<endl;
cout<<"&*aPtr = "<<&*aPtr<<endl;
cout<<"*&aPtr = "<<*&aPtr<<endl;
return 0;
}
6.函数按值传递和按指针传递参数
按数值传递
int cuberByValue(int );
int main(){
int number=5;
cout<<"The original value of number is "<<number<<endl;
number = cuberByValue(number);
cout<<"The new value of number is "<<number<<endl;
return 0;
}
int cuberByValue(int number){
return number*number*number;
}
按引用传递
void cuberByReference(int *);
int main(){
int number=5;
cout<<"The original value of number is "<<number<<endl;
cuberByReference(&number);
cout<<"The new value of number is "<<number<<endl;
return 0;
}
void cuberByReference(int *nPtr){
*nPtr=*nPtr* *nPtr* *nPtr;
}
7.const修饰指针
a.指向非常量数据的非常量指针:权限最大,如int *aPtr;
b.指向常量数据的非常量指针:即你可以改变指针的指向方向,但不能通过指针修改数据。
比如改变指针的指向:
int main(){
const int *aPtr;
int x=4,y=5;
aPtr=&x;
cout<<"指向变量x时指针的值: "<<*aPtr<<endl;
aPtr=&y;
cout<<"指向变量y时指针的值:"<<*aPtr<<endl;
return 0;
}
这样的操作是允许的
但通过指针修改数据:
int main(){
const int *aPtr;
int x=5;
aPtr=&x;
cout<<*aPtr<<endl;
x=6;//允许修改数据
cout<<*aPtr<<endl;
*aPtr=100;//不允许
return 0;
}
c.指向非常量的常量指针:即可以通过指针修改数据,但不能改变指针的指向。
int main(){
int x=5;
int * const aPtr=&x;
cout<<*aPtr<<endl;
*aPtr=6;//允许修改数据
cout<<x<<endl;
int y=7;
aPtr=&y;//不允许修改指向
return 0;
}
d.指向常量数据的常量指针:权限最小,既不允许修改指针方向,也不能通过指针修改数据;
int main(){
int x,y=5;
const int * const aPtr=&x;
cout<<*aPtr<<endl;
*aPtr=6;//不允许修改数据
aPtr=&y;//不允许修改指向
return 0;
}
8.使用按引用传递方式实现选择排序:
void selectionSort(int *const, const int);
void swap(int *const, int *const);
int main(){
const int arraySize=10;
int a[arraySize]={2,6,4,8,10,12,89,68,45,37};
cout<<"Data items in original order
";
for(int i=0;i<arraySize;i++) cout<<setw(4)<<a[i];
selectionSort(a,arraySize);
cout<<"
Data items in ascending order
";
for(int i=0;i<arraySize;i++) cout<<setw(4)<<a[i];
cout<<endl;
return 0;
}
void selectionSort(int *const array,const int size){
int smallest;
for(int i=0;i<size;i++){
smallest=i;
for(int j=i+1;j<size;j++){
if(array[j]<array[smallest]) smallest=j;
}
swap(&array[i],&array[smallest]);
}
}
void swap(int * const element1Ptr,int * const element2Ptr){
int hold=*element1Ptr;
*element1Ptr=*element2Ptr;
*element2Ptr=hold;
}
9.sizeof运算符
size_t getSize(double *);
int main(){
double array[20];
cout<<"The number of bytes in the array is "<<sizeof(array)<<endl;
cout<<"The number of bytes returned by getSize is "<<getSize(array)<<endl;
cout<<"The number of array is "<<sizeof array/sizeof(array[0])<<endl;
return 0;
}
size_t getSize(double *Ptr){
return sizeof(Ptr);
}
size_t是一个类似于unsigned int的无符号整数类型
注意getSize函数返回的是指针字节,是4个字节。
sizeof array/sizeof(array[0])可以计算数组的大小;
10指针算数运算:
int main(){
int v[6]={1,2,3,4,5,6};
int *vPtr1=v;
int *vPtr2=&v[0];
cout<<"数组名字和数组第一个元素的地址是等价的: "<<endl;
cout<<"*vPtr1 = "<<*vPtr1<<endl;//1
cout<<"*vPtr2 = "<<*vPtr2<<endl;//1
vPtr1+=3;
vPtr2++;
cout<<"*vPtr1 = "<<*vPtr1<<endl;//4
cout<<"*vPtr2 = "<<*vPtr2<<endl;//2
vPtr1-=3;
vPtr2--;
cout<<"*vPtr1 = "<<*(vPtr1++)<<endl;//1
cout<<"*vPtr2 = "<<*(++vPtr2)<<endl;//2
return 0;
}