1.
int *p = NULL;
这句代码的意思是,定义一个指向int型的指针变量p,并将p的值(地址)初始化为0x00000000,而不是把*p的值(地址指向的值)置为0x00000000。等价于:
int *p;
p = NULL;
2.
int *p;
*p = NULL;
与1对比,这句代码的意思是,把*p的值(地址指向的值)置为0x00000000,即p指向0x00000000。这种写法p本身的值不知道,也就是p本身保存的可能是非法地址,用以下方法来改写:
int i = 10;
int *p = &i;
*p = NULL;
这是将i的地址赋给指针变量p,并让p指向0x00000000。
3.
int *p = (int *)0x12ff7c;
*p = 0x100;
电脑中有的内存是没有权限访问的,得到一个可以访问的地址的方法是“int i = 0;”,然后查看i的地址,肯定是可以访问的。
这句代码的意思是,将地址0x12ff7c赋给指针变量p(必须进行强制类型转换),p指向0xff00。
这句代码还可以写成:
*(int *)0x12ff7c = 0x100;
4.
char *p = "abcdef";
char a[] = "123456";
char m, n;
m = *(p + 4);
n = a[4];
这段代码,第一行表示定义一个指向一块内存的指针变量p,这块内存存储的是7个字符;第二行表示定义一个字符串;第四、五行分别表示指针形式、下标式访问指针或数组。
5.
int a[5];
int *p, *q, *r;
int m, n, l, k;
p = a + 1;
q = &a[0] + 1;
r = &a + 1;
m = sizeof(a);
n = sizeof(a[5]);
l = sizeof(&a);
k = sizeof(&a[0]);
①
a不能做左值,作为右值时表示数组首元素的首地址,而不是数组首地址;
&a[0]表示数组首元素的首地址;
&a表示数组首地址。
因此a和&a[0]表示的含义相同,都是数组首元素的首地址。
②
m = sizeof(a)的值为sizeof(int)*5,32位系统下为20;
n = sizeof(a[5])的值为sizeof(int),32位系统下为4,这里代表数组中单个元素的大小,是因为sizeof为关键字,不是函数,在编译过程中并没有真正去访问a[5],因此虽然a[5]不存在,但也没有报错;
l = sizeof(&a)的值为一个指针变量的大小,32位系统下为4;
k = sizeof(&a[0])的值为一个指针变量的大小,32位系统下为4。
③
p = a + 1表示a向右偏移1个sizeof(a[0]),这里移动的是1个sizeof(a[0])而不是1个sizeof(a),是因为a作为右值时表示的是数组首元素的首地址;
q = &a[0] + 1表示a向右偏移1个sizeof(a[0]);
r = &a + 1表示a向右偏移1个sizeof[a]。
6.函数指针
int Func(int x);
int (*p)(int x);
p = &Func;
①第一句代码,声明了一个函数。
②第二句代码,定义了一个指向函数的指针变量p(函数指针),首先它是一个指针变量,所以要有一个“*”,即(*p);其次前面的 int 表示这个指针变量可以指向返回值类型为 int 型的函数;后面括号中的 int 表示这个指针变量可以指向一个参数为int型的函数。
③第三句代码,将Func的首地址赋给指针变量p,其中函数名与数组名类似,表示函数的首地址。
函数指针的定义方式:
函数返回值类型 (* 指针变量名) (函数参数列表);
函数指针的定义就是将“函数声明”中的“函数名”改成“(*指针变量名)”;但是这里需要注意的是:“(*指针变量名)
”两端的括号不能省略,括号改变了运算符的优先级。如果省略了括号,就不是定义函数指针而是一个函数声明了,即声明了一个返回值类型为指针型的函数。
举个例子:
#include <stdio.h>
int Max(int, int); //函数声明
int main(void)
{
int (*p)(int, int); //定义一个函数指针
int a, b, c;
p = Max; //把函数Max赋给指针变量p, 使p指向Max函数
printf("please enter a and b:");
scanf("%d%d", &a, &b);
c = (*p)(a, b); //通过函数指针调用Max函数
printf("a = %d\nb = %d\nmax = %d\n", a, b, c);
return 0;
}
int Max(int x, int y) //定义Max函数
{
int z;
if (x > y)
{
z = x;
}
else
{
z = y;
}
return z;
}
7.指针函数
int *F(int a);
int *F(int a)
{
int b[2];
b[0] = a;
b[1] = a;
return b;
}
指针函数,指的是返回值为指针的函数,可以用指针函数来返回一个数组地址。
应与函数指针做区别
8.字符串赋值
char a[10] = "OK!";
char b[10];
char *c;
b[10] = a[10];
*b = a;
*b = *a;
c = a;
a、b为字符串,c为指向char型的指针,在调试过程中可以发现
①b[10] = a[10]企图实现将字符串a赋值给b,但失败了;
②*b = a
也企图实现将字符串a赋值给b,也失败了,这条语句的含义让指针变量b指向的地址a,a作为右值时表示数组的首元素的首地址;
③*b = *a
是让指针变量b指向a地址上的元素,即b指向a[10]的首元素“O”;
④c = a成功的将字符串a赋值给了c指向char型内存。