指针,c语言的灵魂
指针是一个值为内存地址的变量。

变量是一块内存空间,指针是变量,是用来存储内存地址的变量。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 9;
printf("num变量的地址为:%p\n",&num); // p表示指针占位符
return 0;
}

#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 9;
int * ptr_num = #
printf("num变量的地址为:%p\n",ptr_num); // p表示指针占位符
return 0;
}

根据地址,找到空间!然后操作空间!
变量地址也占用空间,只不过占用的不是内存空间,而是寄存器的存储空间。
内存地址实际上是一种偏移量,存储于段寄存器中。内存地址只是一种抽象,不是真正的物理内存地址,而是逻辑地址。由逻辑地址寻找到物理地址需要经过 逻辑地址->线性地址->物理地址 转换过程,而这些过程都是基于寄存器完成的。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 9;
int * ptr_num = #
* ptr_num = 10;
printf("* ptr_num的值为:%d\n",* ptr_num);
printf("num的值为:%d\n",num); // p表示指针占位符
return 0;
}
指针的类型,跟他所指向的数据结构有关。
基本类型的指针指向基本类型的数据结构。
比如:char * p; int *p; float *p; double *p;
分别指向的是char, int ,float, double 类型的变量。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num1 = 1024;
int num2 = 2048;
int * ptr1;
int * ptr2;
ptr1 = &num1;
ptr2 = &num2;
printf("num1的值是%d\tnum1的地址是:%p\n",num1,ptr1);
printf("num2的值是%d\tnum2的地址是:%p\n",num2,ptr2);
// 将变量1的值赋给变量2
num2 = num1;
printf("num1的值是%d\tnum1的地址是:%p\n",num1,ptr1);
printf("num2的值是%d\tnum2的地址是:%p\n",num2,ptr2);
*ptr2 = *ptr1; // 等价于 num2 = num1
printf("num1的值是%d\tnum1的地址是:%p\n",num1,ptr1);
printf("num2的值是%d\tnum2的地址是:%p\n",num2,ptr2);
// 地址变了,num1,num2不受影响
ptr2 = ptr1;
printf("num1的值是%d\tnum1的地址是:%p\n",num1,ptr1);
printf("num2的值是%d\tnum2的地址是:%p\n",num2,ptr2);
return 0;
}
一个变量就是一个内存空间,内存一定是有物理地址的!指针就是保存变量内存物理地址的变量!
指针与数组
数组是一个连续的内存空间,数组名就是它的首地址。
#include <stdio.h>
#include <stdlib.h>
int main()
{
double score[] = {98,87,65,43,76};
printf("数组的首地址:%p\t 数组手元素的地址 :%p\n",score,&score[0]);
}
数组名就是数组元素的首地址。

#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
double score[5] = {98,87,65,43,76};
double * ptr_score;
ptr_score = score;
for (i=0;i<5;i++) {
printf("%.2lf\n",*ptr_score++); // 通过首地址取找数组元素的值
}
for (i=0;i<5;i++) {
printf("%.2lf\n",score[i]);
}
}
等价的!double类型的数据,每个数据移动了8个字节。物理地址是一个十六进制的数字。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int array[] = {15,20,25,30,35};
int i;
int * ptr_array = array;
for (i = 0;i<5;i++) {
printf("第%d个元素的值为%d,地址为%p\n",i,*ptr_array,ptr_array);
ptr_array ++ ;
}
/*
第0个元素的值为15,地址为0028FF0C
第1个元素的值为20,地址为0028FF10
第2个元素的值为25,地址为0028FF14
第3个元素的值为30,地址为0028FF18
第4个元素的值为35,地址为0028FF1C
*/
return 0;
}
int型地址间隔4个字节。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 7
int main()
{
int array[N] = {15,20,25,30,35,40,90};
int i;
int temp;
// 实现数组的逆序
// 数组的首尾元素进行交换
for (i = 0;i<floor(N/2);i++) {
temp = array[i];
array[i] = array[N-i-1];
array[N-i-1] = temp;
}
for (i = 0;i<N;i++) {
printf("交换后第%d元素的值为:%d\n",i,*(array + i));
}
return 0;
}
逆序数组,找规律是写程序必备的技能!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 7
int main()
{
int array[N] = {15,20,25,30,35,40,90};
int i;
int temp;
int * ptr_head;
int * ptr_foot;
ptr_head = &array[0];
ptr_foot = &array[N-1];
// 实现数组的逆序
// 数组的首尾元素进行交换
for (i = 0;i<floor(N/2);i++) {
temp = * ptr_head;
* ptr_head = * ptr_foot;
* ptr_foot = temp;
ptr_head ++;
ptr_foot --;
}
for (i = 0;i<N;i++) {
printf("交换后第%d元素的值为:%d\n",i,*(array + i));
}
return 0;
}
指针实现数组逆序!
二维数组与指针
首地址
&a[0][0]
有祥有略!有精有简!有的放矢有的取舍去学习!
何为二维数组,如何理解?由n个一维数组组成!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int i,j;
double score[5][3] = {
{55,56,57},
{58,59,60},
{61,62,63},
{64,65,66},
{67,68,69}
};
// 传统的访问方式
for (i = 0;i < 5;i++) {
for (j = 0;j <3 ;j++) {
printf("%.2lf\t",score[i][j]);
}
printf("\n");
}
printf("=================================\n");
// 指针的方式访问
for (i = 0;i < 5;i++) {
for (j = 0;j <3 ;j++) {
// printf("%.2lf\t",*(score[i] + j));
printf("%.2lf\t",*(*(score+i) + j));
}
printf("\n");
}
return 0;
}
*(*(score + i) + j) 获取二维数组的公式!
老九语录,会赋值,会打印就差不多了!多练习练习再做个小项目就可以了!
指针,c语言的灵魂的更多相关文章
- C语言的灵魂——指针基础
一.什么是指针 1.指针的定义:地址形象化为指针,通过指针能够找到内存单元. 指针变量就是地址变量,变量的值为指针. 指针其实是我们将变量名和地址的关系显化(独立)出来的一种形式,是为了我们更加方便的 ...
- C语言之灵魂 指针学习
指针是c语言的难点 称之为c语言的灵魂一点也不为过,不过指针用好了能事半功倍,用不好bug满天飞. 一.指针的概念 指针也是变量只不过是特殊的变量,指针的值是另一个变量的地(也就是变量所在的内存地址) ...
- 二维数组和指针(C语言)
二维数组和指针 二维数组和指针1.二维数组和数组元素的地址若有以下定义:int *p, a[3][4]; 1)二维数组a由若干个一维数组组成在C语言中定义的二维数组实际上是一个一维数组,这个一维数组的 ...
- C指针——C语言手记
近期敲代码的时候.发现自己非常多东西都開始忘了. 今天最终有机会好好总结一下指针.当做个笔记同一时候也希望对大家实用.假设有不对的地方.希望大家能帮我指正一下.然后我的实验环境是32位RHEL+ecl ...
- C++基础 (8) 第八天 数组指针 模板指针 C语言中的多态 模板函数
1昨日回顾 2 多态的练习-圆的图形 3多态的练习-程序员薪资 4员工管理案例-抽象类和技术员工的实现 employee.h: employee.cpp: technician.h: technici ...
- 指针C语言
一.PTA实验作业 题目一:6-7输出月份英文名 1.PTA提交列表 2.设计思路和流程图 这题只需补充子函数,定义指针数组month[12],分别从一月到十二月,再定义一个字符,让它为NULL,当输 ...
- 原型模式 -- JavaScript语言的灵魂
原型模式就是将原型对象指向创建对象的类,使这些类共享原型对象的方法与属性.JS是基于原型链实现对象之间的继承,是对属性或者方法的共享,而不是对属性和方法的复制. // 图片轮播类 var LoopIm ...
- C语言入门编程需要掌握的核心要点有哪些? 为你总结了这20个!
摘要: C语言作为编程的入门语言,学习者如何快速掌握其核心知识点,面对茫茫书海,似乎有点迷茫.为了让各位快速地掌握C语言的知识内容,在这里对相关的知识点进行了归纳. 引言 C语言精简的语法集和标准库, ...
- 浅谈c语言的指针
对于非计算机专业的同学,c语言的指针往往就是老师的一句“指针不考“就带过了.c语言的指针号称是c语言的灵魂,是c语言中最精妙的部分. 指针本质上也是变量,也就是一段内存,只是他的特殊之处是他存储的数据 ...
随机推荐
- BZOJ 4756 线段树合并(线段树)
思路: 1.最裸的线段树合并 2. 我们可以观察到子树求一个东西 那我们直接DFS序好了 入队的时候统计一下有多少比他大的 出的时候统计一下 减一下 搞定~ 线段树合并代码: //By SiriusR ...
- Android View事件分发与传递
在Android中,人们主要通过手指与系统交互.Android把所有的touch事件都被封装成MotionEvent来进行处理,其中包括了手指点击的位置,时间等信息.其事件类型主要包括:ACTION_ ...
- 重温前端基础之-css浮动与清除浮动
文档流的概念指什么?有哪种方式可以让元素脱离文档流? 文档流,指的是元素排版布局过程中,元素会自动从左往右,从上往下的流式排列.并最终窗体自上而下分成一行行,并在每行中按从左到右的顺序排放元素.脱离文 ...
- CSS——清除浮动的六种解决方案
内容的高度撑起父元素容器的高度,效果图如下 HTML和CSS代码如下 给p标签加上浮动以后,p{float:left:},此时DIV塌陷,两段内容同行显示,效果如下: 解决方案一:给前面一个父元素设置 ...
- Hibernate中解决No Hibernate Session bound to thread问题
引用:忘了 首先是getCurrentSession()与openSession()的区别: 1.getCurrentSession()与openSession()的区别? * 采用getCurren ...
- ASP.NET CORE读取appsettings.json的配置
如何在appsettings.json配置应用程序设置,微软给出的方法:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/config ...
- js手机网络检测
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset=UTF-8"> ...
- Junit使用第二弹
实例总结 1. 参数化测试 有时一个测试方法,不同的参数值会产生不同的结果,那么我们为了测试全面,会把多个参数值都写出来并一一断言测试,这样有时难免费时费力,这是我们便可以采用参数化测试来解决这个问题 ...
- Windows2012R2 时间同步设置
Windows2012R2里没有了internet时间,或者Internet时间无法同步成功,都可以尝试使用如下方法. 1.打开命令提示符, 输入:gpedit.msc,打开组策略管理器 2.执行上述 ...
- 『转』The Beginning of your Design Career
想想,如果明天我开始学日语,坚持到毕业,其实也可以日语入门了.所以机会都是抓住,当初,也就是去年的时候,我那个时候就开始坚持日语入门,想想现在应该可以开始N2了吧-所以...过去不去理会,现在开始继续 ...