C语言指针学习总结
上学的时候学习C语言,最烦的就是里面指针,可是指针也恰恰是C语言的灵魂。
最近在重温数据结构的内容,因为大多数据结构的教材都是用C语言描述的,而数据结构中也大量的用到了指针的内容,所以我就在这篇笔记中记录一下我这周复习C语言的心得。
先看看百科上对指针的描述。
在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在计算机存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。
作个比喻,假设将计算机存储器当成一本书,一张内容记录了某个页码加上行号的便利贴,可以被当成是一个指向特定页面的指针;根据便利粘贴面的页码与行号,翻到那个页面,把那个页面的那一行文字读出来,这就是指针的作用。
下面将通过一些代码说明指针在C语言中的表现形式。
int main(){
int a ;
a = 10;
int *p;
p = &a;
}
如果用图片描述这段代码,就是下面这个样子。
怎么来理解呢?首先这段代码里通过int a和 int *p定义了两个变量:分别是p和a,p变量与a变量的定义方式有一些不同,a变量就是C语言中一个很普通的int型变量,通过a=10 将10这个整型赋值给了a。
而p变量的定义前面有一个 * ,这个 * 表明了p变量是一个指针变量,指针变量里面只能存放地址,这个地址是内存中的某个位置,在上面的代码中我们在p变量里面存放的是0x2C406B24这个地址,这个地址里面存放的值必须是int值,在我们这里,p变量里面存放的地址是a变量的地址,a变量在定义时就是一个int,所以是符合要求的。
这样一来,我们就说p变量指向了a变量,p = &a 这句代码完成了p指向a的这个操作。这里没有写p = a,那是因为p变量需要的是一个地址,而不是a变量里面存放的值,所以&这个操作符就是取地址的意思,通过&a取到a变量在内存中的地址,将地址赋值给p指针变量,就使p指向了a。
既然p是一个指针变量,那它就可以赋值给另外一个指针变量,如下:
int main(){
int a ;
a = 10;
int *p;
p = &a;
int *q;
q = p;
}
新定义了一个指针变量q,将p变量里的值0x2C406B24这个地址,赋值给q,这样q变量与p变量里都保存了同样的地址,就是说他们都指向同一个值。
int main(){
int a ;
a = 10;
int *p;
p = &a;
int *q;
q = p;
*p = 5; //
*q = 0; //
}
介绍完指针,那这个东西有什么作用呢?如果要修改a变量里面的值,可以执行a=5,这是没介绍指针之前的做法。学习完指针后,通过指针也能达到修改a变量里的值的目的*p=5。
这是很有用的,举个例子,我们来看下面这段代码。
void swap(int a,int b);
int main(){
int a = 5;
int b = 6;
swap(a, b);
printf("a=%d b=%d",a,b);
return 0;
}
void swap(int a, int b){
int temp;
temp = a;
a = b;
b = temp;
}
上面这段代码,这段代码能够达到交换a和b的值的目的吗?答案是不能,因为C语言在调用函数时,永远只能时传值给函数。
在C语言中每个函数都有自己的变量空间,函数的参数也位于这个独立的空间中,与其它函数没有关系,上面的代码中有两个函数,一个是main函数,另一个是swap函数,所以这两个函数里的a,b变量是不同空间中的变量,他们之间毫无关系可言。
所以对swap函数中的a,b做交换,完全不能改变main函数中a,b变量的值。
函数在每次运行的时候,会产生一个独立的变量空间,在这个空间中的变量,是函数这次调用时所独有的,称为本地变量。
定义在函数内部的变量就是本地变量,参数也是本地变量。
变量有 生存期 和 作用域 这两个属性。
- 生存期:什么时候变量开始出现,到这个变量消亡
- 作用域:在代码的什么范围内可以访问这个变量(这个变量可以起作用)
对于本地变量而言,生存期与作用域都是在本地变量所在的大括号(块)内。
既然都说到本地变量了,那就总结一下本地变量的一些规则。
本地变量的规则:
- 本地变量定义在块内
- 本地变量只存在于运行块内语句的期间
- 在块外面定义的变量,块里仍然有效
- 本地变量不会默认初始化
- 参数这样的本地变量在进入函数时就被初始化了
- 列表内容
又说回上面的交换函数,那么怎样才能达到交换main函数里a,b两个变量值的目的呢?
void swap(int a,int b);
int main(){
int a = 5;
int b = 6;
swap(&a, &b);
printf("a=%d b=%d",a,b);
return 0;
}
void swap(int *pa, int *pb){
int temp;
temp = *pa;
*pa = *pb;
*pb = temp;
}
利用上面所学习的指针,改写成上面这样,才能达到交换的目的。
始终记住:C语言在调用函数时,永远只能时传值给函数。在上面的代码中,自然也是传值进的swap函数,只不过在使用指针时,这个值指的是地址,地址当然也是一个值。
将main函数中a和b变量的地址传给了swap函数中的指针变量pa和pb,在swap函数中通过 *pa 和 *pb 操作到了main函数中的a和b,从而达到了交换的目的。
这只是指针的作用之一,用好了指针,才能体现出C语言更多强大的地方。
数组
这是一篇总结指针的文章,那么我为什么要提到数组呢?
因为数组和指针又太多的相似之处。看下面一段代码。
int test(int a[], int numOfa){
int i;
for(i = 0; i<numOfa; i++){
printf("%d",a[i])
}
}
其实数组中的[ ],与 * ,. ,& 等运算符一样,也是一种运算符。
上面test函数里的a数组变量,本身就是一个地址,所以我们在调用这个函数的时候,需要写成这样test( &a, i) ,需要传入一个地址,这个地址所在的变量保存的就是一个数组。
例如:
int a[10]; int *p = a;// 不需要用&取地址,数组变量本身就表达地址a == &a[0]但是数组的单元表示的是变量,需要用&对变量取地址。数组变量第一个单元的地址就是数组变量的地址。p[0] == a[0][ ] 运算符可以对数组做,也可以对指针做*a = 9将数组的第一个单元赋值为9,说明 * 运算符既可以对数组做,也可以对指针做
最后在总结一下const关键字在指针中的规则:
- const int *p = &i :const在前,表示不能通过指针去修改变量
- int * const p = &i :const在后,表示p这个指针变量不能再保存别的地址值
上面就是我在复习C语言指针时的一些总结,今后有需要添加的也会陆续补充。
C语言指针学习总结的更多相关文章
- [转]C语言指针学习经验总结浅谈
指针是C语言的难点和重点,但指针也是C语言的灵魂 . 这篇C语言指针学习经验总结主要是我入职以来学习C指针过程中的点滴记录.文档里面就不重复书上说得很清楚的概念性东西,只把一些说得不清楚或理解起来比较 ...
- C语言指针学习
C语言学过好久了,对于其中的指针却没有非常明确的认识,趁着有机会来好好学习一下,总结一下学过的知识,知识来自C语言指针详解一文 一:指针的概念 指针是一个特殊的变量,里面存储的数值是内存里的一个地址. ...
- (转载)c语言指针学习
前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...
- c语言指针学习【转】
前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...
- 1.C语言指针学习之外挂篇
学习了c语言的指针,那么指针能做什么呢,首先,他可以写外挂 首先我们来编写一个dll,挂载到植物大战僵尸上,记住是dll,因为如果你创建一个应用程序,该应用程序是不能操作其他程序的地址的. 第一步,打 ...
- c语言指针学习笔记
指针变量就是存放内存地址的变量.c语言中使用 int *pa; 的方式来定义指针. ` main() int a = 10, b=20, s, t, *pa, *pb,*pc,*pd; pa = &a ...
- C语言指针学习(续)
五.数组和指针的关系 int array[10] = {0,1,2,3,4,5,6,7,8,9},value; ... ... value = array[0];//也可以写成 value = *ar ...
- GO语言学习(十五)Go 语言指针
Go 语言指针 Go 语言中指针是很容易学习的,Go 语言中使用指针可以更简单的执行一些任务. 接下来让我们来一步步学习 Go 语言指针. 我们都知道,变量是一种使用方便的占位符,用于引用计算机内存地 ...
- 2-Linux C语言指针与内存-学习笔记
Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标准输入输出流以及错误流管道 工具与原理 指针与内存都是c语言中的要点与难点 指针 数组 ...
随机推荐
- webpack优化经验1(持续)
1 不知道该优化哪里 先开启gzip压缩,这样可以很直接的减少请求包的体积,效果显著,不过需要在服务器端作相应的配置才能生效 2拆分vendor包, 减少单体包的体积,并行加载 通过配置,将不同的公用 ...
- 用java写的后台方法可以提供给C#调用吗?(转)
最近和公司搞C#的同事联合搞了一个项目,我把我这边的数据加密之后传给C#,然后C#在对接收到的数据解密.可是问题来了,我这边用JAVA加密的数据C#的同事怎么也解密不出来,于是我就想到了可不可以将JA ...
- Matlab Tricks(二十八)—— 笛卡尔积的实现
笛卡尔积在数学上是一种二元关系,笛卡尔积作用的双方是两个集合,作用的结果是一个新的集合. A×B={(a,b)|a∈Aandb∈B} 现有两向量: >> p = [1, 5, 10]; & ...
- Leetcode 136 Single Number 亦或
题意就是从一堆数中找出唯一的一个只存在一个的数.除了那个数,其他的数都是两个相同的数. 通过亦或的性质: 1)a^a = 0 0^a = a 2)交换律 a^b = b^ a 3)结合律 (a^b)^ ...
- 计算机程序设计的史诗TAOCP
倘若你去问一个木匠学徒:你需要什么样的工具进行工作,他可能会回答你:“我只要一把锤子和一个锯”.但是如果你去问一个老木工或者是大师级的建筑师,他会告诉你“我需要一些精确的工具”.由于计算机所解决的问题 ...
- Mybatis常用操作 专题
parameterType:即将传入的语句参数的完全限定类名和别名.这个属性是可选项的,因为MyBatis可以推断出传入语句的具体参数,因此不建议配置该属性flushCache:默认值为true,任何 ...
- 各种Message中文解释(一部分)
函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.该函数是应用程序和应用程序之间进行消息传递的主要手段之一. 函数原型:LRESUL ...
- ubuntu 16.04快速安装ceph集群
准备工作 假设集群: 选一台作管理机 注意: ceph集群引用hostname,而非ip. 172.17.4.16 test16 #hostname必须是test16 172.17.4.17 test ...
- C# 特性的使用
using ClassLibrary;using System;using System.Collections.Generic;using System.Linq;using System.Refl ...
- MVC EF Code First
1 在Models里面创建类,用[Key]特性指定主键: 2 在Model里面增加导航属性: 3 在web.config里面增加连接字符串 4 创建继承于DbContext的类 5 创建Control ...