C语言基础语法

GNU工具

1.编译工具:把一个源程序编译为一个可执行程序(gcc)

2.调试工具:能对可执行程序进行源码或汇编级调试(gdb)

3.软件工程工具:用于协助多人开发或大型软件项目的管理

gcc编译器

gcc hello.c -o hello
1.预处理:将头文件或宏定义展开加到程序中
gcc -E hello.c -o hello.i
注意:不会检查语法错误
2.编译:将源程序编译成汇编语言
gcc -S hello.i -o hello.s
注意:检查语法错误
3.汇编:将汇编文件编译成二进制文件(目标文件)
gcc -c hello.s -o hello.o
4.链接:将程序运行需要的所有文件链接生成可执行文件
gcc hello.o -o hello
选项:-g:生成调试信息

gdb调试工具

查看文件 (gdb) l ,默认打印前10行数据
设置断点 (gdb) b [行号]
查看断点情况 (gdb) info b
运行代码 (gdb) r :运行到断点处停止,不执行断点所在行的代码
r不能从断点处开始运行,只能从程序开头开始运行
查看变量值(gdb) p n
单步运行 (gdb) n
(gdb) s
不会断点所在行的代码
注意:只能从断点处开始运行,不能从程序开头开始运行
恢复程序运行 (gdb) c
删除断点:delete(del)
退出gdb:(gdb) q

数据类型

1.整型:int  4个字节
短整型 short 2个字节
长整型 long 4个字节
long long 8个字节

sizeof :计算数据字节长度
2.字符型:char 1个字节
3.浮点型 
float  单精度 4个字节
double 双精度 8个字节

隐式转换:int ==> float

数据类型默认有符号

指针

1.声明:
数据类型 *指针变量名;
2.赋值:
(1)在声明的同时初始化指针变量
int *p = &a;
(2)直接操作已有指针变量
p = &a;
3.指针运算:
指针运算的实质就是地址的计算。
p+n表示的实际内存单元的地址量是:
(p) + sizeof(p的类型) * n

p-n表示的实际内存单元的地址量是:
(p) - sizeof(p的类型) * n

++--属于第二级优先级,从右向左结合,++\--如果加在变量后面允许变量先参与其他所有的运算

如果加在变量前面先++/--再运算
*p++ ==> *p;p++
(*p)++ ==> *p;(*p)++
*(p++ )
4.二级指针
指向指针的变量

数组

1.一维数组
(1)数组元素必须在声明时定义好
(2)数组名是数组首地址
(3)数组开辟的是连续的内存空间
2.二维数组
数组元素是一维数组

指针和数组

1.一级指针与一维数组		
int a[3];
int *p = a;
2.指针与二维数组
注意:二维数组的首地址不能直接赋值给指针
3.数组指针
int (*p)[n]; 
n:一维数组元素个数
*(*(p+i)+j)
4.指针数组
int *p[n]

const

const声明的变量是只读型变量不允许被修改。
1.常量化指针的对象
const  <数据类型> *<指针变量名称>;
<数据类型> const  *<指针变量名称>;

eg.int const *
const int *
常量化指针目标是限制通过指针改变其对象的值
2.常量化指针变量 
<数据类型> *const <指针变量名称>= <指针运算表达式>;
eg.int *const 
3.常量化指针变量及其对象
const  <数据类型>  * const    <指针变量名> = 
<指针运算表达式>  ; 
eg.const int * const 

void

void型的指针变量是一种指向不确定数据类型的指针变量()。它可以通过强制类型转换让该变量指向任何数据类型的对象。

函数

1.函数声明
2.函数调用
3.指针函数	
返回指针的函数
4.函数指针
指向函数的指针
函数名就是函数的入口地址
<数据类型>*<函数指针名称>)<参数说明列表>)5.函数传参
(1)赋值传参(复制)
修改形式参数的值不会影响实际参数的值
(2)地址传参
(3)命令行传参
int argc 命令行参数个数(包含文件名)
const char* argv[] 指针数组:将命令行参数首地址作为元素
5.递归函数 
调用函数本身的函数
求3!

结构体

特点:包含不同的数据类型
1.定义:
定义一个结构体类型的一般形式为:
struct  结构体名
{
数据类型   成员名1;
数据类型   成员名2;
:
数据类型   成员名n;
};

结构体类型中的成员名可以与程序中的变量名相同,二者并不代表同一对象,编译程序可以自动对它们进行区分。 
最后,总结一下结构体类型的特点:
(1)结构体类型是用户自行构造的。
(2)它由若干不同的基本数据类型的数据构成。
(3)它属于C语言的一种数据类型,与整型、实型相当。因此,定义它时不分配空间,只有用它定义变量时才分配空间。 

定义变量的方式
(1)声明结构体数据类型的同时定义变量
struct 结构体名
{
成员列表;
}变量名;
注意: 结构体名可以省略,省略后不能再使用数据类型名定义变量
struct 
{
成员列表;
}变量名;

(2)使用数据类型名定义变量
2.结构体的初始化:
std.a = 1;
std.b = ‘a’;
相同数据类型的结构题可以相互赋值
3.结构体大小
sizeof()运算符
Linux系统字节对齐

计算结构体大小的方式:
偏移量:结构体成员变量与结构体首地址的差
(1)成员变量的偏移量=上一个成员变量的偏移量+上一个成员变量的大小
(2)结构体的大小=最后一个成员变量的偏移量+最后一个成员变量的大小

遵循原则:
(1)结构体成员变量的偏移量必须是成员大小的整数倍
(2)结构体大小必须是成员变量数据类型的整数倍
4.结构体数组
5.结构体指针

用->指向成员变量
struct student *p;
p->a = 1;

typedef 重命名

1.typedef struct student
{

}std;
std表示为数据类型起的别名
注意:如果给结构体类型重命名,则结构体名可以省略
2.typedef struct 
{

}std;

3.typedef struct 
{

}std,std1;
为结构体类型起了两个别名

注意:如果使用typedef给结构体类型重命名,则声明结构体类型的同时不能再定义变量 

共用体

可以包含不同的数据类型
特点:所有成员变量共用同一块内存空间

共用体变量总是按其成员中数据长度最大的成员开辟内存空间
定义:
union 共用体名
{
成员表列;
};   、


4字节对齐

字节序:字节在内存中的排列顺序
小端存储:低字节对应低地址,高字节对应高地址
大端存储:低字节对应高地址,高字节对应低地址
默认小端存储

共用体数组
共用体指针

存储类型

1.自动变量(auto)
在函数体内声明的局部变量默认都是自动变量
2.寄存器变量(register)
用register声明的变量直接存放在CPU的寄存器上
3.外部变量(extern)1extern 声明的函数表示该函数是从别的文件中引用过来的
(2extern 声明的变量表示该变量是从别的文件中引用过来的,不在本文件中开辟空间
(3)在所有函数体下面定义的全局变量无法被函数识别,除非在函数体内用extern 声明
4.静态变量(static)
(1static声明的静态局部变量只初始化一次,变量的生命周期不会随着函数调用的结束而结束,函数下一次调用时该变量的初始值是上一次调用结束时该变量的值
(2static声明的函数只能被本文件使用,不能被其他外部文件引用
(3static声明的全局变量只能被本文件使用,不能被其他外部文件引用

:vsp :在同一个vi编辑器中打开多个文件

多文件编程

头文件:
条件编译
优点:防止头文件重复定义
格式:
#ifndef
#define

……
#endif
<>:在系统中寻找头文件
“”:在当前目录寻找头文件

内存区域的划分

1.全局区/静态区
存放全局变量和静态变量
初始化
未初始化:默认值为0

程序结束后释放变量
2.栈区
由系统自动分配和释放
默认值:随机值
自动变量和函数都是在栈区里开辟空间

3.堆区
由程序员手动申请和释放内存,如果没有手动释放,则可能会被操作系统回收

动态分配函数
#include 

void *malloc(size_t size);
功能:在堆区开辟指定大小的内存空间
参数:指定内存空间的大小
返回值:成功:所开辟内存的首地址
失败:NULL


Segmentation fault (core dumped)
段错误:(1)代码溢出 
(2)指针操作有误.程序中出现了野指针
野指针:指向一块未知的内存空间
NULL:表示地址为0的内存空间,不允许被读写

void free(void *ptr);
功能:释放指针指向的内存空间(必须是由动态分配函数申请)
参数:内存空间的首地址
返回值:无
4.常量区
存放常量
int add(int a,int b)
{
retrun a+b;
}

add(a,b);
add(1,2);

char a[] = "hello";
char *p = "hello";
#define N 5
5.程序代码区
存放二进制的可执行指令

Make工程管理工具

自动编译管理器,能够根据文件时间戳自动发现更新过的文件而减少编译的工作量

调用make工具时自动检测上一次调用make工具后文件时间戳是否更新,如果更新了,则重新编译该文件,否则不再重复编译

Makefile
格式:将命令行下的编译命令倒着写
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc main.o add.o -o main

目标文件:依赖文件
<TAB键> 编译命令

调用:直接输入make

变量类型:
(1)用户自定义变量
(2)预定义变量
CFLAGS   C编译器的选项,无默认值。
RM	文件删除程序的名称,默认值为rm -f
(3)自动变量
$@  目标文件的完整名称
$^	 所有不重复的目标依赖文件,以空格分开
$*	  不包含扩展名的目标文件名称
$<	   第一个依赖文件的名称

伪目标:
.PHONY:目标名
用伪目标声明目标后,make不会再在当前目录下寻找有没有同名的目标文件,智慧之星Makefile中的代码

你可能感兴趣的:(tools,linux,c,gcc,gdb,指针)