VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 2857|回复: 42

[交流] C语言的指针、数据、结构体关系总结

[复制链接]
79_avatar_middle
在线会员 发表于 2016-2-21 14:34:44 | 显示全部楼层 |阅读模式
本帖最后由 源代码 于 2016-2-21 14:41 编辑

#指针的类型、指针所指向的类型
A. 指针存储的数值是内存的一个地址
B. 只要把指针声明语句中的指针名去掉,剩下的部分就是指针的类型
C. 只要把指针声明语句中的指针名和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型

例子
代码部分                指针类型        指针所指向的类型
int *ptr;                int *                int
char *ptr;                char *                char
int **ptr;                int **                int *
int (*ptr)[3];                int (*)[3]        int ()[3]
int *(*ptr)[4];                int *(*)[4]        int *()[4]

#指针的值
A. 指针的值是指指针本身存储的数值,这个值会被编译器当做一个地址进行编译
B. 指针本身的大小是一个字长(32位机是4字节,64位机是8字节)
C. 指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度是sizeof(指针所指向的类型)的一片连续内存区域
   注1. 说一个指针的值是X,就是说该指针指向了以X为首地址的一片内存区域
   注2. 说一个指针指向了某块内存区域,相当于说该指针的值是这块内存区域的首地址
D. 指针所指向的内存区和指针所指向的类型是两个完全不同的概念
   注1. 指针光声明但不初始化时,它所指向的内存区域是不存在的

#指针运算
A. 指针可以加减一个整数,注意这种运算的意义和通常的数值加减运算的意义是完全不一样的

例子
代码部分                分析部分
int a[20];                定义一个int类型的数组       
int *ptr = a;                该指针的类型是int *,指向的类型是int,被初始化为a的首地址
ptr++;                        把ptr的值加上sizeof(int),也就是指向了第2个元素的地址,即&a[1]

例子
代码部分                分析部分
char a[20];                定义一个char类型的数组
int *ptr = a;                该指针的类型是int *,指向的类型是int,被初始化为a的首地址
ptr += 4;                把ptr的值加上sizeof(int),在32位机上就是加上了4个int类型的长度,即为4*4=16个字节
                        由于char类型的长度是1个字节,这样指针就指向了第17个元素的地址,即为&a[16]
#运算符&和*
A. & 取址符
B. * 取值符

例子
代码部分                分析部分
int a, b;                定义int类型的变量a、b
int *p, **ptr;                定义指向int类型的指针p、指针的指针ptr
p = &a;                        a是int类型,&a是取到a的地址,所以&a的类型是int *,赋值给同为int *类型的指针变量p
*p = 24;               
ptr = &p;                p是int *类型,&p取到的是的是p的地址,所以&p的类型是int **,赋值给同为int **类型的指针变量ptr
*ptr = &b;                b是int类型,&b取到的是b的地址,所以&b的类型是int *,赋值给同为int *类型的指针变量*ptr
**ptr = 24;

#指针表达式
A. 如果一个表达式的最后结果是一个指针,那么这个表达式就叫做指针表达式

例子
代码部分                分析部分
int a, b;
int array[10];
int *pa;
pa = &a                        a是int类型,&a是int *类型,所以&a是一个指针表达式
int **ptr = &pa;        pa是int *类型,&pa是int **类型,所以&pa是一个指针表达式
*ptr = &b;                b是int类型,&b是int *类型,所以&b是一个指针表达式
pa = array;
pa++;                        pa自增1,返回值同样是一个指针,是指针表达式

#指针和数组的关系
A. 数组的数组名可以看做是个指针(注意用词,“可以看做是”,只是作为右值自动转化为指针)

例子
代码部分                                        分析部分
int array[10] = {0,1,2,3,4,5,6,7,8,9}, value;
value = array[0];                                同value = *array
value = array[3];                                同value = *(array + 3)
value = array[4];                                同value = *(array + 4)

如该例,定义一个数组 TYPE array[n],则数组名array有如下几层含义
1). 它代表整个数组,类型是TYPE[n]
2). 它是一个指针,类型是TYPE *,指向的类型是TYPE
3). 有单独的内存区,和数组第0号单元占据的内存区不同
4). 该指针相当于一个指针常量,不可以修改

#指针和结构体
A. 可以自定义一个指向结构体类型对象的指针

例子
代码部分                                分析部分
struct MyStruct
{
        int a, b, c;
};

struct MyStruct s = {2, 3, 4};
struct MyStruct *p = &s;                使用p->a, p->b, p->c来访问每个成员变量
int *ptr = (int *)&s;                        使用*ptr, *(ptr + 1), *(ptr + 2)来访问每个成员变量

#指针和函数
A. 可以把一个指针声明为一个指向函数的指针

例子
#include <stdio.h>
void fun(char *s)
{
        printf("hello, %s\n", s);
}

int main (int argc, const char * argv[]) {
    // insert code here...
        void (*pfun)(char *) = fun;
        pfun("john");
        return 0;
}

#一些复杂声明的解释
int (* func)(int *p)
1. 先找到未定义的标识符,这里是func,func被一对括号所包围,且前面有个*号,说明func是一个指针
2. 后面有括号,说明(* func)是一个函数,而func是一个指向函数的指针
3. 这个函数的形参是int *
4. 整个函数的返回值是个int
5. 结论,这是一个返回值是int、形参为int *类型的一个指针函数

int (* func)(int *p, int(*f)(int *))
1. (* func)是一个函数
2. 这个函数有两个形参,类型分别是int *和int (*)(int *),也就是一个返回值为int的指针函数
3. 整个函数的返回值是int
4. 结论,这是一个返回值是int、形参分别为int *和一个返回值为int的指针函数的一个指针函数

int (* func[5])(int *p)
1. (* func[5])是一个函数
2. func是一个有5个元素,每个元素都是一个函数指针
3. 这个函数有一个类型为int *的形参
4. 这是返回值是int、形参是int *类型的函数指针数组

int (* (* func)[5])(int *p)
1. func是一个指针数组
2. 这个指针数组的元素是指针
3. 总结,func是一个指向数组的指针,数组的元素是函数指针,这些指针指向具有int *形参,整个函数返回值为int

评分

参与人数 5驿站币 +7 热心值 +7 收起 理由
88_avatar_small 寂寞江湖 + 2 + 2 感谢分享!
16_avatar_small 阳光 + 1 + 1 赞一个!
28_avatar_small 天下 + 1 + 1 很给力!
56_avatar_small wumoo + 1 + 1 感谢分享!
65_avatar_small 编程者 + 2 + 2 感谢分享!

查看全部评分





上一篇:printf函数的返回值
下一篇:如何解决阶乘运算中大数溢出的问题?求助!!!!!!!!!!!
08_avatar_middle
在线会员 发表于 2016-2-22 19:15:43 | 显示全部楼层
C语言的指针、数据、结构体关系总结
08_avatar_middle
在线会员 发表于 2016-2-22 19:16:09 | 显示全部楼层
C语言的指针、数据、结构体关系总结C语言的指针、数据、结构体关系总结
83_avatar_middle
在线会员 发表于 2016-2-22 20:04:28 | 显示全部楼层
学习看看,谢谢楼主分享了
42_avatar_middle
在线会员 发表于 2016-2-22 22:14:12 | 显示全部楼层
看一下。。。
16_avatar_middle
在线会员 发表于 2016-2-22 23:19:32 | 显示全部楼层
支持支持
89_avatar_middle
在线会员 发表于 2016-2-23 15:07:25 | 显示全部楼层
sssssssssssssss
03_avatar_middle
在线会员 发表于 2016-2-25 15:51:27 | 显示全部楼层
學習一下
59_avatar_middle
在线会员 发表于 2016-2-25 19:24:42 | 显示全部楼层
语言的指针、数据
11_avatar_middle
在线会员 发表于 2016-2-25 19:27:57 | 显示全部楼层
学习学习学习学习学习学习学习学习学习学习
46_avatar_middle
在线会员 发表于 2016-2-25 20:32:00 | 显示全部楼层
C语言的指针、数据、结构体关系总结
17_avatar_middle
在线会员 发表于 2016-2-26 14:18:12 | 显示全部楼层
看看。。。。
04_avatar_middle
在线会员 发表于 2016-2-27 20:35:42 | 显示全部楼层
正在找这个,谢谢分享!
27_avatar_middle
在线会员 发表于 2016-2-27 20:58:17 | 显示全部楼层
想知道
42_avatar_middle
在线会员 发表于 2016-2-27 21:45:41 | 显示全部楼层
dddddddd
95_avatar_middle
在线会员 发表于 2016-2-28 23:35:14 | 显示全部楼层
学习看看,谢谢楼主分享了
56_avatar_middle
在线会员 发表于 2016-2-29 09:15:21 | 显示全部楼层
xuexi xuexi
26_avatar_middle
在线会员 发表于 2016-2-29 12:19:15 | 显示全部楼层
顶楼主啦..希望楼主多发精品好帖啦.....
14_avatar_middle
在线会员 发表于 2016-2-29 14:23:04 | 显示全部楼层
C语言的指针、数据、结构体关系总结
49_avatar_middle
在线会员 发表于 2016-2-29 14:34:55 | 显示全部楼层
终于找到了哈
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2019-5-23 12:14

Powered by Discuz! X3.4

© 2009-2019 cctry.com

快速回复 返回顶部 返回列表