指针

常量指针与指针常量

int n;
const int * pc = &n; 		   // pc定义为常量指针类型,不能通过pc改变指向地址中存的值,但pc指向地址可变
// *pc = 2; 			   	   // Error: n cannot be changed through p without a cast
pc = NULL; 			   		   // OK: pc itself can be changed
 
int * const cp = &n; 		   // cp是一个指针常量类型,指向的地址是定值,不可通过cp改变指向地址,但地址中存的值可变
*cp = 2; 			   		   // OK to change n through cp
// cp = NULL; 			   	   // Error: cp itself cannot be changed
 
int * const * pcp = &cp; 	   // non-const pointer to const pointer to non-const int

指针与数组的关系

数组名就是指向数组中第一个元素的地址,可以把它理解为指针,不过是本身指向地址为常量的指针罢了(指针常量),这点我觉得这个老哥说得特别好
*a就是指向地址中的值,这里有一点要说明一下:
C语言中地址默认是按行增长的,这里就拿数组地址按行增长来说

一维数组

#include<stdio.h>
int main()
{
	int	a[3]={7,8,9};
	
	printf("%d\n",*(a+1));//a的指向由原来的指向7的地址,变为指向8的地址
	return 0;
	
}

二维数组

#include<stdio.h>
int main()
{
 	int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
 
	printf("%d\n",**(a+1));//a的指向由原来的指向1的地址,变为指向4的地址
 	return 0;
 
}

但是除了这片地址之外就满足指针常量的性质,指向其它地址就会报错。因为数组名是指针常量,所以它不能做为被赋值的对象,不可当变量使用

自己对指针的一些理解

指针关键要看两个地址,一个是指针本身的地址还有就是指针中存储的地址,只要围绕这两个的东西来看指针无论是二极指针、结构体指针、数组指针都离不开这两个东西,理清这两个东西也是分析问题的关键

int *p;
int *q;
int a=5int b[3];
p=&a;		//不是地址的借助 &运算符获得地址
p=b;		//是地址的直接赋值
p=q;		//指针之间的赋值结果是把q指向的地址赋值给p,让q和p指向同一个地址

自己平时查看地址的一些错误纠正

#include<stdio.h>
int main()
{
 	int  *p=0;//看看他们的地址分别是什么?
 	int  *q;
	int  c=4;
 	printf("p init adder is:%p\n",&p);//这个打印的才是自己的地址
 	printf("p init value is:%p\n",p);//这个打印的不是p本身的地址,而是p指向的地址,不信我们再做一个给p赋值为NULL的测试,已经证实了
 	
 	printf("q init adder is:%p\n",&q);
 	printf("q init value is:%p\n",q);
 	
 	p=&c;
 	printf("&c adder is:%p\n",&c);
 	printf("c  adder is:%p\n",c);//这里要重新申明一下%p的用法,虽然说是用来打印地址的,但用printf来打印时一定得满足%p对应的是一个地址,而不是一个值,否则打印的是值而不是地址,只不过值前面加了个0x罢了,并不是地址
 	printf("p equaled adder is:%p\n",&p);
 	printf("p equaled value is:%p\n",p);//p和&(*p)打印的是同一个地址
 	printf("*p  adder is:%p\n",&(*p));
	return 0;
}

测试结果:

p init adder is:0x7ffe5e522548
p init value is:(nil)
q init adder is:0x7ffe5e522550
q init value is:0x7ffe5e52257e
&c adder is:0x7ffe5e522544
c  adder is:0x4
p equaled adder is:0x7ffe5e522548
p equaled value is:0x7ffe5e522544
*p  adder is:0x7ffe5e522544



函数指针

指针函数与函数指针,说实话这两个字眼有时候就是考语文
函数指针:一个用来指向函数的指针,本质是一个指针,常见代码形式 int (*func)(int x,int y)
指针函数:一个函数的返回值是指针,本质是一个函数,常见代码形式 int * func(int x,int y)

带参数的函数指针
google@ubuntu1404:~/workspace/test/play_game$ cat test.c 
#include<stdio.h>
//有参数的情况 :
void single_life( void(*function)(int arg),int a );
void function(int arg);

void single_life( void(*function)(int arg),int a )
{
        function(a);//通过函数指针调用带参数的函数
}
void function(int arg)
{
        int             a=arg;
        while(a)
        {
                printf("奥里给 ,打工人!\n");
                sleep(3);
        }
}
void main()
{
        single_life(function,1);
}
google@ubuntu1404:~/workspace/test/play_game$ gcc test.c 
google@ubuntu1404:~/workspace/test/play_game$ ./a.out 
奥里给 ,打工人!
奥里给 ,打工人!
奥里给 ,打工人!
^C
google@ubuntu1404:~/workspace/test/play_game$ 
不带参数的函数指针
google@ubuntu1404:~/workspace/test/play_game$ cat test.c 
#include<stdio.h>
//没参数的情况 :
void single_life( void(*function)(void *arg));
void function(void *arg);

void main()
{
        single_life(function);
}

void single_life( void(*function)(void *arg) )
{
        function(0);//由于没有带参数所以通过函数指针调用的时候直接写0,但不能不写不然会抛错
}
void function(void *arg)
{
        while(1)
        {
                printf("加油 ,打工人!\n");
                sleep(3);
        }
}
google@ubuntu1404:~/workspace/test/play_game$ gcc test.c 
google@ubuntu1404:~/workspace/test/play_game$ ./a.out 
加油 ,打工人!
加油 ,打工人!
加油 ,打工人!
加油 ,打工人!
^C
google@ubuntu1404:~/workspace/test/play_game$ 
函数指针作为结构体的成员
google@ubuntu1404:~$ gcc tt.c 
google@ubuntu1404:~$ ./a.out 
hello world!
google@ubuntu1404:~$ cat tt.c 
#include <stdio.h>

typedef struct a
{
        void (*func)(char *);
}a_t;
void hello(char *name)
{
        printf ("%s\n",name);
}

int main()
{
#if 0
        //version 1 结构体成员初始化
        a_t a1;
        a1.func = hello;
        a1.func("hello world!");
#endif

#if 1
        //version 2 结构体成员初始化
        a_t a1={hello};
        a1.func("hello world!");
#endif

        return 0;
}
google@ubuntu1404:~$ 

参考博文:https://www.cnblogs.com/xiaolongxia/articles/2752731.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值