C语言中的指针
请先看C++中的指针概述,这里只是扩充
数组指针
其实这里主要说的就是c++中的指针运算
/* 数组元素指针:
一个变量有地址,一个数组包含若干个元素,每个数组元素都有相应的地址,
指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中)
所谓数组元素的指针就是数组元素的地址
可以用一个指针变量指向一个数组元素 int a[10]={1,2,3,4,5,6,7,3,2,3}; int *p; p=&a[0]; 等同与 p=a; 等同与 int *p=a; 等同与 int*p=&a[0] 注意:
1) 数组名a不代表整个数组,只代表数组首元素的地址
p=a 的作用是"把a数组的首元素的地址赋给指针变量p",而不是"把数组a各个元素的值赋给p" 数组指针:
指向数组元素的指针 数组指针的作用:
使用数组指针间接访问数组的元素 数组指针的定义:
int *p; 数组指针的初始化; int a[4] ={1,2,3,4};
int *p = a;//数组指针,定义了一个指针变量p赋值数组的首地址(第一个元素的地址),P指向数组的第一个元素 int *p = &a[0];//等价上面一句话 数组指针如何访问数组的元素:
1) p+1 表示指向数组的下一个元素
2) p-1 指向数组的上一个元素 误区:
用数组指针遍历数组
for(int i=0;i<4; i++){
printf("%d\t",*p++);
} //学习的误区: 数组名 a 是一个常量 等同与 *(10++)
//数组名++ 这是错误的
printf("*a=%d\n",*a++);//这种写法是错误的 */
逆序数组:把数组中的内容前后对调
void nixuArray(int a[],int len){
int i=0,j=len-1;
while(i<j){
temp=*(p+i);
*(p+i)=*(p+j);
*(p+j)=temp;
//修改下标
i++,j--;
}
}
一维指针数组
指针数组的定义: 数据类型*数组名[数组长度]; int* pa[3]; //定义一个指针数组,数组名是pa,可以用来存放3个指针(必须是int类型变量的指针); 指针数组的使用: int a=3,b=4,c=5; int *pa[3] ={&a,&b,&c}; pa[0] a的地址 pa 数组的首地址,又是变量a的地址 //使用数组名来访问 a的值 printf("%d\n",**pa); int a1[2][2]={1,2,3,4}; //定义了一个指针数组,赋值为a1[0]是第一行的指针
int *pa1[2]={a1[0],a1[1]};
printf("**pa1=%d\n",**pa1); //*pa1 取到的是指针数组pa1中首地址的值= a1[0]
//同时a1[0] = a1的首地址
*pa1 = a1[0] printf("&a1[0] = %d\n",a1[0]); printf("*pa1 = %d\n",*pa1); //正推
//所以 **pa1 即 *(*pa1)=*(*pa1[0])=*(a1)=*(a1[0])=*(&(a1[0][0]))=a1[0][0] =1;
//**(pa1+1)=*(*(pa1+1))=*(*pa1[1])=*(a1[1])=*(&(a1[1][0]))=a1[1][0]=3 //逆推
//所以想拿数字2的时候 就相当于
2=a1[0][1]=*(&a1[0][1])=*(&a1[0][0]+1)=*(a1[0]+1)=*(a1+1)=*(*pa1[0]+1)=*(*pa1+1)
//拿数字3
3=a1[1][1]=*(&a1[1][1])=*(&a1[1][0]+1)=*(a1[1]+1)=*(pa1[1]+1)=*(*(pa1+1)+1)
数组名访问二维数组
公式 *(*(a+i)+j) == a[i][j]
用普通指针访问二维数组
//这种写法虽然也可以获取到二维数组中的元素,但是这样写是不符合规范的,利用了内存存储的机制
数据在内存中存放的方式,从高地址依次向下存放
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int *p=a for(int i=0;i<12;i++){
printf(" %d \n",*(p+i));
}
二维数组指针
一般形式:
数据类型 (*指针变量名)[二维数组列数];
其中"类型说明符"为所指数组的数据类型. “*” 标示其后的变量是指针类型 如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组
p=a; //将该二维数组的首地址赋给p,也就是a[0]或 &a[0][0]
p++; //该语句执行过后,也就是p=p+1; p 跨过行a[0][] 指向行a[1][] 所以数组指针也称指向一维数组的指针 遍历二维数组的元素 int a[3][4]={1,3,4,5,6,7,8,9,10,13,15,17}; int (*p)[4]=a; 所以之前遍历中的 数组a 可以替换为 p :*(*(p+i)+j)
指针数组和二维数组指针变量的区别
int *pa[3]={&a,&b,&c}; pa是一个指针数组
int *pa1[2]={a[0],a[1]}
int (*pa)[3] ;//二维数组指针 应该注入指针数组和二维数组指针变量的区别,这两者虽然都可以用来标示二维数组,但其表示方法和意义是不同的
二维数组指针变量是单个的变量,其一般形式中(*指针变量名)两边的括号不可少,而指针数组类型表示的是多个指
针(一组有序指针)在一般形式中"*指针数组名"两边不能有括号.
例如:
int(*p)[3]; //表示一个指向二维数组的指针变量,该二维数组的列数为3或分解为一维数组的长度为3
int *p[3]; //表示p是一个指针数组,有三个下标变量p[0],p[1],p[2]均为指针变量
字符串指针
char *变量名 ="字符串内容" // "字符串内容"是常量
//当指向的为'' 单引号时,为字符指针 ""双引号时为字符串指针
字符串指针与字符数组的区别
//字符串指针 指向可以改变
char *ss="abc"; ss="bcd"; //字符数组
char s1[]="abc";
s1="hello" 这是错误的 可以改变里面的内容但是不能重新指向
指针函数
一个函数的返回值类型是指针,我们就称为指针函数
格式:
类型说明符 * 函数名( 形参表){
函数体
} 例:
//返回两个数中的大数的地址
//返回的是形参x 和 y 中大数的地址
int * max( int x,int y){
printf("x= %p\n",&x);
printf("y= %p\n",&y);
return x>y?&x:&y;
}
函数指针
函数指针
在C语言中,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。 我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数.然后通过指针变量就可以找到并调用这个函数.我们把这种指向函数的指针变量称为"函数指针变量" 函数指针定义方法:
函数指针变量定义的一般形式为:
类型说明符 (*指针变量名)(函数的参数);
其中"类型说明符" 表示被指函数的返回值的类型
"(* 指针变量名 )" 表示 "*" 后面的变量是定义的指针变量 函数的声明: int sum(int a,int b);----->函数指针 int (*p)(int a,int b); //定义了一个函数指针p
//p可以存放返回值是int类型, 并且有两个形参,形参的类型还都是int类型的函数的地址 //函数指针的初始化
p = sum;//sum存得就是函数在内存中的首地址 //定义函数指针的时候,可以不用写形参名
int (*p)(int int); 函数指针的使用 1.定义函数指针
int(*p) (int int);
2.给函数指针初始化
p=sum;
3.用函数指针间接的调用函数
int s=p(23,45); 函数指针的用处: 例如 + - x /时 ,只需要判断符号 ,然后 p = sum / p = jian 就可以
C语言中的指针的更多相关文章
- C语言中的指针数组
C语言中的指针数组是什么,像 char *a[]={"ddd","dsidd","lll"}; 这里讲一下注意如果我们使用了a也就是首元素的 ...
- 【ZZ】C 语言中的指针和内存泄漏 & 编写高效的C程序与C代码优化
C 语言中的指针和内存泄漏 http://www.ibm.com/developerworks/cn/aix/library/au-toughgame/ 本文讨论了几种在使用动态内存分配时可以避免的陷 ...
- GO语言中的指针
http://www.tizgrape.com/?p=100 Go语言中的指针语法和C++一脉相承,都是用*作为符号,虽然语法上接近,但是实际差异不小. Go使用var定义变量: var v6 *in ...
- C语言中的指针笔记
C语言指针 得到变量的地址 可以使用&运算符找到变量保存在内存中的位置 int x = 1; printf("x的内存地址是"%p\n",&x) %p格式 ...
- C语言中的指针加减偏移量
C语言指针偏移技巧(也是一个要注意的坑) - 陈杰柱的博客 - CSDN博客 https://blog.csdn.net/cjzjolly/article/details/82116772 C语言中 ...
- C 语言中的指针和内存泄漏
引言对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧 ...
- C语言中的指针和内存泄漏
引言 对于任何使用C语言的人,如果问他们C语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧,但是 ...
- C语言中的指针学习(小黑板)
指针是C语言中的精华所在,也是C语言的危险之在,今天又重现温习了一下C语言,做了一下总结. 欢迎批阅. (1)指针的含义指针的本质也是数据类型,它是指向地址的变量.例如: { int a = 10; ...
- [C]C语言中的指针和内存泄漏几种情况
引言 原文地址:http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html,转载请注明源地址. 对于任何使用C语言的人,如果问他们C语言的 ...
- 论C语言中二级指针和二维数组之间的区别
刚开始学习C语言的时候,觉得一个数组可以定义一个一级指针去访问,想当然的就觉得可以定义一个二级指针去访问二维数组.很显然这是错误的. 我们来看看C语言的数组在内存中的存储方式. 实际上C语言中的数组, ...
随机推荐
- 英文单词断行问题:CSS中word-break、word-wrap以及hyphens的兼容性和区别
CSS中一提到单词断行,最先映入脑海的肯定是word-break和word-wrap这两条属性.但对于这两条属性到底有什么区别,兼容性如何,我一直都概念模糊.今天抽空把它们以及CSS3中新加入的断行属 ...
- webstorm中关于vue的一些问题
在进行vue开发中,我使用了webstorm,但是过程坎坷艰辛,遇到了很多问题,我将问题和解决方案贴上,以作参考. 1.vue项目部署在webstorm中,第一个遇到的问题是,webstorm卡住了, ...
- 老李分享:robotium常用API 2
断言: 具体请查看官网 断言方法assert(robotium特有的断言方式,实际项目中和Junit的assert方法配合使用) void assertCurrentActivity (String ...
- 2 Java对象的创建过程
JAVA中创建对象直接new创建一个对象,对么对象的创建过程是怎样的呢? 程序运行过程中有许多的对象被创建出来.那么对象是如何创建的呢? 一 对象创建的步骤 1 遇到new指令时,检查这个指令的参数是 ...
- 30分钟掌握 C#7
1. out 变量(out variables) 以前我们使用out变量必须在使用前进行声明,C# 7.0 给我们提供了一种更简洁的语法 "使用时进行内联声明" .如下所示: va ...
- jquery template.js前端模板引擎
作为现代应用,ajax的大量使用,使得前端工程师们日常的开发少不了拼装模板,渲染模板 在刚有web的时候,前端与后端的交互,非常直白,浏览器端发出URL,后端返回一张拼好了的HTML串.浏览器对其进行 ...
- AES算法,DES算法,RSA算法JAVA实现
1 AES算法 1.1 算法描述 1.1.1 设计思想 Rijndael密码的设计力求满足以下3条标准: ① 抵抗所有已知的攻击. ② 在多个平台上速度快,编码紧凑. ③ 设计 ...
- 复杂SQL查询实例-5种普惠产品必须显示...
复杂SQL需求: 1.查询productCode in (1, 2, 4, 5, 7)五种 2.5种产品必须固定显示,优先显示procuct_status='1'在售产品,在售产品卖完则售罄产品顶上来 ...
- sublime-text-3设置输入中文方法
sublime-text-3 编辑器性感而敏捷,却让人感慨有其长必有其短. 有些缺点都可以通过插件解决.但是要解决输入中文问题却很复杂,不能输入中文实在是太痛苦了. 我在做一个有很多文字的html页面 ...
- kmp(看毛片)算法
别人的两篇博客. 传送门1 传送门2 其中T为主串,P为模式串. 其实就是在T中找P. 其中next数组存的是"部分匹配值". "部分匹配值"就是"前 ...