第一章 概述
设计特性
1) 强大的控制结构。
2) 高效性
3) 可移植性(除特定的访问硬件部分)
4) 功能强大unix操作系统的大部分便是C编写的。
5) 面向编程人员,可以操纵内存中的特定位。
6) 优点和缺点,优点即是缺点,给予编程人员更多的自由,同时也会产生很多不容易发现的错误。
发展方向
使用步骤
1) 定义程序目标
2) 设计程序
3) 编写代码
4) 编译
5) 运行程序
6) 测试和调试程序
7) 维护和修改程序
编程机制
分两步:编译和连接。
分为源文件------>目标文件------>可执行文件
可执行文件比目标代码多了启动代码和库代码。
语言标准
C89/c90/ANSI C 、新标准为 C99。
........
.........
.........
.........
.........
数组和指针
Int powers[8] = {1,2,4,6,8,16,32,64};初始化仅asic C,
常量数组:const int days[months]={31,28,31,30,31,30,31,31,30,31,30,31};
在函数的内部声明,并且没有使用关键字static,不同的存储类具有不同的属性,因此不能把本章的只是推广到其它的存储类。例如:没有进行初始化,一些存储类的变量和数组会把它们的存储单元设置为0;数组则直接读取上面的内容。
如果不初始化数组,数组元素和未初始化的普通变量一样,其中存储的是无用的数值;但是如果部分初始化数组,未初始化的元素则被设置为0;
如果初始化列表中的项目的个数大于数组大小,编译器会毫不留情地认为这是一个错误。但是用另外一种形式可以避免受到编译器的此类奚落:您可以省略括号中的数字,从而让编译器自动匹配数组的大小,和初始化列表中的项目数目。
Sizeof days / sizeof days[0];
C99可以对单个数组元素赋值,
Int arr[6] = {[5] = 212};其它的都为0;
又如:
Int days[MONTHS] = {31,28,[4] = 31,30,31,[1] = 29};
结果为:31,29,0,0,31,30,31,0,0,0,0,0;
声明数组时在方括号内只能使用整数常量表达式,整数常量表达式是由整数常量组成的表达式,sizeof表达式被认为是一个整数常量。而和c++不一样,一个const值却不是整数常量。并且该表达式的值必须大于0;
变长数组 VLA
2维数组的初始化:
一维数组时一行,2维是一个面,3维是一个立方体。
指针和数组
对指针+1的结果就是对该指针增加一个尺存储单元,对于数组而言,地址会增加到下一个元素的地址。而不是下一个字节。
1. 指针的数值就是它所指向的对象的地址,指向float的指针,地址的内部表示方式是由硬件来决定的,很多计算机包含多个字节的数据类型,比如double类型的变量,对象的地址通常指的是其首字节的地址。
2. 指针前运用运算符* 就可以得到该指针所指向的对象的数值。
3. 对指针加1,等价于对指针的值加上它所指向的对象的字节大小。
在函数原型或函数定义头的场合中,可以用int * ar代替 int ar[],无论在任何情况下,形式int * ar都表示ar是指向int的指针。形式int ar[]也可以表示ar是指向int的指针,但只是在声明形式参量时才可以这样使用,使用第二中形式可以提醒读者ar不仅指向一个Int数值,而且它指向的这个int是一个数组中的元素。
由于原型允许省略名称因此下面的声明是等价的:
Int sum (int *ar,int n);
Int sum (int *,int);
Int sum (in tar[],int n);
Int sum (int [], int);
定义函数时,名称是不可以省略的,因此,在定义时下面两种形式是等价的:
Int sum(int *ar,int n)
{
}
Int sum (in tar[],int n)
{
}
Int marbles[size];
Sizeof marbles 是整个数组的大小,
Sizeof ar或者sizeof tar 就是单个数组元素的大小。
也可以传递首指针和尾指针
Int sump(int * start,int * end)
{
Int total = 0;
While(start < end )
{
Total += *start;
Start++;
}
}
在c中,两个表达式 ar[i] 和*(ar+i) 的意义是等价的,而且不管ar是一个数组名还是一个指针变量,这两个表达式都可以工作,然而只有当ar是一个指针变量时,才可以使用ar++这样的表达式。
指针操作
指针之间的减法结果等于相对于他们的类型的值,比如
Pi+3 –pi=3,这个3相对于他们的类型int而言就是3个4字节的地址长度。
指针可以直接赋值给以个指针。
计算机并不检查指针是否依然指向某个数组元素,C保证指向数组的指针和指向数组后的第一个地址的指针都是有效的,但是如果指针在进行了增量或减量运算后超出了这个范围,后果将是未知的,另外,可以对指向数组元素的指针进行取值运算,但不能对指向数组后的第一个地址的指针进行取值运算,尽管这个指针式合法的。
Int *pt;
*pt = 5;
这是不可行的,因为pt的值是随机的,所以随机地址赋值为5,可能是重要的位置。
由于参数传递数组的时候是传递地址的,所以可以改变原数组的值,但是如果不想改变要保护原数组的话,可以在函数原型和定义的形式参量声明中使用关键字const;
使用const来创建符号常量(const double PI = 3.14159),数组常量(const mars [3] ={1,2,3}),指针常量 int * const p=&a;,以及指向常量的指针 const int * p=&a;(const int a=3;)。
1) 指针变量 int * p = &a;
2) 指针常量 int * const a = &b; 这里的a 是个指针常量它指向变量b的地址,不能再修改它的值,a = &c;是错误的。
3) 指向常量的指针它是变量指向的是一个常量
它是一个变量,但它指向的内容是常量。
Const int b = 1,c = 2;
Const int * a;
A = &b;a = &c,由于它本身是变量,所以可以改变它的值,再用它指向常量c.
但是它指向的内存是常量,是不能被修改的。如: *a = 20;是错误的。
还有另外一种写法 int const * a;const的位置,还是在*前面;
4) 指向常量的指针常量它是常量,但是它指向的内容是常量
Cons int b = 1, c = 2;
Int const * const a = &b;
看关键字const,const后面的不可修改。
Int * const a =&b;//则a不能被修改。
Int const * a=&b; //const后面是*a,则说明*a不能被修改。
把常量或非常量数据的地址赋给指向常量的指针式合法的。
然而只有非常量的数据才可以赋给普通的指针:
所以要分三个点来看指向的是常量还是非常量,还有就是常量指针还是指针常量。
多维数组与指针
Int zippo[4][2]:
数组名zippo同事也是数组首元素的地址,本例中,zippo的首元素本省又是包含两个int的数组,因此zippo也是包含两个int数组的地址,
1) Zippo是数组首元素的地址,所以zippo的值和&zippo[0]相同,另一方面,zippo[0]本身是包含两个整数的数组,因此zippo[0]的值同其首元素(一个整数)的地址&zippo[0][0]相同。简单的说zippo[0]是一个整数大小对象的地址,zippo是两个整数大小对象的地址,因为整数和两个整数组成的数组开始同一个地址,因此zippo和zipp[0]具有相同的数值。
2) 对一个指针加1,会对原来的数值加上一个对应类型大小的数值。在这方面,zippo和zippo[0]是不一样的,zippo所指向的对象的大小事两个int,而zippo【0】所指向的大小事一个int,因此zippo+1和zippo[0]+1的结果不同。
3) 对一个指针取值(使用运算符*或者带有索引的[]运算符)得到的是该指针所指向对象的数值,因为zipp[0]是其首元素zippo[0][0]的地址,所以 *(zippo[0])代表存储在zippo[0][0]中的数值,即是一个int数值,同样zippo代表其首元素的地址,但是zippo[0]本身就是int数的地址,即&zippo[0][0],因此*zippo是&zippo[0][0]。对这两个表达式同时应用取值运算符将得到 **zippo等价于*&zippo[0][0],后者简化为一个int数 zippo[0][0].简而言之,zippo是地址的地址,需要两次取值才可以得到通常的数值。地址的地址或指针的指针式双重间接地典型例子。
总结:数组名是它本身元素的首地址,所以一维数组中的数组名就是数组单个元素的第一个元素的首地址,而二维数组就是一维数组的数组,所以它的名称就是一维数组的第一组数组的地址,所以他们相加结果是不一样的。相加就相当于他们元素加1,一维数组的元素是一个元素,而二维数组加1就相当于一维数组的一组数组。三维一样是二维数组的数组。它加1相当于加一个二维数组的量。对于取值来说二维是一维的地址,所以要经过两次取值才能取到数。
Int (* pz)[2] //pz指向一个包含2个int值得数组。加()是因为[]优先级高于*
Int说明数组和指针都int型的。
Int * pz[] //是指2个指向int值的指针构成的数组。
最后一行说明指针的指针不能赋给2维数组名。
相关推荐
从给定的文件标题“C语言笔记”及描述与部分内文中,我们可以提炼出一系列关于C语言的关键知识点,这些知识涵盖了C语言的基础语法、数据类型、运算符、控制结构、字符串处理以及变量的作用域和存储类别等核心概念。...
本文档是一份标准C语言的学习笔记,内容涵盖了结构体、宏定义、操作符优先级、函数声明等知识点,是结合作者在C/C++开发经历和阅读《THE C PROGRAMMING LANGUAGE》以及《C Traps and Pitfalls》等书籍的总结。...
这份“C语言笔记完整版”是作者精心整理的学习资料,旨在帮助初学者和进阶者深入理解C语言的核心概念和技巧。 笔记采用不同的颜色来区分内容的重要性,便于读者快速抓住关键信息: 1. **红色文本** - 标记的是学习...
计算机二级C语言笔记.zip计算机二级C语言笔记.zip计算机二级C语言笔记.zip 计算机二级C语言笔记.zip计算机二级C语言笔记.zip计算机二级C语言笔记.zip 计算机二级C语言笔记.zip计算机二级C语言笔记.zip计算机二级...
这份"C语言笔记全整理"涵盖了C语言的核心概念和实践技巧,是系统学习和理解C语言的理想资源。以下是对笔记内容的详细解读: 一、基础语法 C语言的基础语法包括变量声明、数据类型(如int、char、float、double等)...
在【压缩包子文件的文件名称列表】中,"c笔记综合.doc"可能是整个C语言笔记的综合部分,包括了语言的基本语法、数据类型、控制结构、函数、指针等核心概念的讲解。而"c笔记综合目录.doc"则可能是这份综合笔记的目录...
C语言笔记整理完整版 本文档提供了C语言的基础概念和实践示例,对初学者非常友好。下面是从文档中提取的知识点: 1. 计算机和编程语言 在计算机中,编程语言是用来控制计算机执行任务的指令集合。C语言是一种高级...
这份“C语言笔记”是作者在深入学习C语言过程中积累的知识结晶,对于初学者来说,是一份非常实用的学习参考资料。 首先,C语言的基础部分包括变量、数据类型、运算符和表达式。变量是存储数据的容器,C语言提供了...
C语言笔记总结 以下是对C语言笔记的总结,该笔记记录了一个牛人学习C语言知识点,挺全的。 一、C语言基础 * C语言源文件的扩展名是`.c` * C++源文件的扩展名是`.cpp` * 头文件的扩展名是`.h` * 库文件的扩展名是`...
从提供的文件信息来看,文件内容为一份《C语言笔记PDF》的部分扫描文字。这部分内容似乎是乱码,可能是由于OCR扫描技术导致的识别错误,也可能是文件损坏或者加密。不过,即使内容无法直接理解,我们仍可以从描述中...
通过上述分析可以看出,这份C语言笔记覆盖了循环结构、预处理指令、输入输出、字符串处理、枚举类型以及字符类型等多个方面,是一份非常全面的学习资料。对于初学者来说,这些知识点都是学习C语言的基础,掌握它们...
《郝斌C语言笔记》是一份重要的学习资料,适合希望提升C语言能力的学习者,它全面覆盖了C语言的基础知识点。本文将详细解读笔记中提及的内容,并对重要的知识点进行阐述。 首先,C语言是一种广泛使用的计算机编程...
郝斌老师的C语言课程笔记,从指针开始,动态,链表等等
非常好的一份笔记
《达内C语言笔记》是一份详尽的教程,涵盖了C语言的基础知识,旨在帮助学习者掌握编程的基本结构和核心概念。以下是对笔记内容的详细解读: ### 第一部分:C编程基本结构及输出函数 #### 1. 标准化 在C语言中,...
在提供的【部分内容】中,我们可以识别出一些关键的C语言知识点和语法细节。以下将详细阐述这些知识点。 1. 数据类型和变量声明 在C语言中,基本数据类型包括整型(int)、浮点型(float和double)、字符型(char)...
【亚嵌C语言笔记】是一份专注于C语言学习的资料集合,主要针对的是"亚嵌"(亚洲嵌入式技术培训中心)的教学体系。这份笔记以其精炼且全面的特点,为学习者提供了深入理解C语言的关键知识点。笔记分为46期和50期两个...
c语言笔记.c
这份"C语言笔记(重点、难点)"涵盖了学习C语言过程中最核心的知识点,尤其关注内存管理这一重要主题。以下是对这些关键概念的详细解释: 1. **基本语法**:C语言的基础包括变量定义、数据类型(如int、char、float...