指针
1.指针简介
地址运算符 & ,后面跟一个变量名时,& 给出该变量的地址
间接运算符 *,后面跟一个 指针名或者 一个 地址 的时候, * 给出储存在被指向地址中的数值
注:在指针声明时的 * 和间接运算符 * 含义不同,声明的时只是表达定义的是一个指针
int bah=5;
int *ptr;
ptr = &bah ;
val = *ptr ;
ptr 指向 bah 的地址;
val 获取地址中的数值
指针声明表示如下:
int * pi;
char * pc;
float * pf , * pg ;
- 指针的数值就是它所指对象的地址
- 在指针前运用运算符 * 就能得到指针所指对象的值
- 对指针加 1 就是对指针的值 加上它 所指对象的字节大小(例如;short 两个字节,double 八个字节);就是地址加上对应对象类型所占的字节空间
2.数组和指针
*(ar+n);
*ar+n;
下面写一个计算数组所有元素的例子:
int sum(int *ar,int n)
{
int i;
int total=0;
for(i=0;i<n;i++)
total += ar[i];
return 0;
}
- **int sum(int *ar , int n) **第一个参数将数组的地址和数组类型传给函数,第二个参数将数组中的元素个数传给函数
- 可以用 int *ar 代替 int ar[ ] ;
下面 4 种声明是等价的:
int sum(int *ar,int n);
int sum(int * ,int );
int sum(int ar[],int n);
int sum(int [],int n);
但是定义函数名称是不能省略的,只能是以下两种等价情况
int sum(int *ar,int n)
{
}
int sum(int ar[],int n)
{
}
求数组所有元素之和的另一种方法,即输入的参数第一个指向 开始元素的首地址,第二个指向最后一个元素的地址
int sump(int *start , int *end)
{
int total = 0;
while(start<end)
{
total += *start;
start++;
}
return total;
}
主函数调用方法如下:
int main(void)
{
int eg[5]={1,2,3,4,5};
answer = sump(eg,eg+5);
return 0;
}
- ***start++**运算符 * 和 ++ 的优先级相同,但是计算的时候是从右向左计算,等价于 *(start+1),地址加 1 然后找出其加 1 后地址对应的数值
3.指针操作
1.赋值;可以将一个地址赋给指针
int main(void)
{
int urn[5]={100,200,300,400,500};
int *part1 ,*part2 ;
part1 = urn;
part2 = &urn[2];
}
? 2.求值: 运算符可以取出指针指向地址中储存的地址*
? 3.取指针变量的地址,通过运算符 & 取得
int main(void)
{
int urn[5]={100,200,300,400,500};
int *part1 ,*part2 ;
part1 = urn;
part2 = &urn[2];
printf("part1=%p,*part1=%d,&part=%p",part1,*part1,&part1)
}
输出为 地址 地址中的数 指针变量的地址
? 4.将一个整数加给指针,即地址加上一个指针对象类型的字符空间
part1+4
? 5.增加指针的值
part1++
? 6.给一个指针加上一个整数,同 4 .
? 7.减少指针的值,同 5.
? 8.求差值
注意:不能对未初始化的指针取值!
当创建一个指针的时候,系统只分配了储存指针本身的内存空间,并不分配储存数据的内存空间
int *pt;
*pt=5;
int urn=[3];
int *part ;
part = urn;
4.保护数组内容
当编写诸如 int 这样的基本类型的函数时,可以向函数传递 int 数值 , 也可以传递 int 数值对应的指针。
当传递 int 数值,相当于复制了一份人数据,这样处理程序效率低,所以当需要修改数值的时候我们一般是传递指针;
但是传入指针容易将原始数据更改,要想不更改原始的数据,只需要在函数定义和声明的时候加上关键字 const
void function(const int ar[],int n)
{
continue ;
}
5.指针和多维数组
假设如下声明:
int pp[4][2];
- pp[0]是指一个 int 大小的地址;pp 是指两个 int 大小的地址;
- pp[0]是首元素pp[ 0 ] [0 ]的地址
- pp是pp[0]的地址
- 他们都开始与同一个整数,所以pp和pp[0]具有相同的地址
- pp+1 和 pp[0]+1 不同
- *pp=pp[0] =&pp[0] [0] , **pp= *pp=pp[0] [0]
指向多维数组指针的声明
int (*pz)[2];
int *pz[2];
处理二维数组的函数时,数组的行可以在调用函数时传递,但是数组的列只能被内置在函数内部,具体见一下例子:
int sum2d(int ar[][COLS],int row)
{
int r,c;
int total = 0;
for(r=0;r<rows;r++)
for(c=0;c<4;c++)
total += ar[r][c];
return total;
}
|