C语言-c语言组成

1.C语言的组成

一个C源程序是由 一个或者多个.c文件 和 0个或者多个.h 文件 组成

源程序: 是指未编译的 按照一定的程序设计语言规范书写的文本文件

.c文件 : c源代码

.h文件 : 头文件(接口文件)

  1. .c文件

1)预处理命令

以#开头的行,在编译之前 会事先做处理

在C语言中的预处理命令: 文件包含, 宏定义, 条件编译

(1)文件包含

#include <stdio.h>

把include后面的那个文件的内容 在此处展开

例子:

gcc -E xxx.c -o xxx.i //预处理, test.i 还是C源代码文件

gedit xxx.i //gedit文件编辑器,可用于查看文本文件的内容

头文件的引用

#include <> 从系统标准的头文件路径下进行搜索 (如: /usr/include/ )

#include "" 先从当前的工程路径下进行搜索, 再从系统标准的头文件路径下进行搜索

(2)宏定义

宏定义: 定义一个宏

☆☆☆

宏: 是一个批量处理的称谓, 它只是简单替换, 不作计算, 也不作表达式

使用宏可以提高程序的通用性和可移植性

分类:

(2.1)不带参数的宏, 符号常量

语法:

#define 宏名 要替换的内容

例子:

#define Pi 3.14

double s = r*r*Pi; // OK r*r*3.14

Pi = 3; // error 3.14 = 3;

(2.2)带参数的宏

语法:

#define 宏名(参数列表) 要替换的内容

"参数列表": 在宏里面的参数, 不需要类型

例子:

定义一个宏, 求两个整数的最大值

#define MAX(a,b) a>b ? a : b

int c = MAX(3,5); // 3>5 ? 3 : 5

printf("c = %d\n", c ); // c = 5;

int i = 6;

c = MAX( i++, 5 ); // i++>5 ? i++ : 5 ==> 7 (此时i==8)

//宏定义只是简单替换,不作计算,也不作表达式

c = MAX( 1+2, 3+4 ); // 1+2>3+4 ? 1+2 : 3+4 ==> 7

c = MAX( 1>2, 3<4 ); // 1>2>3<4 ? 1>2 : 3<4 ==> 0

更正:

#define MAX(a,b) ( { typeof(a) _a = a; \

typeof(b) _b = b; \

(_a)>(_b) ? (_a) : (_b); \

} )

练习:

1)定义一个宏, 求数组a的元素个数

#define ARRAY_SIZE(a) ( sizeof(a)/sizeof(a[0]) )

2)定义一个宏, 取一个整数x中的第n个bit位

xxxxaxxx

xxxxxxxa x>>n

00000001 &1


0000000a

#define GET_BIT(x,n) ({ typeof(x) _x = x; \

typeof(n) _n = n; \

( ( _x >> _n ) & 1 ); \

})

#include <stdio.h>
#include "sum.h"

#define N 10 

//带参数的宏
// #define MAX(a,b)  a>b ? a : b 	//有副作用

#define MAX(a,b)  ( {   typeof(a) _a = a;	\
                        typeof(b) _b = b;	\
                        (_a)>(_b) ? (_a) : (_b);	\
                    } )


#define ARRAY_SIZE(a)  ( sizeof(a)/sizeof(a[0]) )


#define GET_BIT(x,n)  ({    typeof(x) _x = x;   \
                            typeof(n) _n = n;   \
                            ( ( _x >> _n ) & 1 );   \
                        })


int main()
{
	int a[N];
	printf("%ld\n", ARRAY_SIZE(a) );

	int c = MAX(3,5);   
	printf("c = %d\n", c );	// 5

	int i = 6;
    c = MAX( i++, 5 );
    printf("c = %d\n", c );	// 7

    c = MAX( 1+2, 3+4 );
    printf("c = %d\n", c );	// 7

    c = MAX( 1>2, 3<4 );
    printf("c = %d\n", c );	// 0

    int x = 7;
    if( GET_BIT(x, 3) )
    {
		printf("1\n");
    }
    else 
    {
		printf("0\n");
    }

	//条件编译
    #if 1 
    	printf("123\n");
    #endif

    #if 0 
    	printf("456\n");	 //少了一个分号
    #endif
}

(3)条件编译

(3.1)条件编译一般在.h文件中

#ifndef XXX_H

#define XXX_H

#endif

为了防止重复包含

(3.2)

#if 表达式

语句

#endif

"表达式"的值为真, 那么就编译"语句" ,

如果为假, 则不编译

类似于if语句

例子:

//条件编译

#if 1

printf("123\n");

#endif

#if 0

printf("456\n"); //不参与编译了

#endif

2)声明

"声明" :

在C语言中, 声明 是用来声明一个已经存在的标识符(对象的名字)

声明就是用来表示一个标识符(对象的名字)到底是什么东西

为什么需要声明?

C语言编译源文件时, 是从第一行到最后一行, 一行一行的进行编译

而且在编译多个文件的时候, 也是一个文件一个文件的编译的

有时候1.c可能会用到2.c中定义的对象(变量/函数等)

在编译1.c时,碰到这个对象的名字, c语言编译器就可能不认识这个标识符,

即使是在同一个文件中, 在前面碰到的标识符,而这个标识符的定义在后面

此时 编译器也会不知道这个标识符是什么东西

一般来说, 在源文件的前面 要进行标识符的声明

约定:

将声明 放在 使用的前面

声明的格式:

(1) 外部变量的声明

extern 变量的类型 变量名; //外部变量声明时, 不能给它初始化

(2) 函数的声明

(2.1) 外部函数的声明:

extern 函数的返回值类型 函数名(参数列表); //extern 函数头;

(2.2)本文件内部的 函数的声明

函数的返回值类型 函数名(参数列表); // 函数头;

例子: 参考函数的例子

注意:

函数声明,形参的名字是可以省略的,但是类型不能省略

int sum( int x, int y ); // OK

int sum( int, int); // OK

int sum( x, y ); // error

  1. 全局变量 和 函数的定义

int a = 10;

int fun()

{}

int main()

{

}

在C语言中, 语句必须在函数的内部, 一个.c文件可以由多个函数组成

一个工程(程序)只能 有且仅有一个main()函数 , 可以有0个或者多个非主函数

main()函数是程序的入口, 程序从这里开始执行, main函数结束了, 那么整个程序就结束了

  1. .h文件

.h文件的作用

1.c sum()

然后 2.c中需要用到1.c中的sum()函数

在2.c中进行外部函数的声明 就可以了

但是 如果 3.c 4.c 5.c ... 都需要用到这个函数?

只需要创建已给1.h文件 进行声明

int sum(int a, int b);

那么 2.c 3.c 4.c .... 只需要包含这个头文件即可

#include "1.h"

.h 头文件 (接口文件)

头文件的格式:

例子: sum.h

#ifndef SUM_H //防止重复包含 //和文件名一致,建议全部大写

#define SUM_H

//头文件 一般包含 宏定义, 函数声明, 类型构造等

#endif

编程规范:

一般头文件的内容 不产生指令 或者 分配空间(比如:定义空间) 代码

头文件的引用

#include <> 从系统标准的头文件路径下进行搜索 (如: /usr/include/ )

#include "" 先从当前的工程路径下进行搜索, 再从系统标准的头文件路径下进行搜索

  1. 模块化设计思想

例子:

造一架飞机

驾驶舱, 机翼, 引擎, 起落架

main.c 包含main()主函数 , 程序的入口 , 进行功能的调用

cockpit.c / cockpit.h 跟驾驶舱相关的功能代码

wing.c / wing.h 跟机翼相关的功能代码

engine.c / engine.h 跟引擎修改的功能代码

...

.c文件 包含具体功能函数的实现

.h文件主要是函数的声明

编译:

gcc main.c cockpit.c wing.c engine.c ... -o main

练习:

  1. 提取字符串中的数字

输入一串字符串, 该字符串中可能包含数字, 把里面找到的数字 进行求和

例如:

输入: abc123def45ghijk6mn

输出: 174 ( <== 123 + 45 + 6 )

#include <stdio.h>
#include <string.h>

int get_num_in_string( char *s )
{
    int num = 0;
    int sum = 0;    //保存结果
    int i;
    for( i=0; i<strlen(s); i++ )    //遍历的字符串s
    {
        if( s[i]>='0' && s[i]<='9' )    //是数字 
        {
            num = num*10 + s[i] - 48;   //合成数字

            if( s[i+1]<'0' || s[i+1]>'9' )  //下一个不是数字
            {
                sum = sum + num;
                num = 0;
            }
        }
    }
    return sum;
}

int main()
{
	char buf[64] = {0};
	scanf("%s", buf );

	int sum = get_num_in_string( buf );
	printf("sum = %d\n", sum );
}
相关推荐
余额不足121384 小时前
C语言基础十六:枚举、c语言中文件的读写操作
linux·c语言·算法
罗伯特祥5 小时前
C调用gnuplot绘图的方法
c语言·plot
嵌入式科普6 小时前
嵌入式科普(24)从SPI和CAN通信重新理解“全双工”
c语言·stm32·can·spi·全双工·ra6m5
lqqjuly7 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++
2401_858286118 小时前
115.【C语言】数据结构之排序(希尔排序)
c语言·开发语言·数据结构·算法·排序算法
2401_858286119 小时前
109.【C语言】数据结构之求二叉树的高度
c语言·开发语言·数据结构·算法
KevinRay_10 小时前
Linux系统编程深度解析:C语言实战指南
linux·c语言·mfc·gdb
灵槐梦10 小时前
【速成51单片机】2.点亮LED
c语言·开发语言·经验分享·笔记·单片机·51单片机
LittleStone839711 小时前
C语言实现旋转一个HWC的图像
c语言
stm 学习ing13 小时前
HDLBits训练5
c语言·fpga开发·fpga·eda·hdlbits·pld·hdl语言