以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语言之指针的更多相关文章

  1. 浅谈c语言的指针

    对于非计算机专业的同学,c语言的指针往往就是老师的一句“指针不考“就带过了.c语言的指针号称是c语言的灵魂,是c语言中最精妙的部分. 指针本质上也是变量,也就是一段内存,只是他的特殊之处是他存储的数据 ...

  2. C#委托与C语言函数指针及函数指针数组

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  3. C语言二重指针与malloc

    (内容主要源于网上,只是加入了些自己的剖析) 假设有一个二重指针: char **p; 同时有一个指针数组 char *name[4]; 如何引用p呢? 首先我们有程序代码如下 #include &l ...

  4. C语言函数指针基础

    本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...

  5. 为什么C/C++语言使用指针

    这是参加面试时,面试官问的一道开放性题目. 问题是:为什么C/C++语言使用指针? 这个问题一问出来,直接被面试官秒杀了,面试官大神,你怎么不按套路出牌啊? 说好的malloc和new的区别呢?说好的 ...

  6. C语言的指针变量

    C语言的指针变量 在C语言中,变量是固定范围的存储空间,它存储的是赋给他的值, 比如: ; /* 这里是定义一个整型变量a,并把12这个值存储在a的地址空间上 这个地址空间是系统随机分配的,对用户是透 ...

  7. Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型

    Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...

  8. “对外部(局部)变量的访问”是C语言函数指针的最大弱点

    1.“对外部(局部)变量的访问”是C语言函数指针的最大弱点 . #include <stdio.h> #include <stdlib.h> /* 结构体定义 */ struc ...

  9. go语言学习--指针的理解

    Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,array/slice,map,chan, fu ...

  10. C语言中指针占据内存空间问题

    以前一直有个疑问,指向不同类型的指针到底占用的内存空间是多大呢? 这个问题我多次问过老师,老师的答案是"指向不同类型的指针占据的内存空间大小不同",我一直很之一这个答案,今天我就做 ...

随机推荐

  1. Helpers\Date

    Helpers\Date The Date helper is used for calculations with dates. Date::difference($from, $to, $type ...

  2. iOS开发技巧系列---使用链式编程和Block来实现UIAlertView

    UIAlertView是iOS开发过程中最常用的控件之一,是提醒用户做出选择最主要的工具.在iOS8及后来的系统中,苹果更推荐使用UIAlertController来代替UIAlertView.所以本 ...

  3. Tomcat启动报错org.apache.coyote.AbstractProtocol.init Failed to initialize end point associated with ProtocolHandler ["http-apr-8080"]”

    1.使用netstat查看端口8080的使用情况: netstat -ano | findstr 8080 结果为: 最后一列表示使用8080端口的进程PID,如果返回结果为空则说明没有被使用. 2. ...

  4. 寻找对象在父元素下的index

    方法一. window.onload=function(){    //寻找对象在父元素下的index    function getIndexParent(element){         var ...

  5. java集合总结

    java中集合是很重要的一点,巩固这边学习的知识,把知识理一下 按马士兵的视频,总结的也很好,集合就是一个“1136” 1个图,1个类Collections,3个知识点:增强for循环,泛型,打包和解 ...

  6. MySQL 테이블 타입(Heap, MyIsam, InnoDB...) 변경하기

    alter table 을 이용해서 기존의 생성된 테이블의 타입(Heap, MyIsam, InnoDB...)을 변경하는 명령어 입니다. 잠시 까먹은 분은 계실지 몰라도 원래 모르는 ...

  7. JAXB - Annotations, Type Mapping: XmlSchemaType

    The annotation XmlSchemaType defines a mapping between an arbitrary Java type and a simple schema bu ...

  8. ASP中双引号单引号和&连接符使用技巧

    ASP中双引号单引号和&连接符使用技巧 一.ASP中处在双引号中的可以是任意的字符.字符串,HTML代码 1.<%response.write ("I am here" ...

  9. VBA文件处理

    Option Explicit ' ▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽ ' Excel对象 ' △△△△△△△△△△△△△△△△△△ ' Open Public Function FileOpen_ ...

  10. Open Flash Chart在php中的使用教程

    http://www.cnblogs.com/huangcong/archive/2013/01/27/2878650.html 为了画一个漂亮的表格,我从网上找到了OpenFlashChart(of ...