c基础(二)
指针:
含义:是一个值,一个值代表着一个内存地址,类似于存放路径
* 运算符 :
1 字符*
表示指针
作用:通常跟在类型关键字的后面,表示指针指向的是什么类型的值
int * foo, * bar;声明指针后会随机分配一个内存空间,指针指向的数据是随机的指针的初始化:
int* p;
int i;p = &i;
*p = 13;未初始化的指针数据最好这样定义:int* p = NULL;
2 运算符
作用:用来取出指针变量所指向的内存地址里面的值
* foo 取出定义的指针的值/*注意,数组名指向的地址是不能更改的*/
& 运算符:
作用:用来取出一个变量所在的内存地址int i = 5;if (i == *(&i)) // 正确,*(&i)含义:先取出i的内存地址,在获取内存地址对应的值
运算:
1 指针与整数值的加减运算
指针与整数值的运算,表示指针的移动。
2 指针与指针的加法运算
两个指针进行加法是非法的
3 指针与指针的减法
相同类型的指针允许进行减法运算,返回它们之间的距离,即相隔多少个数据单位。
高位地址减去低位地址,返回的是正值;低位地址减去高位地址,返回的是负值
返回值:ptrdiff_t
类型,一个带符号的整数类型别名
4 指针与指针的比较运算
比较的是各自的内存地址哪一个更大,返回值是整数1
(true)或0
(false)
函数:
基础结构:
#include <stdio.h>/* 基础结构*/int main(void)
{int m = addNum(3); /* 使用函数, 3 传递的参数*/printf("m=%d", m);
}int addNum(int a) /* int addNum 定义函数名称 (int a 传递参数,可以传递多个,使用逗号分开) */
{ /*{函数体:使用此方法需要执行的语句}*/return a; /* return a; return 返回值,返回计算之后的数据 */
}
参数:
传递的参数是拷贝的数据,非自身数据,不会实时更新数据;
除非1 函数返回最新的数据,才可以获取并赋值最新的数据2 直接修改自身的署,传入变量的地址(函数不要返回内部变量的指针)void Swap(int* x, int* y) {int temp;temp = *x;*x = *y;*y = temp;
}int a = 1;
int b = 2;
Swap(&a, &b);//参数为数组
int sum_array(int a[n], int n) {// ...
}int sum = sum_array(a, 4);
//等同于
int sum = sum_array((int []){3, 5, 7, 3}, 4);/*多维数组*/
int sum_array(int n, int m, int a[n][m]);
参数数量是不确定时,声明函数的时候,可以使用省略号...
表示可变数量的参数
注意:...
符号必须放在参数序列的结尾,否则会报错
#include<stdio.h> #include<stdarg.h> /* 可以操作可变参数的类*/double average(int i, ...);double average(int i, ...) {double total = 0;va_list ap; /*va_list 一个数据类型,用来定义一个可变参数对象*//* va_start(ap, i); 将参数i后面的参数统一放入ap*/va_start(ap, i); /*va_start 一个函数,用来初始化可变参数对象 va_start(可变参数对象,正常参数,用来为可变参数定位)*/printf("i=%d \n", i);for (int j = 1; j <= i; ++j) {/* va_arg(ap, double)用来从ap依次取出一个参数,并且指定该参数为 double 类型*/total += va_arg(ap, double); /* va_arg 一个函数,用来取出当前那个可变参数 va_arg(可变参数对象,当前可变参数的类型)*/printf("total=%d \n", total);}printf("ap=%d \n", ap);va_end(ap); /* va_end 一个函数,用来清理可变参数对象*/return total / i;
}int main(void)
{int total=average(0,8,10);printf("total=%d", total);
}
递归函数:
函数可以调用自身,这就叫做递归(recursion)例如:
#include <stdio.h>int main(void)
{int m = addNum(3);printf("m=%d", m);
}int addNum(int a)
{a++ ;if (a <= 5){addNum(a);}else{return a;}
}注意:在使用递归函数时,注意做好判断,不然容易出现死循环
入口函数:
main()是程序的入口函数,所有的程序必须要有
类似于页面加载方法,首先执行此方法
其他的方法需要通过main调用#include <stdio.h>int main(void)
{int m =3;printf("m=%d", m);return 0; /* 表示函数结束运行,返回0; 返回非零数据表示运行失败*/
}
函数指针:
调用函数的方法
// 写法一 常用的 函数名本身就是指向函数代码的指针,通过函数名就能获取函数地址
print(10)// 写法二
(*print)(10)// 写法三
(&print)(10)// 写法四
(*print_ptr)(10)// 写法五
print_ptr(10)#include<stdio.h> int addNum(int a)
{return a;
}int main(void) /*调用其他方法时,其他方法要么写在最前面, 或者使用函数原型*/
{// int m = addNum(3);// printf("m=%d", m);int m = (*addNum)(10);printf("m=%d", m);
}优点:
可以明确参数是一个函数参数一就是一个函数
int compute(int (*myfunc)(int), int, int);
函数原型:提前告诉编译器,每个函数的返回类型和参数类型int twice(int);int main(int num) {return twice(num);
}int twice(int num) {return 2 * num;
}注意,函数原型必须以分号结尾。一般来说,每个源码文件的头部,都会给出当前脚本使用的所有函数的原型。
exit函数:
作用:终止程序的运行
前提: #include<stdlib.h>
返回值(stdlib.h已定义,无需定义):EXIT_SUCCESS(相当于 0)表示程序运行成功EXIT_FAILURE(相当于 1)表示程序异常中止
atexit()函数:用来登记exit()执行时额外执行的函数,用来做一些退出程序时的收尾工作
说明符:
extern 说明符 :
extern int foo(int arg1, char arg2);
extern 表示:导入使用,声明此方法未在此文件定义,是从其他文件内引入使用的int main(void) {int a = foo(2, 3);// ...return 0;
}
static 说明符:
1 用于函数内部声明变量时,表示该变量只需要初始化一次,不需要在每次调用时都进行初始化
2 static
可以用来修饰函数本身,表示该函数只能在当前文件里使用,如果没有这个关键字,其他文件也可以使用这个函数(通过声明函数原型)
3 用在参数里面,修饰参数数组
int sum_array(int a[static 3], int n) { /* 数组长度至少为3*/}
注意:
static
修饰的变量初始化时,只能赋值为常量,不能赋值为变量
局部作用域中,static
声明的变量有默认值0
const 说明符:
1 函数内部不得修改该参数变量
void f(const int* p) {int x = 13;p = &x; // p本身的地址是允许修改的*p = 0; //const声明的* p 不能修改,修改之后报错
}
void f(int* const p) { //不允许修改p,就使用const定义int x = 13;p = &x; // 该行报错
}/* p和*p 都不允许修改 */
void f(const int* const p) {
}
内存管理:
分类:
系统管理:局部变量存放的内存区域(”栈“(stack)),运行结束后自动从内存卸载
用户手动管理:全局变量存放的内存区域(”堆“(heap)),运行结束后不会自动卸载,需要用户手动释放,此现象叫”内存泄漏“(memory leak)
void 指针:
void:不定类型的指针可以指向任意类型的数据,但是不能解读数据void 指针与其他所有类型指针之间是互相转换关系
注意,由于不知道 void 指针指向什么类型的值,所以不能用*运算符取出它指向的值
内存操作:
分配内存:
malloc:
#include <stdio.h>
#include <stdlib.h> /*内存管理的操作*/int main(){/* malloc(分配的内存字节数--非负整数) 任意类型的数据分配内存 返回值:无类型的 void 指针*///malloc不会对所分配的内存进行初始化,需要自行初始化后再使用,想要初始化为0,还要额外调用memset()函数int* p = malloc(sizeof(int));*p = 12;if (p == NULL) {// 内存分配失败}printf("%d\n", *p); int* n = (int*) malloc(sizeof(int)); //强制转换数据为整数类型printf("n=%d\n",*n);int* i = (int*) malloc(sizeof(*i));printf("i=%d\n",*i);//作用://1 为数组和自定义数据结构分配内存int* t = (int*) malloc(sizeof(int) * 10);for (int i = 0; i < 10; i++)t[i] = i * 5;printf("t==%d",t);//2 创建动态数组int m;int* a = (int*) malloc(m * sizeof(int)); //可以根据变量m的不同,动态为数组分配不同的大小}
calloc:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(){// calloc(数据类型的值的数量,数据类型的单位字节长度) 分配内存, 返回值:无类型的 void 指针,分配失败时,返回 NULL//calloc所分配的内存全部初始化为0int* p = calloc(10, sizeof(int));printf("p==%d, %d \n",p,*p);// 等同于int* n = malloc(sizeof(int) * 10);memset(n, 0, sizeof(int) * 10);printf("n==%d, %d \n",n,*n);
}
释放内存:
free:
#include <stdio.h>
#include <stdlib.h>int main(){//free(malloc返回的内存地址) 释放malloc函数分配的内存//分配的地址释放之后,不可操作和再次释放// 注意:函数调用成功后,一定要释放内存,否则会导致多次调用函数所生成的内存下次无法访问int* p = (int*) malloc(sizeof(int));*p = 12;printf("address=%d",p);free(p);
}
修改内存:
realloc:
#include <stdio.h>
#include <stdlib.h>int main(){//realloc(已经分配好的内存块指针,内存块的新大小,单位为字节) 修改已经分配的内存块的大小,可以放大也可以缩小 , 返回新的内存块的指针,分配失败返回null// 已经分配好的内存块指针--参数设置为null或者不写,会创建一个新的指针// 内存块的新大小 --------参数设置为0,会释放内存块//realloc不会对内存块进行初始化int* p = calloc(10, sizeof(int));float* new_p = realloc(p, sizeof(*p * 40));if (new_p == NULL) {printf("Error reallocing\n");return 1;}else{printf("win--- \n");}
}
拷贝内存:
memcpy拷贝:
#include <stdio.h>
#include <string.h>//自定义复制内存函数:
void* my_memcpy(void* dest, void* src, int byte_count) {char* s = src;char* d = dest;while (byte_count--) {*d++ = *s++;}return dest;}int main(){//memcpy(拷贝地址,被拷贝地址,拷贝的字节数) 前两个参数:不限制指针类型,各种类型的内存数据都可以拷贝char s[] = "Goats!";char t[100];// memcpy(t, s, sizeof(s)); // 拷贝7个字节,包括终止符int m = my_memcpy(t, s, sizeof(s));printf("m=%s\n", m); // "Goats!"return 0;
}
memmove复制:
#include <stdio.h>
#include <string.h>int main(){//memmove(拷贝地址,被拷贝地址,移动的字节数) 允许目标区域与源区域有重叠。如果发生重叠,源区域的内容会被更改char x[] = "Home Sweet Home";printf("x=%s\n", (char *) memmove(x, &x[5], 10));
}
比较内存:
memcmp:
#include <stdio.h>
#include <string.h>int main(){//memcmp(比对者1,比对者2,比较的字节数) 返回值:整数 //相同时返回0,参数一大于参数二时返回大于0,参数一小于参数二返回小于0// char* s1 = "abc";// char* s2 = "acd";// int r = memcmp(s1, s2, 3); // 小于 0// printf("memcmp result=%d",r);//比较内部带有字符串终止符\0的内存区域char s1[] = {'b', 'i', 'g', '\0', 'c', 'a', 'r'};char s2[] = {'b', 'i', 'g', '\0', 'c', 'a', 't'};printf ("3=%d \n",memcmp(s1, s2, 3) == 0) ;// trueprintf ("4=%d \n",memcmp(s1, s2, 4) == 0) ;// trueprintf ("7=%d \n",memcmp(s1, s2, 7) == 0) ;// false}
restrict 说明符 :
restrict :内存区域只有当前指针一种访问方式,其他指针不能读写该内存,这种指针称为“受限指针”(restrict pointer)
相关文章:
c基础(二)
指针: 含义:是一个值,一个值代表着一个内存地址,类似于存放路径 * 运算符 : 1 字符*表示指针 作用:通常跟在类型关键字的后面,表示指针指向的是什么类型的值 int * foo, * bar;声明指针后会…...
人工智能趋势报告解读:ai野蛮式生长的背后是机遇还是危机?
近期,Enterprise WordPress发布了生成式人工智能在营销中的应用程度的报告,这是一个人工智能迅猛发展的时代,目前人工智能已经广泛运用到内容创作等领域,可以预见的是人工智能及其扩展应用还将延伸到我们工作与生活中的方方面面。…...
三、C语言中的分支与循环—goto语句 (10) (完)
在C语言中,goto语句允许程序无条件地跳转到同一函数内的标记位置。这个标记位置通过一个标签和冒号(:)来标示。goto语句可以用于从深层嵌套的循环或条件语句中直接跳出,或者跳过某些代码执行。尽管goto语句在某些情况下可以使程序逻辑变得清晰࿰…...
RabbitMQ 常见问题
1. 如何保证消息顺序消费 在RabbitMQ中,消息最终会保存在队列中,在同一个队列中,消息是顺序的,保持先进先出的原则,这个由Rabbitmq保证。而不同队列中的消息,RabbitMQ 是无法保证其顺序性。顺序消费主要是…...
阶段二-Day10-日期类
日期类结构: 1.java.util.Date是日期类 2.DateFormat是日期格式类、SimpleDateFormat是日期格式类的子类 Timezone代表时区 3.Calendar是日历类,GregorianCalendar是日历的子类 一. 常用类-Date 1.1 Date构造方法 Date(long date) 使用给定的毫秒时间价值构建…...
多任务并行处理相关面试题
我自己面试时被问过两次多任务并行相关的问题: 假设现在有10个任务,要求同时处理,并且必须所有任务全部完成才返回结果 这个面试题的难点是: 既然要同时处理,那么肯定要用多线程。怎么设计多线程同时处理任务呢&…...
Shell脚本学习笔记
1. 写在前面 工作中,需要用到写一些shell脚本去完成一些简单的重复性工作, 于是就想系统的学习下shell脚本的相关知识, 本篇文章是学习shell脚本整理的学习笔记,内容参考主要来自C语言中文网, 学习过程中,…...
ROS-安装xacro
安装 运行下列命令进行安装,xxxxxx处更改为自己的版本 sudo apt-get install ros-xxxxxx-xacro运行 输入下列命令 roscd xacro如果没有报错,并且进入了xacro软件包的目录,则表示安装成功。 参考: [1]https://wenku.csdn.net/ans…...
为什么说 $mash 是 Solana 上最正统的铭文通证?
早在 2023 年的 11 月,包括 Solana、Avalanche、Polygon、Arbitrum、zkSync 等生态正在承接比特币铭文生态外溢的价值。当然,因铭文赛道过于火爆,当 Avalanche、BNB Chain 以及 Polygon 等链上 Gas 飙升至极值,Arbitrum、zkSync 等…...
安装elasticsearch、kibana、IK分词器、扩展IK词典
安装elasticsearch、kibana、IK分词器、扩展IK词典 后面还会安装kibana,这个会提供可视化界面方面学习。 需要注意的是elasticsearch和kibana版本一定要一样!!! 否则就像这样 elasticsearch 1、创建网络 因为我们还需要部署k…...
Spring中常见的BeanFactory后处理器
常见的BeanFacatory后处理器 先给出没有添加任何BeanFactory后处理器的测试代码 public class TestBeanFactoryPostProcessor {public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();context.registerBean("co…...
FPGA LCD1602驱动代码 (已验证)
一.需求解读 1.需求 在液晶屏第一行显示“HELLO FPGA 1234!” 2. 知识背景 1602 液晶也叫 1602 字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵 型液晶模块。它由若干个 5X7 或者 5X11 等点阵字符位组成,每个点阵字符位都可以显示一 个字符,每位之间有一个点距的…...
c++编程要养成的好习惯
1、缩进 你说有缩进看的清楚还是没缩进看的清楚 2、i和i i运行起来和i更快 3、 n%20和n&1 不要再用n%20来判断n是不是偶数了,又慢又土,用n&10,如果n&10就说明n是偶数 同理,n&11说明n是奇数 4、*2和<<…...
后台管理项目的多数据源方案
引言 在互联网开发公司中,往往伴随着业务的快速迭代,程序员可能没有过多的时间去思考技术扩展的相关问题,长久下来导致技术过于单一。为此最近在学习互联网思维,从相对简单的功能开始做总结,比如非常常见的基础数据的…...
视频美颜SDK趋势畅想:未来发展方向与应用场景
当下,视频美颜SDK正不断演进,本文将深入探讨视频美颜SDK的发展趋势,探讨未来可能的方向和广泛的应用场景。 1.深度学习与视频美颜的融合 未来,我们可以期待看到更多基于深度学习算法的视频美颜SDK,为用户提供更高质量…...
C++ const 限定符的全面介绍
C const 限定符的全面介绍 1. const 修饰基本数据类型 定义 const 修饰的基本数据类型变量,值不可改变。 语法 const type variable value;特点 不可变性,增加代码可读性。 作用 定义不可修改的常量。 使用场景 全局常量、配置项。 注意事项…...
Vue 中的 ref 与 reactive:让你的应用更具响应性(上)
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...
华为云CCE-集群内访问-根据ip访问同个pod
华为云CCE-集群内访问-根据ip访问同个pod 问题描述:架构如下:解决方法: 问题描述: 使用service集群内访问时,由于启用了两个pod,导致请求轮询在两个pod之间,无法返回正确的结果。 架构如下&am…...
Kasada p.js (x-kpsdk-cd、x-kpsdk-ct、integrity)
提供x-kpsdk-cd的API服务 详细请私信~ 可试用~ V:zhzhsgg 一、简述 integrity是通过身份验证Kasada检测机器人流量后获得的一个检测结果(数据完整性) x-kpsdk-cd 是经过编码计算等等获得。当你得到正确的解决验证码值之后,解码会看到如下图…...
Thinkphp 5框架学习
TP框架主要是通过URL实现操作 http://servername/index.php/模块/控制器/操作/参数/值.. index.php 为入口文件,在 public 目录内的 index.php 文件; 模块在 application 目录下默认有一个 index 目录,这就是一个模块; 而在 index 目录下有一个 contro…...
麒麟云增加计算节点
一、安装基座系统并配置好各项设置 追加的计算节点服务器,安装好系统,把主机名、网络网线(网线要和其他网线插的位置一样)、hosts这些配置好,在所有节点的/etc/hosts里面添加信息 在控制节点添加/kylincloud/multinod…...
使用Redis进行搜索
文章目录 构建反向索引 构建反向索引 在Begin-End区域编写 tokenize(content) 函数,实现文本标记化的功能,具体参数与要求如下: 方法参数 content 为待标记化的文本; 文本标记的实现:使用正则表达式提取全小写化后的…...
Oracle修改用户密码
文章目录 Oracle修改用户密码Oracle用户锁定常见的两种状态Oracle用户锁定和解锁 Oracle修改用户密码 使用sys或system使用sysdba权限登录,然后执行以下命令修改密码: alter user 用户名 identified by 密码;密码过期导致的锁定,也通过修改…...
LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 描述: 圣诞活动预…...
Vue解决跨域问错误:has been blocked by CORS policy 后端跨域配置
解决跨域问题后端跨域配置代码: /*** 作者 hua* 描述 跨域配置*/ Configuration public class WebConfiguration implements WebMvcConfigurer {/*** 跨域配置对象* return CorsConfiguration对象*/private CorsConfiguration corsConfig() {CorsConfiguration cor…...
【谷歌云】注册谷歌云 创建Compute Engine
文章目录 一、Google Cloud注册1.1 账号信息1.2 付款信息验证1.3 验证成功 二、Compute Engine创建2.1 启动Compute Engine API2.2 创建实例2.3 新建虚拟机实例2.4 等待实例创建完成2.5 查看虚拟机配置信息2.6 创建防火墙规则2.7 SSH远程连接虚拟机 三、参考链接 一、Google Cl…...
面试数据库八股文五问五答第四期
面试数据库八股文五问五答第四期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的! ⭐点赞⭐收藏⭐不迷路!⭐ 1)什么情况下 mysql 会索引失效? 不使用索引列进行查询&a…...
2023 年中国金融级分布式数据库市场报告:TiDB 位列领导者梯队,创新能力与增长指数表现突出
近日,沙利文联合头豹研究院发布了中国数据库系列报告之《2023 年中国金融级分布式数据库市场报告》。 报告认为,金融行业对于分布式数据库信任度与认可度正在逐步提高,中国金融级分布式数据库市场正处于成熟落地的高增长阶段,行业…...
基于ExoPlayer的缓存方案实现
音视频APP 的一个必备功能就是在播放的时候会持续缓存完整个音频,同时进度条会更新缓存进度。但是目前Google推出的播放器ExoPlayer本身并没有提供什么方便的接口去实现这个功能,因此大多数的开发者可能会使用AndroidVideoCache 开源库来实现缓存。 AndroidVideoCache 的原理…...
前缀和算法 -- 寻找数组的中心坐标
个人主页:Lei宝啊 愿所有美好如期而遇 本题链接 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 输入描述 给定一个数组,接口为int pivotIndex(vector<int>& nums) 输出描述 我们以示例1为例画图解释…...
网站开发移动端多少钱/网站平台如何推广
帧中继( Frame Relay)是一种用于连接计算机系统的面向分组的通信方法。它主要用在公共或专用网上的局域网互联以及广域网连接。大多数公共电信局都提供帧中继服务,把它作为建立高性能的虚拟广域连接的一种途径。1.实验器材3台思科路由器 3台…...
东莞做网站优化/百度投诉平台在哪里投诉
1.边角热区 新版Win8取消了开始菜单,但用鼠标点击左下角时仍可进入Metro界面,其实剩余的几个角也都有着类似功用。比如左上角代表在打开的Metro应用间循环切换、右上角代表可以一键激活Charm工具栏、左下角是Metro与传统桌面的切换键,至于右下…...
做鸭网站/如何在百度做推广
一.RF之UI自动化测试环境 1:通过pip安装扩展库: pip install robotframework-seleniumlibrary 2.:下载谷歌游览器和对应驱动 https://www.cnblogs.com/loved-wangwei/p/8993013.html 3.将游览器驱动放在python的目录下 比如:我的python安装在D:\install…...
广州天河网站建设/私人做网站
后端统计函数 函数 返回类型描述pg_stat_get_backend_idset()int设置当前活动的后端ID号pg_stat_get_backend_activity(interger)text后端最近查询文本pg_stat_get_backend_activity_start(interger)timestamp with time zone最近查询开始时间pg_stat_get_backend_client…...
找人做网站推广/海外seo
【SpringBoot高级篇】SpringBoot集成redis缓存1. Redis概述1.1 redis的应用场景2. Redis安装2.1 在线安装2.2 安装包安装2.2.1 在Ubuntu上安装GCC2.2.2 tar安装docker安装拉取镜像启动镜像3. 命令操作Redis key命名规范3.1 redis的数据结构:3.1.1 字符串类型 String…...
抖音排名优化/seo黑帽培训骗局
何时使用领域驱动设计转载自:https://www.cnblogs.com/daxnet/p/15177443.html何时使用领域驱动设计?其实当你的应用程序架构设计是面向业务的时候,你已经开始使用领域驱动设计了。领域驱动设计既不是架构风格(Architecture Style…...