语法复习之C语言与指针

内存是如何存储数据的?

  在C语言中定义一个变量后,系统就会为其分配内存空间。这个内存空间包括了地址和长度。将变量赋值后,该值就被写入到了指定的内存空间中。内存空间的大小一般以字节作为基本单位。
  普通变量存放的是数据,指针变量存放的是地址。

int a = 10 ; //定义了一个整型变量
int *a ;//定义一个指向整型的指针变量

  为什么指针要有数据类型?因为在定义指针的时候,不光要定义指针的起始地址,还要定义指针的地址长度,方便分配内存空间。而指针变量的数据类型就是内存空间长度。
              在这里插入图片描述
由图可以看到地址和数据一一对应。

取地址运算符和取值运算符

//如果要获取某个变量的地址,可以使用取地址运算符&
char *pa = &a;   //将字符串类型的变量a的地址赋值给字符串指针变量pa
int *pb = &f; 	//将整型类型的变量f的地址赋值给整型变量指针pb//如果要访问指针变量指向的数据,可以使用取值运算符 *
int *a = 0x100000000//定义一个整型指针变量a,该指针指向的地址为0x10000000
b = *a ;   //将a指针指向的内存空间中0x10000000的值赋值给b
printf("%c, &d\n\r",*pa, *pb);

直接访问和间接访问

  通过指针变量来访问内存中的数据被称为直接访问
  通过定义变量并访问内存中的数据被称为间接访问

//间接访问
char *p_ptr = 0x10000000;
char p;
p = *p_ptr;
//直接访问
char p = 'a';

使用指针的注意事项

//避免访问未初始化的指针,因为不知道该指针指向何处。语法上正确,但是会产生未知错误。
int *a;
*a = 123;

数组与指针

数组与指针的基本关系

  数组名就是指针的首地址,也是数组第一个元素的地址。数组的下标代表的是指针的偏移,偏移量就是数组内存放的数据类型所占的字节数乘以下标。
  如果想用指针来指向数组,则可以直接用数组名赋值,或者用数组的第一个元素取地址。但是数组名和指针变量有区别。数组名属于右值,不可改变,但指针变量属于左值,可以改变。假如a是一个数组名。a++为错误写法。但是p=a;p++;是可以的。
  当指针变量p指向数组的第一个变量时,指针变量p+1则指向数组的第二个元素

#include<stdio.h>
int main(){char a[] = "FishC";int b[5] = {1,2,3,4,5};float c[5] = {1.1,1.2,1.3,1.4,1.5};double d[5] = {1.1,2.2,3.3,4.4,5.5};printf("*****************************************\n");printf("a[0] -> %p, a[1] -> %p, a[2] -> %p\n",&a[0], &a[1], &a[2]);printf("b[0] -> %p, b[1] -> %p, b[2] -> %p\n",&b[0], &b[1], &b[2]);printf("c[0] -> %p, c[1] -> %p, c[2] -> %p\n",&c[0], &c[1], &c[2]);printf("d[0] -> %p, d[1] -> %p, d[2] -> %p\n",&d[0], &d[1], &d[2]);printf("*****************************************\n");int *p;p = b;printf("p=b赋值时 p -> %p,\n",p);p = &b[0];printf("p = &b[0]赋值时 p -> %p,\n",p);printf("*****************************************\n");printf("*p = %d, *(p+1) = %d, *(p+2) -> %d\n",*p, *(p+1), *(p+2));printf("*****************************************\n");return 0 ;
}

输出结果为

*****************************************
a[0] -> 0x7ffd2fdaaa30, a[1] -> 0x7ffd2fdaaa31, a[2] -> 0x7ffd2fdaaa32
b[0] -> 0x7ffd2fdaa9c0, b[1] -> 0x7ffd2fdaa9c4, b[2] -> 0x7ffd2fdaa9c8
c[0] -> 0x7ffd2fdaa9e0, c[1] -> 0x7ffd2fdaa9e4, c[2] -> 0x7ffd2fdaa9e8
d[0] -> 0x7ffd2fdaaa00, d[1] -> 0x7ffd2fdaaa08, d[2] -> 0x7ffd2fdaaa10
*****************************************
p=b赋值时 p -> 0x7ffd2fdaa9c0,
p = &b[0]赋值时 p -> 0x7ffd2fdaa9c0,
*****************************************
*p = 1, *(p+1) = 2, *(p+2) -> 3
*****************************************

指针数组与数组指针

  指针数组是数组,数组指针是指针。
  指针数组是存放了多个指针的数组。数组指针是指向一整个数组的指针,并不是指向数组第一个元素的指针。虽然他们取值相同,但并不等价,因为他们存储数据的长度不同。

指针数组

int *p1[5];

  首先从优先级开始分析,[]符号的优先级大于* ,所以优先看p1[5],这是一个数组,里面包含五个元素。后面看*,这是一个指针变量,所以p1[5]里面存放了五个指针变量,最后看int,表明了指针变量的存放的数据类型是int类型。结合起来就是定义了一个数组,数组的元素指针,指针指向的地址中存放的数据类型是int类型。

int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int *p1[5] = {&a,&b,&c,&d,&e};

  指针数组的实际用法

#include<stdio.h>
int main(){char *p1[5] = {"char *a =\"hello\"代表的是一个字符串","所以上一句中的a代表的是字符串的首地址","char *p1[5]中的p1[5]存放了五个字符串的首地址","%s代表用字符串的首地址来打印字符串","所以%s中可以用p1[i]可以打印出字符串"};for(int i = 0; i < 5 ;i++){printf("%s\n",p1[i]);}return 0 ;
}

输出结果:

char *a ="hello"代表的是一个字符串
所以上一句中的a代表的是字符串的首地址
char *p1[5]中的p1[5]存放了五个字符串的首地址
%s代表用字符串的首地址来打印字符串
所以%s中可以用p1[i]可以打印出字符串

数组指针

int (*p2)[5]

  也是从优先级开始分析,括号里面的优先级最高,所以p2被定义成了一个指针,指向了一个含有五个元素的数组。指针的类型就是他指向的数据类型,int定义的就是数组元素的类型。所以这个数组指针的含义是定义了一个数组指针p2,指针指向了含有五个整型元素的数组。

#include<stdio.h>
int main(){int temp[5] = {1,2,3,4,5};  //  这是一个数组,temp是数组名。int (*p2)[5] = &temp;       //定义一个整形数组指针p2,p2指向数组temp本身 p2 = &tempint i;for(i=0;i<5;i++){printf("%d\n",*(*p2 + i));  //p2指向数组本身 p2 = &temp  *p2 = temp  所以*(*p2 + i) = *(temp + i)  即可遍历数组元素}return 0;
}

输出结果

1
2
3
4
5

函数与指针

  有些函数需要传递参数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/151378.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ROS入门】雷达、摄像头及kinect信息仿真以及显示

文章结构 雷达信息仿真以及显示Gazebo仿真雷达配置雷达传感器信息xacro文件集成启动仿真环境 Rviz显示雷达数据 摄像头信息仿真以及显示Gazebo仿真摄像头新建xacro文件&#xff0c;配置摄像头传感器信息xacro文件集成启动仿真环境 Rviz显示摄像头数据 kinect信息仿真以及显示Ga…

Python算法练习 10.28

leetcode 700 二叉搜索树中的搜索 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 示例 1: 输入&#xff1a;root [4,2,7,1,…

视频转换器WinX HD Video Converter mac中文特点介绍

WinX HD Video Converter mac是一款功能强大的视频转换器&#xff0c;它可以将各种不同格式的视频文件转换为其他视频格式&#xff0c;以便用户在各种设备上进行播放。WinX HD Video Converter是一个功能强大、易于使用的视频转换器&#xff0c;适用于各种类型的用户&#xff0…

WordPress主题模板 大前端D8 5.1版本完整开源版源码简洁大气多功能配置

源码测评&#xff1a;该模板官方已更新至5.2&#xff0c;但是这个5.1也是非常好用的&#xff0c;经测试所有页面均完好&#xff0c;推荐下载使用。 模板简介&#xff1a; 大前端D8 主题是一款非常牛逼的WordPress博客主题,响应式,功能齐全,支持手机,电脑,平板,非常适合做博客站…

css实现圆形进度条

能用现成组件就用&#xff0c;实现不行再自己写&#xff0c;因为牵扯到上传文件&#xff0c;进度实时出不来&#xff0c;所以只能使用dom元素操作&#xff1b; 1.实现 效果&#xff1a; 上图是100%&#xff0c;如果需要根据百分比显示&#xff0c;我们需要看下代码里面left和…

postgis ST_ClipByBox2D用法

官方文档 概述 geometry ST_ClipByBox2D(geometry geom, box2d box); 描述 以快速且宽松但可能无效的方式通过 2D 框剪切几何体。 拓扑上无效的输入几何图形不会导致抛出异常。 不保证输出几何图形有效&#xff08;特别是&#xff0c;可能会引入多边形的自相交&#xff09;…

STM32 ADC数模转换器

STM32 ADC数模转换器 ADC简介 ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 STM32主要是数字电路&#xff0c;数字电路只有高低电平&#xf…

【Linux】rpm和yum的使用

不知道是不是有和我一样的宝子们&#xff0c;在rpm上卡了老久老久&#xff0c;但其实搞通了&#xff0c;理解了原理之后&#xff0c;不难的&#xff0c;所以不管你现在遇到的困难是什么&#xff0c;都不要放弃&#xff0c;一定要坚持&#xff0c;加油。 一、rpm 1.rpm rpm的…

[ubuntu系统下的文本编辑器nano,vim,gedit,文件使用,以及版本更新问题]

文本编辑器概要 在Ubuntu系统下&#xff0c;有许多文本编辑器可供选择&#xff0c;每个编辑器都有其独特的特性和用途。以下是一些常见的文本编辑器&#xff1a; Gedit&#xff1a; 这是Ubuntu默认的文本编辑器&#xff0c;它简单易用&#xff0c;适合基本的文本编辑任务。 安…

考虑温度影响的vumat子程序在木材受火后强度分析中的应用

木结构在火灾作用下&#xff0c;木材的化学成分及物理特性会发生复杂的变化&#xff0c;导致其力学性能的改变&#xff0c;木构件承载能力降低。本文编写了考虑温度影响的木材本构vumat子程序&#xff0c;并对子程序的正确性进行了验证。 木材是一种复杂的各向异性复合材料&am…

github搜索技巧探索

毕设涉及到推荐系统&#xff0c;那么就用搜索推荐系统相关资料来探索一下GitHub的搜搜技巧 文章目录 1. 基础搜索2. 限定在特定仓库搜索3. 按照语言搜索4. 按照star数量搜索5. 搜索特定用户/组织的仓库6. 查找特定文件或路径7. 按时间搜索8. 搜索不包含某个词的仓库9. 搜索特定…

WebDAV之π-Disk派盘 + 言叶

言叶是一个功能丰富的笔记软件,为跨平台而设计,可以为你在手机、电脑和其他设备中实现多端同步。从而实现高效率的记事和办公。支持Markdown的语言和多种计算机语法高亮功能,让你笔记中的内容更加主次分明,可以在这里记录一些代码什么的。同时还可以在笔记中插入图片,使其…