0%

带你学c带你飞(day1)小甲鱼视频

P1

打广告

P2

1
2
3
4
5
6
7
8
9
1.所有的 C 语言程序都需要包含 main() 函数。 代码从 main() 函数开始执行。

2./* ... */ 用于注释说明。

3.printf() 用于格式化输出到屏幕。printf() 函数在 "stdio.h" 头文件中声明。

4.stdio.h 是一个头文件 (标准输入输出头文件) , #include 是一个预处理命令,用来引入头文件。 当编译器遇到 printf() 函数时,如果没有找到 stdio.h 头文件,会发生编译错误。

5.return 0; 语句用于表示退出程序。

P3

打印

1
2
3
printf("hello world");
print\
f("hi"})//反斜杠表示读下一行开头,可以运行,换行符\n;

p4

变量名:英文字母数字,下划线组成,开头必须是字母下划线。

c有32个关键字

第一类:数 据类型关键 字

A基本数据类 型(5个):

void: 声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果。

char: 字符型类型数据,属于整型数据的一种。

int: 整型数据,通常为编译器指定的机器字长。

float: 单精度浮点型数据,属于浮点数据的一种,小数点后保存6位。

double: 双精度浮点型数据,属于浮点数据的一种,比float保存的精度高,小数点后保存15/16位。

B类型修饰关 键字(4个):

short :修饰int,短整型数据,可省略被修饰的int。

long :修饰int,长整形数据,可省略被修饰的int。

signed :修饰整型数据,有符号数据类型。

unsigned: 修饰整型数据,无符号数据类型。

C复杂类型关 键字(5个):

struct :结构体声明。

union :共用体声明。

enum :枚举声明。

typedef :声明类型别名。

sizeof :得到特定类型或特定类型变量的大小。

D存储级别关 键字(6个):

auto :指定为自动变量,由编译器自动分配及释放。通常在栈上分配。

static :指定为静态变量,分配在静态变量区,修饰函数时,指定函数作用域为文件内部。

register :指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数形参,建议编译器通 过寄存器而不是堆栈传递参数。

extern :指定对应变量为外部变量,即在另外的目标文件中定义,可以认为是约定由另外文件声明的。

const :与volatile合称“cv特性”,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改

volatile :与const合称“cv特性”,指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存 中取得该变量的值。

第二类:流 程控制关键 字

A跳转结构(4 个):

return :用在函数体中,返回特定值(或者是void值,即不返回值)。

continue: 结束当前循环,开始下一轮循环。

break :跳出当前循环或switch结构。

goto :无条件跳转语句。

B分支结构(5 个):

if :条件语句。

else: 条件语句否定分支(与if连用)。

switch: 开关语句(多重分支语句)。

case :开关语句中的分支标记。

default: 开关语句中的“其他”分治,可选。

C循环结构(3 个):

for :for循环结构,for(1;2;3)4;的执行顺序为1->2->4->3->2…循环,其中2为循环条件。

do:do循环结构,do 1 while(2);的执行顺序是1->2->1…循环,2为循环条件。

while: while循环结构,while(1) 2;的执行顺序是1->2->1…循环,1为循环条件, 以上循环语句,当循环条件 表达式为真则继续循环,为假则跳出循环。

c99新增5个关键字

1、inline关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中表达式形式的宏定义

引入原因:C语言是一个效率很高的语言,这种宏定义在形式及使用上像一个函数,但它使用预处理器实现,没有了参数压栈,代码生成等一系列的操作

2、restrict关键字只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。

3、_Bool关键字是用于表示布尔值。包含标准头文件 stdbool.h 后,我们可以用 bool 代替 _Bool ,true 代替 1 ,false 代替 0 。

4、_Complexand_Imaginary关键字

C99标准中定义的复数类型如下:float_Complex; float_Imaginary; double_Complex; double_Imaginary; long double_Complex; long double_Imaginary.

头文件中定义了complex和imaginary宏,并将它们扩展为_Complex和_Imaginary,因此在编写新的应用程序时,应该使用头文件中的complex和imaginary宏。

C语言32个关键字(C99新增5个、C11新增7个)

按年份起始:

auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while1999年12月16日,ISO推出了C99标准,该标准新增了5个C语言关键字:

inline restrict _Bool _Complex _Imaginary2011年12月8日,ISO发布C语言的新标准C11,该标准新增了7个C语言关键字:

_Alignas _Alignof _Atomic _Static_assert _Noreturn _Thread_local _Generic

1
2
3
4
5
6
7
%d//int
%c//char
%11.9//11位,小数点后9位
gcc test.c -o test && ./test //这个-o可以改a.out为你想要的名字, 用&&可以合并编译运行两个阶段,而/ 的意思:目录级别分隔符
. 的意思:当前目录
./a 的意思就是:当前目录下文件名为“a”的文件。
Linux中还有 .. 代表上抄级目录

P5

字符常量单引号,字符串常量双引号

1
2
3
//宏定义, 标识符全大写,宏定义
#define 标识符 常量
#define pi 3.1415926535

C++ 语言可以用const 来定义常量,也可以用#define 来定义常量。但是前者比后者有更多的优点:
(1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。
(2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。规则5-2-1:在C++ 程序中只使用const 常量而不使用宏常量,即const 常量完全取代宏常量。

2.实现机制

宏是预处理命令,即在预编译阶段进行字节替换。const常量是变量,在执行时const定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态存储区的只读数据区。根据c/c++语法,当你声明该量为常量,即告诉程序和编译器,你不希望此量被修改。 程序的实现,为了保护常量,特将常量都放在受保护的静态存储区内。凡是试图修改这个区域内的值,都将被视为非法,并报错。 这不能理解为凡是字符串都是放在静态存储区域的。这个跟数据类型没有关系,而是这个量是变量还是常量的问题。例如,一个字符串变量就是可以被修改的。 这种静态存储区域的保护机制是由编译器实现的,而非存储该值的内存的电器属性。换言之,实质上内存永远都可以被用户随意修改,只是编译器给用户的代码注入了一些自己的保护代码,通过软件手段将这段内存软保护起来。这种保护在汇编级别可以轻松突破,其保护也就无效了。)。

3.用法区别

define宏定义和const常变量区别:
1.define是宏定义,程序在预处理阶段将用define定义的内容进行了替换。因此程序运行时,常量表中并没有用define定义的常量,系统不为它分配内存。const定义的常量,在程序运行时在常量表中,系统为它分配内存。
2.define定义的常量,预处理时只是直接进行了替换。所以编译时不能进行数据类型检验。const定义的常量,在编译时进行严格的类型检验,可以避免出错。3.define定义表达式时要注意“边缘效应”,例如如下定义:
#define N 2+3 //我们预想的N值是5,我们这样使用N,int a = N/2; //我们预想的a的值是2.5,可实际上a的值是3.5原因在于在预处理阶段,编译器将 a = N/2处理成了 a = 2+3/2;这就是宏定义的字符串替换的“边缘效应”因此要如下定义:#define N (2+3)。const定义表达式没有上述问题。const定义的常量叫做常变量原因有二:const定义常量像变量一样检查类型;const可以在任何地方定义常量,编译器对它的处理过程与变量相似,只是分配内存的地方不同。

1
字符串常量, '\0'遇到这个会知道字符串结束了

P6

C语言数据类型的分类方式如下:

  • 基本类型
    • 标准整数类型,以及扩充的整数类型
    • 实数浮点类型,以及复数浮点类型
  • 枚举类型
  • void类型
  • 派生类型
    • 指针类型
    • 数组类型
    • 结构类型
  • 联合类型
  • 函数类型
1
2
sizeof(a);//return size of a
sizeof(int);//return 4单位是字节

objective-c 中的BOOL 实际上是一种对带符号的字符类型(signed char)的类型定义(typedef),它使用8位的存储空间。通过#define指令把YES定义为1,NO定义为0。

C99标准定义了一个新的关键字_Bool,提供了布尔类内型。以前,C程序员总是使用自己的方法定义布尔类型。0表示false,非0表示true。

可能使用char类型表示一个布尔类型,也可能使用int类型表示一个布尔类型。

1、类型不同百 : BOOL为int型 , bool为布尔型

2、长度不同 : bool只有一个字节 , BOOL长度视实际环境来定,一般可认为是4个字节

3、取值不同 :bool取值false和true,是0和1的区别; false可以代表0,但true有很多种,并非度只有1。

4、bool表示布尔型变量,也就是逻辑型变量的定义符,以英国数学家、布尔代数的奠基人乔治·布尔(George Boole)命名。

总结bool是true,false,而_Bool is 0,1 但是都是1字节。

1
sign unsigned//带符号不带符号,如果不用会引发栈溢出栈泄露

P7

printf是输出一个字符串,putchar输出一个char。

printf格式字符:

打印格式 对应数据类型 含义
%d int 接受整数值并将它表示为有符号的十进制整数
%hd short int 短整数
%hu unsigned short 无符号短整数
%o unsigned int 无符号8进制整数
%u unsigned int 无符号10进制整数
%x,%X unsigned int 无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF
%f float 单精度浮点数
%lf double 双精度浮点数
%e,%E double 科学计数法表示的数,此处”e”的大小写代表在输出时用的”e”的大小写
%c char 字符型。可以把输入的数字按照ASCII码相应转换’对应的字符
%s char * 字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符)
%p void * 以16进制形式输出指针
%% % 输出一个百分号

%d 整形 int

%f 浮点型 float

%c 字符型 char

%hd 短整型 short

%ld 长整形 long

%lld 长长整形 long long

1
2
3
4
1bit=8 bytes
pow(a,b)//#include <math.h>,一般打印需要<stdio.h>, a的b次方
gcc -lm test.c && ./a.out// warning:overflow in implicit constant conversion
unsign int 用%u,sign int用%d

使用math.h中声明的库函数还有一点特殊之处,gcc命令行必须加-lm选项,因为数学函数位于libm.so库文件中(这些库文件通常位于/lib目录下),-lm选项告诉编译器,我们程序中用到的数学函数要到这个库文件里找。本书用到的大部分库函数(例如printf)位于libc.so库文件中,使用libc.so中的库函数在编译时不需要加-lc选项,当然加了也不算错,因为这个选项是gcc的默认选项。

C标准主要由两部分组成,一部分描述C的语法,另一部分描述C标准库。C标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类型 声明和宏定义。要在一个平台上支持C语言,不仅要实现C编译器,还要实现C标准库,这样的实现才算符合C标准。不符合C标准的实现也是存在的,例如很多单 片机的C语言开发工具中只有C编译器而没有完整的C标准库。

在Linux平台上最广泛使用的C函数库是glibc,其中包括C标准库的实现。几乎所有C程序都要调用glibc的库函数,所以glibc是Linux平台C程序运行的基础。glibc提供一组头文件和一组库文件,最基本、最常用的C标准库函数和系统函数在libc.so库文件中,几乎所有C程序的运行都依赖于libc.so,有些做数学计算的C程序依赖于libm.so,以后我们还会看到多线程的C程序依赖于libpthread.so。以后我说libc时专指libc.so这个库文件,而说glibc时指的是glibc提供的所有库文件。

1. 原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]

[-127 , 127]

原码是人脑最容易理解和计算的表示方式.

2. 反码

反码的表示方法是:

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.

3. 补码

补码的表示方法是:

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.

P8

字符用ASCII字符表写的,常用的ascii: 空格的ASCII码值为32;数字0到9的ASCII码值分别为48到57;大写字母“A”到“Z”的ASCII码值分别为65到90;小写字母“a”到“z”的ASCII码值分别为97到到122。

字符类型是特殊的整型,ascii有0-255个字符

1
unsigned char 170//这是正数,若不用unsigned,则是负数

字符串

1
char name[length];//0 to length-1
1
2
3
4
5
//经典问题
char a[2]={'a','b'};
printf("%s\n",a);
printf("Hi\n");//会出现错误,因为字符数组a没有\0,改法: char a[3]={'a','b','\0'};
char a[]="hi";//字符串常量

P9

1
2
3
4
5
6
7
5/3=1
5%3=2
5.0%3.0//出错
//强制类型转换
1+2.0;//->1.0+2.0
1+(int)2.0;//->3
1+(int)1.8;//2

P10

关系表达式返回0,1

c语言中没有true,false,只有1,0

c和java一样采用短路与和短路或