其他分享
首页 > 其他分享> > 菜鸟教程C语言笔记3

菜鸟教程C语言笔记3

作者:互联网

(16)字符串
在 C 语言中,字符串实际上是使用 null 字符 \0 终止的一维字符数组

#include <stdio.h>
 
int main ()
{
   char site[7] = {'R', 'U', 'N', 'O', 'O', 'B', '\0'};
 
   printf("菜鸟教程: %s\n", site );
 
   return 0;
}
菜鸟教程: RUNOOB

序号 函数 & 目的
1 strcpy(s1, s2);
复制字符串 s2 到字符串 s1。
2 strcat(s1, s2);
连接字符串 s2 到字符串 s1 的末尾。
3 strlen(s1);
返回字符串 s1 的长度。
4 strcmp(s1, s2);
如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。
5 strchr(s1, ch);
返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
6 strstr(s1, s2);
返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

(17)结构体
C数组允许定义可存储相同类型数据项的变量。
结构:允许存储不同类型的数据项。用于表示一条记录。

  1. struct定义结构体
    例:
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;

结构变量的初始化

#include <stdio.h>
 
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book = {"C 语言", "RUNOOB", "编程语言", 123456};
 
int main()
{
    printf("title : %s\nauthor: %s\nsubject: %s\nbook_id: %d\n", book.title, book.author, book.subject, book.book_id);
}

访问结构成员
成员访问运算符(.)
可以把结构作为函数参数,传参方式与其他类型的变量或指针类似里是引用

指向结构的指针

struct Books *struct_pointer;

位域

把一个一个字节中二进制位划分为不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按照域名进行操作。
这样就可以把不同的对象按照一个字节的二进制位域来表示。

struct 位域结构名 
{

 位域列表

};
类型说明符 位域名: 位域长度 

一个位域存储在同一个字节中,如一个字节所剩的空间不够存放另一位域时,则会从下一单元起存放该位域。也可以有意使某位域从下一单元开始。

由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。如果最大长度大于计算机的整数字长,一些编译器可能会允许域的内存重叠,另外一些编译器可能会把大于一个域的部分存储在下一个字中。

位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的

位域的使用

位域变量名.位域名
位域变量名->位域名

(18)共用体
允许在相同的内存存储不同的数据类型;
可以定义一个带有多成员的共用体,但任何时候只能一个成员带有值。

  1. 定义共同体
    union语句
    例:
union Data
{
   int i;
   float f;
   char  str[20];
} data
  1. 访问共同体成员
    成员访问运算符(.)

(19)位域

struct
{
  type [member_name] : width ;
};

(20)typedef
功能:为类型起一个新名字。

typedef unsigned char BYTE;
//在这个类型定义之后,标识符 BYTE 可作为类型 unsigned char 的缩写,
例如:
BYTE  b1, b2;
  1. typedef vs #define
    #define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同:typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。

(21)输入&输出
1、scanf() 和 printf() 函数
scanf()从标准输入(键盘)读取并格式化
printf()发送格式化输出到标准输出(屏幕)

2、getchar() & putchar() 函数
getchar() 从屏幕读取下一个可用的字符,并把它返回为一个整数。在同一个时间内只会读取一个单一的字符。可以在循环内使用这个方法,以便从屏幕上读取多个字符。
putchar() 把字符输出到屏幕上,并返回相同的字符。这个函数在同一个时间内只会输出一个单一的字符。您可以在循环内使用这个方法,以便在屏幕上输出多个字符。
3、gets() & puts() 函数
char *gets(char *s) 函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。
int puts(const char *s) 函数把字符串 s 和一个尾随的换行符写入到 stdout。

(22)文件读写
如何创建、打开、关闭文本文件或二进制文件。

  1. 打开和创建:fopen()
    FILE *fopen( const char * filename, const char * mode );
  2. 关闭fclose()
    int fclose( FILE *fp );
  3. 写入fputc()
    int fputc( int c, FILE *fp );
  4. 读取fgetc()
    int fgetc( FILE * fp );

(23)预处理器
预处理指令

#define 定义宏
#include 包含一个源代码文件
#undef 取消已定义的宏
#ifdef 如果宏已经定义,则返回真
#ifndef 如果宏没有定义,则返回真
#if 如果给定条件为真,则编译下面代码
#else #if 的替代方案
#elif 如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif 结束一个 #if……#else 条件编译块
#error 当遇到标准错误时,输出错误消息
#pragma 使用标准化方法,向编译器发布特殊的命令到编译器中

预定义宏

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

预处理器运算符

C 预处理器提供了下列的运算符来帮助您创建宏:
宏延续运算符(\)
一个宏通常写在一个单行上。但是如果宏太长,一个单行容纳不下,则使用宏延续运算符(\)

字符串常量化运算符(#)
在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)。在宏中使用的该运算符有一个特定的参数或参数列表

标记粘贴运算符(##)
宏定义内的标记粘贴运算符(##)会合并两个参数。它允许在宏定义中两个独立的标记被合并为一个标记

参数化的宏

在使用带有参数的宏之前,必须使用 #define 指令定义。参数列表是括在圆括号内,且必须紧跟在宏名称的后边。宏名称和左圆括号之间不允许有空格

#include <stdio.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int main(void)
{
   printf("Max between 20 and 10 is %d\n", MAX(10, 20));  
   return 0;
}

(24)错误处理
errno、perror() 和 strerror()

C 语言提供了 perror() 和 strerror() 函数来显示与 errno 相关的文本消息。
perror() 函数显示您传给它的字符串,后跟一个冒号、一个空格和当前 errno 值的文本表示形式。
strerror() 函数,返回一个指针,指针指向当前 errno 值的文本表示形式。

#include <stdio.h>
#include <errno.h>
#include <string.h>
 
extern int errno ;
 
int main ()
{
   FILE * pf;
   int errnum;
   pf = fopen ("unexist.txt", "rb");
   if (pf == NULL)
   {
      errnum = errno;
      fprintf(stderr, "错误号: %d\n", errno);
      perror("通过 perror 输出错误");
      fprintf(stderr, "打开文件错误: %s\n", strerror( errnum ));
   }
   else
   {
      fclose (pf);
   }
   return 0;
}

(25)递归
函数在使用时,调用自身
语法格式如下:

void recursion()
{
   statements;
   ... ... ...
   recursion(); /* 函数调用自身 */
   ... ... ...
}
 
int main()
{
   recursion();
}

(26)可变参数
希望函数带有可变数量的参数,而不是预定义数量的参数。
例:

int func(int, ... ) 
{
   .
   .
   .
}
 
int main()
{
   func(2, 2, 3);
   func(3, 2, 3, 4);
}

注意:函数 func() 最后一个参数写成省略号,即三个点号(…);
省略号之前的那个参数是 int,代表了要传递的可变参数的总数。为了使用这个功能,需要使用 stdarg.h 头文件,该文件提供了实现可变参数功能的函数和宏。
具体步骤如下:
定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数。在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。
使用 int 参数和 va_start 宏来初始化 va_list 变量为一个参数列表。宏 va_start 是在 stdarg.h 头文件中定义的。
使用 va_arg 宏和 va_list 变量来访问参数列表中的每个项。
使用宏 va_end 来清理赋予 va_list 变量的内存。

(27)内存管理
动态分配内存
例:
char name[100];
free() 释放内存
realloc() 增加或减少已分配的内存块的大小

(28)命令行参数

执行程序时,可以从命令行传值给 C 程序。这些值被称为命令行参数。
命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向传递给程序的每个参数

(29)排序算法
冒泡排序

重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来

选择排序

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕

插入排序

的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到 {\displaystyle O(1)} {\displaystyle O(1)}的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间

希尔排序

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位

归并排序

把数据分为两段,从两段中逐个选最小的元素移入新数据段的末尾。
可从上到下或从下到上进行。

快速排序

在区间中随机挑选一个元素作基准,将小于基准的元素放在基准之前,大于基准的元素放在基准之后,再分别对小数区与大数区进行排序。

标签:运算符,教程,int,菜鸟,C语言,char,参数,位域,排序
来源: https://blog.csdn.net/m0_51959453/article/details/115014262