C语言-c语言组成
1.C语言的组成
一个C源程序是由 一个或者多个.c文件 和 0个或者多个.h 文件 组成
源程序: 是指未编译的 按照一定的程序设计语言规范书写的文本文件
.c文件 : c源代码
.h文件 : 头文件(接口文件)
2. .c文件
1)预处理命令
以#开头的行,在编译之前 会事先做处理
在C语言中的预处理命令: 文件包含, 宏定义, 条件编译
(1)文件包含
#include <stdio.h>
把include后面的那个文件的内容 在此处展开
例子:
gcc -E xxx.c -o xxx.i //预处理, test.i 还是C源代码文件
gedit xxx.i //gedit文件编辑器,可用于查看文本文件的内容
头文件的引用
#include <> 从系统标准的头文件路径下进行搜索 (如: /usr/include/ )
#include "" 先从当前的工程路径下进行搜索, 再从系统标准的头文件路径下进行搜索
(2)宏定义
宏定义: 定义一个宏
☆☆☆
宏: 是一个批量处理的称谓, 它只是简单替换, 不作计算, 也不作表达式
使用宏可以提高程序的通用性和可移植性
分类:
(2.1)不带参数的宏, 符号常量
语法:
#define 宏名 要替换的内容
例子:
#define Pi 3.14
double s = r*r*Pi; // OK r*r*3.14
Pi = 3; // error 3.14 = 3;
(2.2)带参数的宏
语法:
#define 宏名(参数列表) 要替换的内容
"参数列表": 在宏里面的参数, 不需要类型
例子:
定义一个宏, 求两个整数的最大值
#define MAX(a,b) a>b ? a : b
int c = MAX(3,5); // 3>5 ? 3 : 5
printf("c = %d\n", c ); // c = 5;
int i = 6;
c = MAX( i++, 5 ); // i++>5 ? i++ : 5 ==> 7 (此时i==8)
//宏定义只是简单替换,不作计算,也不作表达式
c = MAX( 1+2, 3+4 ); // 1+2>3+4 ? 1+2 : 3+4 ==> 7
c = MAX( 1>2, 3<4 ); // 1>2>3<4 ? 1>2 : 3<4 ==> 0
更正:
#define MAX(a,b) ( { typeof(a) _a = a; \
typeof(b) _b = b; \
(_a)>(_b) ? (_a) : (_b); \
} )
练习:
1)定义一个宏, 求数组a的元素个数
#define ARRAY_SIZE(a) ( sizeof(a)/sizeof(a[0]) )
2)定义一个宏, 取一个整数x中的第n个bit位
xxxxaxxx
xxxxxxxa x>>n
00000001 &1
----------------
0000000a
#define GET_BIT(x,n) ({ typeof(x) _x = x; \
typeof(n) _n = n; \
( ( _x >> _n ) & 1 ); \
})
#include <stdio.h>
#include "sum.h"#define N 10 //带参数的宏
// #define MAX(a,b) a>b ? a : b //有副作用#define MAX(a,b) ( { typeof(a) _a = a; \typeof(b) _b = b; \(_a)>(_b) ? (_a) : (_b); \} )#define ARRAY_SIZE(a) ( sizeof(a)/sizeof(a[0]) )#define GET_BIT(x,n) ({ typeof(x) _x = x; \typeof(n) _n = n; \( ( _x >> _n ) & 1 ); \})int main()
{int a[N];printf("%ld\n", ARRAY_SIZE(a) );int c = MAX(3,5); printf("c = %d\n", c ); // 5int i = 6;c = MAX( i++, 5 );printf("c = %d\n", c ); // 7c = MAX( 1+2, 3+4 );printf("c = %d\n", c ); // 7c = MAX( 1>2, 3<4 );printf("c = %d\n", c ); // 0int x = 7;if( GET_BIT(x, 3) ){printf("1\n");}else {printf("0\n");}//条件编译#if 1 printf("123\n");#endif#if 0 printf("456\n"); //少了一个分号#endif
}
(3)条件编译
(3.1)条件编译一般在.h文件中
#ifndef __XXX_H__
#define __XXX_H__
#endif
为了防止重复包含
(3.2)
#if 表达式
语句
#endif
"表达式"的值为真, 那么就编译"语句" ,
如果为假, 则不编译
类似于if语句
例子:
//条件编译
#if 1
printf("123\n");
#endif
#if 0
printf("456\n"); //不参与编译了
#endif
2)声明
"声明" :
在C语言中, 声明 是用来声明一个已经存在的标识符(对象的名字)
声明就是用来表示一个标识符(对象的名字)到底是什么东西
为什么需要声明?
C语言编译源文件时, 是从第一行到最后一行, 一行一行的进行编译
而且在编译多个文件的时候, 也是一个文件一个文件的编译的
有时候1.c可能会用到2.c中定义的对象(变量/函数等)
在编译1.c时,碰到这个对象的名字, c语言编译器就可能不认识这个标识符,
即使是在同一个文件中, 在前面碰到的标识符,而这个标识符的定义在后面
此时 编译器也会不知道这个标识符是什么东西
一般来说, 在源文件的前面 要进行标识符的声明
约定:
将声明 放在 使用的前面
声明的格式:
(1) 外部变量的声明
extern 变量的类型 变量名; //外部变量声明时, 不能给它初始化
(2) 函数的声明
(2.1) 外部函数的声明:
extern 函数的返回值类型 函数名(参数列表); //extern 函数头;
(2.2)本文件内部的 函数的声明
函数的返回值类型 函数名(参数列表); // 函数头;
例子: 参考函数的例子
注意:
函数声明,形参的名字是可以省略的,但是类型不能省略
int sum( int x, int y ); // OK
int sum( int, int); // OK
int sum( x, y ); // error
3) 全局变量 和 函数的定义
int a = 10;
int fun()
{}
int main()
{
}
在C语言中, 语句必须在函数的内部, 一个.c文件可以由多个函数组成
一个工程(程序)只能 有且仅有一个main()函数 , 可以有0个或者多个非主函数
main()函数是程序的入口, 程序从这里开始执行, main函数结束了, 那么整个程序就结束了
3. .h文件
.h文件的作用
1.c sum()
然后 2.c中需要用到1.c中的sum()函数
在2.c中进行外部函数的声明 就可以了
但是 如果 3.c 4.c 5.c ... 都需要用到这个函数?
只需要创建已给1.h文件 进行声明
int sum(int a, int b);
那么 2.c 3.c 4.c .... 只需要包含这个头文件即可
#include "1.h"
.h 头文件 (接口文件)
头文件的格式:
例子: sum.h
#ifndef __SUM_H__ //防止重复包含 //和文件名一致,建议全部大写
#define __SUM_H__
//头文件 一般包含 宏定义, 函数声明, 类型构造等
#endif
编程规范:
一般头文件的内容 不产生指令 或者 分配空间(比如:定义空间) 代码
头文件的引用
#include <> 从系统标准的头文件路径下进行搜索 (如: /usr/include/ )
#include "" 先从当前的工程路径下进行搜索, 再从系统标准的头文件路径下进行搜索
4. 模块化设计思想
例子:
造一架飞机
驾驶舱, 机翼, 引擎, 起落架
main.c 包含main()主函数 , 程序的入口 , 进行功能的调用
cockpit.c / cockpit.h 跟驾驶舱相关的功能代码
wing.c / wing.h 跟机翼相关的功能代码
engine.c / engine.h 跟引擎修改的功能代码
...
.c文件 包含具体功能函数的实现
.h文件主要是函数的声明
编译:
gcc main.c cockpit.c wing.c engine.c ... -o main
练习:
1) 提取字符串中的数字
输入一串字符串, 该字符串中可能包含数字, 把里面找到的数字 进行求和
例如:
输入: abc123def45ghijk6mn
输出: 174 ( <== 123 + 45 + 6 )
#include <stdio.h>
#include <string.h>int get_num_in_string( char *s )
{int num = 0;int sum = 0; //保存结果int i;for( i=0; i<strlen(s); i++ ) //遍历的字符串s{if( s[i]>='0' && s[i]<='9' ) //是数字 {num = num*10 + s[i] - 48; //合成数字if( s[i+1]<'0' || s[i+1]>'9' ) //下一个不是数字{sum = sum + num;num = 0;}}}return sum;
}int main()
{char buf[64] = {0};scanf("%s", buf );int sum = get_num_in_string( buf );printf("sum = %d\n", sum );
}相关文章:
C语言-c语言组成
1.C语言的组成 一个C源程序是由 一个或者多个.c文件 和 0个或者多个.h 文件 组成 源程序: 是指未编译的 按照一定的程序设计语言规范书写的文本文件 .c文件 : c源代码 .h文件 : 头文件(接口文件) 2. .c文件 1)预处理命令 以#开头的行,在编译之前 会事…...
编程题 7-13 日K蜡烛图【PAT】
文章目录 题目输入格式输出格式输入样例1输出样例1输入样例2输出样例2输入样例3输出样例3 题解解题思路完整代码 编程练习题目集目录 题目 股票价格涨跌趋势,常用蜡烛图技术中的 K K K 线图来表示,分为按日的日 K K K 线、按周的周 K K K 线、按月的…...
iOS开发工程师面试
iOS开发工程师面试题可以涵盖多个方面,包括但不限于iOS开发的基础知识、高级概念、性能优化、架构设计、最新技术等。 1. 基础知识 1.1 请解释iOS中的Xcode是什么,以及它在开发中的作用和功能有哪些? Xcode是用于iOS和macOS等苹果平台开发的集成开发环境(IDE),提供了代…...
无人机避障—— 激光雷达定高北醒TF03-UART(二)
无人机避障过程,光靠大疆飞控内部的气压计不准,很容易在高度较低的时候受到地面植被等障碍物影响,使得掉高严重,因此采用激光雷达定高模块进行定高。 硬件: 北醒TF03-UART、Xavier-NX 软件代码: 北醒官…...
在虚幻引擎中实现Camera Shake 相机抖动/震屏效果
在虚幻引擎游戏中创建相机抖动有时能让画面更加高级 , 比如 遇到大型的Boss , 出现一些炫酷的特效 加一些短而快的 Camera Shake 能达到很好的效果 , 为玩家提供沉浸感 创建Camera Shake 调整Shake参数 到第三人称或第一人称蓝图 调用Camera Shake Radius值越大 晃动越强...
SQL Server的文本和图像函数
新书速览|SQL Server 2022从入门到精通:视频教学超值版_sql server 2022 出版社-CSDN博客 《SQL Server 2022从入门到精通(视频教学超值版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) SQL Se…...
PN8034非隔离12V300MA,SOP7/DIP7开关电源芯片
PN8034宽输出范围非隔离交直流转换芯片 PN8034SSC-R1B----SOP7, PN8034NSC-T1 ----DIP7, PN8034概述 PN8034集成PFM控制器及650V高雪州能力智能功本MOSFET,用于外图元器件极精简的小功率非隔离开关电源。PN8034内置高压启动模块,…...
VMware下Ubuntu找不到共享文件夹
在VMware的设置中已经设置了共享文件夹,在Ubuntu系统中找不到,参考了网上其他的文章,发现还是不能解决问题,无意中尝试了一小步,没想到成功解决了,在这里记录一下。 1)首先查询本机的gid 2&…...
银河麒麟桌面操作系统V10登录闪退问题解决
银河麒麟桌面操作系统V10登录闪退问题解决 1、问题描述2、问题分析3、问题解决方法第一步:修改/tmp文件夹权限第二步:重启图形化服务 💐The Begin💐点点关注,收藏不迷路💐 在使用银河麒麟桌面操作系统V10时…...
【Git原理与使用】分支管理
分支管理 1.理解分支2.创建分支2.1创建分支2.2切换分支2.3合并分支 3.删除分支4.合并冲突4.分支管理策略5.分支策略6.bug分支7.删除临时分支8.小结 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励&…...
Linux操作系统分析实验-多线程与内核模块编程,实验一
实验一 多线程与内核模块编程 一、实验目的 1、理解Linux下进程的结构; 2、理解Linux下产生新进程的方法(系统调用—fork函数); 3、掌握如何启动另一程序的执行; 4、理解Linux下线程的结构; 5、理解…...
AI绘画Stable Diffusion人物背景替换实操教程,让创意无限延伸
大家好,我是灵魂画师向阳 Stable Diffusion以其强大的能力可以实现人物背景的更换。本文将带你深入了解如何利用Stable Diffusion中的Inpaint Anything插件快速且精准地实现人物背景的替换,从而让你的图片焕发新生。 前期准备 本文会使用到Inpaint An…...
linux环境oracle11.2.0.4打补丁(p31537677_112040_Linux-x86-64.zip)
上传补丁及opatch工具 创建目录并上传opatch工具和补丁包 百度网盘地址 链接: https://pan.baidu.com/s/1EA5oerm52aesZUnb5OnQsA 提取码: ib8f [oraclerhel64 ~]$ mkdir /u01/psu [oraclerhel64 ~]$ cd /u01/psu [oraclerhel64 psu]$ ll total 514572 -rw-r--r-- 1 oracle o…...
华为 HCIP-Datacom H12-821 题库 (29)
🐣博客最下方微信公众号回复题库,领取题库和教学资源 🐤诚挚欢迎IT交流有兴趣的公众号回复交流群 🦘公众号会持续更新网络小知识😼 1.运行 IS-IS 的两台路由器,只有 IIH 发送的时间间隔相同才可以建立邻接关系 A、正…...
MySQL 为什么一定要有一个主键
引言 在数据库设计中,主键(Primary Key)是一个至关重要的概念。MySQL 作为最广泛使用的关系型数据库之一,主键在 MySQL 表设计中扮演着关键角色。主键不仅决定了表中数据的唯一性和完整性,还对数据库性能、数据查询、…...
Pycharm 本地搭建 stable-diffusion-webui
一、下载工程源码 Github官方连接 https://github.com/AUTOMATIC1111/stable-diffusion-webui 二、Pycharm打开工程 1、设置环境 文件-设置-项目-Python解析器-添加解释器-添加本地解释器 Conda环境-创造新环境-Python版本3.10 注意一定要选择Python3.10版本,否…...
python/爬虫技术/lxml工具介绍/XML和HTML解析
1.lxml介绍: lxml 是一个Python库,它提供了非常强大的XML和HTML解析功能。它基于libxml2和libxslt,是处理XML和HTML文档的首选库之一。 2.安装 首先,需要安装lxml库。可以通过pip来安装,在控制台内执行安装命令。 p…...
Kafka技术详解[5]: 集群启动
目录 集群启动 相关概念 代理:Broker 控制器:Controller 启动ZooKeeper 启动Kafka 初始化ZooKeeper 初始化服务 启动任务调度器 创建数据管理器 创建远程数据管理器 创建副本管理器 创建ZK元数据缓存 创建Broker通信对象 创建网络通信对象 注册Brok…...
记一次教学版内网渗透流程
信息收集 如果觉得文章写的不错可以共同交流 http://aertyxqdp1.target.yijinglab.com/dirsearch dirsearch -u "http://aertyxqdp1.target.yijinglab.com/"发现 http://aertyxqdp1.target.yijinglab.com/joomla/http://aertyxqdp1.target.yijinglab.com/phpMyA…...
[Python学习日记-31] Python 中的函数
[Python学习日记-31] Python 中的函数 简介 语法定义 函数的参数 简介 引子: 你是某公司的一个高级程序员,现在老板让你写一个监控程序,需要24小时全年无休的监控公司网站服务器的系统状况,当 CPU、Memory、Disk 等指标的使用…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
电脑桌面太单调,用Python写一个桌面小宠物应用。
下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡,可以响应鼠标点击,并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...
