Linux C语言(8)

1、指针

1.1 概念

 指针就是地址
 指针是一种数据类型,是一种保存地址的数据类型
 int是一种数据类型,是一种保存整数的数据类型 1 2 3 4
 float是一种数据类型,是一种保存浮点数的数据类型 3.14

1.2 什么是地址

 内存分配的最小单位是字节,每一个字节都有一个编号,我们把整个编号就叫做地址
 ​
 地址的本质:内存单元的编号
 ​
 指针:指针就是地址
 ​
 指针的本质:内存单元的编号

1.3 什么是指针变量

 int a;
 ​
 float b;
 ​
 指针变量:专门原来保存地址(内存单元的编号)的变量

1.4 定义

 存储类型 数据类型 *指针变量名;
 int * p;
 数据类型表示本指针变量所指向的变量的数据类型
 存储类型表示本指针变量所指向的变量的存储类型
 指针变量名是*后面的内容,*只是说明定义的是一个指针变量
 只能指向相同数据类型的变量
 int * p;
 存储类型:auto、static、extern、register
 数据类型:指针所执行的数据类型 //int
 指针数据类型(去掉指针变量名):数据类型 *  //int*  
 *在c语言中有3种用法:
 1、作为双目运算符,表示乘法 3*4
 2、在定义变量的时候使用,表示指针这种数据类型
 3、作为单目运算符,表示取值  *p(取指定变量p所存储的地址)    通过指针间接访问指针所指向的对象
 在C语言中,变量的地址是由编译系统分配的,用户不知道变量的具体位置。C语言中提供了地址运算符“&”来表示变量的地址,其一遍形式为    &变量名;   
 int i,*p;
 p = &a;

注意

 1、指针的指向是可以改变的
 2、给指针赋值时,要注意数据类型的匹配
 &是取地址运算符 *(地址)是取值运算符
 3、&和*互为逆运算,可以相互抵消,正和负的关系
 4、&为引用,*为解引用

在32OS系统中,所有的指针都占4个字节

在64OS系统中,所有的指针都占8个字节

思考

 1、什么是指针
     指针是一种数据类型,是一种保存地址的数据类型(内存单元的编号)
 2、什么是地址
     内存单元的编号
 3、什么是指针变量
     专门用来保存指针的变量
 4、如何定义一个指针变量
     存储类型 数据类型 * 指针变量名
 5、如果给指针变量赋值
     p = &a
 6、赋值之后可以做什么呢
     修改、操作变量a

2、空指针

空指针:int * p = NULL;

没有指向的指针(值为0的指针,就认为该指针没有指向)

注意:0号地址禁止操作(一旦操作会出现段错误//Segmentation fault (core dumped))非法访问内存空间。

要操作必须改变空指针的指向

3、野指针

int * p;

不知道指向哪里的指针

局部变量没有初始化的时候,其值为随机值

局部指针变量没有初始化,就成了野指针

空指针操作不会出问题,野指针操作可能会出问题(随机值)//不清楚具体指向,修改取值会报错

如何避免野指针的出现?初始化为NULL

4、gdb的调试

Linux中调试使用调试器gdb

编辑器:vim
编译器:gcc
调试器:gdb

调试步骤

(1)编译程序的时候添加 "-g"参数
gcc -g error.c -o error
(2)启动gdb调试器
gdb 可执行文件的名字 (gdb error)
(3)设置断点
b main
b 行号
(4)运行
r
(5)其它参数
n(next):下一步,不进入子函数
s(step):下一步,进入子函数
p(printf) a(要打印的值)
c(continue):可以直接跳出循环,执行下一步
q(quit):退出

5、值传递

编写一子函数,实现两个数的交换

值传递:以下类型变量作为函数参数传递,包括基本数据类型变量(例如int、char、double等)、结构体类型变量。被调函数中对形参值的修改,不影响主调函数中的实参值。

值传递:类似物体的克隆,被调函数操作克隆的物体,主调函数操作源物体。本质是形参的地址空间与实参的地址空间不同。

6、地址传递

include <stdio.h>

void swp(int * m, int * n);

int main(void)
{
        int a = 1;
        int b = 2;
        swp(&a,&b);
        printf("%d\n",a);
        printf("%d\n",b);
        return 0;
}
void swp(int * m, int * n)
{
        int tmp =0;
        tmp = *m;
        *m = *n;
        *n = tmp;
}

地址传递:以下类型变量作为函数参数传递,包括数组名、指针或地址。被调函数中对形参值的修改,会影响主调函数中的实参值。

地址传递:类似物体的移动,两个函数先后操作同一个物体。本质是形参的地址空间与实参的地址空间相同。

7、const修饰的指针

const:只读

用来修饰变量,使用const修饰的变量只能读,不能被修改(未修改存储位置,仍在栈区)

int a = 10;//存放在栈区
const int a = 10;//

判断const修饰的变量是否在常量区

const修饰的指针:

指针变量:
(1)指针常量: 指针的指向不能发生改变
int * const p = NULL;//值可改,指向不可改
(2)常量指针: 指针所指向的内容不能被修改
int const *p = NULL;//指向可改,值不可改
(3)值和指向都不能修改
const int * const p = NULL;//值和指向都不能被修改 

8、二级指针

8.1 概念

二级指针:指针的指针

二级指针的内存空间存放的是一级指针变量的地址

8.2 定义

一级指针: 存储类型 数据类型 *指针变量名;
数据类型:指针所指向的数据类型
一级指针:列指针,*一级指针:取值
二级指针:行指针,*二级指针:变为一级指针(列指针、一维数组名)
二级指针的定义:
存储类型 数据类型 **指针变量名;
二级指针的数据类型:数据类型 **
p = &a;
pp = &p;
pp = &&a;//不能对a的地址常量取地址

案例

(1).若有语句int *point, a=4;point=&a;下面均代表a的地址的一组选项是(D)
    A. a, point,*&a B. &*a, &a,*point
    C. &point, *&point, &a D. &a, &*point, point
(2).已有定义int k=2; int*ptr1,*ptr2;且ptr1和ptr2均已指向变量k,下面不能正确执行赋值语句的
是(B)
    A. k=*ptr1+*ptr2; B.ptr2=k;
    C.ptr1=ptr2; D. k=*ptr1*(*ptr2);

总结

1、指针指向的数据类型就是将变量名和*(一个)去掉,剩下的就是指针所指向的数据类型
    int *p; // int
    int **p; //int *
    int ***p;//int **
2、指针的数据类型就是就变量名去掉,剩下的就是数据类型
    int *p;//int *
    int **p;//int **
    int ***p;//int ***
3、*p所能访问的空间大小,有p指向的数据类型来决定
    char *p;//*p所能访问的内存空间的大小为1byte
    int *p;//*p所能访问的内存空间的大小为4byte
    int **p;//**p所能访问的空间的大小为4byte

作业

int a[5] = {0};
1-------数组的输入
2-------数组的输出
3-------求数组中的次大值
4-------排序
-1 -----exit

#include <stdio.h>
#define N 5
#include <stdlib.h>

void menu();
void input();
void output();
void sub();
void swap();
void quit();

int main(void)
{
        int fun = 0;
        int a[N] = {0};
        while(1)
        {
                menu();
                printf("请选择功能");
                scanf("%d",&fun);
                switch(fun)
                {
                        case 1:
                                input(a);
                                break;
                        case 2:
                                output(a);
                                break;
                        case 3:
                                sub(a);
                                break;
                        case 4:
                                swap(a);
                                break;
                        case -1:
                                quit();
                }
        }

        return 0;
}
void menu()
{
        printf("功能菜单\n");
        printf("1-数组的输入\n");
        printf("2-数组的输出\n");
        printf("3-求数组中的次大值\n");
        printf("4-排序\n");
        printf("-1-exit\n");
}
//输入
void input(int * a)
{
        for(int i = 0; i <N; i++)
        {
                scanf("%d",&a[i]);
        }
}
//输出
void output(int * a)
{
        for(int i = 0; i <N; i++)
        {
                printf("%d\n",a[i]);
        }
}
//次大值
void sub(int * a)
{
        int i,max,mid;
        for(i = 0;i<5;i++)
        {
                if(a[i]>max)
                {
                        mid = max;
                        max =a[i];
                }
        else if(a[i]>mid&&a[i]<max)
        {
                //另一种情况 arr[i]在两者之间*/
                mid = a[i];
                // 把arr[i]赋给mid
                }
        }
        printf("次大值:%d\n",mid);

}
//排序
void swap(int * a)
{
        int i,j,tmp = 0;
        for(i=1;i<N;i++)
        {
                for(j=0;j<N-i;j++)
                {
                        if(a[j]>a[j+1])
                        {
                                tmp=a[j];
                                a[j]=a[j+1];
                                a[j+1]=tmp;
                        }
                }
        }
}
//退出
void quit()
{
        exit(0);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Leetcode】【数据结构】【C语言】判断两个链表是否相交并返回交点地址

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode *tailAheadA;struct ListNode *tailBheadB;int count10;int count20;//分别找尾节点&#xff0c;并顺便统计节点数量&#xff1a;while(tailA){tailAtailA->next;c…

flutter开发报错The instance member ‘widget‘ can‘t be accessed in an initializer

文章目录 问题描述问题原因解决方法 问题描述 The instance member ‘widget’ can’t be accessed in an initializer. 问题原因 “The instance member ‘widget’ can’t be accessed in an initializer” 错误是因为在初始化器列表中&#xff08;constructor initializer…

Shell 脚本介绍及应用案例

目录 Shell传递参数 $特殊符号含义 示例&#xff1a; Shell运算符 关系运算符 文件运算符 示例&#xff1a; Shell 流程控制 if判断 格式&#xff1a; 示例&#xff1a; 结果&#xff1a; for循环 格式&#xff1a; 示例&#xff1a; 结果&#xff1a; w…

Webpack 中 Plugin 的作用是什么?常用 plugin 有哪些?

说说webpack中常见的Plugin&#xff1f;解决了什么问题&#xff1f;- 题目详情 - 前端面试题宝典 1、plugin 的作用 Plugin 是一种计算机应用程序&#xff0c;它和主应用程序互相交互&#xff0c;以提供特定的功能。 是一种遵循一定规范的应用程序接口编写出来的程序&#…

如何上传自己的Jar到Maven中央仓库

在项目开发过程中&#xff0c;我们常常会使用 Maven 从仓库拉取开源的第三方 Jar 包。本文将带领大家将自己写好的代码或开源项目发布到 Maven中央仓库中&#xff0c;让其他人可以直接依赖你的 Jar 包&#xff0c;而不需要先下载你的代码后 install 到本地。 注册帐号 点击以…

【MySQL篇】数据库角色

前言 数据库角色是被命名的一组与数据库操作相关的权限&#xff0c;角色是权限的集合。因此&#xff0c;可以为一组具有相同权限的用户创建一个角色&#xff0c;使用角色来管理数据库权限可以简化授权的过程。 CREATE ROLE&#xff1a;创建一个角色 GRANT&#xff1a;给角色授…

进程(3)——进程优先级与环境变量【Linux】

进程&#xff08;3&#xff09;——进程优先级与环境变量【Linux】 一. 进程如何在cpu中如何执行1.1进程在CPU中的特性1.2 寄存器1.2.1 进程的上下文 二. 进程优先级2.1 如何查看进程优先级2.2 修改进程的优先级2.2.1 NI值2.2.2 修改方法 三. 环境变量3.1 什么是环境变量&#…

华为ICT——第六章:深度学习和卷积神经网络/详篇

目录 1&#xff1a;深度学习卷积的重要概念&#xff1a; 2&#xff1a;CNN核心思想——局部感知&#xff1a; CNN核心思想——参数共享&#xff1a; 3&#xff1a;卷积层的功能&#xff1a; 4&#xff1a;不同深度的卷积层提取的特征&#xff1a; 5&#xff1a;卷积效果——…

【公益案例展】火山引擎公益电子票据服务——连接善意,共创美好

‍ 火山引擎公益案例 本项目案例由火山引擎投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2023中国数据智能产业最具社会责任感企业》榜单/奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 捐赠票据是慈善组织接受捐赠后给捐赠方开具的重要凭证&…

saleae逻辑分析仪在win10上的安装: 驱动安装失败的解决办法

1. 安装 安装64位的&#xff1a;Logic Setup 1.1.16 (64-bit).exe 选择安装目录&#xff1a; 安装其间&#xff0c;如果弹出驱动安装对话框&#xff0c;要选择信任并安装驱动。 安装结束&#xff0c;打开软件&#xff0c;是未连接的状态。 此时打开电脑的设备管理器&#xff…

程序员男盆友给自己做了一款增进感情的小程序

前言 又是无聊的一天&#xff0c;逛GitHub的时候发现一个给女朋友做了一个互动微信小程序&#xff0c;据说女朋友更爱自己了&#xff0c;所以当晚。。。。给自己做了丰盛的晚餐&#xff0c;我当即点开立马开发粘贴复制起来&#xff0c;想到做的小程序可以和未来的女朋友增进感…

基于React开发的chatgpt网页版(仿chatgpt)

在浏览github的时候发现了一个好玩的项目本项目&#xff0c;是github大神Yidadaa开发的chatgpt网页版&#xff0c;该开源项目是跨平台的&#xff0c;Web / PWA / Linux / Win / MacOS都可以访问。非常有意思&#xff0c;本人就部署了一套&#xff0c;喜欢的同学可以体验一番。 …

快速教程|如何在 AWS EC2上使用 Walrus 部署 GitLab

Walrus 是一款基于平台工程理念的开源应用管理平台&#xff0c;致力于解决应用交付领域的深切痛点。借助 Walrus 将云原生的能力和最佳实践扩展到非容器化环境&#xff0c;并支持任意应用形态统一编排部署&#xff0c;降低使用基础设施的复杂度&#xff0c;为研发和运维团队提供…

干货 | 接口自动化测试分层设计与实践总结

接口测试三要素&#xff1a; 参数构造 发起请求&#xff0c;获取响应 校验结果 一、原始状态 当我们的用例没有进行分层设计的时候&#xff0c;只能算是一个“苗条式”的脚本。以一个后台创建商品活动的场景为例&#xff0c;大概流程是这样的(默认已经是登录状态下)&#…

FMCW雷达论文速览 | TRS 2023, 基于FMCW雷达的多天线高精度测距算法及性能分析

注1:本文系“最新论文速览”系列之一,致力于简洁清晰地介绍、解读最新的顶会/顶刊论文 TRS 2023 | High Accuracy Multi-antenna Ranging Algorithm and Performance Analysis for FMCW Radar 论文原文:https://ieeexplore.ieee.org/document/10309162 Z. Xu, S. Qi and P. Zh…

webgoat-(A1)SQL Injection

SQL Injection (intro) SQL 命令主要分为三类&#xff1a; 数据操作语言 &#xff08;DML&#xff09;DML 语句可用于请求记录 &#xff08;SELECT&#xff09;、添加记录 &#xff08;INSERT&#xff09;、删除记录 &#xff08;DELETE&#xff09; 和修改现有记录 &#xff…

springboot本地启动多个模块报错:Address already in use: JVM_Bind

目录 背景解决方法 背景 环境&#xff1a; jdk1.8 idea 2019.2.4idea本地启动多个模块联调时&#xff0c;提示报错&#xff1a; 错误: 代理抛出异常错误: java.rmi.server.ExportException: Port already in use: 9090; nested exception is: java.net.BindException: Addre…

SpringBoot系列之集成Redission入门与实践教程

Redisson是一款基于java开发的开源项目&#xff0c;提供了很多企业级实践&#xff0c;比如分布式锁、消息队列、异步执行等功能。本文基于Springboot2版本集成redisson-spring-boot-starter实现redisson的基本应用 软件环境&#xff1a; JDK 1.8 SpringBoot 2.2.1 Maven 3.2…

【算法-链表2】反转链表 和 两两交换链表节点

今天&#xff0c;带来链表相关算法的讲解。文中不足错漏之处望请斧正&#xff01; 理论基础点这里 反转链表 1. 思路 链表操作的本质是修改连接关系&#xff0c;本题我们需要反转链表&#xff0c;也就是每次都让当前节点的next指向自己的上一个。而题目给的是单链表&#xf…

【React-Native开发3D应用】React Native加载GLB格式3D模型并打包至Android手机端

【React-Native开发3D应用】React Native加载GLB格式3D模型并打包至Android手机端 【加载3D模型】**React Native上如何加载glb格式的模型**第零步&#xff0c;选择相关模型第一步&#xff0c;导入相关模型加载库第二步&#xff0c;自定义GLB模型加载钩子第三步&#xff0c;借助…
最新文章