您好,欢迎来到筏尚旅游网。
搜索
您的当前位置:首页C语言学习笔记-详细而全面的基础教程

C语言学习笔记-详细而全面的基础教程

来源:筏尚旅游网
1028 C语言笔记

冯诺依曼——程序=算法+数据结构。

1. 程序——机器可执行代码:预处理(执行#开头的指令,通常

Preprocessor整合于编译器)、编译(compiler 把程序翻译成机器目标代码O,但还不可以运行)、链接(linker整合目标代码和附加代码,如库函数printf函数,此时最终可执行)。

2. 主函数:执行程序时系统会自动调用唯一的main函数,C语言区分

字母大小写,不要写成MAIN。建议main函数末尾用一条return语句结束(否则某些编译器示警,返回的值是状态码,在某些操作系统中程序终止时可以检测到状态码),向操作系统返回0表示程序正常终止(任意终止程序状态则可调用

exit函数)。

3. /* 注释开始

*良好的注释风格有:文件名,功能,作者,日期。下面为注释结束符。

*有些注释使用C++中的//简化,但这不符合C标准,而且不同于各编译器,可移植性差。 */

#include \"stdio.h\" /* 双引号告诉compiler先当前目录搜索需要包

*/

含的文件,再从指定的系统头文件目录下搜索

main( ) /* 翼型注释,自动调用唯一的main函数*/

{ 同齐 */

/* 可以使大括号一行,并且缩进与main

int height; /* main函数中的变量等声明必须放在程序语句之

*/

前,并建议以空白行隔开

printf(\"\\n\"); /* 缩进可用3个”空格“;注意各编译器Tab键占符

不一,如8个、4个,故不宜用之 */

return 0; }

4. 对实体标识符命名中,可以含有字母、数字和下划线,开头。C语言区分大小写。标识符常小写,并符前后可添加空格,以突显之。

但数字不能

命名中间插以“_。”运算

#define PI 3.1415926 大写*/ #define

/* #为命令行,无需”;“,常量可以字母

EDIS asm(\" EDIS\")

typedef unsigned int Uint16;

typedef double Dollars; /* 类型定义方便程序移植于不同编译平台,

*/

可以首字母大写;有时类型定义比宏定义更强大

5. C标准仅对各整型数规定了最小允许范围,char8,short16,int8,

简单数据类型

long32。小端(小印第安序)低址存地位。默认情况下,都是signed,除char依编译器机器字符集而定。

进行算术运算时,float型变量通常比int型变量慢,而且更占存储空间;float型变量所存数值往往只是实际数值的一个近似值,有舍入误差。

双精度浮动的小数点数据double,为浮点常量默认存储形式。人为转换

可0377L(为八进制长整型处理,或l),15U(无符号常量处理,或u),57.0e0f( 或F 有小数和指数部分

)。

6. 运算符/和%用于负的操作数时,其结果与具体实现有关如-9/5可能

为-1或-2。-9%5可能为2 或-2。注意5.0/9.0 不等于5/9的取整。赋值=\" 指针为右向左结合。

++i意味着”立即自增i”,而常用的i++为下条语句前i才将自增。

例如,i=1;

printf(\"i is %d\\n\/* 输出i为1*/

printf(\"i is %d\\n\又如,i=1;

); /* 输出i为2*/

printf(\"i is %d\\n\/* 输出i为2*/

printf(\"i is %d\\n\); /* 输出i为2*/

7. if级联:可有{ 复合语句; }。

if (表达式)

语句;

else if (表达式)

语句; ……

又有return (i>j ? i : j ) ;

可不加括号,又如

return (i+j)/2 ;

还有switch语句往往比级联式if语句更易阅读,且执行速度快。循环中,可有初始表达式

for(sum = 0.0 , i = 1; i <=N; i ++)

sum += i;

逗号运算符允许将多个表达式“黏贴”在一起构成单独的一个表达式。似于复合句把;多语句当做是唯一一条语句的作用。

8. C语言有有两种聚合类型:array、structure结构记录。C语言不要求检查下标的范围,当下标超出范围时,程序执行将不可预知。化式完全为空是非法的。至少有:int a[3] = {0};

数组初始

数组定义中,有不可修改的常量数组: const int a[ ] = {1, 2, 4};

m[i , j]等同于逗号运算后的组的。

m[ j ] 。对于数组是按照行主序存储数

对数组a的清零方法有:for (i = 0; i < sizeof(a) / sizeof(a(0)) ; i++ ) = 0;

9. C语言中,函数不一定要有参数和计算数值。不带返回值的函数需指明void返回类型。函数无法返回整个数组,仅有单个返回值(多值回“唯有void函中传址调用);忽略返回类型将自动假定返回为

a[i]

”调int型。

函数调用:函数名(实际参数列表)定义中每个形参都要进行类型说明型的函数调用是语句,非

; 不加括号将为函数名地址;函数,return后返回值可不加(),void

void型的函数调用是表达式。

主函数前的函数原型声明,可以防止编译器对先遇到的函数调用进行纠结的假设。原型为如何调用函数提供了一个完整的描述:参数的类型,返回结果的类型。

多少实际参数,

函数原型不需要说明形参的名字,只需显示各类型即可,如,int sum_array(int [ ] , int ); 还是不忽略名字以示自我提醒。

函数原型中数组的名字和长度。但最好

而在sum_array 函数调用时,total = sum_array (b , LEN); 函数调用中数组名后不能加[ ]。

当函数有一位数组a作为形式参数时,*a比a[ ]更通用。

数组变量不同于指针变量,至少sizeof(a)的值是数组中字节的总数,

sizeof(p)的则是用来存储指针值所需的字节数量。

若是形式参数为二维数组等,可配。

忽略第一维的长度,但必须说明数组中的列数

以示空间分

二维数组b[2][2]中,b和b[ ]都指向同一位置——b[0][0]。但是C语言认为b不是二维数组而是指向

b[0]的指针,是作为一位数组,且这个

编译器认为,b用作指针时具有int

= &(*(b[i] +0))

一位数组的每个元素又是一个数组。

**型的指针(指向整数指针的指针)。有b[i] = &*b[i] 指向数组a的i行的指针。

10. C语言要求每个指针变量唯一指向特性类型。

赋值运算符要求它左边的操作数必须是左

值,如变量、*p等。左值表示存储在计算机内存中的对象,而不是常量或计算结果,

声明指针:int i, *p = & i ; j = *&i ; 只要p指向了i,那么*p 就是i的别名了。

旦指针变量指向了对象,就可以使用对象中的内容了

*(间接寻址)运算符访问存储在

。但不要把间接寻址符用于为初始化的指针变量。

int *max(int *a, int *b) /*指针作为返回值,但是原型

*/

int (*max)(int

*a, int *b); 中有函数指针作为实际参数

return *a > *b? a : b; /*函数返回指向两整数中较大数的指针,调

用时可以p = max(&x , &y); */

在一些计算机上,指针可能是“偏移量”而不完全是地址。

数组元素之和:for(sum=0.0 , p = &a[0] ; p <&a[N] ; p++) += *p; 甚至可以写为for(……) sum += p[i];

sum

虽然数组名可用于指针但不能给数组名赋新的值。

11. #指令总是在第一个换行符处结束,除非用“”指明继续。

带参数的宏会更通用点。如

#define MAX(x , y) ((x)>(y) ? (x) : (y)) 后面的程序:

i = MAX(a , b) ;

*programa指令为要求编译器执行某些特殊操作提供一种方法。

0. 存储位置(普通内存、运行时的堆栈、CPU内部的通用寄存器);作用域(声明处的程序块如if,函数内,C文件内,C文件外)…………

具有自动存储期限的变量没有默认的初始值,期限的变量默认情况下的值为针。

不能预测;具有静态存储

0,浮点变量为0.0,而指针初始化为空指

1. 在局部自动数组中开设大数组如8K字节时,是需要仔细评估的,程序员必须非常清楚自己的堆栈空间是否够用。安全起见可以采用char buf[8*1024]”的方法定义。

“static

注意:当buf[]数组变量是通过堆栈或CPU内部寄存器自动存放时,将

其地址作为指针传递到函数外部是非常危险的或是没有意义的。

2. 当为申请内存块而调用内存分配函数(malloc、calloc、realloc)时,

由于函数无法知道计划存储在内存块中的数据是啥类型,函数会返回void *型的值,它是“通用”指针,本质是内存地址。

当调用内存块分配函数时,无法定位满足我们需要的足够大的内存块,函数会返回空指针null pointer,指向为空类型。

mallac()库函数返回值是一个指向void类型的指针,因此好的编程风格

是在将这个返回值被赋给其他类型的指针变量前进行显式的强制类型转换(不同于编译器的自动隐性类型转换)

。如,p=(char*)mallac(1024)。

中函数可把数组b复制给数组b:memcpy(a , b , sizeof(a));

3. 避免内存泄露,以免内存空间无法释放回系统堆(heap)。

4. void体现了一种抽象(无类型),有(若不写函数的返回值类型,数没有入口参数;

3个用途:修饰函数没有返回值

声明函

默认为随机的int型返回值);

声明空类型指针void*,其不指向任何类型的数据

仅表示一个内存地址,其引入实际上是为了程序编写的方便,再对指针进行强制类型转换。

在需要时

5. 凡是在函数外声明的变量都是运行。默认作用域仅为该

全局变量(编译于普通内存,并静态

C文件中,除非extern重声明使之作用域外,

易于简单调用)。

extern外部函数或变量可编写于头文件中

如,DSP28_GlobalPrototypes.h ——函数原型头文件中有:extern void InitSpi(void); extern void InitSysCtrl(void);

……

),3大用途:函数内编译时已分配于永久

用于函数的定义在用于全局变量

6. static关键词(声明处静态,便于模块化设计

部局部变量声明,从自动存储期限变为静态变量,静态地址空间,但作用域不变,仍为该时,该函数只能用于定义该函数的的声明时,作用域局限于

函数内部;

C文件中引用;

C文件内。

7. struct结构变量之位域,节省存储空间并便于处理,字节中顺序分出二进制位段存区:

// 此为Dsp的常用注释方法,High speed peripheral clock register bit definitions:

struct HISPCP_BITS { Uint16 HSPCLK:3; Uint16 rsvd1:13; };

union HISPCP_REG { Uint16

all;

// bits description // 2:0

Rate relative to SYSCLKOUT

// 15:3 reserved

struct HISPCP_BITS bit; };

而联合变量的所有成员共享同一片存储区,成员的值。

某时刻只能保存它的某一个

8. volatile 定义的变量,可能会被意想不到的被改变,这样编译器就不会去假设这个变量的值了,即优化器会慎用之。如,用于一个中断服务子程序中会访问到的非自动变量,多线程应用中被几个任务共享的变量,并行设备的硬件寄存器(如状态寄存器)。extern cregister volatile unsigned int IFR;

C语言中没有真正意义的常量概念,如const修饰为只读变量,#define 预处理时已成立即数。

9. 指针三要素:指针变量的值(地址),指针指向的地址上的内容,指针变量本身的地址。

10. C语言编译器在传递函数参数时,实际上通过将参数的值压入堆栈或者传参寄存器进行传递(即所有的参数都是以“传值调用”的方式调用的,或称复制参数)。但是当函数的入口参数中包含数组时,

C语言将

以数组首地址待之,函数内部通过这个地址引用的数组自然是外函那数组了,从而可以实现传址调用,真正修改caller调用者。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务