C语言基础总结

函数
标准库函数
直接调用 #include<头文件>

自定义函数
返回值类型  函数名(形参列表){
	函数体
}
返回值类型:  
	返回值的类型
	一个函数可以没有返回值  声明为 void
	return语句可以返回多个数据,
	但函数调用接收时,只接收到一个  return 1,2;
	返回值类型可以为指针(指针即内存地址)
		但需要注意,不能返回局部变量的地址
函数名: 标识符
形参列表: 表明函数在需要的参数个数和类型
	多个参数用,隔开
	即使类型相同,类型关键字也不能省略
	参数传递过程:值传递(复制)
	实参和形参只是在函数调用时值相等  是不同的变量
void func();  表明在调用时可以传递任意多的参数
void func(void);  表明在调用时不可以传递参数
	
return: 
	return [x]; 结束一个函数调用  返回结果
	
结束一个程序:
	exit(status);
	如果是在main函数用 return 

main:是C语言程序的入口,一个C语言程序中有且只有一个main函数


有一种特殊的函数: 参数个数不固定
void func(const char *format, ...);

函数声明 和 定义:
函数声明:只是声明一个函数,没有函数体
函数定义: 一定是包含函数体(实现)

基本上 声明和定义是一起的

void func(int);//声明  形参名可省,只保留形参类型
void func(int a){//定义
	
}

隐式声明:
	在编译C语言代码中,如果遇到一个调用的函数
在此之前没有被声明过,那么编译器会隐式声明一个
同名的函数,并且返回值类型默认为int

C函数默认返回值类型为int,所以为int时可省

extern 可以声明外部定义的函数

数组
是同类型的多个变量
数组中的元素是同类型的
一维数组 二维数组 三维数组 语法支持n维数组
定义:
类型 数组名[数组长度];
int drr[5]={};//全部0
int err[5]={1,2,3,4,5,6};//警告
int frr[5]={[2]=3,[4]=1};
int grr[] = {1,2,3,4};//由值决定数组长度 一定需要初始化
int hrr[];//错误的
二维数组:
数组长度 = sizeof(数组名)/sizeof(数组元素)

数组作为参数传递:
int arr[10] = {};
func(arr,10);//需要传递数组长度
字符数组
char str[10] = "Hello";
reverse(str);//不需要传递字符串长度

二维数组: 有多少个一维数组 
int arr[10][5] = {};//有10个长度为5的一维数组 
func(arr,10); bar(arr,10);
void func(int arr[][5],int len);
void bar(int (*arr)[5],int len);

下标运算符[]
	arr[n]  ==  *(arr+n) == *(n+arr) == n[arr]
int *p;//一级指针   指针指向一个int类型的数据
int *arr[5];//指针数组  本质是数组 数组中的元素是指针
int crr[5];//数组 
crr ==  &crr[0]  == &(*(crr+0)) == &*crr
数组名: 数组首元素的地址
&crr  //整个数组的地址 

int arr[10];
arr == &arr[0]
&arr == 数组指针   int (*parr)[10];

int brr[10][5];
二维数组名 是一个 数组指针  这个指针指向一个一维数组
brr  ==  &brr[0]  ==  &*(brr+0)  == &*brr
brr[0]  ==  &brr[0][0] ==  &*(brr[0]+0)
brr[0] 相当于二维数组中第一个元素的地址  int*
brr =  &brr[0]  ==  int (*p)[5];

指针
指针即内存地址
内存地址从0开始编号
一个程序有4G的内存地址[0,0Xffff ffff]
保存内存地址只需要4个字节
sizeof(指针) == 4 (有的系统为8)

定义指针变量:
类型 *指针变量;
类型  是指指针所指向的那片内存区域中数据的类型
(类型 *)  指针的类型

指针的运算:
&  取址
*  取值
+  整数   +1相当于加一个单位长度的内存

char *p;p+1    1个字节
int *pi; pi+1; 4字节
double *pd;pd+1; 8字节
int (*pa)[5]; pa+1;20
double (*pb)[2][5];pa+1; 80
char (*pc0)[10][5]; pc0+1;  50
char *(*pc1)[10][5];pc1+1;  200=10*5*4  
char **pc2[10][5];  pc2+1;  20=5*4
char *pc3[10][5];   pc3+1;  20  
int arr[5];         arr+1;  4

void 作为返回值类型  作为形能列表
空指针NULL
万能指针 void *
	任意类型的指针都可以隐式转换为void*任何
	该指针丢失了类型限定
	万能指针不能取*运算 
	虽然不能进行取*运算,但非常有用

字符串
一串字符并能’\0’为结束标识称为字符串
字符串的长度,通过字符串首地址能求得
字符串有结束符’\0’
形式:
1.字面值字符串
“Hello”
特点: (1)不改修改
(2)存储代码区
(3)字面值相同的字符串在内存中共享一份
(4)连续的字面值字符串自动合并
“Hello”“World”
2.字符数组
char str[5] = {‘H’,‘e’,‘l’,‘l’,‘o’};
如果只是单纯作为字符数组没问题
但是如果作为字符串,有问题
char s[] = “Hello”;//s在栈区
需要有足够的内存保存’\0’
特点:(1)存储在栈区
(2) 可以修改
3.字符指针
对于字符串而言,只需要记录字符串开始地址
char *p = “Hello”;// *p取到是’H’
//*p = ‘e’ 不可以
char s[] = “Hello”;
char *ps = s;// *ps ‘H’
*ps = ‘E’;//可以的
数组指针
本质是指针,指针指向一个数组
int (*arr)[5];
指针数组
本质是数组,数组中的元素是指针
int *arr[5];
函数指针: 在C语言中的应用很广泛
本质是指针,指针指向一个函数
int (*func)();
func是一个函数指针,本质是指针
指针函数
本质是函数,函数返回值类型是指针
int *func();

其它的字符串函数:
scanf() 以空白字符为分隔 读到的字符串不能有空白字符
char *gets(char *s);//C语言不建议使用 c11删除
一直读到’\n’为止 不会对容量进行检查 非常危险
char *fgets(char *s,size_t n,FILE *stream);
从stream中读取n个字符到s中,能够确保有’\0’
最多能读到n-1个字符 ,如果不到n-1字符,会连’\n’也一并读取
需要手动处理’\n’

FILE *stream:    stdin
stdin: 标准输入
stdout: 标准输出 
stderr: 标准错误输出 

int puts(const char *s);//输出字符串到控制台
int fputs(const char *s,FILE *stream);//输出字符串到stream

getc/fgetc
putc/fputc

标准输入输出函数:
参数不定 >=1
printf
int printf(const char *format,…);
把内容输出到输出缓冲区
数据什么时候会输出到终端控制台呢?
1.遇到\n
2.强制刷新输出缓冲区 fflush(stdout)
3.当输出缓冲区满了 4kB

int scanf(const char *format,...);
从输入缓存区中格式读取内容,如果输入缓存区中没有内容
则等待用户输入
如果输入缓存区中有内容,不会让用户输入

用户输入内容时,遇到Enter,
会把用户输入的内容全部写入到输入缓存区中
	输入缓存区:3.14\n
	%d  3     .14\n
	%lf       0.14    \n
	%c        \n   不会跳过空白字符 
//清空输入缓存区
scanf("%*[^\n]");//读取缓存区中的内容(不是\n)舍弃
scanf("%*c");//读取任意一个字符舍弃

	

格式占位符
"%-m.nf"
	m内容所占宽度
	n小数所占宽度
	+ 右对齐  -左对齐

不定长参数列表:
void func(int x, …);
在…之前一定要有一个有名参数 但不限类型
第一个参数,是为了知道在调用该函数时,后面传递了多少个实参
printf() scanf() format中有格式占位符

#include <stdarg.h>
void va_start(va_list ap,last);
type va_arg(va_list ap,type);
void va_end(va_list ap);

取出 ... 的数据:
1.定义一个 va_list 变量   
	va_list ap;
2.初始化ap变量
	va_start(ap,last);   //last是有名参数的最后一个参数的名字
	
3.每调用一次能从不定长列表中取出一个数据
	如果每一个数据的类型不一样,还得考虑当前是什么类型
		例如printf scanf通过格式占位符来获取类型信息
	type  va_arg(ap,type);
	type 是类型 
4.释放资源 
	va_end(ap);

const char *s;
const 表示只读
不可以修改(并不是一定不能修改)

const char * p1; //const修饰*p1 p1只读
char const * p2; //const修饰
p2 *p2只读
char * const p3; //const修饰 p3 p3只读
const char * const p4; // *p4 和 p4都是只读

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值