声明一个指针并为他分配一些空间,但却不行,下面的代码有什么问题呢?
char *p;
*p=malloc(10);
你声明的指针是p,而不是*p,当操作指针本身时(例如当你对其赋值时,使之指向别处时),只需要使用指针的名字即可;
p=malloc(10);
当操作指针所指向的内存时,才需要使用*作为间接操作符:
*p=‘H’;
然而,如果像下边这样子局部变量的声明中使用malloc调用作为初始式:
char *p=malloc(10);
则很容易犯下问题中的错误。
在把一个指针声明分成一个声明和一个后续赋值的时候,要记得去掉 *号。
总之,在表达式中,p是指针,*p是他指向的内容。
*p++自增p还是p所指向的变量?
后缀++和--操作符本质上比前缀一元操作符的优先级高,因此*p++和*(p++)等价,它自增p并返回p自增之前所指向的值。要自增p指向的值,则使用(*p)++,如果副作用烦人顺序无关紧要也可以使用++*p。
用指针操作int数组的时候遇到了麻烦。下边的代码有什么问题?
int array[5],i,*ip;
for(i=0;i<5;i++)
array[i]=i;
ip=array;
printf("%d\n",*(ip+3*sizeof(int)));
本以为最后一行会打印3,但是它打印了一堆垃圾信息。
c语言中的指针运算总是自动的采纳它所指向的对象的大小。你所需要的就是:
printf("%d\n",*(ip+3));
这就可以打印出数组的第三个元素。在类似的代码中,你无需考虑按指针指向的元素的大小。如果你那样计算,会不经意的访问并不存在的数组元素。
我有一个char *型指针碰巧指向一些int变量,我想跳过他们,为什么((int *)p)++;这样的代码不行?
在c语言中,类型转换操作符并不意味这“把一些二进制位看做另一种类型,并作相应的处理”。这是一个转换操作符,根据定义它只能生成一个右值。而右值既不能赋值,也不能用++自增。(如果编译器接受这样的表达式,那要么是一个错误,要么是有意做出的非标准扩展。)要达到你的目的可以用:
p=(char*)((int *)p+1);
或者,因为p是char*型,直接用:
p+=sizeof(int);
要想真正明白无误,你得用
int *p=(int *)p;
p=(char *)(ip+1);
但是,可能的话,你还是应该一开始就选择适当的指针类型,而不是一味的试图李代桃僵。
我看到了用指针调用函数的不同语法的形式,到底是怎么回事?
最初,函数指针必须用*操作符(和一堆括号)“转换为”一个“真正的”函数才能调用。
int r,(*fp)(),func();
fp=fun();
r=(*fp)();
最后一行的解释很明确:fp是一个函数指针,因此*fp是个函数。在括号内加上函数参数列表(再在*fp外加上一对括号用于使运算的优先级正确),就完成了一个完整的函数调用。
而函数总是通过指针进行调用的,所有“真正的”函数名在表达式和初始化中,总是隐式的退化为指针。
通用指针类型是什么?当我把函数指针赋向void* 类型的时候编译不通过。
没有什么“通用指针类型”。void*指针只能保存对象(也就是数据)指针。将函数指针转换为void* 指针是不可移植的。(在某些机器上,函数指针可能很大--比任何数据指针都大。)
但是,可以确保的是,所有的函数指针类型都可以互相转换,只要在调用之前转回了正确的类型即可。因此以能容纳对象指针又能容纳函数指针的地方,可移植的解决方案是使用包含void *指针和通用函数指针的联合。
臭名昭著的空指针到底是什么?
语言定义中说明,每一种指针类型都有一个特殊值--“空指针”--他与同类型的其他所有指针值都不相同,它“保证与任何对象或函数的指针值都不相等”。也就是说,空指针不会指向任何地方,他不是任何对象或函数的地址。取地址符&永远不会返回空指针。同样对malloc的成功调用也不会返回空指针。(如果失败,malloc的确返回空指针,这是空指针的典型用法:表示“未分配”或者“尚未指向任何地方”的“特殊”指针值。)
空指针在概念上不同于未初始化的指针。空指针可以确保不指向任何对象获函数,为初始化的指针则可能指向任何地方。
如上文所述,每种指针类型都有一个空指针,而不同类型的空指针的内部表示可能不尽相同。尽管程序员不必知道内部值,但是编译器必须时刻明确哪种空指针,以便在需要的时候加以区分。