一、什么是指针

1、指针的定义:地址形象化为指针,通过指针能够找到内存单元。

        指针变量就是地址变量,变量的值为指针。

指针其实是我们将变量名和地址的关系显化(独立)出来的一种形式,是为了我们更加方便的读取数据和进行操作而设计的,是c语言的灵魂。

解释:

int a;
printf("%d,a");

如上,我们通常是通过变量名来引用变量的值,如上面的printf("%d,a");一句,我们就是通过引用a的变量名来输出变量a的值。

为了理解上述的概念,我们必须理解这两个概念:

存储单元的地址  系统分配地址  类似于房间号

存储单元的内容  自定义内容   类似于房间里的人

2、常用的两种访问方式

直接访问  间接访问

int a;
a = ;
//直接访问
printf("%d,a");
//间接访问
int *a_pointer;
a_pointer = &a; printf("%d,*a_pointer");

直接访问就是通过变量名进行访问,间接访问就是通过指针进行访问。

二、指针变量

定义:存放地址(指针)的变量。

1、定义指针变量

方式:类型名 *指针变量名

int *p;// int——基类型,不可少

基类型用来指定此类指针变量可以指向的变量类型。如上面的p指针只可以用来指向整数类型的变量。

Zu:指针变量是基本数据类型派生出来的数据类型不能脱离基类型而独立存在。

int a,*a;
double b,*p;
float *p;
上面的定义都是正确的。

“ *  "用来表示该变量是指针变量.

如上面的 int a,*a;我同时定义了整数型变量a,和整数型指针变量a。

2、不同指针类型,不能混用

int a;
int *p;
char *t;
p = &a;//√
t = &a;//×

变量的指针包含存储单元的纯地址和该变量的数据类型两方面。

3、指针变量只可以存储地址

int a, *pointer;
a = ;//√
pointer = ;//×

三、两个重要的指针操作符

&  取地址运算符

*  指针运算符(我更习惯叫他取内容运算符)

int a=;
int *pointer;
pointer = &a;//取出a的地址赋给pointer,此时pointer指向a(即pointer的值是a的地址)
if(*pointer==)//取出pointer所指向的变量的值(即取出pointer存储的地址下的内容),在这里是a的值,然后进行比较
printf(“ture!”);//输出ture!

四、指针变量作为函数参数

1、两种传递方式   (函数通过参数(实参、形参)的传递来实现数据或地址的相互调用)

①值传递

②地址传递(引用传递):实际上就是指针传递

  值传递不改变实参的值,而是传递实参的值。

  地址传递可能改变实参的值,传递的是实参的地址,可以通过地址访问数据。

实例:

//交换函数
#include<stdio.h>
int main()
{
void swap(int *p1,int *p2); int a=,b=; int *k1,*k2; k1=&a;k2=&b; if(a<b) swap(k1,k2); printf("max=%d min=%d",a,b);//输出max=5 min=4 return ;
} void swap(int *p1,int *p2)
{
int temp;
temp=*p1;
*p1=*p2;
*p2=*p1;
}

五、通过指针引用一维数组

数组元素的指针就是数组元素的地址。

切记:c中,数组名代表数组中首元素的地址

所以:两式等价

int *p,a[10];

p=&a[0];

p=a;

1、数组中指针的运算

指针拥有两类运算,一类是赋值运算,一类是算术运算。

指针指向的是地址,赋值运算代表的是地址的赋值。那算术运算代表什么意思呢?

  其实代表的是(通过算术运算)而导致指向的地址的改变。

1)运算规则:自加(p++,++p)、自减(p--,--p)

      加减整数(p+n,p-n)

这些运算代表什么意思呢:

首先我们定义一个数组int a[10],一个指针变量int *p=a;并赋值

此时的p代表的是数组a首元素的地址——就是a[0]的地址

那么p+1代表什么呢?

代表的是,指向数组中的下一个元素的地址,p+1等同于&a[1];同理p-1也是一样的道理。

2)讲解一个a[i]和p+i的联系与区别

[ ] 是变址运算符,a[ i ]按a+i计算地址,然后找出此地址单元中的值,所以我们常用的a[i]法引用数组元素值的方法和指针调用其实区别不大。

2、通过指针引用数组元素的两种方法

1)下标法。a[ i ]形式

2)指针法。如*(a+i)的形式,a为数组名,i为数组的序号。

例子:便利数组元素。

前提是定义了数组a[]
for(int *p=a;p<(a+);p++)
*p=;//数组元素置零

for(int i;i<;i++)
a[i]=;

3)值得注意的一点就是数组名代表数组元素的首地址,那么他就是一个指针型常量,它的值在程序运行的过程中是不变的,无法实现自加自减运算(a++  a --  ×)

但是我们可以通过赋值将首地址复制到指针变量中,然后再进行运用  如:for(int *p=a;p<(a+10);p++)。

3、特殊表达式分析:

1、*p++
由于++与*同优先级
所以:先输出*p的值,然后使p值加1,即现在的p是p+
解释:如果有一个数组,p指向a[],执行过一次*p++后,*p++代表的意义是a[]的内容。
2、*p++等价于*(p++)
有时候我都感觉很奇葩,如果就从字面上来看*(p++),很明显,这里的意义是先使得p++,就是p自加之后取值,但是事实上却是和上面的意义是一样的。
3、*(++p)
相当于a[++i]
意义:先使p加1,在取*p。
4、*(p--)
相当于a[i--]
意义:先求*p,再使p减1.
5、*(--p)
相当于a[--i]
先使p自减1,然后取*p
6、++(*p)
意义:先取*p,然后加1.

六、数组名用作函数参数

我们之前在传递数组到函数里的时候,通常都是以数组名作为实参进行传递,而形参通常会设定为数组。

例子:

//主体省略,已定义数组 array[100]
fun(array,); void fun(int arr[],int a)
{ }
//其实也可以这样做
void fun(int *arr,int a)
{ }

上面两种方法等价。为什么呢?

因为我们实际上传递的是地址,而arr[ ]和*arr是等价的。所以我们已数组作为形参和以指针变量作为形参其实意义是一样的。

我们在考略一些东西的时候我们一定要使用抓住主要,舍弃次要,理解关键,专注细节,明白实质的方法。

而我们函数传递数组的时候实质便是地址的传递,所以我们只要能够传递地址的方法不都是可以的吗?

C语言的灵魂——指针基础的更多相关文章

  1. C语言之灵魂 指针学习

    指针是c语言的难点 称之为c语言的灵魂一点也不为过,不过指针用好了能事半功倍,用不好bug满天飞. 一.指针的概念 指针也是变量只不过是特殊的变量,指针的值是另一个变量的地(也就是变量所在的内存地址) ...

  2. Swift3.0语言教程使用指针创建和初始化字符串

    Swift3.0语言教程使用指针创建和初始化字符串 Swift3.0语言教程使用指针创建和初始化字符串苹果的Swift团队花了不少功夫来支持C的一些基础特性.C语言中为我们提供了指针,Swift也不例 ...

  3. 深入解析C语言数组和指针

    概述 指针是C语言的重点,同时也是让初学者认为最难理解的部分.有人说它是C语言的灵魂,只有深入理解指针才能说理解了C语言.暂且撇开这些观点不谈.这章是我在阅读<C和指针>这本书的读书笔记. ...

  4. C语言的10大基础算法

    C语言的10大基础算法 算法是一个程序和软件的灵魂,作为一名优秀的程序员,只有对一些基础的算法有着全面的掌握,才会在设计程序和编写代码的过程中显得得心应手.本文包括了经典的Fibonacci数列.简易 ...

  5. C语言之漫谈指针(上)

    C语言之漫谈指针(上) 在C语言学习的途中,我们永远有一个绕不了的坑,那就是--指针. 在这篇文章中我们就谈一谈指针的一些基础知识. 纲要: 零.谈指针之前的小知识 一.指针与指针变量 二.指针变量的 ...

  6. C语言之漫谈指针(下)

    C语言之漫谈指针(下) 在上节我们讲到了一些关于指针的基础知识: 详见:C语言之漫谈指针(上) 本节大纲: 零.小tips 一.字符指针 二.指针数组与数组指针 三.数组传参与指针传参 四.函数指针及 ...

  7. C语言中的指针数组

    C语言中的指针数组是什么,像 char *a[]={"ddd","dsidd","lll"}; 这里讲一下注意如果我们使用了a也就是首元素的 ...

  8. 【ZZ】C 语言中的指针和内存泄漏 & 编写高效的C程序与C代码优化

    C 语言中的指针和内存泄漏 http://www.ibm.com/developerworks/cn/aix/library/au-toughgame/ 本文讨论了几种在使用动态内存分配时可以避免的陷 ...

  9. GO语言中的指针

    http://www.tizgrape.com/?p=100 Go语言中的指针语法和C++一脉相承,都是用*作为符号,虽然语法上接近,但是实际差异不小. Go使用var定义变量: var v6 *in ...

随机推荐

  1. python numpy.array插入一行或一列

    numpy.array插入一行或一列 import numpy as np a = np.array([[1,2,3],[4,5,6],[7,8,9]]) b = np.array([[0,0,0]] ...

  2. BZOJ 3576: [Hnoi2014]江南乐 (SG函数)

    题意 有nnn堆石子,给定FFF,每次操作可以把一堆石子数不小于FFF的石子平均分配成若干堆(堆数>1>1>1). 平均分配即指分出来的石子数中最大值减最小值不超过111.不能进行操 ...

  3. mysql 解决忘记密码 mysql5.7 远程登录不上MySQL(解决腾讯服务器初始mysql密码问题)

    一.修改MySQL启动配置文件 #如果不知道配置文件,先查找find / -name my.cnf#编辑配置文件 vim /etc/my.cnf 在[mysql]  下面第一行加入 skip-gran ...

  4. EF非常见错误:EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配

    EF非常见错误:EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 问题原因: 两个表A\B之间存在外键关系,当插入表A的时候,A的外键B在B表中不存在可以引起这个问题: ...

  5. BZOJ 2169 连边 DP

    思路:DP 提交:\(1\)次(课上刚讲过) 题解: 如果不管重边的话,我们设\(f[i][j]\)表示连了\(i\)条边,\(j\)个点的度数是奇数的方案数,那么显然我们可以分三种状态转移: \(f ...

  6. springBoot怎样访问静态资源?+静态资源简介

    1.静态资源 怎样通过浏览器访问静态资源? 注意:不需要加static目录.因为只是告诉springboot目录,而不是静态资源路劲. 这时访问路径就需要加上/static

  7. ECMAScript 提案阶段

    stage0 strawman任何讨论.想法.改变或者还没加到提案的特性都在这个阶段.只有TC39成员可以提交. stage1 proposal (1)产出一个正式的提案. (2)发现潜在的问题,例如 ...

  8. redis之订阅功能

    redis订阅 Redis 通过 PUBLISH . SUBSCRIBE 等命令实现了订阅与发布模式. 举例1: qq群的公告,单个发布者,多个收听者 发布/订阅 实验 命令 PUBLISH chan ...

  9. 下载安装 binary editor

    http://www.eecanalyzer.net/downloads

  10. cesium billboard跨域问题1

    群里小伙伴问道使用billboard加载图片时出现跨域问题,一般认为在服务器端设置 Access-Control-Allow-Origin: * 例如用tomcat发布图片服务,可以这样设置:http ...