黑马程序员——C语言助记(一) 基础知识及规范

来源:互联网 发布:魅丽文化网络编辑招聘 编辑:程序博客网 时间:2024/06/01 08:50

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

       虽然之前也学过C语言,但是很久不用,知识点都有些遗忘了,所以现在来整理下一些容易遗忘的知识。发现再次学习,有新的收获呢!

1.关键字

       C语言一共提供了32个关键字:

autodouble int struct break else long registercase enum static typedef char extern return unsignedconstfloatshortgoto sizeofdoifcontinueforsignedvoid default unionswitch while  volatile

2.标识符命名规则

1)只能由26个英文字母的大小写、10个阿拉伯数字0~9、下划线_组成
2)严格区分大小写,比如test和Test是2个不同的标识符
3)不能以数字开头
4)不可以使用关键字作为标识符

3.数据类型

1)基本数据类型:
      int:整数
      浮点型:①float单精度②double双精度
      char:字符型
2)空类型 void
3)指针类型 int* void*
4)构造类型:
      struct:结构体
      数组
      union:共用体
      enum:枚举

4.内存由小到大寻址,优先分配内存地址较大的字节给变量。而在变量所占的区域内由小到大存放数据。

5.头文件".h"与源文件".c"的关系

        1)头文件中保存的是对应源文件中的函数声明

        2)在代码中包含文件的本质就是:在编译时,将所包含内容添加到当前代码中,一起编译

        其实,头文件".h"和源文件 ".c"在使用上都属于编译预处理,而编译预处理的作用就是将这些命令所表示的内容替换成相应的内容。

        比如#include一个.h文件,就会把.h文件中的内容替换到对应的位置,而.h文件中一般写的都是该.h文件所对应.c文件中函数的声明语句,所以包含.h文件后,就相当于在该源文件中添加另一个.c文件中函数的声明部分,从而可以在本文件中调用另一个.c文件的函数。

        再比如#include一个.c文件,就会把.c文件中的内容替换到相应位置上,如果这个.c文件中只有一些代码语句,而正好被包含的位置是一个语句执行块,那么经过编译预处理后,执行该语句块,当执行到#include的位置是,就相当于执行了这个.c文件中的语句。

6.输入

       关于这部分我会写一篇专题,探究输入,稍后补上

7.输出

       关于这部分我会写一篇专题,探究输出,稍后补上。

8.进制转换

       关于这部分我会写一篇专题,探究进制转换,稍后补上。

9.必须记住的一些数

        2^31 = 2147483648

        2^16 = 65536

        2^15 = 32768

        2^10 = 1024

        2^8 = 256

10.常见字符的ASCII码 

        0:48

        A:65

        a:97

        '\0':0

        另外 ,文件结束符EOF的值为-1,该值是在stdio.h的头文件中定义的。

11.常用占位符

%c

读入一个字符

%d

读入十进制整数

%i

读入十进制,八进制,十六进制整数

%o

读入八进制整数

%x,%X

读入十六进制整数

%s

读入一个字符串,遇空格、制表符或换行符结束。

%f,%F,%e,%E,%g,%G

用来输入实数,可以用小数形式或指数形式输入。

%p

读入一个指针

%u

读入一个无符号十进制整数

%n

至此已读入值的等价字符数

12.sizeof

        sizeof用来计算一个变量或者一个常量、一种数据类型所占的内存字节数,使用方法有如下三种:

<span style="font-size:18px;">int a;int size;size = sizeof(a);//第一种size = sizeof a;//第二种size = sizeof(int);//第三种</span>

        注:如果用sizeof计算一个指针的大小,在64位编译器下,返回值为8
        下面是我关于sizeof用法的讨论:

        sizeof用法讨论1

        sizeof用法讨论2

        sizeof用法讨论3

13.sizeof与strlen函数的对比:

        sizeof计算的是数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。

        strlen计算的是字符数组中的字符数,以'\0'结束,若字符数组或字符串中包含'\0'字符,则不将该该字符之后的字符计入长度。若整个字符数组中不包含'\0'字符,则继续往后寻找,直到遇到第一个'\0'字符。(在字符串的末尾默认会有一个'\0'字符)。

        下面是验证代码:

<span style="font-size:18px;">#include <stdio.h>#include <string.h>int main(){char str1[] = {'s', '1', '\0'};char str2[] = {'s', '2'};char str3[] = "s\03";printf("str1:%s\t\tsizeof:%d\tstrlen:%d\n", str1, sizeof(str1), strlen(str1));printf("str2:%s\tsizeof:%d\tstrlen:%d\n", str2, sizeof(str2), strlen(str2));printf("str3:%s\t\tsizeof:%d\tstrlen:%d\n", str3, sizeof(str3), strlen(str3));return 0;}</span>

输出:

str1:s1         sizeof:3        strlen:2
str2:s2s1     sizeof:2        strlen:4
str3:s           sizeof:3        strlen:1


        由于C语言是从高到低寻址,所以str1首先存入高地址,依次是str2和str3进入内存。

        str1是正常的字符串,占3个字符,所以sizeof函数的返回值是3,strlen返回2。

        而str2由于没有字符串结束标志,只能继续访问后面的地址,直到访问到更高地址的str1中的'\0'才结束,所以sizeof返回2,strlen返回4。

        str3由于字符串中包含字符串结束符,所以strlen会在访问到第一个'\0'就结束计算长度,返回1,而由于字符串中已经包含了结束符,所以不会自动在最后添加结束符'\0',计算sizeof计算长度时,是计算了字符's','\0','3',所以返回值是3。

14.结构体

        1)结构体的内存分配算法:补齐算法(对齐算法)

                结构体所占空间大小一定是最大成员的倍数。

        2)结构体变量的三种定义方式:

            1>先定义类型,再定义变量:

<span style="font-size:18px;">struct Student{int age;</span>
<span style="font-size:18px;">double height;};struct Student stu;</span>

            2>定义类型的同时定义变量

<span style="font-size:18px;">struct Student{int age;</span>
<span style="font-size:18px;">double height;} stu;</span>

            3>定义类型的同时定义变量(忽略结构体类型名称)

<span style="font-size:18px;">struct</span>
<span style="font-size:18px;">{int age;</span>
<span style="font-size:18px;">double height;} stu;</span>


        3)结构体数组的定义(以上面结构体为例)

<span style="font-size:18px;">struct Strudent stuArr[3];</span>

        4)结构体指针

            定义方式:

<span style="font-size:18px;">struct Strudent *stup;</span>
<span style="font-size:18px;">stup = &stu;</span>

        5)访问结构体成员的方式:

<span style="font-size:18px;">stu.age;//方法一 (*stup).age;//方法2 (*stup)->age;//方法3 </span>

15.枚举

        1)关键字为enum,声明方式与结构体第一种声明方式类似,但是结构体内部用的是分号分割,而枚举是用都好分割。

        2)枚举值默认从1开始往后递增

        3)可以主动给枚举值赋值,其后面的枚举值则根据这个值递增

例如:

<span style="font-size:18px;">#include <stdio.h>int main(){enum Test{aa,//1bb,//2cc = 1,//1dd,//2ee = 4,//4ff//5};enum Test t1 = aa;enum Test t2 = bb;enum Test t3 = cc;enum Test t4 = dd;enum Test t5 = ee;enum Test t6 = ff;printf("%d%d%d%d%d%d\n", t1, t2, t3, t4, t5, t6);//011245return 0;}</span>

16.编译预处理——宏定义

        1)不带参数的宏定义

            写法: #define 宏名 常量

            作用:它的作用是在编译预处理时,将源程序中所有"宏名"替换成右边的"字符串",常用来定义常量。

            注意:①宏名一般用大写字母,以便与变量名区别开来,但是小写也没有语法错误②宏定义不会替换掉字符串中的代码。

        2)带参数的宏定义

            写法:#define 宏名(参数列表) 表达式

            作用:在编译预处理时,将源程序中所有宏名替换成字符串,并且将 字符串中的参数 用 宏名右边参数列表 中的参数替换

            注意:①宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串②带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以表达式一定要考虑到优先级因素,所以最好对每个参数加括号,对整体表达式也加括号。

例如:

<span style="font-size:18px;">#include <stdio.h>#define average(a, b) (((a) + (b)) / 2)int main (){    int a = average(10, 4);        printf("平均值:%d", a);    return 0;}</span>


17.编译预处理——条件编译

        1)基本写法:

<span style="font-size:18px;">#if 条件1 ...code1...#elif 条件2 ...code2...#else ...code3...#endif</span>

        2)#if defined()与   !#if defined()

判断是否定义过某个宏。

        3) #ifdef  和 #ifndef

后面跟宏名,判断是否定义过某个宏

18.编译预处理——文件包含

        1)文件包含允许嵌套包含,但不允许递归包含

        2)包含多个头文件可能会导致有些声明重复,从而降低编译效率

            放置头文件重复包含问题,会在头文件中加入如下代码:

<span style="font-size:18px;">#ifndef _ONE_H_#define _ONE_H_void one();//声明#endif</span>

19.函数指针

<span style="font-size:18px;">#include <stdio.h>void test(){printf("调用了test函数\n");}int sum(int a, int b){return a + b;}int main (){    void (*p)();//定义指针     p = test;//将指针指向函数p();//调用test函数   方法1 (*p)();//调用test函数   方法2 test(); //调用test函数  方法3int (*pp)(int, int) = sum;//定义指向 sum的函数指针     return 0;}</span>


19.typedef

        1)格式为:typedef 类型名 所要定义的名字

此类格式同样适用于结构体、枚举等等。

<span style="font-size:18px;">typedef struct Student{       int Age;} MyStu;</span>


        2)函数指针例外!

如:

<span style="font-size:18px;"> typedef int (*MyPoint)(int, int);</span>


20.static和extern

        1)外部函数

        1>默认情况下,所有函数都是外部函数;

        2>不允许有同名的外部函数

        2)内部函数

        1>定义的内部函数只能被本文本文件访问

        2>允许不同文件中有同名的内部函数

        3)static对函数的作用

        定义或声明一个内部函数

        4)extern对函数的作用

        完整的定义或声明一个外部函数(extern可以省略,默认情况下定义和声明的函数都是外部函数)

例子:

在文件static1.c中写入如下代码:

<span style="font-size:18px;">void test(); void test2(){}int main (){test();//调用另一个文件中的 test2();//调用本文件的test2函数 //test3();//无法调用另一个文件的内部函数     return 0;}</span>

在文件static2.c中写入如下代码:

<span style="font-size:18px;">#include <stdio.h>static void test2();extern void test(){printf("调用了test函数\n");test2();}static void test2(){printf("调用了test2函数\n");}static void test3(){printf("调用了test3函数\n");}</span>

        5)外部变量与内部变量

        1>外部变量extern:①默认情况下所有的全部变量都是外部变量;②外部变量也可以在函数中声明

        2>内部变量static:①如果有同名的外部全局变量,又有内部全局变量,则采用就近原则;②static定义的变量只会在第一次执行时对数据进行初始化,为变量分配存储空间,生命周期一直伴随到程序结束;③static修饰符并不会改变变量的作用域。

21.共用体

        1)union的声明方法:

        与struct声明方法类似:

union StateMachine{   char character;   int number;   char *str;   double exp;};
        2)union使用方法:

        union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。

        一个union 只配置一个足够大的空间以来容纳最大长度的数据成员,以上例而言,最大长度是double 型态,所以StateMachine 的空间大小就是double 数据类型的大小。

        3)union中数据的存储方法

        union中数据的存储方法与存储模式有关:分为大端模式(Big_endian)和小端模式(Little_endian)

        1>大端模式:字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。

大端模式

        2>小端模式:字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。








 

       

 

 

 

 

 

 

 

 

 

 

 

0 0
原创粉丝点击