十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
空指针有以下三种用法:
创新互联长期为上千余家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为常山企业提供专业的网站设计制作、成都做网站,常山网站改版等技术服务。拥有十年丰富建站经验和众多成功案例,为您定制开发。
(1)用空指针终止对递归数据结构的间接引用。
递归是指一个事物由这个事物本身来定义。请看下例:
/*Dumb implementation;should use a loop */
unsigned factorial(unsinged i)
{
if(i=0 || i==1)
{
return 1;
}
else
{
return i * factorial(i-1);
}
}
在上例中,阶乘函数factoriai()调用了它本身,因此,它是递归的。
一个递归数据结构同样由它本身来定义。最简单和最常见的递归数据结构是(单向)链表,链表中的每一个元素都包含一个值和一个指向链表中下一个元素的指针。请看下例:
struct string_list
{
char *str; /* string(inthiscase)*/
struct string_list *next;
};
此外还有双向链表(每个元素还包含一个指向链表中前一个元素的指针)、键树和哈希表等许多整洁的数据结构,一本较好的介绍数据结构的书中都会介绍这些内容。
你可以通过指向链表中第一个元素的指针开始引用一个链表,并通过每一个元素中指向下一个元素的指针不断地引用下一个元素;在链表的最后一个元素中,指向下一个元素的指针被赋值为NULL,当你遇到该空指针时,就可以终止对链表的引用了。请看下例:
while(p!=NULL)
{
/*dO something with p-str*/
p=p-next;
}
请注意,即使p一开始就是一个空指针,上例仍然能正常工作。
(2)用空指针作函数调用失败时的返回值。
许多C库函数的返回值是一个指针,在函数调用成功时,函数返回一个指向某一对象的指针;反之,则返回一个空指针。请看下例:
if(setlocale(cat,loc_p)==NULL)
{
/* setlocale()failed;do something*/
/* ...*/
}
返回值为一指针的函数在调用成功时几乎总是返回一个有效指针(其值不等于零),在调用失败时则总是返回一个空指针(其值等于零);而返回值为一整型值的函数在调用成功时几乎总是返回一个零值,在调用失败时则总是返回一个非零值。请看下例:
if(raise(sig)!=0){
/* raise()failed;do something*/
/* ... */
}
对上述两类函数来说,调用成功或失败时的返回值含义都是不同的。另外一些函数在调用成功时可能会返回一个正值,在调用失败时可能会返回一个零值或负值。因此,当你使用一个函数之前,应该先看一下它的返回值是哪种类型,这样你才能判断函数返回值的含义。
(3)用空指针作警戒值
警戒值是标志事物结尾的一个特定值。例如,main()函数的预定义参数argv是一个指针数组,它的最后一个元素(argv[argc])永远是一个空指针,因此,你可以用下述方法快速地引用argv中的每一个元素:
/*
A simple program that prints all its arguments.
It doesn't use argc ("argument count"); instread.
it takes advantage of the fact that the last
value in argv ("argument vector") is a null pointer.
*/
# include stdio. h
# include assert. h
int
main ( int argc, char * * argv)
{
int i;
printf ("program name = \"%s\"\n", argv[0]);
for (i=l; argv[i] !=NULL; ++i)
printf ("argv[%d] = \"%s\"\n", i, argv[f]);
assert (i = = argc) ; / * see FAQ XI. 5 * /
return 0; / * see FAQ XVI. 4 * /
}
1、空函数:返回值为void类型的函数,可以用return,也可以不用return。 不用return和在函数结束处有个return是等效的。但要注意return后面除了分号以外什么也没有。
2、空值函数:返回值为NULL的函数。 如果是有返回类型的函数, 返回空指针用“return NULL;"。这种函数就空值函数。
语言定义中说明, 每一种指针类型都有一个特殊值—— “空指针” —— 它与同类型的其它所有指针值都不相同, 它“与任何对象或函数的指针值都不相等”;
不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。
指针是个很强大的工具,可是正因为它太强大,所以要操作它不是件易事。操作不当造成的野指针,甚至会引起系统死机等比较严重的后果。
如果程序定义了一个指针,就必须要立即让它指向一个我们设定的空间或者把它设为NULL,如果没有这么做,那么这个指针里的内容是不可预知的,即不知道它指向内存中的哪个空间(即野指针),它有可能指向的是一个空白的内存区域,可能指向的是已经受保护的区域,甚至可能指向系统的关键内存,如果是那样就糟了,也许我们后面不小心对指针进行操作就有可能让系统出现紊乱,死机了
1.
if(y
==
NULL
w
==
NULL
d
==
NULL)这个语法上是对的,但是逻辑上不对,应该任何变量为空指针都不能执行,所以改为if(y
==
NULL
||
w
==
NULL
||
d
==
NULL)
2.
if...else...
的用法问题,else后并不是一定要再加if的。而且if后面一定要有条件。
3.
循环只要是收敛的就可以用,但是要记得初始化
a=a初值;
b=b初值;
epsilon
=较小值;
for(c
=
abs(a-b);
cepsilon
;
c
=
abs(a-b);){
a
=
(a+b)/2;
b
=
sqrt(a*b);
}
4.
要修改y,w,d所指向的值,所以要用指针。否则直接用int
y,w,d的话只能修改函数内部变量,不能带出函数。(形参和实参的概念)
程序修改如下:
int
convertTime(int
days,
int
*y,
int
*w,
int
*d){
if(days
0){
return
1;
}
else
if(y
==
NULL
||
w
==
NULL
||
d
==
NULL){//去掉多余的if,并修改为||
return
1;
}
else{//去掉多余的if
int
a
=
days%365;
*y
=
days
/
365;
//可以直接这么写,由于分子分母都是整数,所以这里的除号是做整除
*w
=
a
/
7;
*d
=
a
%
7;
return
0;
}
}
空指针指的就是NULL
也就是0指针
指针的含义 是一个地址。 而0地址是非法地址。对这个地址进行赋值 或者取值 就会出现空指针错误
在实际编程中,经常把指针初始化为空指针, 在访问的时候进行判断, 如果为空,那么就是还没有正确赋值的, 应该避免访问。