10W+字C语言硬核总结(一),值得阅读收藏!

一. C语言概述


欢迎大家来到c语言的世界,c语言是一种强大的专业化的编程语言。


10W+字C语言硬核总结(二),值得阅读收藏!


10W+字C语言硬核总结(三),值得阅读收藏!


熬夜整理的C语言/C++万字总结(四)


熬夜整理的C/C++万字总结(五),文件操作


程序员必备硬核资料,点击下载


1.1 C语言的起源


贝尔实验室的Dennis Ritchie在1972年开发了C,当时他正与ken Thompson一起设计UNIX操作系统,然而,C并不是完全由Ritchie构想出来的。它来自Thompson的B语言。


1.2 使用C语言的理由


在过去的几十年中,c语言已成为最流行和最重要的编程语言之一。它之所以得到发展,是因为人们尝试使用它后都喜欢它。过去很多年中,许多人从c语言转而使用更强大的c++语言,但c有其自身的优势,仍然是一种重要的语言,而且它还是学习c++的必经之路。


高效性。c语言是一种高效的语言。c表现出通常只有汇编语言才具有的精细的控制能力(汇编语言是特定cpu设计所采用的一组内部制定的助记符。不同的cpu类型使用不同的汇编语言)。如果愿意,您可以细调程序以获得最大的速度或最大的内存使用率。


可移植性。c语言是一种可移植的语言。意味着,在一个系统上编写的c程序经过很少改动或不经过修改就可以在其他的系统上运行。


强大的功能和灵活性。c强大而又灵活。比如强大灵活的UNIX操作系统便是用c编写的。其他的语言(Perl、Python、BASIC、Pascal)的许多编译器和解释器也都是用c编写的。结果是当你在一台Unix机器上使用Python时,最终由一个c程序负责生成最后的可执行程序。


1.3 C语言标准


1.3.1 K&R C


起初,C语言没有官方标准。1978年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言。布莱恩•柯林汉(Brian Kernighan) 和 丹尼斯•里奇(Dennis Ritchie) 出版了一本书,名叫《The C Programming Language》。这本书被 C语言开发者们称为K&R,很多年来被当作 C语言的非正式的标准说明。人们称这个版本的 C语言为K&R C。


K&R C主要介绍了以下特色:结构体(struct)类型;长整数(long int)类型;无符号整数(unsigned int)类型;把运算符=+和=-改为+=和-=。因为=+和=-会使得编译器不知道使用者要处理i = -10还是i =- 10,使得处理上产生混淆。


即使在后来ANSI C标准被提出的许多年后,K&R C仍然是许多编译器的最准要求,许多老旧的编译器仍然运行K&R C的标准。


1.3.2 ANSI C/C89标准


1970到80年代,C语言被广泛应用,从大型主机到小型微机,也衍生了C语言的很多不同版本。1983年,美国国家标准协会(ANSI)成立了一个委员会X3J11,来制定 C语言标准。


1989年,美国国家标准协会(ANSI)通过了C语言标准,被称为ANSI X3.159-1989 "Programming Language C"。因为这个标准是1989年通过的,所以一般简称C89标准。有些人也简称ANSI C,因为这个标准是美国国家标准协会(ANSI)发布的。


1990年,国际标准化组织(ISO)和国际电工委员会(IEC)把C89标准定为C语言的国际标准,命名为ISO/IEC 9899:1990 - Programming languages -- C[5] 。因为此标准是在1990年发布的,所以有些人把简称作C90标准。不过大多数人依然称之为C89标准,因为此标准与ANSI C89标准完全等同。


1994年,国际标准化组织(ISO)和国际电工委员会(IEC)发布了C89标准修订版,名叫ISO/IEC 9899:1990/Cor 1:1994[6] ,有些人简称为C94标准。


1995年,国际标准化组织(ISO)和国际电工委员会(IEC)再次发布了C89标准修订版,名叫ISO/IEC 9899:1990/Amd 1:1995 - C Integrity[7] ,有些人简称为C95标准。


1.3.3 C99标准


1999年1月,国际标准化组织(ISO)和国际电工委员会(IEC)发布了C语言的新标准,名叫ISO/IEC 9899:1999 - Programming languages -- C ,简称C99标准。这是C语言的第二个官方标准。


例如:


增加了新关键字 restrict,inline,_Complex,_Imaginary,_Bool


支持 long long,long double _Complex,float _Complex 这样的类型


支持了不定长的数组。数组的长度就可以用变量了。声明类型的时候呢,就用 int a[*] 这样的写法。不过考虑到效率和实现,这玩意并不是一个新类型。


二、内存分区


2.1 数据类型


2.1.1 数据类型概念


什么是数据类型?为什么需要数据类型? 数据类型是为了更好进行内存的管理,让编译器能确定分配多少内存。


我们现实生活中,狗是狗,鸟是鸟等等,每一种事物都有自己的类型,那么程序中使用数据类型也是来源于生活。


当我们给狗分配内存的时候,也就相当于给狗建造狗窝,给鸟分配内存的时候,也就是给鸟建造一个鸟窝,我们可以给他们各自建造一个别墅,但是会造成内存的浪费,不能很好的利用内存空间。


我们在想,如果给鸟分配内存,只需要鸟窝大小的空间就够了,如果给狗分配内存,那么也只需要狗窝大小的内存,而不是给鸟和狗都分配一座别墅,造成内存的浪费。


当我们定义一个变量,a = 10,编译器如何分配内存?计算机只是一个机器,它怎么知道用多少内存可以放得下10?


所以说,数据类型非常重要,它可以告诉编译器分配多少内存可以放得下我们的数据。


狗窝里面是狗,鸟窝里面是鸟,如果没有数据类型,你怎么知道冰箱里放得是一头大象!


数据类型基本概念:


类型是对数据的抽象;


类型相同的数据具有相同的表示形式、存储格式以及相关操作;


程序中所有的数据都必定属于某种数据类型;


数据类型可以理解为创建变量的模具: 固定大小内存的别名;


10W+字C语言硬核总结(一),值得阅读收藏!


2.1.2 数据类型别名


typedef unsigned int u32;

typedef struct _PERSON{

char name[64];

int age;

}Person;

void test(){

u32 val; //相当于 unsigned int val;

Person person; //相当于 struct PERSON person;

}

2.1.3 void数据类型


void字面意思是”无类型”,void* 无类型指针,无类型指针可以指向任何类型的数据。


void定义变量是没有任何意义的,当你定义void a,编译器会报错。


void真正用在以下两个方面:


对函数返回的限定;


对函数参数的限定;


//1. void修饰函数参数和函数返回
void test01(void){
 printf("hello world");
}
//2. 不能定义void类型变量
void test02(){
 void val; //报错
}
//3. void* 可以指向任何类型的数据,被称为万能指针
void test03(){
 int a = 10;
 void* p = NULL;
 p = &a;
 printf("a:%d\n",*(int*)p);
 char c = 'a';
 p = &c;
 printf("c:%c\n",*(char*)p);
}
//4. void* 常用于数据类型的封装
void test04(){
 //void * memcpy(void * _Dst, const void * _Src, size_t _Size);
}


2.1.4 sizeof 操作符


sizeof 是 c语言中的一个操作符,类似于++、--等等。sizeof 能够告诉我们编译器为某一特定数据或者某一个类型的数据在内存中分配空间时分配的大小,大小以字节为单位。


基本语法:


sizeof(变量);

sizeof 变量;

sizeof(类型);

sizeof 注意点:


sizeof返回的占用空间大小是为这个变量开辟的大小,而不只是它用到的空间。和现今住房的建筑面积和实用面积的概念差不多。所以对结构体用的时候,大多情况下就得考虑字节对齐的问题了;


sizeof返回的数据结果类型是unsigned int;


要注意数组名和指针变量的区别。通常情况下,我们总觉得数组名和指针变量差不多,但是在用sizeof的时候差别很大,对数组名用sizeof返回的是整个数组的大小,而对指针变量进行操作的时候返回的则是指针变量本身所占得空间,在32位机的条件下一般都是4。而且当数组名作为函数参数时,在函数内部,形参也就是个指针,所以不再返回数组的大小;


//1. sizeof基本用法
void test01(){
 int a = 10;
 printf("len:%d\n", sizeof(a));
 printf("len:%d\n", sizeof(int));
 printf("len:%d\n", sizeof a);
}
//2. sizeof 结果类型
void test02(){
 unsigned int a = 10;
 if (a - 11 < 0){
  printf("结果小于0\n");
 }
 else{
  printf("结果大于0\n");
 }
 int b = 5;
 if (sizeof(b) - 10 < 0){
  printf("结果小于0\n");
 }
 else{
  printf("结果大于0\n");
 }
}
//3. sizeof 碰到数组
void TestArray(int arr[]){
 printf("TestArray arr size:%d\n",sizeof(arr));
}
void test03(){
 int arr[] = { 10, 20, 30, 40, 50 };
 printf("array size: %d\n",sizeof(arr));
 //数组名在某些情况下等价于指针
 int* pArr = arr;
 printf("arr[2]:%d\n",pArr[2]);
 printf("array size: %d\n", sizeof(pArr));
 //数组做函数函数参数,将退化为指针,在函数内部不再返回数组大小
 TestArray(arr);
}

2.1.5 数据类型总结


数据类型本质是固定内存大小的别名,是个模具,C语言规定:通过数据类型定义变量;


数据类型大小计算(sizeof);


可以给已存在的数据类型起别名typedef;


数据类型的封装(void 万能类型);



上一篇:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现


下一篇:笔试题目“翻转字符串”的实现