C语言学习笔记

C语言学习笔记
本人不是计算机相关专业,专业选修C讲的内容不多,更多的是我的课外学习,如有问题欢迎指出

C介绍

c语言一种通用高级语言,有丹尼斯·里奇在贝尔实验室为开发UNIX操作系统而设计

c的优点

执行效率高,可移植性好,可用来开发应用软件,驱动,操作系统

其他高级语言的底层

环境

C语言是编译型语言,编写的代码是源码,计算机无法直接执行,需要使用编译器进行编译才能被计算机执行

编写运行C程序则需要编辑器和编译器,如vscode和mingw

大学常见的vc6则是IDE(集成开发环境),将编辑器,编译器,调试器,图形化界面进行了集成 (vc6不好使,可以去试试codeblock,或者喜欢轻量化试试vscode)

C结构

  • 头文件

    • 预处理命令,通知编译器在编译之前的预处理工作
  • 主函数 有且只有一个

  • 函数 实现代码逻辑的最小单元

    最新的C标准中,main函数前的类型为int而不是void

  • 语句

  • 注释

#include <stdio.h>     //头文件
int main(){   //主函数
    print("Hello Word!")    //函数体
    return 0;
}

基础

变量

实质是内存中的一块区域,变量名中存储地址值,内存地址中储存真正的数据

int a=0;
//a -->  OxF98A
//OxF98A  --> 0

定义方式 数据类型 变量名

不允许连续赋值

int a ;
int b=1;
int a,b,c=3;
//int a=b=2;    不合法

数据类型

  • 基本类型
    • int
    • char ‘’
    • float/double
  • 构造类型
    • 枚举
    • 数组
  • 指针类型
  • 空类型
    • null

C没有字符串变量,字符串只能存在字符数组中

格式化输出

printf()格式化输出函数,在stdio头文件中

占位符

  • %d 带符号的十进制数
  • %c 单个字符
  • %s 字符串
  • %f 6位小数

转义字符:

  • \b 退格
  • \n
  • ?
  • \0 空字符null

流程控制

数组

存储数据的容器,C中是一块连续的,大小固定并且数据类型一致的内存空间,其中元素按照一定顺序放置

声明:

/*
类型  数组名[元素个数]
int a[];   4个字节
char b[];   1个字节
double c[];   8个字节
*/

int arr[5];
int arr[ ]={2,45,43,2};

注:数组无法动态定义,数组的大小和初始值同时定义主义匹配

int arr[2]={1,2,3};
int n=2;
int arr[n];
//这两种情况均不合法

访问方式

数组名[下标]

int arr[ ]={1,24,54,1223,22};
//遍历
for(int i=0;i<5;i++){
    printf("%d\t",arr[i]);
}

需要避免出现数组越界的错误,C没有检测机制可能会编译通过但结果会出error

C数组长度固定无法改变,C没有提供计算数组长度的方法

可以用如下方式获取长度

int length=sizeof(arr)/sizeof(arr[0]);
//sizeof可查看数占用多大的内存块

数组的初始化

  • 将数组所欲元素初始化为0
  • 直接赋值
  • 部分赋值,未赋值的元素自动初始化0

字符串

C中没有直接的字符串数据类型,需要使用字符数组去实现

例 字符串 Hello

char str[6]={'H','e','l','l','0','\0'};
// 结尾的 \0 代表结尾,读到此处停止

根据数组初始化规则,上面语句还可以改写为

char str[]="Hello"

操作字符的函数 string头文件中

  • strcpy(s1,s2); 复制字符串s2到s1中
  • strcat(s1,s2)链接字符串s2到s1中
  • strlen(s1) 字符串s1的长度

#include <stdio.h> 
#include <string.h>
int main(){
    char a[]="hello";
    printf("%s\n",a);
    char b[]="world";
    strcat(a,b);
    printf("%s\n",a);
    printf("%s\n",b);
    return 0;
}
/*
结果为
hello
helloworld
world
*/

自定义函数

定义方式 [ ]内容可以不写

[数据类型] 函数名称 ([参数]){
	//函数体
	return   ;
}

数据类型省略时默认int

尽量放在main之前,如果在main之后需要在使用前声明

[数据类型] 函数名称 ([参数]);

变量存储类别

根据生命周期划分,静态存储方式和动态存储方式

  • 静态:是指在程序运行期间分配固定的存储空间的方式。静态存储区中存放了在整个程序执行过程中都存在的变量

  • 动态:是指在程序运行期间根据需要进行动态的分配存储空间的方式。动态存储区中存放的变量是根据程序运行的需要而建立和释放的

存储类型

  • auto
  • static
  • register(寄存器)
    • 为提高效率允许把局部变量放在cpu寄存器
  • extern(外部)
    • 脱离函数依然可以使用

静态局部变量在整个程序运行期间不会被释放,定义时不赋值时会自动赋值为0或null

C的内存模型

四大区域

代码区:存在函数程序的二进制代码

数据区:全局变量;静态变量;常量

堆heap:有程序员分配和释放,C语言可通过动态内存分配(malloc)操控

栈stack:栈内存的大小一般由操作系统设定好,存放函数的参数值,局部变量值等,操作方式同数据结构中相同

指针

指针(pointer):变量地址,可以用取地址运算符&得到一个变量的地址

声明方式

数据类型 *name

int a=3;
int *p=&a;
//  a变量名储存一个内存地址,内存地址内为真正的数据:整形数字3
//  通过&取址符将这个地址传递给*p
//  此时*p变量名的内存地址指向的内存空间中储存的是a变量的内存地址

注:变量名储存一个内存地址,内存地址内存放的才是真正的数据

当对指针操作时会操作指针指向的变量

int a=3;
int *p=&a;
*p=6;
print("%d %d %p",*p,a,*p);
//   6 6 0061FF24

操作数组

int arr[]={1,23,4,5,2};
int *p=arr  //等价于  int *p=&(arr[0])
//arr[i] == p[i] ==*(p+i)

解引用运算符 * 的到一个指针变量指向的变量,

指针与数组

C语言中指针与数组关系非常密切,数组名就是指向数组首地址的指针变量,在访问数组时就有两种方法

  • 数组名[下标]
  • *(指针+N)
    int c[]={1,2,4,5};
    printf("%d,%d",c[0],*c);

上例的结果为 1,1

指针与二维数组

以int 数组为例

二维数组就是数组的数组,数组的元素是数组,根据指针和数组的关系可以理解为 数组名是指向二维数组首地址的指针,但他指向的不再是一个int数据,而是一个另一个数组。他的类型也不再是int类型指针,而是int类型数组指针。

int arr[3][4];

arr,arr[0]都是指向首地址的指针,对其解引用都可以获得第一个元素的值

*arr[0] == **arr == arr[0][0]

如果递增arr,arr的类型为二维指针(int数组指针),其大小是一维数组的大小,arr+1 便指向第二个一位数组

arr+1 == arr[1]

如果递增arr[0],arr的类型类一维指针(int指针),其大小是一个int的大小,arr[0]+1 便指向第一个一维数组的第二个元素

*(arr[0]+1) == arr[0][1]

结构体struct

用户定制类型,由程序员组合基本类型,形成所需的数据类型,

C

struct User{
    char name[10];
    int password;
    int uid;
};
//一条语句,主义最后;

struct User user;
user.uid=22;
strcpy(user.name,"jerry"); 
//此处不能直接对字符串赋值,需要str中copy进行赋值

与指针配合时,用()提高 解引用优先级保证程序正常,也可使用 直接访问运算符 ->访问

struct *p;
p=&user;

(*p).name
p->name
//两者相同效果

共同体union

union User{
    int id;
    char name[256];
    char password[256];
}

多个类型共存,但实际只储存其中一个,一般是最长的哪一个,节省空间,使用场景不多

声明,使用和结构体相同

枚举enum

enum Color{
    RED,
   	BLUE,
    WHITE
}
//约定枚举使用全大写命名

typedef 类型定义

通过typedef定义自己的类型,实际作用更贴近给变量自定义名称

例如

typedef int id;

id就是定义的类型,实际上就是int,用于增强代码的可读性

使用方法与基本类型相同

typedef int id;

id i =1;

动态内存分配

常见的定义形式

struct User user[30]; 为静态内存分配,数组空间大小确定不可更改

为节省空间出现动态内存分配

其函数在malloc头文件中

int *p=(int *)malloc(sizeof(int)*5);  //向计算机操作系统申请堆内存空间
//

p = (int *)realloc(sizeof(int)*10);  //重新分配内存,有失败的可能

free(p)   //使用完之后需要释放资源,否则可能会内存泄漏

头文件提供常用的函数

void *calloc(int num,int siez);
//内存中分配 num 个长度为 size 字节的内存空间,进行初始化,初始值为0
void *malloc(int num);
//在堆内存中分配 num 个字节的空间,会不初始化,其值是为指导
void *realloc(void *address,int newsize);
//重新分配 newsize 字节的内存,并拷贝address的内容
void free(void *address);
//释放 address 的内存空间

of(int)*5); //向计算机操作系统申请堆内存空间
//

p = (int *)realloc(sizeof(int)*10); //重新分配内存,有失败的可能

free§ //使用完之后需要释放资源,否则可能会内存泄漏

头文件提供常用的函数

void *calloc(int num,int siez);
//内存中分配 num 个长度为 size 字节的内存空间,进行初始化,初始值为0
void *malloc(int num);
//在堆内存中分配 num 个字节的空间,会不初始化,其值是为指导
void *realloc(void *address,int newsize);
//重新分配 newsize 字节的内存,并拷贝address的内容
void free(void *address);
//释放 address 的内存空间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值