当前位置: 首页 > wzjs >正文

医院网站建设官网短视频推广渠道有哪些

医院网站建设官网,短视频推广渠道有哪些,邢台移动网络优化是哪家公司,企业网站怎样做可以搜索到文章目录 入门hello.c变量常量 Constants注释打印文本控制空格数字符串 Strings条件判断三元运算符SwitchWhile 循环Do/While 循环For 循环跳出循环 Break/ContinueWhile Break 示例While continue 示例数组 Arrays枚举 Enum枚举示例应用用户输入用户输入字符串内存地址创建指针…

文章目录

    • 入门
      • hello.c
      • 变量
      • 常量 Constants
      • 注释
      • 打印文本
      • 控制空格数
      • 字符串 Strings
      • 条件判断
      • 三元运算符
      • Switch
      • While 循环
      • Do/While 循环
      • For 循环
      • 跳出循环 Break/Continue
      • While Break 示例
      • While continue 示例
      • 数组 Arrays
      • 枚举 Enum
      • 枚举示例应用
      • 用户输入
      • 用户输入字符串
      • 内存地址
      • 创建指针
      • 指针变量
      • 取消引用
    • 运算符
      • 算术运算符
      • 赋值运算符
      • 比较运算符
      • 逻辑运算符
      • 运算符示例
      • 位运算符
    • 数据类型 Data Types
      • 基本数据类型
      • 数据类型
      • 基本格式说明符
      • 基本格式说明符
      • 数据格式示例
    • 预处理器
      • 预处理器指令
      • 预定义宏
        • 预定义宏示例
      • 宏延续运算符(\)
      • 字符串常量化运算符(#)
      • 标记粘贴运算符(##)
      • defined() 运算符
      • 参数化的宏
      • Warning 和 Error
    • 函数
      • 函数声明和定义
      • 调用函数
      • 函数参数
      • 多个参数
      • 返回值
      • 递归示例
      • 数学函数
    • Structures 结构
      • 创建结构
      • 结构中的字符串
      • 访问结构成员
      • 复制结构
      • 修改值
    • 文件处理
      • 文件处理函数
      • 打开模式参数
      • 打开文件:fopen()
      • 写入文件:fprintf()
      • 读取文件:fscanf()
      • 写入文件:fputc()
      • 读取文件:fgetc()
      • 写入文件:fputs()
      • 读取文件:fgets()
      • fseek()
      • rewind()
      • ftell()
    • C 网络编程
      • 网络编程介绍
      • 创建套接字
        • 服务端
        • 客户端
      • 绑定套接字
        • 服务端
      • 监听和接收连接
        • 服务端
      • 连接到服务端
        • 客户端
      • 发送和接收数据
        • 服务端
        • 客户端
      • 关闭套接字
        • 服务端
        • 客户端
    • I/O多路复用
      • 多路复用介绍
      • 使用select
      • 使用poll
      • 使用epoll
    • 杂项
      • Docker 运行环境

提供基本语法和方法的 C 快速参考备忘单。

入门

hello.c

#include <stdio.h>int main() {printf("Hello World!");return 0;
}

使用 gcc 编译 hello.c 源文件

$ gcc -o hello hello.c

运行编译后的二进制文件可执行文件(hello)

$ ./hello
# 输出 => Hello World

变量

int myNum = 15;int myNum2; // 声明变量 myNum2
// 变量声明后第一次赋值我们称为初始化
// 如果 初始化 和 赋值 在同一行
// 那么我们可以直接称为 定义变量 myNum2
myNum2 = 15; int myNum3 = 15;  // myNum3 值为 15
myNum3 = 10;      // 现在 myNum3 值为 10float myFloatNum = 5.99; // 浮点数
char myLetter = 'D';     // 字符int x = 5;
int y = 6;
int sum = x + y;  // 添加变量相加
// 声明多个变量
int x = 5, y = 6, z = 50;
int a, b, c = 10;//仅声明变量不初始化
int result;
// 如果未初始化,变量的值是未定义的,使用它会导致错误的结果。
// 此时,变量的值是随机的,因此在使用该变量之前必须进行初始化。
result = result + 10;  // 错误:未初始化的变量 result 会导致不可预测的结果// 部分编译器会输出 Warning,警告未初始化的变量可能导致未定义行为。

常量 Constants

常量在 C 语言中我们一般理解为不能被改变的值,活用常量与符号常量,可以使代码更加清晰和安全

const int minutesPerHour = 60;
const float PI = 3.14;

最佳实践

const int BIRTHYEAR = 1980;

说明与补充:

  1. 常量命名规范:常量通常使用全大写字母,多个单词之间用下划线分隔(例如 BIRTHYEAR、MAX_LENGTH)。

  2. #defineconst

    • #define:宏常量通常在预处理阶段进行替换,不进行类型检查;
    • const:类型安全的常量,编译器可以检查类型,一般更推荐使用 const
  3. 数组大小:可以使用 const 来定义数组的常量大小,这样编译器会将其作为编译时常量处理

注释

// 这是一个注释
printf("Hello World!"); // 这是一个注释
/* 多行注释:用于注释跨多行的内容上面的代码将打印出 Hello World! 到屏幕上注意:多行注释不能嵌套,否则会导致编译错误
*/

注意:
单行注释//可以嵌套,这种注释也是对的
但行内注释应避免过长,以免影响代码可读性

多行注释不能嵌套,否则会导致编译错误(详见下文 ### Warning 和 Error )

/* 这是一个多行注释的开始/* 这是嵌套的多行注释,C语言不支持 */

打印文本

printf("I am learning C.");
int testInteger = 5;
printf("Number = %d", testInteger);float f = 5.99; // 浮点数
printf("Value = %f", f);short a = 0b1010110;  // 2 进制数字
int b = 02713;        // 8 进制数字
long c = 0X1DAB83;    // 16 进制数字
//变量a和c分别为short和long型,所以输出必须加上对应的修饰符h和l// 以 8 进制形式输出
printf("a=%ho, b=%o, c=%lo\n", a, b, c);
// 输出 => a=126, b=2713, c=7325603// 以 10 进制形式输出
printf("a=%hd, b=%d, c=%ld\n", a, b, c);
// 输出 => a=86, b=1483, c=1944451// 以 16 进制形式输出(字母小写)
printf("a=%hx, b=%x, c=%lx\n", a, b, c);
// 输出 => a=56, b=5cb, c=1dab83// 以 16 进制形式输出(字母大写)
printf("a=%hX, b=%X, c=%lX\n", a, b, c);
// 输出 => a=56, b=5CB, c=1DAB83

控制空格数

int a1=20, a2=345, a3=700;
int b1=56720, b2=9999, b3=20098;
int c1=233, c2=205, c3=1;
int d1=34, d2=0, d3=23;// %-9d: 十进制输出,最少宽度为9,左对齐
printf("%-9d %-9d %-9d\n", a1, a2, a3);
printf("%-9d %-9d %-9d\n", b1, b2, b3);
printf("%-9d %-9d %-9d\n", c1, c2, c3);
printf("%-9d %-9d %-9d\n", d1, d2, d3);

输出结果

20        345       700  
56720     9999      20098
233       205       1    
34        0         23   

%-9d 中,d 表示以 10 进制输出,9 表示最少占 9 个字符的宽度,宽度不足以空格补齐,- 表示左对齐,如果不使用左对齐则默认右对齐

对于整型数据,假设:

int a = 12345;
printf(%md”,a);
  1. 若 m <= 实际数据的宽度,则按实际情况输出
  2. 若 m > 实际数据的宽度,则在实际数据的左边用空格补齐
  3. printf(“%0md”,a); 则实际的结果不够 m 位的在数据的左边用0补齐

对于浮点型数据,宽度=整数部分的位数+小数点+小数部分的宽度
假设:

float a = 1.2345; 
printf(%m.nf”,a); //m --整个数据的宽度,n--小数位数
  1. 实际小数位数>n,截去小数右边多余的小数,截去的第一位要注意四舍五入
  2. 实际小数位数< n,在小数的最后补0
  3. 若m省略则写作%.n ,整数部分按照实际输出,小数部分按照以上两个规则进行
  4. m < n+1,自动突破宽度为m的限制,按照实际数据进行输出
  5. m > n+1,整个数据的最左边补空格

字符串 Strings

char greetings[] = "Hello World!";
printf("%s", greetings);

访问字符串

char greetings[] = "Hello World!";
printf("%c", greetings[0]);

修改字符串

char greetings[] = "Hello World!";
greetings[0] = 'J';printf("%s", greetings);
// 输出 "Jello World!"

另一种创建字符串的方法

char greetings[] = {'H','e','l','l','\0'};printf("%s", greetings);
// 输出 "Hell!"

C 没有 String 类型,使用 char 类型并创建一个字符 array

条件判断

int time = 20;
if (time < 18) {printf("再会!");
} else {printf("晚上好!");
}
// 输出 -> "晚上好!"
int time = 22;
if (time < 10) {printf("早上好!");
} else if (time < 20) {printf("再会!");
} else {printf("晚上好!");
}
// 输出 -> "晚上好!"int time = 10;
if (time > 8) {//再嵌套一个ifif (time < 12) {printf("中午好!")}
}
// 输出 -> "中午好!"

三元运算符

三元运算符(? :)是一种简洁的条件判断方式,常用于根据条件选择表达式的值,由三个部分组成:

  • 一个条件表达式
  • 条件为真时的结果
  • 条件为假时的结果
    基本语法:(condition) ? expression1 : expression2;
    如果condition为真,则返回expression1否则返回expression2
int time = 20;
(time < 18) ? printf("再会!") : printf("晚上好!");
// 输出 -> "晚上好!"

三元运算符可以嵌套使用,但嵌套层级太多会导致代码可读性下降,不建议在实际场景使用

int time = 22;
printf((time < 10) ? "早上好!" : (time < 20) ? "再会!" : "晚上好!");
// 输出 -> "晚上好!"

Switch

int day = 4;switch (day) {case 3: printf("周三"); break;case 4: printf("周四"); break;default:printf("期待周末");
}
// 输出 -> "周四" (day 4)

While 循环

int i = 0;while (i < 5) {printf("%d\n", i);i++;
}

注意:不要忘记增加条件中使用的变量,否则循环永远不会结束,成为“死循环”!

Do/While 循环

int i = 0;do {printf("%d\n", i);i++;
} while (i < 5);

For 循环

int i;for (i = 0; i < 5; i++) {printf("%d\n", i);
}

跳出循环 Break/Continue

int i;for (i = 0; i < 10; i++) {if (i == 4) {break;}printf("%d\n", i);
}

i 等于 4 时跳出循环

int i;for (i = 0; i < 10; i++) {if (i == 4) {continue;}printf("%d\n", i);
}

示例跳过 4 的值

While Break 示例

int i = 0;while (i < 10) {if (i == 4) {break;}printf("%d\n", i);i++;
}

While continue 示例

int i = 0;while (i < 10) {i++;if (i == 4) {continue;}printf("%d\n", i);
}

数组 Arrays

int myNumbers[] = {25, 50, 75, 100};
printf("%d", myNumbers[0]);
// 输出 25

更改数组元素

int myNumbers[] = {25, 50, 75, 100};
myNumbers[0] = 33;printf("%d", myNumbers[0]);

循环遍历数组

int myNumbers[] = {25, 50, 75, 100};
int i;for (i = 0; i < 4; i++) {printf("%d\n", myNumbers[i]);
}

设置数组大小

// 声明一个由四个整数组成的数组:
int myNumbers[4];
// 添加元素
myNumbers[0] = 25;
myNumbers[1] = 50;
myNumbers[2] = 75;
myNumbers[3] = 100;

枚举 Enum

enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };

定义枚举变量

enum week a, b, c;enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a, b, c;

有了枚举变量,就可以把列表中的值赋给它

enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
enum week a = Mon, b = Wed, c = Sat;
// 或者
enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a = Mon, b = Wed, c = Sat;

枚举示例应用

enum week {Mon = 1, Tues, Wed, Thurs} day;scanf("%d", &day);switch(day){case Mon:   puts("Monday"); break;case Tues:  puts("Tuesday"); break;case Wed:   puts("Wednesday"); break;case Thurs: puts("Thursday"); break;default:    puts("Error!");
}

用户输入

// 创建一个整数变量来存储我们从用户那里得到的数字
int myNum;// 要求用户输入一个数字
printf("请输入一个数字: \n");// 获取并保存用户输入的号码
scanf("%d", &myNum);// 输出用户输入的数字
printf("您输入的数字: %d", myNum);

用户输入字符串

// 创建一个字符串
char firstName[30];
// 要求用户输入一些文本
printf("输入您的名字: \n");
// 获取并保存文本
scanf("%s", firstName);
// 输出文本
printf("Hello %s.", firstName);

内存地址

创建变量时,会为该变量分配一个内存地址

int myAge = 43;printf("%p", &myAge);
// 输出:0x7ffe5367e044

要访问它,请使用引用运算符 (&)

创建指针

int myAge = 43;      // 一个 int 变量
printf("%d", myAge); // 输出 myAge(43)的值// 输出 myAge 的内存地址(0x7ffe5367e044)
printf("%p", &myAge);

指针变量

int myAge = 43;            // 一个 int 变量
int* ptr = &myAge;         // 名为 ptr 的指针变量,用于存储 myAge 的地址printf("%d\n", myAge);     // 输出 myAge (43) 的值printf("%p\n", &myAge);   // 输出 myAge 的内存地址(0x7ffe5367e044)printf("%p\n", ptr);       // 用指针(0x7ffe5367e044)输出myAge的内存地址

取消引用

int myAge = 43;     // 变量声明
int* ptr = &myAge;  // 指针声明// 参考:用指针输出 myAge 的
// 内存地址(0x7ffe5367e044)
printf("%p\n", ptr);
// 取消引用:用指针输出 myAge 的值 (43)
printf("%d\n", *ptr);

运算符

算术运算符

int myNum = 100 + 50;
int sum1 = 100 + 50;    // 150 (100 + 50)
int sum2 = sum1 + 250;  // 400 (150 + 250)
int sum3 = sum2 + sum2; // 800 (400 + 400)

OperatorNameDescriptionExample
+将两个值相加x + y
-从另一个值中减去一个值x - y
*将两个值相乘x * y
/将一个值除以另一个x / y
%取模返回除法余数x % y
++增量将变量的值增加 1++
--乘量将变量的值减 1--x

赋值运算符

符号示例如同
=x = 5x = 5
+=x += 3x = x + 3
-=x -= 3x = x - 3
*=x *= 3x = x * 3
/=x /= 3x = x / 3
%=x %= 3x = x % 3
&=x &= 3x = x & 3
|=x |= 3x = x | 3
^=x ^= 3x = x ^ 3
>>=x >>= 3x = x >> 3
<<=x <<= 3x = x << 3

比较运算符

int x = 5;
int y = 3;printf("%d", x > y);
// 返回 1(真),因为 5 大于 3

符号名称示例
==等于x == y
!=不等于x != y
>大于x > y
<小于x < y
>=大于或等于x >= y
<=小于或等于x <= y

比较运算符用于比较两个值

逻辑运算符

符号名称说明示例
&&逻辑如果两个语句都为真,则返回真x < 5 && x < 10
||逻辑如果其中一个语句为真,则返回真x < 5 || x < 4
!逻辑反转结果,如果结果为真则返回假!(x < 5 && x < 10)

运算符示例

unsigned int a = 60; /* 60 = 0011 1100 */  
unsigned int b = 13; /* 13 = 0000 1101 */
int c = 0;           c = a & b;      /* 12 = 0000 1100 */ 
printf("Line 1 - c 的值是 %d\n", c );c = a | b;      /* 61 = 0011 1101 */
printf("Line 2 - c 的值是 %d\n", c );
c = a ^ b;      /* 49 = 0011 0001 */
printf("Line 3 - c 的值是 %d\n", c );
c = ~a;         /*-61 = 1100 0011 */
printf("Line 4 - c 的值是 %d\n", c );
c = a << 2;     /* 240 = 1111 0000 */
printf("Line 5 - c 的值是 %d\n", c );
c = a >> 2;     /* 15 = 0000 1111 */
printf("Line 6 - c 的值是 %d\n", c );

位运算符

运算符描述实例
&按位与操作,按二进制位进行"与"运算(A & B) 将得到 12 即为 0000 1100
|按位或运算符,按二进制位进行"或"运算(A | B) 将得到 61 即为 0011 1101
^异或运算符,按二进制位进行"异或"运算(A ^ B) 将得到 49 即为 0011 0001
~取反运算符,按二进制位进行"取反"运算(~A) 将得到 -61 即为 1100 0011
<<二进制左移运算符A << 2 将得到 240 即为 1111 0000
>>二进制右移运算符A >> 2 将得到 15 即为 0000 1111

数据类型 Data Types

基本数据类型

数据类型大小 Size范围 Range描述 Description
char1 字节−128 ~ 127单个字符/字母/数字/ASCII
signed char1 字节−128 ~ 127-
unsigned char1 字节0 ~ 255-
int24 字节−32,768 ~ 32,767存储整数
signed int2 字节−32,768 ~ 32,767
unsigned int2 字节0 ~ 65,535
short int2 字节−32,768 ~ 32,767
signed short int2 字节−32,768 ~ 32,767
unsigned short int2 字节0 ~ 65,535
long int4 字节-2,147,483,648 ~ 2,147,483,647
signed long int4 字节-2,147,483,648 ~ 2,147,483,647
unsigned long int4 字节0 ~ 4,294,967,295
float4 字节
double8 字节
long double10 字节

数据类型

// 创建变量
int myNum = 5;             // 整数
float myFloatNum = 5.99;   // 浮点数
char myLetter = 'D';       // 字符串
// 高精度浮点数据或数字
double myDouble = 3.2325467;
// 打印输出变量
printf("%d\n", myNum);
printf("%f\n", myFloatNum);
printf("%c\n", myLetter);
printf("%lf\n", myDouble);

数据类型说 明
char字符型
short短整型
int整型
long长整型
float单精度浮点型
double双精度浮点型
void无类型

基本格式说明符

格式说明符数据类型
%d%iint 整数
%ffloat 单精度的十进制类型
%lfdouble 高精度浮点数据或数字
%cchar 字符
%s用于 strings 字符串

基本格式说明符

shortintlong
8 进制%ho%o%lo
10 进制%hd%d%ld
16 进制%hx / %hX%x / %X%lx / %lX

数据格式示例

int myNum = 5;
float myFloatNum = 5.99; // 浮点数
char myLetter = 'D';     // 字符串
// 打印输出变量
printf("%d\n", myNum);
printf("%f\n", myFloatNum);
printf("%c\n", myLetter);

预处理器

预处理器指令

指令描述
#define定义宏
#include包含一个源代码文件
#undef取消已定义的宏
#ifdef如果宏已经定义,则返回真
#ifndef如果宏没有定义,则返回真
#if如果给定条件为真,则编译下面代码
#else#if 的替代方案
#elif如果 #if 条件为假,当前条件为
#endif结束一个 #if……#else 条件编译块
#error当遇到标准错误时,输出错误消息
#pragma使用标准化方法,向编译器发布特殊的命令到编译器中
// 所有的 MAX_ARRAY_LENGTH 替换为 20
#define MAX_ARRAY_LENGTH 20
// 系统库中获取 stdio.h
#include <stdio.h>
// 本地目录中获取 myheader.h
#include "myheader.h"
#undef  FILE_SIZE
#define FILE_SIZE 42 // 取消已定义并定义为 42

预定义宏

描述
__DATE__当前日期,一个以 “MMM DD YYYY” 格式表示的字符常量
__TIME__当前时间,一个以 “HH:MM:SS” 格式表示的字符常量
__FILE__这会包含当前文件名,一个字符串常量
__LINE__这会包含当前行号,一个十进制常量
__STDC__当编译器以 ANSI 标准编译时,则定义为 1

ANSI C 定义了许多宏,您可以使用这些宏,但是不能直接修改这些预定义的宏

预定义宏示例
#include <stdio.h>int main() {printf("File :%s\n", __FILE__);printf("Date :%s\n", __DATE__);printf("Time :%s\n", __TIME__);printf("Line :%d\n", __LINE__);printf("ANSI :%d\n", __STDC__);
}

宏延续运算符(\)

一个宏通常写在一个单行上。

#define  message_for(a, b)  \printf(#a " 和 " #b ": 我们爱你!\n")

如果宏太长,一个单行容纳不下,则使用宏延续运算符 \

字符串常量化运算符(#)

#include <stdio.h>#define  message_for(a, b)  \printf(#a " 和 " #b ": 我们爱你!\n")int main(void) {message_for(Carole, Debra);return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Carole 和 Debra: 我们爱你!

需要把一个宏的参数转换为字符串常量时,使用字符串常量化运算符 #

标记粘贴运算符(##)

#include <stdio.h>#define tokenpaster(n) \printf ("token" #n " = %d", token##n)int main(void){int token34 = 40;tokenpaster(34);return 0;
}

defined() 运算符

#include <stdio.h>#if !defined (MESSAGE)#define MESSAGE "You wish!"
#endifint main(void) {printf("信息如下: %s\n", \MESSAGE);  return 0;
}

参数化的宏

int square(int x) {return x * x;
}

宏重写上面的代码,如下:

#define square(x) ((x) * (x))

宏名称和左圆括号之间不允许有空格

#include <stdio.h>
#define MAX(x,y) ((x) > (y) ? (x) : (y))int main(void) {printf("20 到 10 之间的最大值是 %d\n", \MAX(10, 20));  return 0;
}

Warning 和 Error

在 C 语言中,警告(Warning)和错误(Error)是编译器用于标识代码潜在问题或阻止代码编译的两种机制

警告
警告提示代码中可能存在的问题,但不会阻止代码编译。处理警告可以提升代码质量和可移植性。

常见警告示例

  1. 未使用的变量
    int x; printf("%d",x);
  2. 类型隐式转换(可能导致数据丢失)
    int x = 3.14; //浮点数被隐式转换
    int a = 2147483647 + 1; //可能溢出
  3. 函数声明与定义不匹配

错误
警告提示代码中可能存在的问题,但不会阻止代码编译。处理警告可以提升代码质量和可移植性。

常见错误示例

  1. 语法错误(如缺少分号)
    int x=1
  2. 函数定义冲突
void func(int);
void func(double);
  1. 函数或变量未定义
    y = 10; printf("%d",y);
  2. 头文件缺失或冲突
    #include <unknown.h>

使用编译器指令控制警告和错误:

  1. 抑制警告
    可以使用编译器选项来关闭特定的警告,例如在 GCC 中:
gcc -w file.c      # 禁用所有警告
gcc -Wall file.c   # 启用所有常见警告
gcc -Werror file.c # 将警告视为错误
  1. 使用 #pragma 控制警告
    在某些编译器中,可以使用#pragma指令启用或禁用警告
#include <stdio.h>
#pragma warning(disable : 4996) // 禁用警告(适用于 MSVC 编译器)int main() {printf("Hello, world!");return 0;
}

总结

区别点Warning(警告)Error(错误)
严重程度程序可继续编译,但可能存在隐患编译无法完成,必须修复
编译结果生成可执行文件无法生成可执行文件
触发原因潜在问题,例如隐式转换或未使用的变量语法或语义错误,例如语法错误或未定义变量
修复必要性可选择修复,但建议修复以避免潜在问题必须修复才能继续编译
编译器选项调整可以忽略或转换为错误(如 -Werror无法调整,必须修复

函数

函数声明和定义

int main() {printf("Hello World!");return 0;
}

函数由两部分组成

void myFunction() { // 声明 declaration// 函数体(要执行的代码)(definition)
}

  • Declaration 声明函数名称、返回类型和参数 (如果有)
  • Definition 函数体 (要执行的代码)

// 函数声明
void myFunction();
// 主要方法
int main() {myFunction(); // --> 调用函数return 0;
}
void myFunction() {// 函数定义printf("晚上好!");
}

调用函数

// 创建函数
void myFunction() {printf("晚上好!");
}
int main() {myFunction();  // 调用函数myFunction();  // 可以被多次调用return 0;
}
// 输出 -> "晚上好!"
// 输出 -> "晚上好!"

函数参数

void myFunction(char name[]) {printf("Hello %s\n", name);
}
int main() {myFunction("Liam");myFunction("Jenny");return 0;
}
// Hello Liam
// Hello Jenny

多个参数

void myFunction(char name[], int age) {printf("你好 %s 你 %d 岁了。\n",name,age);
}
int main() {myFunction("Liam", 3);myFunction("Jenny", 14);return 0;
}
// 你好 Liam 你 3 岁了。
// 你好 Jenny 你 14 岁了。

返回值

int myFunction(int x) {return 5 + x;
}int main() {printf("结果: %d", myFunction(3));return 0;
}
// 输出 8 (5 + 3)

两个参数

int myFunction(int x, int y) {return x + y;
}int main() {printf("结果: %d", myFunction(5, 3));// 将结果存储在变量中int result = myFunction(5, 3);printf("结果 = %d", result);return 0;
}
// 结果: 8 (5 + 3)
// 结果 = 8 (5 + 3)

递归示例

int sum(int k);
int main() {int result = sum(10);printf("%d", result);return 0;
}int sum(int k) {if (k > 0) {return k + sum(k - 1);} else {return 0;}
}

数学函数

#include <math.h>
printf("%f", sqrt(16));   // 平方根
printf("%f", ceil(1.4));  // 四舍五入 (入)
printf("%f", floor(1.4)); // 四舍五入 (舍)
printf("%f", pow(4, 3));  // x(4)的y(3)次方

  • abs(x) 绝对值
  • acos(x) 反余弦值
  • asin(x) 反正弦值
  • atan(x) 反正切
  • cbrt(x) 立方根
  • cos(x) 余弦
  • exp(x) Ex 的值
  • sin(x) x 的正弦值
  • tan(x) 角度的正切

Structures 结构

创建结构

struct MyStructure {  // 结构声明int myNum;     // 成员(int 变量)char myLetter; // 成员(char 变量)
}; // 用分号结束结构

创建一个名为 s1 的结构变量

struct myStructure {int myNum;char myLetter;
};int main() {struct myStructure s1;return 0;
}

结构中的字符串

struct myStructure {int myNum;char myLetter;char myString[30]; // String
};int main() {struct myStructure s1;strcpy(s1.myString, "Some text");// 打印值printf("我字符串: %s", s1.myString);return 0;
}

使用 strcpy 函数为字符串赋值

访问结构成员

// 创建一个名为 myStructure 的结构
struct myStructure {int myNum;char myLetter;
};int main() {// 创建一个名为 s1 的 myStructure 结构变量struct myStructure s1;// 为 s1 的成员赋值s1.myNum = 13;s1.myLetter = 'B';// 创建一个名为 s2 的 myStructure 结构变量// 并为其赋值struct myStructure s2 = {13, 'B'};// 打印值printf("My number: %d\n", s1.myNum);printf("My letter: %c\n", s1.myLetter);return 0;
}

创建不同的结构变量

struct myStructure s1;
struct myStructure s2;
// 为不同的结构变量赋值
s1.myNum = 13;
s1.myLetter = 'B';s2.myNum = 20;
s2.myLetter = 'C';

复制结构

struct myStructure s1 = {13, 'B', "Some text"
};struct myStructure s2;
s2 = s1;

示例中,将 s1 的值复制到 s2

修改值

// 创建一个结构变量并为其赋值
struct myStructure s1 = {13, 'B'
};
// 修改值
s1.myNum = 30;
s1.myLetter = 'C';
// 打印值
printf("%d %c %s",s1.myNum,s1.myLetter);

文件处理

文件处理函数

函数描述 Description
fopen()打开新文件或现有文件
fprintf()将数据写入文件
fscanf()从文件中读取数据
fputc()将一个字符写入文件
fgetc()从文件中读取一个字符
fclose()关闭文件
fseek()将文件指针设置到给定位置
fputw()将整数写入文件
fgetw()从文件中读取一个整数
ftell()返回当前位置
rewind()将文件指针设置为文件的开头

C 库中有许多函数可以打开/读取/写入/搜索关闭文件

打开模式参数

模式 Mode描述 Description
r读取模式打开一个文本文件,允许读取文件
w模式打开一个文本文件,允许写入文件
a追加模式打开一个文本文件
如果文件不存在,则会创建一个新文件
r+读写模式打开一个文本文件,允许读写文件
w+读写模式打开一个文本文件,允许读写文件
a+读写模式打开一个文本文件,允许读写文件
rb读取模式打开二进制文件
wb写入模式打开二进制文件
ab追加模式打开二进制文件
rb+读写模式打开二进制文件
wb+读写模式打开二进制文件
ab+读写模式打开二进制文件

打开文件:fopen()

#include<stdio.h>void main( ) {FILE *fp;char ch;fp = fopen("file_handle.c", "r");while (1) {ch = fgetc(fp);if (ch == EOF)break;printf("%c", ch);}fclose(fp);
}

对文件执行所有操作后,必须关闭 fclose() 该文件

写入文件:fprintf()

#include <stdio.h>main() {FILE *fp;fp = fopen("file.txt", "w"); // 打开文件// 将数据写入文件fprintf(fp, "fprintf 的 Hello 文件..\n");fclose(fp); // 关闭文件  
}  

读取文件:fscanf()

#include <stdio.h>  
main(){FILE *fp;char buff[255]; // 创建char数组存储文件数据fp = fopen("file.txt", "r");while(fscanf(fp, "%s", buff)!=EOF) {printf("%s ", buff);}fclose(fp);
}

写入文件:fputc()

#include <stdio.h>main(){FILE *fp;fp = fopen("file1.txt", "w"); // 打开文件fputc('a',fp); // 将单个字符写入文件fclose(fp);    // 关闭文件
}

读取文件:fgetc()

#include<stdio.h>
#include<conio.h>
void main() {FILE *fp;char c;clrscr();fp=fopen("myfile.txt", "r");while((c=fgetc(fp))!=EOF){printf("%c", c);}fclose(fp);getch();
}

写入文件:fputs()

#include<stdio.h>
#include<conio.h>void main(){FILE *fp;clrscr();fp = fopen("myfile2.txt","w");fputs("hello c programming",fp);fclose(fp);getch();
}

读取文件:fgets()

#include<stdio.h>
#include<conio.h>void main() {FILE *fp;char text[300];clrscr();fp=fopen("myfile2.txt", "r");printf("%s", fgets(text, 200, fp));fclose(fp);getch();
}

fseek()

#include <stdio.h>
void main(){FILE *fp;fp = fopen("myfile.txt","w+");fputs("This is Book", fp);// 将文件指针设置到给定位置fseek(fp, 7, SEEK_SET);fputs("Kenny Wong", fp);fclose(fp);
}

将文件指针设置到给定位置

rewind()

#include<stdio.h>
#include<conio.h>
void main(){FILE *fp;char c;clrscr();fp=fopen("file.txt", "r");while((c=fgetc(fp)) != EOF){printf("%c", c);}rewind(fp); // 将文件指针移动到文件的开头while((c=fgetc(fp)) != EOF){printf("%c", c);}fclose(fp);getch();
}
// 输出
// Hello World!Hello World!

ftell()

#include <stdio.h>
#include <conio.h>void main (){FILE *fp;int length;clrscr();fp = fopen("file.txt", "r");fseek(fp, 0, SEEK_END);length = ftell(fp); // 返回当前位置fclose(fp);printf("文件大小: %d bytes", length);getch();
}
// 输出
// 文件大小: 18 bytes

C 网络编程

网络编程介绍

C使用sockets进行网络通信。包含头文件:

  • #include <sys/socket.h>: 套接字操作,如创建、绑定和监听套接字
  • #include <arpa/inet.h>: IP 地址转换
  • #include <unistd.h>: 关闭套接字等
  • #include <netinet/in.h>: 网络地址结构定义和相关敞亮

创建套接字

网络通信的第一步是创建套接字。套接字是网络通信的基础,通过它可以与远程主机进行数据交换。

服务端
int server_fd, new_socket; // 定义服务器文件描述符和新连接的套接字
int port = 8080; // 服务器使用的端口号// 创建套接字文件描述符
// AF_INET 表示使用 IPv4 协议,SOCK_STREAM 表示使用 TCP 协议,协议参数通常为 0(默认 TCP)
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);
}
客户端
int sock = 0;  // 客户端的套接字描述符
struct sockaddr_in serv_addr;  // 定义服务器地址结构体// 创建套接字
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {perror("Socket creation failed");exit(EXIT_FAILURE);
}

绑定套接字

服务端创建套接字后,需要将其绑定到特定的 IP 地址和端口,以便客户端能够连接。

服务端
struct sockaddr_in address;  // 定义存储地址信息的结构体
address.sin_family = AF_INET;  // 设置地址族为 IPv4
address.sin_addr.s_addr = INADDR_ANY;  // 将服务器绑定到所有可用的网络接口(即本机的所有 IP 地址)
address.sin_port = htons(port);  // 将端口号转换为网络字节序,大端模式// 将套接字绑定到指定的地址和端口上
// bind() 将服务器的文件描述符与 IP 地址和端口号进行绑定,以便客户端能够通过该地址和端口访问服务器
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);
}

监听和接收连接

服务端在绑定套接字之后,需要进入监听状态,以等待客户端的连接请求。

服务端
// 开始监听客户端连接
// 监听连接请求
// listen() 函数将套接字设置为被动模式,准备接收来自客户端的连接请求
if (listen(server_fd, 3) < 0) {  // 第二个参数 3 表示连接请求的队列大小perror("listen failed");exit(EXIT_FAILURE);
}int addrlen = sizeof(address);  // 获取地址结构体的大小
// accept() 函数会阻塞等待客户端的连接请求,一旦连接请求到来,创建一个新的套接字 new_socket 用于数据传输
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept failed");exit(EXIT_FAILURE);
}

连接到服务端

客户端使用 connect() 函数连接到服务器的 IP 地址和端口。

客户端
// 设置服务器地址
serv_addr.sin_family = AF_INET;  // 设置地址族为 IPv4
serv_addr.sin_port = htons(port);  // 将端口号转换为网络字节序// 将 IP 地址转换为二进制并存储在 serv_addr 结构体中
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {perror("Invalid address/ Address not supported");exit(EXIT_FAILURE);
}// 连接服务器
// connect() 函数将客户端的套接字与服务器的地址绑定,从而建立连接
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {perror("Connection Failed");exit(EXIT_FAILURE);
}

发送和接收数据

一旦连接建立,服务端和客户端可以通过套接字发送和接收数据。

服务端
// 服务端从客户端接收数据
char buffer[1024] = {0};  // 缓冲区,用于存储接收的数据
int valread = read(new_socket, buffer, 1024);  // 从客户端读取数据
printf("Client: %s\n", buffer);  // 打印接收到的客户端数据// 服务端发送响应数据给客户端
const char *response = "Hello from server";  // 响应消息
send(new_socket, response, strlen(response), 0);  // 发送数据到客户端
printf("Server message sent\n");
客户端
// 客户端发送数据给服务端
const char *message = "Hello from client";  // 要发送的消息
send(sock, message, strlen(message), 0);  // 发送数据到服务端
printf("Client message sent\n");// 客户端从服务端接收响应数据
char buffer[1024] = {0};  // 缓冲区,用于存储接收到的数据
int valread = read(sock, buffer, 1024);  // 读取服务端的响应数据
printf("Server: %s\n", buffer);  // 打印接收到的服务端数据

关闭套接字

完成通信后,双方都应关闭各自的套接字以释放资源。

服务端
// 关闭服务端套接字
close(new_socket);  // 关闭用于数据传输的客户端套接字
close(server_fd);   // 关闭服务器的监听套接字
客户端
// 关闭客户端套接字
close(sock);  // 关闭客户端的套接字

I/O多路复用

多路复用介绍

在网络编程中,服务端可以使用 I/O 多路复用 技术,如 selectpollepoll。这些技术允许服务端同时监听多个文件描述符(如套接字),并在其中一个发生事件时进行处理,提升系统效率。包含头文件:

  • #include <sys/select.h>: 提供 select
  • #include <poll.h>: 提供 poll
  • #include <sys/epoll.h>: 提供epoll

使用select

fd_set read_fds;  // 定义文件描述符集合
FD_ZERO(&read_fds);  // 清空集合
FD_SET(server_socket, &read_fds);  // 将服务端套接字加入集合int max_fd = server_socket;
int activity = select(max_fd + 1, &read_fds, NULL, NULL, NULL);  // 等待事件发生if (activity < 0 && errno != EINTR) {perror("select error");
}

使用poll

struct pollfd fds[2];  // 定义文件描述符数组
fds[0].fd = server_socket;
fds[0].events = POLLIN;  // 监听读事件int poll_count = poll(fds, 2, -1);  // 等待事件if (poll_count < 0) {perror("poll error");
}

使用epoll

int epoll_fd = epoll_create1(0);  // 创建 epoll 文件描述符
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = server_socket;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_socket, &event) == -1) {perror("epoll_ctl failed");
}struct epoll_event events[10];  // 事件数组
int event_count = epoll_wait(epoll_fd, events, 10, -1);  // 等待事件发生for (int i = 0; i < event_count; i++) {if (events[i].data.fd == server_socket) {// 处理服务端套接字上的事件}
}

杂项

Docker 运行环境

  • 安装 Docker

  • 创建 Dockerfile 文件

    FROM alpine:3.14
    RUN apk add --no-cache gcc musl-dev
    RUN apk add --no-cache g++
    
  • 生成本地 myalpine 镜像

    docker build -t myalpine .
    
  • 运行映像,把当前路径 ($PWD) 映射至容器的 /test 目录,用 gcc 编译程序,exit返回

    docker run -it -v $PWD:/test myalpine
    root@b1a38bd7107a:/# cd test
    root@b1a38bd7107a:/test# gcc -o hello hello.c
    Hello World
    root@b1a38bd7107a:/test# exit
    exit
    
http://www.dtcms.com/wzjs/106193.html

相关文章:

  • 免费申请注册网站网络推广理实一体化软件
  • 怎么设置网站支付功能网站seo优化怎么做
  • 网站开发技术指标是什么营销手段和营销方式
  • 网站设计毕业论文的模板咋写如何进行推广
  • 网站制作制作网站建网站链接式友谊
  • 昆明做网站猫咪科技seo快速排名软件案例
  • 常州网站优化百度推广后台登陆首页
  • 邹平网站建设优化公司爱链工具
  • 大连网站建设培训班深圳推广公司哪家正规
  • 查内部券的网站是怎么做的代运营公司可靠吗
  • 做网站怎么弄如何推销产品给客户
  • 张家港本地论坛seo优化效果怎么样
  • 游戏类网页设计seo外包网站
  • 做直播导航网站搜索引擎优化策略包括
  • 免费html网站模板深圳搜索竞价账户托管
  • 西安做营销型网站建设windows优化大师提供的
  • 智能网站外链吧怎么使用
  • 流媒体视频网站建设互联网营销怎么做
  • 厦门网站建设模板英雄联盟韩国
  • 龙岗做网站公司百度seo网站优化 网络服务
  • 重庆档案馆建设网站东莞网络营销推广专业
  • 做英文网站价格下载手机百度最新版
  • 申请云应用wordpressseo优化关键词放多少合适
  • 买医疗产品的网站建设中国十大it培训机构排名
  • 杭州市建设工程交易网西安官网seo技术
  • wordpress 伪原创插件seo关键词优化费用
  • 湖南企业建网站公司腾讯疫情实时数据
  • 建设的网站打开速度很慢seo网站优化培
  • 成都网站建设设计搜索引擎优化的步骤
  • 电脑维护网站模板优化公司治理结构