C语言中的二级指针(双指针)

 
2011年度CSDN高校俱乐部“优秀主席”火热出炉!      点击了解英特尔云计算      2012年1月当选微软MVP的CSDN会员名单揭晓!

C语言中的二级指针(双指针)

分类: Linux 编程 3530人阅读 评论(35) 收藏 举报

原创作品,转载请标明出处 http://blog.csdn.net/yming0221/article/details/7220688

二级指针又叫双指针。C语言中不存在引用,所以当你试图改变一个指针的值的时候必须使用二级指针。C++中可以使用引用类型来实现。

下面讲解C中的二级指针的使用方法。

例如我们使用指针来交换两个整型变量的值。

错误代码如下:

一级指针

[cpp] view plain copy print ?
  1. #include    
  2.   
  3. void swap(int *a,int *b)  
  4. {  
  5.         int *tmp=NULL;  
  6.         tmp=a;  
  7.         a=b;  
  8.         b=tmp;  
  9. }  
  10.   
  11. int main(int argc,char **argv)  
  12. {  
  13.         int a=2;  
  14.         int b=3;  
  15.         printf("Before swap a=%d  b=%d\n",a,b);  
  16.         swap(&a,&b);  
  17.         printf("After swap a=%d  b=%d\n",a,b);  
  18.         return 0;  
  19. }  
#include void swap(int *a,int *b) { int *tmp=NULL; tmp=a; a=b; b=tmp; } int main(int argc,char **argv) { int a=2; int b=3; printf("Before swap a=%d b=%d\n",a,b); swap(&a,&b); printf("After swap a=%d b=%d\n",a,b); return 0; }
输出的结构如下:


结果分析:不论是数值还是指针,swap函数中的参数传递的是总是值,所以在上述函数中即使a和b的地址已参数传递给swap函数,而在函数内交换的是a和b的值(main函数中a的地址和b的地址),而交换完毕,函数相应的参数从栈中弹出,并不能返回给调用函数,所以该swap函数中的操作是徒劳。

这里完全可以直接交换a和b的值,不过如果a和b不是一个32位的整型变量,而是一个复杂的数据结构,这样做会降低效率。如下;

[cpp] view plain copy print ?
  1. void swap(TYPE *a,TYPE *b)  
  2. {  
  3.         TYPE tmp;  
  4.         tmp=*a;  
  5.         *a=*b;  
  6.         *b=tmp;  
  7. }  
void swap(TYPE *a,TYPE *b) { TYPE tmp; tmp=*a; *a=*b; *b=tmp; }


二级指针

下面是使用二级指针分配内存的例子

[cpp] view plain copy print ?
  1. #include    
  2. #include    
  3. #include    
  4. void memorylocate(char **ptr)  
  5. {  
  6.         *ptr=(char *)malloc(10*sizeof(char));  
  7. }  
  8. int main(int argc,char **argv)  
  9. {  
  10.         char *buffer;  
  11.         memorylocate(&buffer);  
  12.         strcpy(buffer,"12345");  
  13.         printf("buffer %s\n",buffer);  
  14.         return 0;  
  15. }  
#include #include #include void memorylocate(char **ptr) { *ptr=(char *)malloc(10*sizeof(char)); } int main(int argc,char **argv) { char *buffer; memorylocate(&buffer); strcpy(buffer,"12345"); printf("buffer %s\n",buffer); return 0; }

当想改变指针的值的时候不妨考虑使用二维指针。


上一篇: Linux网络编程--struct hostent结构体 下一篇: Gentoo Linux下读写NTFS格式分区(ntfs-3g解决NTFS只读不可写的问题)
查看评论
20楼 lylzerty 3小时前发表 [回复] [引用] [举报]
main函数的参数是 main(int argc,char **argv) ??
19楼 youbuxiaosan 4小时前发表 [回复] [引用] [举报]
#include

void swap(int **a,int **b)
{
int temp = **a;
**a = **b;
**b = temp;
}

int main()
{
int i = 1;
int j = 2;

int *p1 = &i;
int *p2 = &j;

int *a = p1;
int *b = p2;

swap(&a,&b);
printf("a = %d,b = %d\n",*a,*b);
return 0;
}
Re: yming0221 3小时前发表 [回复] [引用] [举报]
回复youbuxiaosan:多取一次地址没有什么价值
18楼 lele1966 6小时前发表 [回复] [引用] [举报]
还就不C了,都看不太懂了!
17楼 ubuntu606 昨天 21:29发表 [回复] [引用] [举报]
这两天刚看完指针,如果要是开辟动态内存的话,不用这么绕吧,另外,主函数中的两个形参没看出来有什么用?解释一下
Re: yming0221 昨天 22:28发表 [回复] [引用] [举报]
回复ubuntu606:当然在这里没用
Re: yming0221 昨天 22:28发表 [回复] [引用] [举报]
回复ubuntu606:int main(int argc,int **argv)函数的两个参数是用来传递命令行参数的,第一个参数是表示参数的个数,第二个表示参数的首地址
16楼 SNOM_Me 昨天 18:37发表 [回复] [引用] [举报]
指针交换的是二个数值 那二级指针就是交换地址了 是这样理解么?
Re: yming0221 昨天 20:29发表 [回复] [引用] [举报]
回复SNOM_Me:二级指针就是指向指针的指针,二级指针取内容就是指向一个具体类型的指针
15楼 awfty 前天 13:57发表 [回复] [引用] [举报]
二维数组不能用二级指针
Re: alex_xhl 前天 15:33发表 [回复] [引用] [举报]
回复awfty:下面的程序算二维数组使用二级指针吗?

#include

void modifyElement(int **p)
{
**p = 1;
}

int main(void)
{
int a[2][3] = {0, 0, 0, 0, 0, 0};
int i = 0;
int j = 0;
int *p = (int *)&a[0][0];

printf("Before modify: \n");
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("a[%d][%d] = %d ", i, j, a [j] );
}
}
printf("\n");

modifyElement((int **)&p);

printf("After modify: \n");
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("a[%d][%d] = %d ", i, j, a[j] );
}
}
printf("\n");

return 0;
}

运行结果:

Before modify:
a[0][0] = 0 a[0][1] = 0 a[0][2] = 0 a[1][0] = 0 a[1][1] = 0 a[1][2] = 0
After modify:
a[0][0] = 1 a[0][1] = 0 a[0][2] = 0 a[1][0] = 0 a[1][1] = 0 a[1][2] = 0
14楼 onelsh 4天前 15:48发表 [回复] [引用] [举报]
现在是更正过了?看不出问题啊?
13楼 Huangpc123 4天前 12:13发表 [回复] [引用] [举报]
int *a写成int* a比较好,这样说明声明的是a的变量的内存,而不是*a的内存,如果直接访问*a,是要出错的
12楼 yeenfei 4天前 09:56发表 [回复] [引用] [举报]
"当操作二维数组时传递参数"

这个可不一定,要看是什么二维法。。。

如 int array[3][3];
对于电脑来讲,数据都是连续的(contiguous)
11楼 guanzhongw 4天前 09:16发表 [回复] [引用] [举报]
void swap( int &a , int &b )
{
int p = 0 ;

p = a ;

a = b ;

printf( "swap a=%d\n", a) ;

b = p ;

printf("swap b=%d\n", b);
}

int _tmain(int argc, _TCHAR* argv[])
{


int a = 2 ;

int b = 3 ;

printf("before swap a=%d,b=%d\n", a,b) ;

swap( a , b ) ;

printf("after swap a=%d,b=%d", a,b) ;

getchar() ;

return 0;
}
Re: yming0221 4天前 11:07发表 [回复] [引用] [举报]
回复guanzhongw:C语言中不存在引用
10楼 faithpl 4天前 08:34发表 [回复] [引用] [举报]
没有关系,交流总可以提高认识.但是尽可能写成交流,免得别人误会.呵呵,2012年快乐!
9楼 Mrs_chengj 4天前 21:57发表 [回复] [引用] [举报]
给来个小项目,给我练练可以吗,不然水平提不高啊。可以的话发到这个邮箱[email protected],谢谢了
Re: yming0221 4天前 11:09发表 [回复] [引用] [举报]
回复Mrs_chengj:给你个看看吧,这是gzshun的CSDN博客备份工具,请勿用于商业用途。
8楼 intel286 4天前 21:26发表 [回复] [引用] [举报]
C语言教材里有
void swap(int *a,int *b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
这个例题
Re: yming0221 4天前 21:38发表 [回复] [引用] [举报]
回复intel286:嗯,不过这样是移动int型变量。如果是较大的数据结构这样效率不高。
7楼 aoyihuashao 5天前 14:29发表 [回复] [引用] [举报]
这专家过计算机2级没? 这东西2级应该考的吧,专家今天才发现啊
6楼 backspace7 5天前 12:33发表 [回复] [引用] [举报]
void swap(int *a,int *b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
Re: yming0221 5天前 16:11发表 [回复] [引用] [举报]
回复backspace7:的确是自己理解不对
5楼 JAVA2010CZP 5天前 12:25发表 [回复] [引用] [举报]
2
Re: yming0221 5天前 16:11发表 [回复] [引用] [举报]
回复JAVA2010CZP:不好意思,理解有误
4楼 zhjting 5天前 12:19发表 [回复] [引用] [举报]
csdn认证专家的水平啊
Re: yming0221 5天前 16:11发表 [回复] [引用] [举报]
回复zhjting:汗。。。。确实水平不咋的
3楼 userlll1986 5天前 12:19发表 [回复] [引用] [举报]
太二了,上首页,让人失望啊!!!!
Re: yming0221 5天前 16:12发表 [回复] [引用] [举报]
回复userlll1986:水平有待提高...........
2楼 sqfasd 5天前 12:02发表 [回复] [引用] [举报]
博主,你确定二级指针是这样用吗,你确定你不是在误导人吗?
swap函数的形参是二级指针,但是你传实参的时候明显是个一级指针啊,这样编译都会有警告(我是mingwin gcc 默认编译)。
正确的应该是这样
#include

void swap(int *a, int *b)
{
int tmp;
printf("swap(): a=%#x, b=%#x\n", a, b);
printf("swap(): &a=%#x, &b=%#x\n", &a, &b);
tmp = *a;
*a = *b;
*b = tmp;
}

int main()
{
int a = 2;
int b = 3;
printf("main(): &a=%#x, &b=%#x\n", &a, &b);
swap(&a, &b);
printf("main(): after swap a=%d,b=%d\n", a, b);
return 0;
}

输出结果:
main(): &a=0x22ff4c, &b=0x22ff48
swap(): a=0x22ff4c, b=0x22ff48
swap(): &a=0x22ff30, &b=0x22ff34
main(): after swap a=3,b=2

看看打印的地址就明白了,指针跟普通变量一样,只不过它的值是另外一个变量的地址,指针本身也会有地址。通过*对指针解引用后就可以得到指针指向的那个变量的值,再做修改就可以了。
Re: yming0221 5天前 16:15发表 [回复] [引用] [举报]
回复sqfasd:在网上看了点资料,被误导了。
有错就及时改正,免得影响其他人。
自己的水平有待提高呀
Re: supsoon 5天前 12:42发表 [回复] [引用] [举报]
引用“sqfasd”的评论:博主,你确定二级指针是这样用吗,你确定你不是在误导人吗?
swap函数的形参是二级指针,但是你传实参...

回复sqfasd:


我也觉得有点奇怪,以前一直都用的,怎么到他这里就用到2级指针..原来是int temp;哎呀呀~~
那个二级指针我不知道怎么用,报错
cannot convert parameter 1 from 'int *__w64 ' to 'int **'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

看不懂..
Re: yming0221 5天前 16:16发表 [回复] [引用] [举报]
回复supsoon:不好意思,参考了网上的资料,有点被误导,及时改正。
1楼 jom_ch 5天前 11:29发表 [回复] [引用] [举报]
这个二级指针让人有点头晕啊!

你可能感兴趣的:(C)