// 引入头文件。里面包含了重要的 printf。
#include <stdio.h>
// 入口函数。
// 参数一指输入的参数个数,参数二保存了全部参数。
// 返回值为 int 类型,通常 0 表明成功,负数表明失败。
int main(int argc,char* argv[]){
printf("Hello World!\n");
return 0; // 表明执行成功。
}
复制代码
经过指令的编译与执行:linux
MAC 下的编译使用 clang,Linux 下的编译使用 gcc。数组
gcc/clang -g -o Hello xxx.c微信
-g 是 debug 模式,带有调试信息的。markdown
-o 指明输出文件的名字函数
xxx.c 源代码oop
在 MAC 或 Linux 下使用 ./Hello 来执行ui
集成环境的运行,后台其实也是这个步骤。编码
short(短整型)、int(整型)、long(长整型)spa
float(单精度浮点型,通常状况使用 float。)、double(双精度浮点型,精度高,适用于科学计算等。)操作系统
char(字符)、char*(字符串)
void(对类型不关心时)
int main(int argc,char* argv[]){
int a = 10;
float b = 12.5;
// 打印结果;a+b=22.500000 (float 类型)
printf("a+b=%f\n",a+b);
// 打印结果;... , a*b=125.000000 (float 类型)
printf("a+b=%f\n,a*b=%f\n",a+b,a*b);
char c = 'a';
// 打印结果;c=f(c 为字符 a,c 加数字能够变为另外一个字符,c+1=b,c+2=c,...)
printf("c=%c\n",c+5);
// 打印结果;c=102(f 的实际编码的值就是 102)
printf("c=%d\n",c+5);
int d = 10;
int e = d % 6; // 取余
int f = d / 6; // 取商
// 打印结果;e=4,f=1
printf("e=%d\n,f=%d\n",e,f);
return 0; // 表明执行成功。
}
复制代码
int a = 0; // 变量,能够再赋值。能够不赋值初始值。
变量在计算机中的物理意义,就是一个寄存器。寄存器是临时存储数据的,它的速度很是快。从内存中取一块数据时,首先存储到寄存器,当改变这个值时,刷新的是寄存器,可擦除。这样能够加快程序的执行速度。
const int len = 265; // 常量,不可改变。须要赋值初始值。
在编译程序时,程序中设定了一段静态缓冲区,静态缓冲区是受保护的,经过正常途径是不可修改的。但若是知道内存的具体物理地址,也是能够改变的。
数组是有序的元素序列(C 语言的数组存放的是同一种类型的元素,索引从 0 开始),C 语言中定义数组须要告诉编译器数组的长度。C 语言中数组的定义; char c[2], int arr[10]
int main(int argc,char* argv[]){
// int arr[10];
// arr[0] = 1;
// arr[1] = 2;
// printf("%d,%d\n",arr[0],arr[1]);
int arr[10] = {1,2,3,};
// 打印结果;1,2,3,0(默认状况下,不赋值的状况下,数组会初始化为 0。)
printf("%d,%d,%d,%d\n",arr[0],arr[1],arr[2],arr[3]);
float f[2] = {1,2};
// 打印结果;1.000000,2.000000
printf("%f,%f\n",f[0],f[1]);
return 0;
}
复制代码
// 它是没有保护的概念的(如 private 等)
struct st {
int a; // 成员 a
int b; // 成员 b
};
复制代码
// 结构体能够理解为它是一个类
struct st{
int a;
float f;
};
int main(int argc,char* argv[]){
struct st ss;
ss.a = 12;
ss.f = 10.2;
// 打印结果;struct:12, 10.200000
printf("struct:%d, %f\n",ss.a,ss.f);
return 0; // 表明执行成功。
}
复制代码
枚举能够认为它是一个有限制的整型。通常状况下的使用,是在有必定数值范围的,好比某个属性的取值只能为 一、二、3。
enum em {
red_color = 0, // 值为 0,若是值为 1
green_color, // 值为 1,则值为 2
black_color // 值为 2,则值为 3
};
复制代码
enum em {
red_color = 5,
green_color,
black_color = 10,
yellow_color
};
int main(int argc,char* argv[]){
enum em ee;
ee = green_color;
// 打印结果;enum:6
printf("enum:%d\n",ee);
ee = yellow_color;
// 打印结果;enum:11
printf("enum:%d\n",ee);
return 0; // 表明执行成功。
}
复制代码
指针就是存放内存地址的变量。地址空间内的存的值,在 C 语言中,它除了能够存放普通的数值,还能够存放另外一个内存的地址,这个值就是指针,经过这个值就能够访问到其它地址,而后就能够取出这个地址所存放的数据。因此,这个值能够有多重含义,具体跟业务逻辑相关。
指针的做用:
提高执行效率。
通常状况下,将字符串传入函数中,函数对字符串进行操做时,它是一个拷贝的过程,函数将字符串拷贝到本身的函数空间存放起来。屡次的拷贝会对整个 CPU 形成巨大的浪费。而指针,只须要向函数传递这个字符串所在的地址,函数经过指针访问字符串。
更强的控制力。
由于它具备访问地址的能力。像计算机的硬件实际到操做系统层都会有一个对应的映射地址,经过这个地址,C 语言就能访问到硬件设备,并进行控制。C 语言是更底层的语言,它能够访问设备。
指针的操做:
一是对指针自己的操做。
实际就是对地址的操做。好比,当获取某个空间的指针后,能够对这个指针进行加减乘除的操做,对其加一,就指向了下一个空间。
二是对所指向的内容操做。
指针指向某一个内存地址时,能够获取其内容,能够对这个内容进行加减乘除的操做。
指针的定义与使用:
type* var:
*var:表示获取指针所指向的内容
堆内存的分配与释放:
分配内存:void* mem = malloc(size);
释放内存:free(mem);
#include <stdio.h>
#include <stdlib.h> // malloc() 须要的头文件
int main(int argc,char* argv[]){
// malloc() 通常返回的是 void* 类型。
// malloc() 在 <stdlib.h> 头文件中。
char* p = (char*)malloc(10); // 分配十个字符的空间
*p = 'a'; // 第一个字符的位置
*(p+1) = 'b'; // 第二个字符的位置
// 将内存分配的地址告诉 printf,
// printf 将 p 地址所指向的空间的内容以字符串的形式打印出来。
printf("%s\n",p); // 打印结果;ab
// 将 p 所指向的空间释放掉
// 系统管理层将内存又还给了堆空间
free(p);
*p = 'd';
// 即便把空间释放掉,但由于仍然掌握此空间的位置,知道 p 的指向。
// 因此即便被释放掉了,仍是能够对其操做。
printf("%s\n",p); // 打印结果;db
// 因此为了避免让再访问这个地址,要将其指向 NULL,设置为无效地址。
p = NULL;
// *p = 'e'; // crash
return 0;
}
复制代码
栈空间:栈的机制,后进先出。最大的特色是,在 C 语言中写的函数,在函数内所分配的全部变量都是在栈空间分配的,当从函数退出时,从栈空间分配的资源会被自动释放。(分配的资源是有限的,默认每一个函数栈空间的大小是 8兆。)
堆空间:须要明确的使用 malloc() 函数来分配资源,使用完内存后,要经过 free() 函数将资源释放回堆空间,这样别人使用时还能从堆空间分配资源。(分配的资源几乎能够认为是无限的,适合须要大空间的时候。)
内存映射:像一些动态库通常都是将它直接导入内存映射区,也是一段专门的空间。好比将某个文件直接映射到内存中,文件的内容与内存造成映射关系,当改变内存中的值时,会直接在系统内部自动更新到文件中。
Linux 内存地址的划分:4G 32 位系统
0 ~ 0x08048000:这段是受保护空间,咱们的进程是不能访问的。
code:存放的是进程所要执行的代码段。
堆空间的增加是从下向上,栈空间是从上向下,每次分配空间是向下走的。堆空间与栈空间这样的划分是为了减小冲突。
共享库,或者叫内存映射区,当想经过内存改变文件时,就能够将文件映射到 mmap 这段空间中。
内存泄漏:
野指针:占用别人的内存称为野指针。
比较运算:>、<、>=、<=、==、!=
if/else 语句:
if( a> b){ ... }else{ ... }
for 语句:
for(int i =0; i<100; i++){ ... }
while 语句:
#include <stdio.h>
#include <unistd.h> // usleep() 须要的头文件
int main(int argc,char* argv[]){
while (1) { // 死循环
printf("while...\n"); // 一秒钟打印一次
usleep(1000000); // 微秒
}
return 0;
}
复制代码
C 语言中的命名通常以 Linux 的风格,单词与单词用下划线链接,单词通常都是缩写。
// void 返回类型
// func 函数名称
// int a 形参
void func(int a){
... // 函数不能太大,通常不超过 50 行。
}
复制代码
函数指针:指向函数的指针变量。经过 C 语言的函数指针能够实现 C++ 中的多态,就是定义的函数指针既能够指向 a 函数,也能够指向 b 函数,对外层来讲,只须要调用这个函数指针就能够了。(多态就是指一个函数能够有不一样的含义)
函数指针的格式:返回值类型 (*指针变量名) ([形参列表]);
int func(int x); // 声明一个函数
int (*f)(int x); // 声明一个函数指针。返回类型和形参必须与指定的函数一致。
f = func; // 将 func 函数的首地址赋值给指针 f。而后调用 f 便可。
复制代码
#include <stdio.h>
int func(int a){
printf("a=%d\n",a);
return 0;
}
int func1(int b){
printf("b=%d\n",b+5);
return 0;
}
int main(int argc,char* argv[]){
int (*f)(int);
// 在 C++ 中这就是多态。
// 对上层来说,调用的都是 f 这个函数指针,但在底层返回的是不一样的结果。
f=func;
f(2);
f=func1;
f(3);
// 打印结果;a=2 b=8
return 0;
}
复制代码
文件类型:FILE* file; (FILE* 在 Linux 下叫指针,在 Windows 下叫句柄。)
打开文件:FILE* fopen(path,mode);
关闭文件:fclose(FILE*);
#include <stdio.h>
void createfile(char* filename){
// open/create file
FILE* file = fopen(filename,"w");
if (!file) {
printf("Failed to create file (%s)\n",filename);
return;
}
// 向建立好的文件内写入内容。
// 参数一指写入的字符串,参数二指字符串中的每一项多大,参数三指一共有几项,参数四指写到哪一个文件
size_t len = fwrite("aaaaa", 1, 5, file);
if (len !=5) {
// size_t 使用的打印为 %zu。
printf("Failed to write file,(%zu)",len);
fclose(file);
return;
}
printf("Successed to write file\n");
fclose(file);
printf("Successed to create file\n");
}
void read_data(char* filename){
FILE* file = fopen(filename,"r");
if (!file) {
printf("Failed to create file (%s)\n",filename);
return;
}
// 定义为 1k 大小,并初始化为 0。
char buffer[1024] = {0,};
// 参数:读出的数据存放位置,长度,读多少,从哪读。
size_t len = fread(buffer, 1, 10, file);
if (len <= 0) {
printf("Failed to read file!\n");
fclose(file);
return;
}
printf("read_data:%s\n",buffer);
fclose(file);
return;
}
int main(int argc,char* argv[]){
// create file
// createfile("/Users/jianghouren/Downloads/1.txt");
// read file
read_data("/Users/jianghouren/Downloads/1.txt");
return 0;
}
复制代码
参考资料:
慕课网-音视频基础(李超)
欢迎关注微信公众号:非也缘也