C语言-基础


标识符的命名规则和规范

标识符:自己起名字的叫做标识符

标识符的命名规则

1. 由26个英文字母大小写,0-9,_或者$组成

2. 数字不可以开头 3. 不可以使用关键字和保留字,但能包含关键字和保留字

4. C语言中严格区分大小写,长度无限制

5. 标识符不能包含空格

顺序程序设计

数据的表现形式 - 常量和变量 - 常量:用#define指令来指定用一个符号(一般大写)来代表一个常量(好处是一改全改) - 符号常量是预编译指定,在预编译仅仅是进行字符替换,在预编译之后,符号常量将不存在

    #define PI 3.14159267       //注意尾部并没有;
    const int PI = 3.14;//使用const来定义常量
    - `const `和 `#define`的区别
        1. const定义的常量时,带类型,define不带类型.
        2. const是在编译、运行的时候起作用,而#define是在编译的预处理阶段起作用
        3. define只是简单的替换,没有类型检查,简单的字符串替换会导致边界效应
        4. const常量可以进行调试的,define是不能进行调试,主要是预编译阶段就已经替换掉了,调试的时候就没有它了
        5. const不能重定义,不可以定义两个一样的。而define通过取消某个符号的定义再重新定义
//使用const定义
const int PI = 3,14;
const double PI = 3.14;//这是不可取的
#define PI 3.14
#undenfine PI //可以使用#undefine来取消
#define PI 3.1415 //这是可以使用的
        6. define可以配合`ifdef`、`ifndef`、`endif`来使用,可以让代码更加灵活,比如我们可以通过define来启动或者关闭调试信息。
#define PI 3.14
#ifdef PI
printf("存在信息输出");
#endif
#ifndef PI
printf("不存在信息输出");

    - 变量:变量必须先定义,后使用
        - 常变量(const):定义常变量`const float pi = 3.1415926;`
- 数据类型(`用unsigned代表无符号`)(默认有符号)
    - 整型类型
        - 基本类型
            - 基本整型(`int`)
            - 短整型(`short int` )
            - 长整型(`long int`)
            - 双长整型(`long long int`)
            - 字符型(`char`)
            - 布尔型(`bool`)
        - 浮点类型
            - 单精度浮点()
            - 双精度浮点
            - 复数浮点
    - 枚举类型(enum)
    - 空类型(void)
    - 派生类型
        - 指针类型(*)
        - 数组类型([])
        - 结构体类型(struct)
        - 共用体类型(union)
        - 函数类型

注:`基本类型(包括整型和浮点型)和枚举类型变量的值都是数值,统称为算数类型`

`算数类型和指针类型统称纯量类型`,`因为其变量的值是以数字来表示`

`数组类型和结构体类型统称为组合类型`

函数类型用来定义函数

运算符和表达式

C运算符
- 算数运算符
    - 取模公式:a%b = a-a/b*b
- 关系运算符(0是假)
    - 关系运算符只是用非零的数表示真,2也是真.C语言默认是1
- 逻辑运算符
- 位运算符
- 赋值运算符
- 三元运算符(表达式 1 ? 表达式2 : 表达式3)
- 条件运算符
- 逗号运算符
- 指针运算符
- 求字节数运算符
- 强制类型转换运算符
- 成员运算符
- 下标运算符
- 其他运算符

函数

函数参数的传递方式 1. 值传递 1. 基本数据类型 2. 结构体 3. 共用体 4. 枚举类型 2. 引用传递 1. 指针 2. 数组

注意事项

  1. 函数的形参列表可以是多个
  2. C语言传递参数可以是值传递,也可以是传递指针也叫引用传递
  3. 函数命名
  4. 函数中的变量是局部变量
  5. 基本数据类型默认是值传递
  6. 如果希望函数内的变量能够改变函数外的白变量,可以使用指针

Static关键字

基本介绍:

局部变量使用static修饰 1. 局部变量别static修饰之后,我们称为静态局部变量 2. 对应静态局部变量在声明时未赋初始值,编译器会自动初始化为零 3. 静态局部变量存储与进程的静态存储区(全局性质),只会被初始一次,即使函数返回,它的值也会保持不变

1.使用非静态函数之前需要声明(使用extern[外部]关键字)  

- 2.不同的文件可以使用相同名字的静态函数,互不影响.
- *静态函数只能在声明它的文件中可见,其他文件不能引用该函数*

常用的系统函数

字符串<string.h>
strcoy(s1,s2)复制字符串s2到字符串s1
strcat(s1,s2)连接字符串s2到字符串s1的末尾
strcmp(s1,s2)如果s1和s2是相同的返回0;如果s1<s2则返回小于0;如果s1>s2则返回大于0
strlen(s1)返回s1的长度
strchr(s1,ch)返回一个指针,指向字符串s1中字符ch第一次出现的位置
strstr(s1,s2)返回一个指针,指向字符串s1中字符串s2的第一次出现的位置

C语言宏定义

基本介绍 1. #define叫做宏定义命令,它也是C语言预处理命令的一种.所谓宏定义,就是用一个标识符来表示一个字符串,如果在后面的代码中出现了该标识符,那么就全部替换成指定的字符串 2. 宏定义是由源程序中的宏定义命令#define完成的,宏替换是由预处理程序完成的

#define 宏名  字符串(广义)

带参数的宏定义 1. C语言允许宏带有参数,在宏定义中的参数称为"形式参数",在宏调用中的参数称为"实际参数" 2. 对于参数的宏,在展开过程中不仅要进行字符串的替换,还要用实参替换形参 3. 带参宏定义的一般形式为

#define 宏名(形参列表) 字符串   //带参宏定义的一般形式为
宏名(实参列表); //带参宏调用的一般形式

数组

基本介绍

数组可以存放多种同一类型数据.数组也是一种数据类型,是构造类型,传递是以饮用的方式传递(即传递的是地址)
排序和查找
排序:排序也称排序算法(Sort Algorithm),排序是将一组数据,依照指定的顺序进行排列的过程.
#include <stdio.h>
//
// Created by zyq on 2023/3/30.
//

/**
 * 冒泡排序
 */
 

void main() {
    int arr[] = {23, 1, 34, 89, 100};
    int len = sizeof(arr) / sizeof(int);
    int temp = 0;
    for (int i = 0; i < len - 1; i++) {
        for (int j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    for (int i = 0; i < len; i++) {
        printf("%d\t", arr[i]);
    }





排序的分类 1. 内部排序:指将需要处理的所有数据都加载到内存存储器中进行排序 2. 外部排序:数据量过大,无法全部加载到内存,需要借助外部存储进行排序

查找:

顺序查找
#include <stdio.h>
//
// Created by zyq on 2023/3/30.
//
/**
 * 顺序查找
*/
int fine(int arr[], int len, int flag) {

    for (int i = 0; i < len; i++) {
        //printf("%d\n", arr[i]);
        if (arr[i] == flag) {
            return i;
        }
    }


}

void main() {
    int arr[] = {23, 1, 34, 89, 100};
    int len = sizeof(arr) / sizeof(int);
    int flag = 100;
    int a = fine(arr, len, flag);
    printf("%d", a);

} 
二分查找
#include <stdio.h>

//
// Created by zyq on 2023/3/30.
//
/**
* Binary lookup:二分查找
*/

int binaryLookup(int arr[], int left, int right, int find) {


    int mid = (left + right) / 2;
    int midValue = arr[mid];
    if (left > right) {
        return -1;
    }
    if (midValue > find) {
        binaryLookup(arr, left, right - 1, find);
    } else if (midValue < find) {
        binaryLookup(arr, left + 1, right, find);
    } else {
        return mid;
    }

}

void main() {
    int arr[] = {1, 8, 10, 89, 1000, 1234};
    int len = sizeof(arr) / sizeof(int);
    int index = binaryLookup(arr, 0, len - 1, -1);
    printf("%d", index);//0
}
二维数组
//定义二维数组
数据类型 数组名称[][] = {{},{},{}};

#include <stdio.h>
//
// Created by zyq on 2023/3/30.
//

/**
 * 二维数组
 */

int main() {
    int arr[5][5] = {
            {1,4,7,8},
            {6,8,3,2},
            {7,9,0,7},
            {2,12,34,90}
    };
    //遍历二维数组
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            printf("%d\t",arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

字符数组与字符串

用字符数组存放一个字符串

用字符指针指向一个字符串

字符串注意事项 1. 在C语言中,字符串实际上是使用NULL字符('\0')终止的一维字符数组.因此,一个以null结尾的字符串,包含了组成字符串的字符 2. '\0'是ASCII码中的第0个字符,用NULL表示,称为空字符.该字符即不能显示,也不是控制字符,输出该字符不会有任何效果,它在C语言中仅仅作为字符串的结束标志. 3. 字符数组(字符串)在内存中的布局分析


指针

什么是指针
1. 指针是一个变量,其值为另一个变量的地址.
指针的基本介绍
1. 指针也就是内存的地址;所谓指针变量,也就是保存了内存地址的变量。关于指针的基本使用,在讲变量的时候做了入门级的介绍
2. 获取变量的地址,用&比如:int num = 10;,获取num的地址:&num
3. 指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值。
int *ptr = &num;//prt就是指向int类型的指针变量,即ptr是int*类型
4. 获取指针类型所指向的值,使用:*
指针数组
基本介绍:要让数组的元素指向int或者其他数据类型的指针.可以使用指针数组

指针数组的定义:
数据类型 *指针数组名[大小]

指向指针的指针(多种指针)
基本介绍

  指向指针的指针是一种**多级间接寻址**的形式,或者是一个指针链.通常,一个指针包含一个变量地址.当我们定义个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含及实际值的位置 
函数指针
函数指针的定义
returnType (*pointerNme)(param list);
1. returnType为函数的返回类型
2. pointerName为指针名称
3. param list为函数参数列表
4. 参数列表中可以同时给出参数的类型和名称,也可以只给出参数的类型,省略参数的名称
指针的注意事项和细节
1. 指针变量存放的是地址,从这个角度看指针的本质就是地址
2. 变量声明的时候,如果没有确切的地址赋值,为指针变量赋值一个NULL值是一个好的习惯
3. 赋NULL值的指针被称为空指针,NULL指针是一个定义在标准库<stdio.h>中的值为零的常量#define NULL 0
void main(){
  int *p = NULL;
  int num = 34;
  p = &num;
  }

动态内存分配

  1. 全局变量—内存中的静态存储区
  2. 非静态的局部变量—内存中的动态存储区—stack栈
  3. 临时使用的数据—建立动态内存分配区域,需要随时开辟,不需要及时释放—heap堆

内存动态分配的相关函数

---

结构体和共用体

结构体


/**
 结构体
 */
void main(){

//结构体的定义
struct Cat{
    char* name;
    int age;
    char* color;
};
//也可以
struct Cat{
    char* name;
    int age;
    char* color;
}a = {"李华",23,"灰色"}....;

struct Cat cat1;
cat1.name = "lihua";
cat1.age = 19;
cat1.color = "baise2"; 
}

共用体(联合体)

基本介绍

1. 共用体(Union)属于构造类型,他可以包含多个类型的不同成员,和结构体非常类似,但是也有不同的地方
2. 空间大小是共用的,共有数据空间,该空间的大小以占用空间最大的成员变量决定

定义
union 共用体名{
  成员列表
};

//定义共用体的三种方式
//第一种
union data{
  int n;
  char ch;
  double f;
  };
  union data a,b,c;
//第二种
union data{
  int n;
  char ch;
  double f;
  } a,b,c;
//第三种
//匿名共用体
union {
  int n;
  char ch;
  double f;
  } a,b,c;

使用

结构体和共用体的区别

1. 结构体的各个成员会占用不同的内存.互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员

文件操作

文件操作的基本介绍
1. 文件是数据源(保存数据的地方)
2. 文件在程序中是以流的形式来操作的

    ![](https://secure2.wostatic.cn/static/2eTaL2KTnLbq3oNPg75Ufn/image.png)
3. 输入流:数据从数据源(文件)到程序(内存)的路径
4. 输出流:数据从程序(内存)到数据(文件)的路径
getchar()&putchar()函数&gets()&puts()
1. `getchar(void)`:从屏幕读取下一个可用字符,并把它返回为一个整数.这个函数在同一个时间内只会读取一个单一的字符,可以在循环内使用这个方法,以便从屏幕上读取多个字符
2. `int putchar(int c)`:把字符输出到屏幕上,并返回相同的字符,这个函数在同一个时间只会输出一个单一的字符.您可以在循环内使用这个方法,以便在屏幕上输出多个字符
3. `gets()`:从stdin读取一行到s指向的缓冲区,知道读取一个终止或者EOF
4. `puts()`:把字符串s和一个尾随的换行符写入到stdout
文件的打开和关闭
**打开文件**

`fopen()`:用来创建一个新的文件或者打开一个已经存在的文件,这个调用会初始化类型FILE的一个对象,类型FILE包含了所有用来控制流的必要的信息
FILE*fopen(const char * filename(字符串的名字),const char * mode(模式));
**关闭文件**

`int fclose(FILE *fp);`

1. 如果关闭成功返回0,关闭发生错误返回EOF
2. 这个函数实际上会清空缓冲区的数据,关闭文件,并释放用于该文件的所有内存
3. EOF是一个定义在头文件的stdio.h中的常量



在这里,**filename** 是字符串,用来命名文件,访问模式 **mode** 的值可以是下列值中的一个:
模式描述
r打开一个已有的文本文件,允许读取文件。
w打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。
a打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。
r+打开一个文本文件,允许读写文件。
w+打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。
a+打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。
写入文件

下面是把字符写入到流中的最简单的函数:

int fputc( int c, FILE *fp );

函数 fputc() 把参数 c 的字符值写入到 fp 所指向的输出流中。如果写入成功,它会返回写入的字符,如果发生错误,则会返回 EOF

您可以使用下面的函数来把一个以 null 结尾的字符串写入到流中:

int fputs( const char *s, FILE *fp );

函数 fputs() 把字符串 s 写入到 fp 所指向的输出流中。

如果写入成功,它会返回一个非负值,如果发生错误,则会返回 EOF

您也可以使用 **int fprintf(FILEfp,const char format, ...) 函数把一个字符串写入到文件中。

//创建一个文件指针
    FILE* fp = NULL;

    //打开文件
    fp=fopen("D:/test100.txt","r");
    fprintf(fp,"你好北京--\n");
    fputs("你好上海\n",fp);
    fclose(fp);
    printf("完成\n");
读取文件

下面是从文件读取单个字符的最简单的函数:

int fgetc( FILE * fp );

fgetc() 函数从 fp 所指向的输入文件中读取一个字符。返回值是读取的字符,

如果发生错误则返回 EOF。下面的函数允许您从流中读取一个字符串:

char *fgets( char *buf, int n, FILE *fp );

  1. 函数 fgets() 从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 buf,并在最后追加一个 null 字符来终止字符串。
  2. 如果这个函数在读取最后一个字符之前就遇到一个换行符 '\n' 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符。
  3. 也可以使用 **int fscanf(FILEfp, const char format, ...) 函数来从文件中读取字符串,但是在遇到第一个空格和换行符时,它会停止读取。
 char buff[1024];
    while (fgets(buff, 1024, (FILE*)fp) !=NULL){
        printf("%s\n", buff );
    }
    fscanf(fp,"%s",buff);
    printf("%s\n",buff );

typedef

C 语言提供了 typedef 关键字,您可以使用它来为类型取一个新的名字。下面的实例为单字节数字定义了一个术语 BYTE

typedef unsigned char BYTE;

在这个类型定义之后,标识符 BYTE 可作为类型 unsigned char 的缩写,例如:

BYTE  b1, b2;

按照惯例,定义时会大写字母,以便提醒用户类型名称是一个象征性的缩写,但您也可以使用小写字母,如下:

typedef unsigned char byte;

您也可以使用 typedef 来为用户自定义的数据类型取一个新的名字。例如,您可以对结构体使用 typedef 来定义一个新的数据类型名字,然后使用这个新的数据类型来直接定义结构变量,

typedef vs #define

#define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同:

  • typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。
  • typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。
#include <stdio.h>
 
#define TRUE  1
#define FALSE 0
 
int main( )
{
   printf( "TRUE 的值: %d\n", TRUE);
   printf( "FALSE 的值: %d\n", FALSE);
 
   return 0;
}

C语言程序设计知识点总结归纳(全书)_《c语言程序设计》知识点-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值