kotlin做网站/百度竞价代运营托管
目录
前言:
指针详解
前言:
1.CSDN由于我的排版不怎么好看,我的有道云笔记比较美观,请移步有道云笔记
2.修炼必备
1)入门必备:VS2019社区版,下载地址:Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本 (microsoft.com)
2)趁手武器:印象笔记/有道云笔记
3)修炼秘籍:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
4)雷劫必备:leetcode 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
注:遇到瓶颈怎么办?百度百科_全球领先的中文百科全书 (baidu.com)
指针详解
——指针是C语言中最核心的部分,不了解指针,就掌握不了C语言的精髓
1.指针是什么?
1)指针是内存中一个最小单元的编号,即指针就是地址
2)指针变量是用来存放内存地址的变量
图解:
2.我们如何取出变量的地址?
——使用&符号取出变量的地址,使用相应数据类型的指针变量保存该地址
#include <stdio.h>int main()
{int num = 10;int* p = #//取出了num的地址赋给了p//打印查看地址printf("&num = %p\n", &num);printf("p = %p\n", p);return 0;
}
运行结果:
3.指针的大小
——32位平台下的指针大小是4个字节,64位的平台下指针的大小是8个字节
#include <stdio.h>int main()
{printf("%d\n", sizeof(char*));printf("%d\n", sizeof(short*));printf("%d\n", sizeof(int*));printf("%d\n", sizeof(long*));printf("%d\n", sizeof(long long*));printf("%d\n", sizeof(float*));printf("%d\n", sizeof(double*));return 0;
}
32位平台运行结果:
64位平台运行结果:
4.指针和指针类型
1)指针的定义的方式
a.指针的定义方式:数据类型*;
char*:字符指针
int*:整型指针
long long*:长长整型指针
float*:单精度指针
double*:双精度指针
b.一般情况下,那种类型的指针则存储那种类型变量的地址
#include <stdio.h>int main()
{char c = 'a';int num = 10;float f = 1.342;double data = 13.14;//一般情况,那种类型的指针变量存储那种类型变量的地址char* ch = &c;int* p = #float* p1 = &f;double* p2 = &data;return 0;
}
2)指针的类型决定了指针向前或向后走一步有多大的字节距离
#include <stdio.h>int main()
{char c = 'c';int num = 10;char* p1 = &c;int* p2 = #printf("%p\n", p1);printf("%p\n", p1+1);printf("%p\n", p2);printf("%p\n", p2+1);return 0;
}
运行结果:
3)指针的类型决定了指针在解引用的时候能操作几个字节【访问权限多大】
#include <stdio.h>int main()
{int num = 0x44332211;char* p1 = #int* p2 = #printf("%d\n", *p1);printf("%d\n", *p2);*p1 = 0;*p2 = 0;return 0;
}
调试查看结果:
5. 野指针的问题
野指针就是指针指向的位置是不可知的【随机、不正确、无限制】
1)指针未初始化
#include <stdio.h>int main()
{int* p;printf("%p\n", p);return 0;
}
运行结果:
2)指针越界访问
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr;for (int i = 0; i <= 11; i++){//p的访问范围超过了数组的下标范围,p就是野指针printf("%d ", *p);p++;}return 0;
}
3)返回局部变量的地址
#include <stdio.h>
int test()
{int a = 10;return &a;
}int main()
{int *p = test();return 0;
}
4)指针指向的空间未释放
6.防止野指针的问题
1)指针初始化
2)小心指针越界
3)指针指向空间释放,及时置为NULL
4)避免返回局部变量的地址
5)使用指针之前检查指针的有效性
#include <stdio.h>void test(int* p)
{//检查指针的有效性if(p == NULL){}
}int main()
{int* p = NULL;//不知道指针指向哪里的时候置为NULLtest(p);return 0;
}
7.指针运算
1)指针+-整数
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p;for (p = arr; p < &arr[10]; p++){printf("%d ", *p);}return 0;
}
2)指针-指针【地址-地址】
两个指针指向的是同一块空间且类型是一致的,两者相减得到是元素个数
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p1 = arr;int* p2 = &arr[10];//指针-指针printf("%d\n", p2 - p1);//10return 0;
}
3)指针的关系运算
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p;for (p = &arr[10]; p > &arr[0];){*--p = 0;}return 0;
}
为什么这种方法也可以,但是不使用呢?
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p;for (p = &arr[9]; p >= &arr[0]; p--){*p = 0;}return 0;
}
C语言中的标准规定,允许指向数组元素的指针能与指向数组最后一个元素的后面那个内存位置的指针比较,但不允许与数组元素第一个元素前面的那一个内存地址的指针比较
8.指针与数组
1)数组名是数组首元素的地址,&数组名是取出整个数组的地址
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr;printf("arr = %p\n", arr);printf("arr + 1 = %p\n", arr + 1);printf("&arr = %p\n", &arr);printf("&arr + 1 = %p\n", &arr + 1);return 0;
}
运行结果:
2)指针能指向数组的任意一个元素,即数组每个元素的地址指针均能获取
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr;for (int i = 0; i < 10; i++){printf("%p == %p\n", &arr[i], p+i);}return 0;
}
运行结果:
9.二级指针【指针的指针】
int num = 10;
int* p = #//*p代表这是指针,int表示指向的类型是int类型
int**pp = &p;//*pp代表是指针,int*表示指向的类型是int*类型
#include <stdio.h>int main()
{int num = 10;int* p = #//*p表示这是一个指针,指向的类型是intint** pp = &p;//*pp表示这是一个指针,指向的类型是int*printf("%d\n", num);//10printf("%d\n", *p);//10printf("%d\n", **pp);//10return 0;
}
10.字符指针的使用方式
1)字符指针指向一个字符变量
2)字符指针指向一个常量字符串【常量字符串的首元素地址赋给字符指针】
#include <stdio.h>int main()
{char ch = 'a';//字符指针指向一个字符变量char* p1 = &ch;printf("%c\n", *p1);//字符指针指向一个常量字符串char* p2 = "abcdef";printf("%c\n", *p2);printf("%s\n", p2);return 0;
}
运行结果:
一道简单的笔试题:
#include <stdio.h>int main()
{char str1[] = "abcdef";char str2[] = "abcdef";const char* arr1 = "abcdef";const char* arr2 = "abcdef";if (str1 == str2){printf("str1 and str2 are same\n");}else{printf("str1 and str2 are not same\n");}if (arr1 == arr2){printf("arr1 and arr2 are same\n");}else{printf("arr1 and arr2 are not same\n");}return 0;
}
运行结果:
为什么?当const char*是存储字符串常量的时候,两个指针均指向字符串常量首元素地址
11.指针数组【数组】
整型数组:数据是整型的数组
浮点数组:数据是浮点型的数组
指针数组:数据是指针的数组【即数组中的元素是指针类型】
图解三种数组类型:
#include <stdio.h>int main()
{int arr1[5] = { 1,2,3,4,5 };int arr2[5] = { 2,3,4,5,6 };int arr3[5] = { 3,4,5,6,7 };int* arr[3] = { arr1,arr2,arr3 };//存储了三个数组的首元素地址for (int i = 0; i < 3; i++){for (int j = 0; j < 5; j++){printf("%d ", *(arr[i] + j));//arr[i][j]}printf("\n");}return 0;
}
运行结果:
12.数组指针【指针】
——指向数组的类型 (*p)[大小] = &所指数组名
int num = 10; int* p = #//指向int的指针
double data = 13.14; double* p = &data;//指向double的指针
int arr[10]; int (*p)[10] = &arr;//指向数组的指针
——如何判断数组指针?
()的结合性比[]高,所以先与*()里面的*号结合,再与[]结合 -> 指针
#include <stdio.h>void printArr(int(*p)[5], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){//printf("%d ", p[i][j]);//printf("%d ", *(*(p + i) + j));printf("%d ", *(p[i] + j));}printf("\n");}
}int main()
{int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };int row = sizeof(arr) / sizeof(arr[0]);int col = sizeof(arr[0]) / sizeof(arr[0][0]);printArr(arr, row, col);return 0;
}
13.数组传参和指针传参
1)一维数组传参
#include <stdio.h>//一维数组传参
//传参方式1
void test(int arr[]){}
//传参方式2
void test1(int arr[10]){}
//传参方式3
void test2(int* arr){}//一维指针数组传参
//传参方式1
void demo1(int* p[10]){}
//传参方式2
void demo2(int** arr){}
//解释:*arr接收str数组,另一个*表示元素是指针int main()
{int arr[5] = { 0 };test(arr);test1(arr);test2(arr);//一维指针数组传参int* str[10] = { 0 };demo1(str);demo2(str);return 0;
}
2)二维数组的传参方式
#include <stdio.h>//传参方式1
void test(int arr[3][3]){}
//传参方式2
void test1(int arr[][3]){}
//传参方式3
void test2(int(*arr)[3]){}int main()
{int arr[3][3] = { 0 };test(arr);test1(arr);test2(arr);return 0;
}
3)一级指针传参
#include <stdio.h>
//传参方式1
void test(int* p){}
//传参方式2
void test1(int* *p){}int main()
{int* p = NULL;test(p);return 0;
}
4)二级指针传参
#include <stdio.h>void test(int** p) {}int main()
{int** p = NULL;test(p);return 0;
}
14.函数指针
——指向的函数返回值 (*p)(指向函数的形参) = &所指函数名
int* p; //指向int的指针
double* p; //指向double的指针
int (*p)(int,int);//指向函数的指针
//解答:*和p结合,说明是指针,然后和(int,int)结合,说明是函数,int是返回值
#include <stdio.h>int add(int x, int y)
{return x + y;
}int main()
{//函数是有地址的//printf("%p\n", &add);int (*p)(int, int) = &add;int ret = p(5, 3);printf("%d\n", ret);//8return 0;
}
思考以下代码
//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int);
解释
代码1:把0强制转为为void(*)()的函数指针,在0地址处有一个函数,
函数无返回值,无形参,这个地方表调用代码2:函数名是signal,参数为int和函数指针void(*)(int),
signal的返回类型是函数指针,该函数指针的函数返回值是void,参数是int
15.函数指针数组
——把函数地址存储在数组里面,这个数组就叫做函数指针数组
int (*p[])(形参);
——使用途径:转移表
#include <stdio.h>int Add(int x, int y)
{return x + y;
}
int Sub(int x, int y)
{return x - y;
}
int Mul(int x, int y)
{return x * y;
}
int Div(int x, int y)
{return x / y;
}void menu()
{printf("******************************\n");printf("**** 1. add 2.sub *****\n");printf("**** 3. mul 4.div *****\n");printf("**** 0. exit *****\n");printf("******************************\n");
}int main()
{int input = 0;int x = 0;int y = 0;int ret = 0;//转移表 - 函数指针的数组int (*pfArr[])(int, int) = { NULL, Add, Sub, Mul, Div };//0 1 2 3 4do{menu();printf("请选择:>");scanf("%d", &input);if (input == 0){printf("退出计算器\n");break;}else if (input >= 1 && input <= 4){printf("请输入两个操作数:>");scanf("%d %d", &x, &y);ret = pfArr[input](x, y);printf("%d\n", ret);}else{printf("选择错误\n");}} while (input);return 0;
}
相关文章:

筑基九层 —— 指针详解
目录 前言: 指针详解 前言: 1.CSDN由于我的排版不怎么好看,我的有道云笔记比较美观,请移步有道云笔记 2.修炼必备 1)入门必备:VS2019社区版,下载地址:Visual Studio 较旧的下载 -…...

内存清理、动画制作、CPU检测等五款实用软件推荐
人类与99%的动物之间最大差别在于是否会运用工具,借助好的工具,能提升几倍的工作效率。 1.内存清理软件——MemReduct MemReduct是一款内存清理软件,现在越来越多的软件由于硬件的普遍发展,对内存的使用都开始肆无忌惮起来&…...

RocketMQ 5.0 学习笔记
1. 需求 背景:业务需要,平台将使用rocketMQ来实现消息的发送与消费,替代redis的消息功能。 需要在搭建好rocketMQ平台后,进行研究和验证。 技术:Springboot RocketMQ5.0 使用场景:签到活动,…...

796.子矩阵的和
输入一个 n行 m列的整数矩阵,再输入 q个询问,每个询问包含四个整数 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。 对于每个询问输出子矩阵中所有数的和。 输入格式 第一行包含三个整数 n,m,q。 接下来 n…...

【PySide6】信号(signal)和槽函数(slot),以及事件过滤器
说明 在PYQT中,父控件可以通过两种方式响应子控件的事件: 通过信号(signal)和槽函数(slot)机制连接子控件和父控件父控件可以通过设置eventFilter()方法来监听响应子控件的事件 一、信号(signal)和槽函数(slot) 示例 在PYQT中,每个组件都…...

canal admin管理端配置(二)
下载安装 下载地址: 下载解压即可 配置 修改canal.admin-1.1.5\conf\application.yml server:port: 8089 #端口根据是否冲突修改 spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8spring.datasource:address: 192.0.16.12:3306#数据库ip和端口…...

Servlet 生命周期
Servlet的生命周期有四个阶段:加载并实例化、初始化、请求处理、销毁。主要涉及到的方法有init、service、doGet、doPost、destory等 加载并实例化 Servlet容器负责加载和实例化Servelt。当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一…...

redis集群模式登陆
总结redis单机模式时,登陆redis的命令格式: ./redis-cli -h 地址 -p 端口redis集群模式时,登陆redis的命令格式: ./redis-cli -h 地址 -p 端口 -c举例1:redis单机模式下登陆rootubuntu:/usr/local/redis/redis-7.0.0/b…...

04-useMemo 、React.memo、useCallback
useMemo 、React.memo、useCallback 一、useMemo 基本用法 缓存数据,模拟 Vue 中的计算属性。 同样useMemo跟vue中component一样,也是有缓存的,会将结果缓存下来 import React, { useMemo, useState } from react;export default functio…...

windows下安装emqx Unable to load emulator DLL@if ===/ SET data_dir=“
1.报错内容 I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\bin>emqx start Unable to load emulator DLL (I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\erts-12.3.2.9\bin\beam.smp.dll) 此时不应有 SET。 I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\bin&…...

Redis常见问题(未完待续)
Redis常见问题Redis为什么快 ?Redis为什么快 ? 根据官方数据,Redis 的 QPS 可以达到约 100000(每秒请求数); 基于内存 对于磁盘数据库来说,首先要将数据通过 IO 操作读取到内存里再读取&#x…...

2024秋招BAT核心算法 | 详解图论
图论入门与最短路径算法 图的基本概念 由节点和边组成的集合 图的一些概念: ①有向边(有向图),无向边(无向图),权值 ②节点(度),对应无向图,…...

凝聚共识,锚定未来 | 第四届OpenI/O 启智开发者大会NLP大模型论坛成功举办!
2023年2月24日下午,第四届OpenI/O启智开发者大会NLP大模型分论坛在深圳人才研修院隆重举办。该论坛以“开源集智创新探索中文NLP大模型生态发展”为主题,众多业内人士和研发者在此共享NLP领域的前沿动态和研发经验,畅想中国NLP领域的发展前景…...

99.【Git】
Git(一)、什么是版本控制1.什么是版本控制2、常见的版本控制工具(二)、版本控制分类1、本地版本控制2、集中版本控制 SVN3、分布式版本控制 Git(三)、Git与SVN的主要区别1、Git历史(四)、Git下载与环境配置1.git下载2、启动Git(五)、常用的Linux命令1.Linux常用命令(六)、Git必…...

Linux驱动交叉编译把驱动文件放入开发板,以及printk函数打印级别
上一篇介绍了一个最简单的驱动程序和驱动程序大体结构,但那还是用本地编译只能在Ubuntu上运行,我们该怎么编译一个能加载到开发板上呢,就需要交叉编译,交叉编译通常都是在嵌入式开发中使用到的。 交叉编译 理解交叉编译前先了解…...

力扣(LeetCode)433. 最小基因变化(2023.03.07)
基因序列可以表示为一条由 8 个字符组成的字符串,其中每个字符都是 ‘A’、‘C’、‘G’ 和 ‘T’ 之一。 假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。 例如,“AACCGGTT”…...

网络基础(2)
目录1. 端口号2. 套接字socket3. 网络通信3.1 sockaddr与sockaddr_in3.2 接口服务端3.2.1 创建套接字,打开网络文件3.2.2 给该服务器绑定端口和ip(特殊处理)3.2.3 初始化相关服务器3.2.4 提供服务客户端3.2.5 绑定3.2.6 使用服务4. makefile实…...

掌握Spring Cloud Gateway:构建高性能API网关的原理和实践
Spring Cloud Gateway 是一个基于 Spring Boot 的 API 网关,用于构建微服务架构中的网关服务。它提供了统一的路由、请求转发、过滤器、负载均衡、熔断等功能,帮助开发者更好地管理和控制微服务系统的请求流量。 本文将介绍 Spring Cloud Gateway 的原理…...

NAST概述
一、NATS介绍 NATS是由CloudFoundry的架构师Derek开发的一个开源的、轻量级、高性能的,支持发布、订阅机制的分布式消息队列系统。它的核心基于EventMachine开发,代码量不多,可以下载下来慢慢研究。 不同于Java社区的kafka,nats…...

【JS知识点】——原型和原型链
文章目录原型和原型链构造函数原型显式原型(prototype)隐式原型(\_\_proto\_\_)原型链总结原型和原型链 在js中,原型和原型链是一个非常重要的知识点,只有理解原型和原型链,才能深刻理解JS。在…...

c盘怎么清理到最干净?有什么好的清理方法
c盘怎么清理到最干净?有什么好的清理方法?清理C盘空间是电脑维护的重要步骤之一。C盘是Windows操作系统的核心部分,保存了许多重要的系统文件,因此空间不足会影响计算机的性能和稳定性。下面是一些清理C盘空间的方法 一.清理临时文件 在使用…...

day26_HTML
今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、二阶段介绍 二、HTML 零、 复习昨日 见代码 一、二阶段介绍 第一阶段: 基础入门 java基本语法编程基础(方法,数组)面向对象编程常用类高级(IO,线程,新…...

深度剖析C语言预处理
致前行的人: 人生像攀登一座山,而找寻出路,却是一种学习的过程,我们应当在这过程中,学习稳定冷静,学习如何从慌乱中找到生机。 目录 1.程序翻译过程: 2.字符串宏常量 3.用宏定义充当注释符号 4…...

【WPF 值转换器】ValueConverter 进阶用法
【WPF 值转换器】ValueConverter 进阶用法介绍基类实现子类实现效果介绍 值转换器在WPF开发中是非常常见的,当然不仅仅是在WPF开发中。值转换器可以帮助我们很轻松地实现,界面数据展示的问题,如:模块隐藏显示、编码数据展示为可读…...

Vue2的基本使用
一、vue的基本使用 第一步 引入vue.js文件 <script src"https://cdn.staticfile.org/vue/2.7.0/vue.min.js"></script> 或者<script src"./js/vue.js"></script> 第二步 在body中设置一个挂载点 {{msg}} <div id"app…...

【云原生kubernetes】k8s数据存储之Volume使用详解
目录 一、什么是Volume 二、k8s中的Volume 三、k8s中常见的Volume类型 四、Volume 之 EmptyDir 4.1 EmptyDir 特点 4.2 EmptyDir 实现文件共享 4.2.1 关于busybox 4.3 操作步骤 4.3.1 创建配置模板文件yaml 4.3.2 创建Pod 4.3.3 访问nginx使其产生访问日志 4.3.4 …...

SerDes---CDR技术
1、为什么需要CDR 时钟数据恢复主要完成两个工作,一个是时钟恢复,一个是数据重定时,也就是数据的恢复。时钟恢复主要是从接收到的 NRZ(非归零码)码中将嵌入在数据中的时钟信息提取出来。 2、CDR种类 PLL-Based CDROve…...

如何实现在on ethernetPacket中自动回复NDP response消息
对于IPv4协议来说,如果主机想通过目标ipv4地址发送以太网数据帧给目的主机,需要在数据链路层填充目的mac地址。根据目标ipv4地址查找目标mac地址,这是ARP协议的工作原理 对于IPv6协议来说,根据目标ipv6地址查找目标mac地址,它使用的不是ARP协议,而是邻居发现NDP(Neighb…...

CSS清楚浮动
先看看关于浮动的一些性质 浮动使元素脱离文档流 浮动元素可以设置宽高,在CSS中,任何元素都可以浮动,浮动元素会生成一个块级框,而不论其本身是何种元素。 如果没有给浮动元素指定高度,,那么它会以内容的…...

HTTPS详解(原理、中间人攻击、CA流程)
摘要我们访问浏览器也经常可以看到https开头的网址,那么什么是https,什么是ca证书,认证流程怎样?这里一一介绍。原理https就是httpssl,即用http协议传输数据,数据用ssl/tls协议加密解密。具体流程如下图&am…...