1、 指针常量和常量指针的区别
Const *p是常量指针。指针所指向的地址里的内容不能被改变。但指针可以指向别的地址。(我们可以改变它指向的地址,但是不能改变指向的地址的内容)
* Const p是指针常量。可以理解为指针是常量。指针只能赋值一次(定义时除外),不能再修改。(我们可以改变它指向的地址的内容,但不能改变它指向的地址)
2、 NULL和0的区别
虽然可以比较NULL和0的大小,而且NULL的大小和0的大小一样,但是NULL和0并不一样。
3、viod 指针
void指针,是没有指定数据类型的指针。void指针可以容纳任何类型的指针,并且可以转换到任何类型。void指针是一种特别的指针
void *vp
说它特别是因为它没有类型,或者说这个类型不能判断出指向对象的长度。
任何指针都可以赋值给viod指针。Viod只获得变量(对象)的地址,而不是大小。
void指针赋值给其他类型的指针时都要进行转换,转换类型也就是获得指向变量/对象大小。
void指针不能复引用,因为void指针只知道,指向变量/对象的起始地址,而不知道指向变量(对象)的大小(占几个字节)所以无法正确引用。
4、数组指针和指针数组
指针数组就是一个数组,不过数组里面的元素都是指针。
数组指针就是指向数组的指针。数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。数组指针存放的是指向的数组的首元素的地址。
5、sizeof和strlen的区别
Sizeof是c语言的一个运算符,求的是所所占空间的大小,比如char为1个字节。
Strlen是一个函数,求的是字符串的长度。
Char c[ ] = “abcd”;
Sizeof(c)得出的是5;strlen(c)得出的是4。因为sizeof会计算字符串后面的\0,而strlen(c)是求字符串的长度,遇到\0结束。但若c[ ]={‘a’, ‘b’, ‘c’, ‘d’}; 则strlen(c)输出不确定的值,因为d后面没有\0,所以继续计算。
6、指针函数和函数指针的区别
指针函数是函数,它的返回值是指针。如int*fun(int a) 这个函数的返回值是类型为int*的指针。也就是说返回的是一个地址
函数指针是指向函数的指针,int (*fun)( a)这个指针定义为一个指向一个返回值为int,有1个类型为char的参数。
7、typedef
可以定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:
typedef char* PCHAR; // 一般用大写
PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针
虽然: char *pa, *pb; 也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。
8、int a[ 3][ 4];
%p, a是打印首行的地址,单位为行,a+1是下一行的地址,即a[1][0]的地址。
%p, &a是打印该数组的地址,单位为数组,&a+1是打印数组最后一个元素的下一个地址。
%p, a[0]是打印首元素的地址,单位为元素,a[0]+1是打印下一元素的地址,即a[0][1]的地址。
%p, *a (与a[0])相同,是打印首元素的地址,单位为元素,*(a+1)是打印下一元素的地址,即a[0][1]的地址。
9、右左法则
int *a[10];
首先我们确定a是一个数组,向右看,看到“*”,证明这个数组里的每一个元素存放的都是地址,即指针数组,那么接下来便要确认地址的类型。再向右看,看到“;”,这时返回,再向左看,看到“int”,证明地址是整型的。即整型指针数组。
int (*a)[10];
首先我们找到变量a,向右看,看到“)”,返回向左看,看到“*”,便确定a是一个指针变量,再向右看,看到“【”,说明指针变量里保存的地址是数组的地址,即数组指针变量,再向右看,看到“int”,说明这个数组指针变量里的每一个元素都是整型的,即整型数组指针变量。
int (*a)(int);
首先我们确定a是一个指针变量,向右看,看到“(”,说明这个指针变量里保存的是函数,即函数指针变量;而这个函数的形参是整型的,返回值也是整型。
如果确定a是一个指针变量,并且向右看看到“(”,即指针变量指向函数,即函数指针变量。
int (*a[10])(int);
首先我们确定a是一个指针数组,而这个指针指向函数,即为函数指针数组,并且函数的形参为整型,返回值也是整型。
10、指针的类型转换
如果有一个指针p,我们需要把它的类型和所指向的类型改为TYEP *TYPE, 那么语法格式是: (TYPE *)p;
这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE *,它指向的类型是TYPE,它指向的地址就是原指针指向的地址。
而原来的指针p 的一切属性都没有被修改。