1、如何将数值存储到指定的内存地址上?
int *p = (int *)0x12ff7c;//将地址0x12ff7c强转成int *,赋给指针p
*p = 0x10;//将10存储到地址0x12ff7c上
2、int *p = &p;//将p指向了自身 地址p处 保存 &p。图1
*p =NULL;//对p指向的内存地址空间赋值NULL。图2,赋值完后变成p =NULL,及P指向空
图1
图2
char *p = &p;//假设 &p = 0x12ff7c
*p = NULL;//将p指向的空间内存,赋值空
p = ?
指针占用4字节如下图所示:
由于p是个char指针,*p只能改变1个字节。
所以*p =NULL后。p = 0x12ff00
3、数组名与指针
3.1 数组名作右值时作指针用,指向首元素首地址。
3.2 在以下两种情况下,数组名做数组用
3.2.1 sizeof(数组名):sizeof()求的是变量类型所占的内存长度
int a[5];a的类型为int [5],是一个数组,所以sizeof(a) =5 * sizeof( int )
3.2.2 &a+1,指针加减移动的是元素个数,先弄清指针代表的含义。
int (*p) [5];
int a[5] ;
a是一个列指针,对列指针取&,将变成行指针。即&a的类型 = p。所以&a+1 = p+1;
同理,对行指针取*,行指针将变成列指针,(*P+1) = a + 1; //指向第2元素
4、数组指针与指针数组
int *p[10] -[ ]优先级高于*,所以p先与[ ]结合,组成一数组p[10]。数组的成员类型是int *,即成员都是指针,所以这个表达式是指针数组。
int (*P)[10]-( )优先级高于[ ],所以p先于*结合,表示一个指针。那是什么指针类型?指针指向int [10]是一数组,即表示一指针指向一数组,数组指针。
5、二维数组与二级指针
5.1二维数组,可以理解为一维数组,数组元素又是一个数组。如下:
a[i][j] =*((* (a+i)+j),a为数组首元素首地址,a+i表示移动i个数组元素=a[i],a+i表示行指针,*(a+i)转为列指针,a[i][j]地址为*(a+i)+j(列指针移动j个元素)
5.2 二维数组赋值:
int a[3][2] = { (0,1),(2,3),(4,5) };//1式
int a[3][2] = { {0,1},{2,3},{4,5} };//2式
以上两个数据赋值有什么区别?
1式赋值是逗号表达式,取逗号后的值,所以1式表达结果为a[3][2] = {1,3,5};
2 式赋值用{}表示一个整体,起打包隔离外界作用
5.3 二级指针
获取二级指针流程(如int **p)
1、先得到p的内存地址
2、用取值符*打开这个内存,取出它里面包含的地址值,即*p
3、再次用取值符*,打开*p的内存所包含的值
6、数组和指针作函数参数时
6.1、一维数组作函数参数时,编译器把数组解析成一个指向数组首元素首地址的指针(数组转为指向首元素首地址的指针)
int fun(int p[ ]) = int fun(int *p) // p = &p[ 0]
6.2 不能把指针变量本身传递给一个函数,函数用的只是实参的一个拷贝而已
void GetMemory(char *p,int num)
{
// p = (char *)xxxxx; 指针的类型强制转化,将整型xxxxx强制为char ×指针,malloc返回起始地址
p =(char *)malloc(num*sizeof(char));//p处理的只是形参,实参的拷贝而已
}
int main()
{
char *str =NULL;
GetMemory(str,100);//将指针str传递给函数,但是函数处理的只是实参的拷贝。
strcpy(str,"hello"); //段错误
}
6.3 如果想在调用函数里改变实参的值,只要传入的是实参的地址就可以。通过指针改变其指向的值
void GetMemory(char **p,int num)
{
*p =(char *)malloc(num*sizeof(char));//char **p = & str ->*p = str
}
int main()
{
char *str =NULL;//如果要改变str只要传入&str就OK
GetMemory(&str,100);//
strcpy(str,"hello"); //
}