C语言之指针
以32为系统为例。
1、指针与地址
指针是一种变量,保存了所指向对象的地址。
1.1 定义
int i = 10;
int *p = &i; //定义了一个指针p,它指向一个int型的变量
&是地址运算符,*是间接引用运算符。
&i是取i在内存中的地址,*p = &i是将i的地址赋值给p,即p的值是i的地址。
1.2 引用
*p = 100 等价于 i = 100,即将i的值改成100
*p += 1 等价于 i += 1,即将i的值加1
*p++改变了p所指向的地址,此时p不再指向i的地址,而是指向i的地址+4的新地址。因为*(间接引用运算符)和++具有相同的优先级,且是从右到左的结合性,所以等价于*(p++)。p++是将指针加1,指向内存中下一个地址。由于这里的p是int型的,实际上是偏移了sizeof(int)=4个字节。例:
int i = 10;
int *p = &i;
*p++;
printf("i=%d, &i=%p, p=%p\n", i, &i, p);
打印结果:i=10, &i=0xbf99bd78, p=0xbf99bd7c
注意:绝对不能这么写*p++ = 111,因为这无意中非法改变了p下一个内存地址的值。
++*p 等价于 i的值加1
*++p 等价于 *p++
*p + 1 等价于 i 的值 加1
*(p + 1) 等价于*p++
2、指针和数组
int a[10];
int *p = &a[0]; //指针p指向数组a的首地址元素a[0]
或者int *p = a; //数组名所代表的就是该数组的第一个元素的地址,直接赋值给p
引用第i个元素:
a[i] 或者 *(a+i) 或者 *(p+i) 或者 p[i]
数组名和指针的差别:
指针是一个变量,可以赋值或者++,如p=a,p++
但数组名不行,不能这样:a=p, a++
指针的运算包括:
相同类型指针之间的赋值运算;指针同整数之间的加减法运算;指向相同数组中元素的两个指针的减法或比较运算;指针赋值为0,或指针与0之间的比较运算。
3、指针数组和指向指针的指针
指针数组:int *p[10]; //p是一个指针数组,具有10个元素,每个元素都是一个指向int型对象的指针。
指向指针的指针: int **p; //p是一个指针,指向一个int *型对象
4、二维数组
int a[10][20]; //二维数组,有10行,每行20列
int a[][20] = {........}; //二维数组,每行20列,行数会根据{...}内的值的个数自动计算,行数={...}中值的个数/20 + 1
二维数组必须要指定列数,行数可以不用指定。
二维数组作函数参数时,函数的声明方式可以是:
f (int a[10][20]) {...} 或者
f (int a[][20]) {...} 或者
f (int (*a)[20]) {...}
不能是f (int *a[20]) {...}
数组指针(行指针):char (*p)[20]是一个指针,指向具有20个char型元素的一维数组。
sizeof(p)=4,占用一个指针的存储空间
char a[10][20];
char (*p)[20];
p=a; //二维数组首地址给p,p指向a[0][0],即第0行的第0个元素
p++; //执行后,p指向a[1][0],即第1行的第0个元素
指针数组:char *p[20]是一个数组,具有20个元素,每个元素都是一个指向char型对象的指针
sizeof(p)=80,占用20个指针的存储空间
char a[10][20];
char *p[20];
p[0]=a[0]; //p[0]指向二维数组a的第0行
p[1]=a[2]; //p[1]指向二维数组a的第2行
两者的引用方式一样,都是:*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]
原因:[]的优先级高于*的优先级。
5、指向函数的指针
int (*f)(int i, int j) 定义了一个函数指针,这个函数有两个参数i和j,函数返回一个int型对象。
圆括号是必须的,否则就变成了int *f(int i, int j),这表示函数f返回一个int *型对象。
6、总结
char **x:x是指向指针的指针
char (*x)[10]:x是一个数组指针,指向一个具有10个元素的数组
char *x[10]:x是一个指针数组,每个元素都是一个指向char型对象的指针
char *x( ):x是一个函数,该函数返回一个指向char型对象的指针
char (*x)( ):x是一个函数指针,该函数返回一个char型对象
char (*(*x( ))[10 ])( ):定义了一个函数,该函数返回一个具有10个元素的数组指针,元素类型是函数x返回的指向char类型对象的指针
char (*(*x[10])())[2]:定义了一个数组,数组有两个元素,每个元素的类型是函数返回的指向一个10个元素的指针数组的指针
C语言之指针的更多相关文章
- 浅谈c语言的指针
对于非计算机专业的同学,c语言的指针往往就是老师的一句“指针不考“就带过了.c语言的指针号称是c语言的灵魂,是c语言中最精妙的部分. 指针本质上也是变量,也就是一段内存,只是他的特殊之处是他存储的数据 ...
- C#委托与C语言函数指针及函数指针数组
C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...
- C语言二重指针与malloc
(内容主要源于网上,只是加入了些自己的剖析) 假设有一个二重指针: char **p; 同时有一个指针数组 char *name[4]; 如何引用p呢? 首先我们有程序代码如下 #include &l ...
- C语言函数指针基础
本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...
- 为什么C/C++语言使用指针
这是参加面试时,面试官问的一道开放性题目. 问题是:为什么C/C++语言使用指针? 这个问题一问出来,直接被面试官秒杀了,面试官大神,你怎么不按套路出牌啊? 说好的malloc和new的区别呢?说好的 ...
- C语言的指针变量
C语言的指针变量 在C语言中,变量是固定范围的存储空间,它存储的是赋给他的值, 比如: ; /* 这里是定义一个整型变量a,并把12这个值存储在a的地址空间上 这个地址空间是系统随机分配的,对用户是透 ...
- Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型
Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...
- “对外部(局部)变量的访问”是C语言函数指针的最大弱点
1.“对外部(局部)变量的访问”是C语言函数指针的最大弱点 . #include <stdio.h> #include <stdlib.h> /* 结构体定义 */ struc ...
- go语言学习--指针的理解
Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,array/slice,map,chan, fu ...
- C语言中指针占据内存空间问题
以前一直有个疑问,指向不同类型的指针到底占用的内存空间是多大呢? 这个问题我多次问过老师,老师的答案是"指向不同类型的指针占据的内存空间大小不同",我一直很之一这个答案,今天我就做 ...
随机推荐
- PAT 1005
1005. Spell It Right (20) Given a non-negative integer N, your task is to compute the sum of all the ...
- scrollLeft、offsetLeft、clientLeft、clientHeight详解
offsetLeft:Html元素相对于自己的offsetParent元素的位置 scrollLeft:返回和设置当前横向滚动务的坐标值 scrollLeft.offsetLeft.clientLef ...
- Conclusion
Conclusion This concludes our brief look at building a simple, but fully functional, Zend Framework ...
- 在aws ec2上使用root用户登录
aws ec2默认是使用ec2-user账号登陆的,对很多文件夹是没有权限的.如何使用root账号执行命令就是一个问题了.解决办法如下: 1.根据官网提供的方法登录连接到EC2服务器(官网推荐wind ...
- CSS3 旋转的八卦图
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 用expect做自动应答脚本
Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools).使用它系统管理员可以创 ...
- 【转】monkeyrunner学习总结二:连接、安装、启动
一.获取packageName与startActivity 前置条件:已成功安装配置SL4A并连接PC调试(参见:monkeyrunner学习总结一:环境搭建:http://www.amsoft.cn ...
- (原创)openvswitch实验连载2-cisco模拟器IOU-Web安装及网络环境配置
IOU的使用可以选择自己到官网https://docs.google.com/file/d/0B2AgRhS2cfxCQ01tN2NrQ0pvNUk/edit下载iou-web 软件,然后部署在lin ...
- css模块化思想(一)--------命名是个技术活
引子: 女孩子都喜欢买衣服,而我也不例外,奈何钱包太瘦,买不起高大上的定制,只能买撞衫率极高的休闲衣,不过对于我来说,我还是开心的,毕竟买衣服买的不仅是衣服,更是一种心情.在web前端的世界里,css ...
- 【转】代码高处走 从VC6到VC9移植代码问题说明
首先可以直接用Visual Studio 2008的打开VC6的工作区文件和项目文件(dsw和dsp),并将其升级为VS2008的解决方案格式和项目格式(sln和vcproj),VC9的编译器相对于V ...