C语言
文章平均质量分 55
tyustli
不抛弃,不放弃
展开
-
【C语言】—— 宏和枚举区别
宏定义使用#define关键字进行定义,可以定义常量、函数或代码片段。例如:(a) :(b))3.14159(a) :(b))(a) :(b))(a) :(b))(a) :(b))(a) :(b))(a) :(b))(a) :(b))(a) :(b))(a) :(b))?(a) :(b))(a) :(b))(a) :(b))(a) :(b))(a) :(b))枚举使用enum关键字进行定义,用于定义一组具名常量的数据类型。例如:宏定义适用于定义常量、函数或代码片段,可以根据需要进行灵活的文本替换。原创 2023-07-12 22:30:51 · 1486 阅读 · 1 评论 -
【C语言】- inline
翻译单元只要用到某个 inline 函数,必须重复定义此 inline 函数,因此,inline 函数的定义常常被放在头文件中。因为内联函数要在调用点展开,所以编译器必须随处可见内联函数的定义,要不然就成了非内联函数的调用了。所以,这要求每个调用了内联函数的文件都出现了该内联函数的定义。因此,将内联函数的定义放在头文件里实现是合适的,省却你为每个文件实现一次的麻烦。声明跟定义要一致:如果在每个文件里都实现一次该内联函数的话,那么,最好保证每个定义都是一样的,否则,将会引起未定义的行为。原创 2023-07-08 20:17:23 · 393 阅读 · 0 评论 -
C语言——计算数组长度
C 语言计算 一维数组长度 二维数组长度 多维数组长度原创 2022-12-06 22:00:00 · 16671 阅读 · 0 评论 -
C 语言整数强制类型转换
C 语言强制类型转换注意C 语言中定点整数是使用补码存储的无符号数和有符号数强制类型转换无符号数和有符号数强制类型转换,不改变数据内容,改变解释形式例如数字 -4321原码:1001 0000 1110 0001 (最高位为符号位 1:负数,0:正数)反码:1110 1111 0001 1110 (除符号位外各个位取反)补码:1110 1111 0001 1111 (反码加一)其在计算机中存储形式为补码 1110 1111 0001 1111 ,当将其解释为无符号数时就是数字 6121原创 2022-03-26 22:02:41 · 4191 阅读 · 0 评论 -
time 相关函数
**## 结构struct timeval{ time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */}struct timezone{ int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of DST correction */};原创 2022-01-21 08:56:38 · 499 阅读 · 0 评论 -
侵入式链表
侵入式链表普通链表学习数据结构的时候写的链表是下面这个样子的typedef struct LNode{ int data; /* 数据域 */ int num; /* 数据域 */ struct LNode *pre; /* 指向下一个结点 */ struct LNode *next; /* 指向上一个结点 */}侵入式链表在 Linux 内核中链表是这样定义的struct list_node{原创 2021-08-29 17:37:10 · 1490 阅读 · 0 评论 -
C语言--函数定义
函数定义最近在远古代码里见到一种函数的写法,有点颠覆三观,记录一下新版函数定义/* new function define */int new_function(int n){ printf("new function define %d\r\n", n); return 1;}旧版函数定义/* old function define */int old_function(n)int n;{ printf("old function define %d\r\原创 2021-04-15 22:48:43 · 432 阅读 · 0 评论 -
C语言--用静态数组实现堆栈
array_stack.c 文件#include "stack.h"static STACK_TYPE stack[STACK_SIZE];static int top_element = -1;void push(STACK_TYPE value){ if (is_full()) { printf("stack is full\n"); return; } top_element++; stack[top_elemen原创 2021-02-01 23:03:23 · 249 阅读 · 0 评论 -
C语言--字符串操作
## 字符串基础字符串是一种重要的数据类型,但是 C 语言并没有显式的字符串数据类型,因为字符串以字符串常量的形式出现或者存储于字符数组中。字符串就是一串零个或多个字符,并且以一个位模式为全 0 的 NUL 字节结尾。因此,字符串所包含的字符内部不能出现 NUL 字节。NUL 字节是字符串的终止符,但他本身并不是字符串的一部分,所以字符串的长度并不包括 NUL 字节。##原创 2021-01-26 08:45:45 · 255 阅读 · 0 评论 -
C语言-测试一个整数中有多少个1
#include <stdio.h>/*** 这个函数返回参数值中值为 1 的位的个数。*/int count_one_bits0(unsigned value){ int ones; for (ones = 0; value != 0; value = value >> 1) { if (value % 2 != 0) ones = ones + 1; } return ones;}原创 2021-01-22 22:37:06 · 708 阅读 · 0 评论 -
C语言-const char *ptr、char const *ptr、和 char *const ptr 的区别
const char *prt定义一个指针 ptr,指针所指向的类型是 const char 型的字符常量,这里 ptr 是一个指向 char* 类型的常量,所以不能用 ptr 来修改所指向的内容,换句话说,*ptr 的值为 const,不能修改。但是 ptr 的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对 ptr 而言,这原创 2021-01-21 08:05:17 · 1596 阅读 · 0 评论 -
C语言-不对称边界实现二分法查找
# `C` 语言-不对称边界实现二分法查找## 问题描述对一个已经排序的整数表执行二分查找。函数的输入包括一个指向表头的指针,表中的元素,以及待查找的数值,函数的输出是一个指向满足查找要求的元素的指针,当未查找到要求的数值时,输出一个 `NULL` 指针。## 实现### 方法一```cint bsearch(int *t, int n, int x){ int lo; int hi; int mid; lo = 0; /* 第一个入界点*/原创 2021-01-18 22:28:57 · 155 阅读 · 0 评论 -
C语言-一种写缓存区数组的方法
#include <stdio.h>#include <stdlib.h>#include <string.h>#define WRITE_BUFFER_SIZE 4096static unsigned char write_buffer[WRITE_BUFFER_SIZE];static unsigned char *bufptr;static int flushbuffer(int size){ return 0;}static voi原创 2021-01-14 22:38:52 · 1141 阅读 · 0 评论 -
C语言--词法陷阱
词法陷阱引言if (x > big) big = x;在 C 语言中,符号之间的空白(包括空格符,制表符或换行符)将被忽略,因此上面的语句还可以写成:if(x>big)big=x;= 不同于 === 表示赋值,== 表示等于例如下面的语句本意似乎是要检查 x 是否等于 y:if(x = y) break;而实际上是将 y 的值赋给了 x,然后检查该值是否为零。& 和 | 不同于 && 和 ||& 按位原创 2021-01-05 23:26:14 · 126 阅读 · 0 评论 -
C语言--连接器
连接概述一个 C 程序可能是由多个分别编译的部分组成,这些不同部分通过一个通常叫做连接器的程序合并成一个整体。什么是连接器C 语言中的一个重要思想就是分别编译,即若干个源程序可以在不同的时候单独进行编译,然后在恰当的时候整合在一起。但是连接器一般是与 C 编译器分离的,它不可能了解 C 语言的诸多细节。尽管连接器并不理解 C 语言,然而它却能够理解机器语言和内存布局。编译器的责任就是把 C 源程序 翻译 成对连接器有意义的形式,这样连接器就能够 读懂 C 源程序了。典型的连接器把由编译器或汇编器生原创 2020-12-31 23:44:56 · 2264 阅读 · 0 评论 -
C语言-标准库
C 标准库函数简介stdio.h 头文件定义了三个变量类型,一些宏和各种函数来执行输入输出。库变量变量描述size_t这是无符号整型,它是 sizeof 关键字的结果FILE这是一个适合存储文件流信息的对象类型fops_t这是一个适合存储文件中任何位置的对象类型fopen 函数描述C 库函数 FILE *fopen(const char *filename, const char *mode) 使用给定的模式 mode 打开 filename 所指向的原创 2020-12-28 23:30:12 · 175 阅读 · 0 评论 -
C语言-指针数组和数组指针
指针数组和数组指针指针数组概念指针数组:首先它是一个数组,数组里面的元素存放的是指针定义例如:int *p1[5]由于 [] 的优先级比 * 的优先级高,所以先组成 p1[5],构成一个数组的定义,数组名为 p1,而 int * 修饰的是数组的内容,即数组的每个元素。也就是说,该数组包含 5 个 指向 int 类型数据的指针。测试代码#include <stdio.h>int main(int argc, char *argv[]){ printf("hello原创 2020-12-24 21:06:15 · 239 阅读 · 0 评论 -
C语言-比较字符串是否相等(计时攻击)
C 语言版#include <stdio.h>int util_cmp_const(const void *a, const void *b, const size_t size){ const unsigned char *_a = (const unsigned char *)a; const unsigned char *_b = (const unsigned char *)b; unsigned char result = 0; size_t i原创 2020-12-23 13:32:13 · 466 阅读 · 0 评论 -
递归的定义与实现原理
递归递归的定义若一个对象部分地包含它自己,或用它自己给自己定义,则称这个对象是递归的。若一个过程直接地或间接地调用自己,则称这个过程是递归的过程。求 n 的阶乘斐波拉切序列汉诺塔等需要用到递归的情况递归定义的数学函数阶乘问题2 阶的斐波拉契序列具有递归特性的数据结构二叉树广义表可递归求解的问题迷宫问题汉诺塔问题### 递归的思想用分治法求解分治法:对于一个较为复杂的问题,能够分解成几个相对简单的且解法相同或类似的子问题来原创 2020-11-16 23:02:45 · 417 阅读 · 0 评论 -
C 语言隐藏结构体细节
C 语言隐藏结构体细节头文件中声明在头文件的声明结构体的类型和对结构体的操作方法#ifndef __MY_INCLUDE_H__#define __MY_INCLUDE_H__#include <stdio.h>#include <malloc.h>struct thread;char get_thread_flag(struct thread * thread);char get_thread_flags(struct thread * thread);ch原创 2020-09-17 23:58:37 · 814 阅读 · 0 评论 -
C 语言 32 个关键字
C 语言 32 个关键字编号关键字意义1auto声明自动变量,缺省时编译器一般默认为 auto2int声明整型变量3double声明双精度变量4long声明长整型变量5char声明字符型变量6float声明浮点型变量7short声明短整型变量8signed声明有符号类型变量9unsigned...原创 2020-04-05 19:32:35 · 181 阅读 · 0 评论 -
数组名作为函数参数时会退化为指针
测试代码#include <stdio.h>#include <string.h>char buf_arr[100] = {0};char buf_char[100] = "this is a strint";int fun(char *buf, char *string);int fun(char *buf, char *string){ ...原创 2020-02-19 18:30:17 · 339 阅读 · 0 评论 -
C-指针加/减一个整数
给指针加上一个整数实际上加的数是这个整数和指针数据类型对应字节数的乘积。用在数组中就是对数组元素的偏移测试程序#include "stdio.h"int main(int argc, char *argv){ int test_arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9 ,10}; int test_num = 3; int...原创 2020-01-19 17:40:49 · 1191 阅读 · 0 评论 -
C语言--break、continue、return和goto
1、break: break 语句,它不仅可以跳出“循环体”,还可以跳出switch语句。同时,break 也只能用于这两种情况。break 语句不能用于循环语句和 switch 语句之外的任何其他语句中。 break是用于永久终止循环。即不执行本次循环中break后面的语句,直接跳出循环。 不管是for循环,还是while循环,或者是do…while循环,都可以用brea...原创 2018-12-26 16:53:35 · 731 阅读 · 0 评论 -
C语言--字节对齐问题
结构体中字节对齐问题 为了提高CPU访问内存的效率,可能CPU在读取数据的时候回一次性读取4字节、或者2字节、8字节等大小的数据,所有编译器在把数据存放于内存的时候,会自动对齐。 1、字节对齐规则: 字节对齐有以下几种规律: 1.1以最大的成员占据的空间大小对齐 typedef struct { char a; /*1...原创 2018-11-28 14:38:46 · 283 阅读 · 0 评论 -
C语言--union联合
联合union简单测试例程: #include<stdio.h>union{ int k; struct { int x; int y; int z; }u;}a;int main(void){ a.u.x=45; a.u.y=67; a.u.z=25; a....原创 2018-11-28 13:53:04 · 363 阅读 · 0 评论 -
C语言——malloc函数详解
malloc函数和free函数详解引言:为什么使用动态内存分配当你声明数组时,你必须用一个编译时常量指定数组的长度。但是,数组的长度常常在运行时才知道,这是由于它所需要的内存空间取决于输入数据。例如,一个用于计算学生等级和平均分的程序可能需要存储一个班...原创 2018-10-23 11:55:50 · 57066 阅读 · 6 评论 -
C语言---数组和指针
令人震惊的事实:数组和指针并不相同文件1:int my_array[5];文件2:extern int *my_array;这样的程序能不能运行呢?肯定是不能运行的这里文件1定义了一个数组my_array,但文件2申明它为指针。这有什么错误吗?,无论如何,“每个人都知道”在C语言中,数组和指针非常相似。问题在于“每个人”这种说法是错误的。定义和申明的区别...原创 2018-10-10 20:37:31 · 158 阅读 · 0 评论 -
C语言---《C陷阱与缺陷》边界计算与不对称边界
以第一个入界点和第一个出界点来表示一个数值范围这里下界是“入界点”,即包括在取值范围之中;而上界是“出界点”,即不包括在取值范围之中。这种不对称也许从数学上而言并不优美,但是它对于程序设计的简化效果很好。对于像C语言这样的数组下标从0开始的语言,不对称边界给程序设计带来的便利尤其明显:这种数组的上界(即第一个“出界点”)恰好是数组元素的个数!因此,如果我们要在C语言中定义一个拥有10个元素...原创 2018-10-10 13:43:31 · 249 阅读 · 0 评论 -
C语言---《C陷阱和缺陷》字符和字符串
C语言中的单引号和双引号含义迥异,在某些情况下如果把二者弄混,编译器并不会检测报错,从而在运行时产生难以预料的结果。用单引号引起来的一个字符实际上代表一个整数,整数值对应于该字符在编译器采用的字符集中的序列值。因此对于采用ASCII字符集的编译器而言,'a'的含义与0141(八进制)或者97(十进制)严格一致。用双引号引起的字符串,代表的却是一个指向无名数组起始字符的指针,该指针数组被双引...原创 2018-10-10 13:18:52 · 177 阅读 · 0 评论 -
C语言---《C专家编程》编译器日期被破坏
char * localized_time(char * filename){ struct tm *tm_ptr; struct stat stat_block; char buffer[120]; stat(filename,&stat_block); tm_ptr = localtime(&stat_block.st_m...原创 2018-10-09 10:30:45 · 144 阅读 · 0 评论 -
C语言---C语言中的符号重载
《C专家编程》符号重载符号 意义 static 在函数内部,表示 该变量的值在各个调用间一直保持延续性 在函数这一级,表示该函数只对本文件可见 extern 用于函数定义,表示全局可见(属于冗余的) 用于变量,表示它在其他地方定义 void 作为函数的返回类型,表示不返回任何值 在指针申明中,表...原创 2018-10-08 13:12:45 · 343 阅读 · 0 评论 -
C语言---sizeof运算符的返回类型
1、sizeof 运算符返回的是一个 unsigned 类型#include<stdio.h>int array_table[6]={12,14,15,35};#define LEN (sizeof(array_table)/sizeof(array_table[0]))int main(void){ int x=-1; if(x<=LEN...原创 2018-10-08 12:46:37 · 10845 阅读 · 0 评论 -
C语言--《C专家编程》C语言申明的优先级规则
A 申明从它的名字开始读取,然后按照优先级顺序依次读取。B 优先级从高到低依次是: B.1 申明中被括号括起来的部分 B.2 后缀操作符:括号()表示这是一个函数,而方括号[]表示这是一个数组。 B.3 前缀操作符:星号*表示“指向---的指针”。C 如果const和volatile关键字后面紧跟类型说明符(如int ,long等),那它作用于类型说明符,在其...原创 2018-10-09 21:32:09 · 196 阅读 · 0 评论 -
C语言--字符串操作
1、字符串基础 字符串是一种重要的数据类型,但是C语言并没有显式的字符串数据类型,因为字符串以字符串常量的形式出现或者存储于字符数组中。 字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结尾。因此,字符串所包含的字符内部不能出现NUL字节。NUL字节是字符串的终止符,但他本身并不是字符串的一部分,所以字符串的长度并不包括NUL字节。2、字符串长度 库函数s...原创 2018-12-28 21:22:37 · 1372 阅读 · 0 评论 -
C语言--一维数组
一维数组: int a[10]; 一维数组名a是一个指针常量,而不是指针变量。你不能修改常量的值 在几乎所有使用数组名的表达式中,数组名的值是一个指针常量,也就是数组第一个元素的地址。它的类型取决于数组元素的类型;如果他们是int类型,那么数组名的类型就是“指向int的常量指针“;如果他们是其他类型,那么数组名的类型就是”指向其他类型的常量指针“。 只有在两种场合下...原创 2019-01-11 23:11:17 · 332 阅读 · 0 评论 -
C语言--main函数的两个参数argc和argv
1、理论部分:C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv。第一个形参:argc(arguments count参数数)必须是整型变量第二个形参:argv(arguments value/vector参数值)必须是指向字符串的指针数组。所以main函数的函数应写为以下两种形式的一种:int main(int argc,char *argv[]){…}i...原创 2019-01-07 13:37:05 · 14979 阅读 · 1 评论 -
C语言--函数指针(二、回调函数)
如果让你在一个单链表中查找一个值,你会怎么写呢?是不是像下面这样:Node *search_list(Node *node, int const value){ while (node != NULL) { if (node->value == value) break; node = node->n...原创 2019-06-22 12:01:04 · 151 阅读 · 0 评论 -
C语言--函数指针(一、概述)
函数指针最常见的两个用途是跳转表和作为参数传递给另一个函数。简单声明一个函数指针并不意味着它马上就可以使用。和其它指针一样,对函数指针进行间接访问之前必须把它初始化为指向某个函数。#include<stdio.h>#include<stdlib.h>int f(int a); /*声明一个函数 f */int (*pf)(int a);...原创 2019-04-21 19:06:45 · 134 阅读 · 0 评论 -
C语言--函数指针(三、跳转表)
跳转表就是一个函数指针数组。创建一个跳转表需要两个步骤。1、首先,声明并初始化一个函数指针数组,唯一需要留心之处就是确保这些函数的原型出现在这个数组的声明之前2、使用下面的语句替换 switch 语句:result = switch_table(num)(value1, value2);num:用于从数组中选择正确的函数指针,而函数调用操作符将执行这个函数。value...原创 2019-04-21 17:39:51 · 1897 阅读 · 0 评论