C语言学习笔记

1.单位

bit--8--byte--1024--kb--1024--mb--1024--tb--1024--pb      (bit为比特位,byte为字节)

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

2.进制转化

以十进制12为例

十进制

                     1                2

                     1 * 10^1 + 2 * 10^0 = 12

二进制

                     1             1              0             0

                     1 * 2^3 + 1 * 2^20* 2^1 + 0 * 2^0 = 12

总结:二进制位中从第一位开始对应要乘的数依次成等比数列{1,2,4,8...2^n},故计算时将1或0乘上对应数列中的数即可(例如:1101=8+4+0+1=13)

注:在编写代码时,以数据123的表示方法为例

十进制:123        八进制:0123        十六进制:0x123或0X123

附科学表示法: 12*10^2 = 12e2 或 12E2

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

3.数据类型                             

char                   字符数据类型                1 byte               %c

short                  短整型                           2 byte 

int                       整形                              4 byte               %d

long                   长整型                           4/8 byte            %ld

long long           更长的整形                   8 byte

float                   单精度浮点数                4 byte               %f

double               双精度浮点数                8 byte               %lf

*                          指针                              4/8 byte            %p

注:int最大表示约9位数,long long最大表示约18位数

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

4.输入输出

输入

scanf

//例
scanf("%d%d",&x,&y):

注:

①需要声明输入格式,存入的对象前面需要加&

②只会读取声明的格式,两个输入值间以空格(若读取格式为字符串,则将其空格转化为\0)作为间隔符,以换行或EOF作为输入结束标志,读取后缓冲区会剩一个\n

③若读取时遇到双引号中未声明的形式,则读取终止,如下

//若x=1,y=2
scanf("%d%d",&x,&y);        //正确输入为1 2,输入1a2或1 a 2或1,2或1 , 2都只会读取到1就结束
scanf("%d %d",&x,&y);       //正确输入为1 2
scanf("%da%d",&x,&y);       //正确输入为1a2,输入1 a 2或其他都只会读取到1
scanf("%d a %d",&x,&y);     //正确输入为1 a 2
scanf("%d , %d",&x,&y);     //正确输入为1 , 2

gets

//例
gets(str);

注:

①读取缓冲区所有字符

②严格遵循字符串形式,以换行或EOF作为输入结束标志,同时将/n转化为/0

③不安全,会溢出

fgets

//例
char a[10] = {0};
fgets(a, 5, stdin);

注:

①从某个源读取特定长度字符串。第一个参数是存入对象,第二个参数是读取长度,第三个参数是读取源,stdin为标准输入设备即键盘

②安全,不会溢出

getchar()

//例
str[0]=getchar();
getchar();

注:

①从缓冲区读取一个字符,可以只读取数据而不储存起来

②一般与循环搭配使用,在循环以EOF作为结束标志

区别:scanf不能读空格和\n,回车结束;gets能读空格和\n,但\n转化成\0,回车结束;getchar()能读空格和\n

输出

printf

输出格式控制

printf("%011d",x);    //输出11位整数x,不足位数用0补全(超过部分原样输出)

printf("%-11d",x);    //左对齐,在输出结果右边用空格补齐

printf("%11d",x);     //右对齐,在输出结果左边用空格补齐

printf("%.3f",x);     //输出x保留3位小数:

puts

//例
puts(arr);

注:

①输出字符串

②输出结果自带\n(可以理解为\0转化为\n)

putchar()

//例
putchar('A');               //以下输出结果均为A  
putchar(65);
char ch='A';putchar(ch);

注:

①只输出一个字符

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

4.特定符

关键字

1.数据类型关键字(12个)

  • (1)char: 声明字符型变量或函数(1字节)
  • (2)short: 声明短整型变量和函数(2字节)
  • (3)int: 声明整型变量或函数(2/4字节)
  • (4)long: 声明长整型变量或函数(4/8字节)
  • (5)float: 声明浮点型变量或函数(4字节)
  • (6)double: 声明双精度变量或函数(8字节)
  • (7)signed: 声明有符号类型变量或函数
  • (8)unsigned: 声明无符号类型变量或函数
  • (9)void: 声明函数无返回值或无参数,声明无类型指针
  • (10)enum: 声明枚举类型
  • (11)struct: 声明结构体变量
  • (12)union: 声明共用体(联合)数据类型

2.控制语句关键字(12个)

  循环语句

  • (1)for: 一种循环语句
  • (2)do: 循环语句的循环体
  • (3)while : 循环语句的循环条件
  • (4)break: 跳出当前循环
  • (5)continue: 结束当前循环,开始下一轮循环

  条件语句

  • (6)if: 条件语句
  • (7)else: 条件语句否定分支(与 if 连用)
  • (8)goto: 无条件跳转语句

  开关语句

  • (9)switch : 用于开关语句
  • (10)case: 开关语句分支
  • (11)default:开关语句中的“其他”分支

  返回语句

  • (12)return:子程序返回语句(可以带参数,也可不带参数)

3. 存储类型关键字(4个)

  • (1)auto: 声明自动变量
  • (2)extern: 声明全局变量
  • (3)register: 声明寄存器变量
  • (3)static:声明全局变量

4. 其他功能关键字 (4个)

  • (1)const: 声明只读变量
  • (2)sizeof: 计算存储空间
  • (3)typedef: 给数据类型取别名
  • (4)volatile: 说明变量在程序执行中可被隐含地改变

5. C99新增(5个)

  • (1)inline:内联函数,是为了解决C 预处理器宏存在的问题所提出一种解决方案,用来提高函数使用效率。内联函数使用inline关键字定义,并且函数体和申明必须结合在一起, 否则编译器将他作为普通函数对待。
  • (2)restric: 关键字只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。
  • (3)bool:布尔类型,用来表示真或假,零表示假,非零表示真。所有非零的数赋值给布尔型变量,最终的值还是1,包含标准头文件 stdbool.h 后,我们可以用 bool 代替 _Bool ,true 代替 1 ,false 代替 0
  • (4)_complex:表示复数,复数类型包括一个实部和一个虚部: 说明变量在程序执行中可被隐含地改变
  • (5)_Imaginary:表示虚数,虚数类型没有实部,只有虚部

分隔符

/  #  ()  []  {}  '  "  ;  :  ,  

运算符(缺)

5.标识符和间隔符

标识符:变量,类型,函数等的名字

规则;①以字母开头②内容仅包括字母和数字③下划线看作字母

(例:"_abc_123"正确,"0abc 123&"错误)

间隔符:用于分离两个相邻的语法单位。包括空格,空白,行结束符,水平制表符,垂直制表符,换页符等

规定:由字面常量组成的两个相邻的语法单位之间至少存在一个间隔符

(例:"#define pi 3.14"正确,"int x,y;"正确,"< ="错误)

6.转义字符

\?              在书写连续多个问号时使用,防止他们被解析成三字母词

\'               用于表示字符常量'

\“              用于表示一个字符串内部的双引号

\\               用于表示一个反斜杠,防止它被解释为一个转义序列符

\a              警告字符,蜂鸣

\b              退格符

\f               进纸符

\n              换行

\r               回车

\t               水平制表符

\v              垂直制表符

\ddd         ddd表示1~3个八进制的数字。 如: \32 表示ASCII值26对应的字符(八进制32的                     十进制值为26)

\xdd         dd表示2个十六进制数字。 如: \x61 表示ASCII值97对应的字符(十六进制61的十                   进制值为97)

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

7.常量

const 修饰的常变量
#define 定义的标识符常量
枚举常量

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

8.*字符串

定义:由双引号引起来的一串字符。
注:字符串的结束标志是一个\0 的转义字符。在计算字符串长度的时候\0 是结束标志,不算作字符串内容。

以打印字符串test为例:

char arr1[] = "test";
char arr2[] = {'t','e','s','t'};
char arr3[] = {'t','e','s','t''\0'};

*其sizeof和strlen

//sizeof用来计算占有几个字节,包括\0
//strlen用来计算字符串长度,需引头文件,包括\0
    
char arr1[9] = "abc";                //sizeof为9,strlen为3
char arr2[] = "abc";                 //sizeof为4,strlen为3
char arr3[] = {'a','b','c','\0'};    //sizeof为4,strlen为3
char arr4[] = {'a','b','c'};         //sizeof为3,strlen为35(随机值)

//arr1虽然指定大小大于字符串大小,但计算机以9字节的空间存储字符串abc,并不附加内容以补全大小
//arr2和arr3是相同数据的两种不同表达形式,双引号自带\0,大括号不带\0
//arr4由于没有\0,所以字符串长度为随机值
//说明:1个char类型占1个字节

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

*数组

一维数组

以数组{1,2,3}为例:

int arr[3] = {1,2,3};    //该数组内元素对应下标依次为0,1,2 (范围0~+∞)

注:①中括号内数值为数组大小,若填入则指定数组大小,否则自适应

     ②若指定大小大于实际大小,则默认用0补全(二维数组同样也是),该形式为不完全初始化

printf("%d",arr[0]);    //输出结果为1,即第一个元素

二维数组

以矩阵  [1 2 3]为例

             [4 5 6]

int arr[2][3]={{1,2,3},{4,5,6}};    //二维数组的两个中括号分别表示行和列
int arr[ ][3]={{1,2,3},{4,5,6}};    //行的初始化可以省略,但列的不行
printf("%c",arr[0][1]);    //输出结果为2,即第一行第二列的元素

注:①一二维数组在内存中的储存都是连续的,且相邻地址间差十六进制的4

     ②数组名可以看作是指针变量,存放的是首元素的地址,例:arr和&arr[0]的打印结果相同且           都是首元素的地址

     ③&arr打印的结果虽然与前两者相同,但后者打印的是整个数组的地址

     ④arr+1和&arr[0]+1的结果是下一位元素的地址,&arr+1的结果是该数组外的下一个地址

     ⑤一维数组本质是列指针,二维数组本质是行指针

*其sizeof和strlen

int arr1[  ] = {1,2};    //sizeof为2*4=8,strlen为1
int arr2[20] = {1,2};    //sizeof为20*4=80,strlrn为1
                         //说明:1个int类型占4个字节,任何数组字符串长度都为1

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

操作符

单目操作符:

!                         逻辑反操作
-                         负值
+                        正值
&                        取地址
sizeof                操作数的类型长度(以字节为单位)
~                        对一个数的二进制按位取反
--                        前置、后置--
++                      前置、后置++
*                         间接访问操作符(解引用操作符)
(类型)                 强制类型转换

关系操作符:

>
>=
<
<=
!= 或 -                  “不等”
==                        “相等”

逻辑操作符:

&&                        逻辑与
||                           逻辑或

条件操作符:

exp1 ? exp2 : exp3

如果表达式1为真,那么就运行表达式2,否则为表达式3

例如:

if (a == 1)
	b = 666 ;
else 
	b = 233 ; 

可以写成

b = ( a == 1 ? 666 : 233 ) ;

逗号表达式

exp1, exp2, exp3, …expN

  1. 逗号表达式从表达式1开始顺序从左向右执行;
  2. 其逗号表达式最后的值为最后一个表达式的值;
  3. 逗号运算的优先级最低,也就说明与其他运算符结合使用的时候,在没有括号的情况下逗号运算符最后才执行。
//用法举例//
//声明变量
    int a = 0,b = 0,x = 0,y= 0 ;
//作为表达式
    a = (x = 1,y = 2,x + y);//输出结果为3
//for循环
    for(a = 0,b = 10;(a < 5)&&(b > 5);a++,b++) 
    {
         printf("%d %d\n",a,b);
    }

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

*函数

①库函数

//strcpy
//字符串拷贝,直接将源字符串覆盖到目标字符串上
//由于字符串结束符\0也会被拷贝
//所以输出的结果只会包括被覆盖的内容,多余的部分因为\0而被忽略
//反过来,若源字符串过长则会溢出
//语法
strcpy(str2,str1);    //将str1的内容拷贝至str2中

②自定义函数(分有返回值和无返回值两种形式)

实际参数(实参):真实传给函数的参数,叫实际参数。

形式参数(形参):形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用                                  的过程中才实例化(分配内存单元),所以叫形式参数。

//以加法为例:
//传值调用(有返回值需求)
int Add(int x, int y)
{
        int z = x+y;
        return z;
}
int main()
{
        int num1 = 0;
        int num2 = 0;
        int sum = 0;
        scanf("%d %d", &num1, &num2);
        sum = Add(num1, num2);    //sum= 这一步体现了这种写法需要返回值
        printf("sum = %d\n", sum);
        return 0;
}
//以两值互换函数为例
//传址调用(有改变外部变量需求)
void swap(int* x, int* y)
{
	int z = 0;
	z = *x;
	*x = *y;
	*y = z;
}
int main()
{
	int a = 123, b = 456;
	swap(&a, &b);    //没有等号,不需要返回值,此函数起到操作作用
	return 0;
}
//以下是复合用法函数+指针
//head.h
    void search(int x[], int y,int* z);    //在头文件中声明后
                                           //主函数中函数的定义就可以放在任意位置
//main.c
#include "head.h"
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int t=9;
	int sz= sizeof(arr) / sizeof(arr[0]);
	search(arr, sz,&t);
	if (t != -1)
		printf("FOUND\nIt's NO.%d\n", t);
	else
		printf("NOT FOUND\n");
	return 0;
}
void search(int x[], int y,int* z)
{
	int left = 0;
	int right = y;
	while (left<right-1)
	{
		int mid = (left + right) / 2;
		if (x[mid] > *z)
			right = mid;
		else if (x[mid] < *z)
			left = mid;
		else
		{
			*z = mid;
			return 0;
		}		
	}
	*z=-1;
}

typedef

含义:类型定义,或类型重命名

typedef unsigned int zhengxing;

int main()
{
unsigned int num1 = 0;    //unsigned 声明被修饰数据类型为无符号数据类型
zhengxing num2 = 0;
//num1和num2的类型是一样的
    return 0;
}

static

1. 修饰局部变量-称为静态局部变量:可以将局部变量的作用域扩大至整个程序
2. 修饰全局变量-称为静态全局变量:可以将全局变量的作用域缩小至其所在源文件
3. 修饰函数-称为静态函数:可以将函数的作用域缩小至其所在源文件

#define

#define又称宏定义,标识符为所定义的宏名,简称宏。#define 的功能是将标识符定义为其后的常量。一经定义,程序中就可以直接用标识符来表示这个常量,且不能被赋值

定义标识符常量:

#define _CRT_SECURE_NO_WARNINGS    //scanf不报错

定义宏:

#define ADD(x,y) ((x)+(y)) ;   
#define ADD(x+y) ;
//以上ADD在程序中代表表达式x+y    

*指针

//取出并打印变量地址
int main()
{
    int num = 10;
    &num;    //这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
    printf("%p\n", &num);
    return 0;
}
//利用指针变量储存变量地址
int main()
{
    int num = 10;
    int* p;
    p = &num;    //指针变量只能被赋值变量的地址
    return 0;
}
//另一种直接写法
int main()
{
    int num = 10;
    int* p= &num;
    return 0;
}
//利用指针变量修改变量的值
int main()
{
	int a = 10;
	int* pa = &a;
	*pa = 20;    //*为解引用操作符,使得我们能通过指针变量间接对变量的值进行修改
                 //在解引用前,pa只是a的内存地址
	return 0;
}

注:指针变量的大小只取决于地址的大小

     32位平台下地址是32个bit位(即4个字节)
     64位平台下地址是64个bit位(即8个字节)

*结构体

//结构体单独定义
struct student
{
char name[20];    //名字
int age;          //年龄
char sex[5];      //性别
char id[15];     //学号
};
//结构体单独声明
struct student xiaoming={"xiongming",18,"male","12345"};

//结构体同时声明和定义
struct student
{
char name[20];    //名字
int age;          //年龄
char sex[5];      //性别
char id[15];     //学号
}xiaoming={"xiongming",18,"male","12345"};
//以复数加减乘法运算为例
#include<stdio.h>
//结构体定义
struct complex
{
	float real;
	float imag;
};
//结构体类函数声明
struct complex add(struct complex c1, struct complex c2);
struct complex subtract(struct complex c1, struct complex c2);
struct complex multiply(struct complex c1, struct complex c2);
void complexprint(struct complex c);
//主函数
int main()
{
	float r1, i1, r2, i2;
	scanf("%f%f%f%f", &r1, &i1, &r2, &i2);
	struct complex c1 = { r1,i1 }, c2 = { r2,i2 };
	complexprint(add(c1, c2));
	complexprint(subtract(c1, c2));
	complexprint(multiply(c1, c2));
}
//打印功能函数
void complexprint(struct complex c)
{
	if (c.imag > 0) printf("%.2f+%.2fi", c.real, c.imag);
	else if (c.imag < 0) printf("%.2f%.2fi", c.real, c.imag);
	else printf("%.2f", c.real);
}
//加法功能函数
struct complex add(struct complex c1, struct complex c2)
{
	struct complex result;
	result.real = c1.real + c2.real;
	result.imag = c1.imag + c2.imag;
	return result;
}
//减法功能函数
struct complex subtract(struct complex c1, struct complex c2)
{
	struct complex result;
	result.real = c1.real - c2.real;
	result.imag = c1.imag - c2.imag;
	return result;
}
//乘法功能函数
struct complex multiply(struct complex c1, struct complex c2)
{
	struct complex result;
	result.real = c1.real * c2.real- c1.imag * c2.imag;
	result.imag = c1.real * c2.imag + c2.real * c1.imag;
	return result;
}

分支语句

if语句:

//第一种
if(表达式)
{
    语句;
}
//第二种
if(表达式)
{
    语句;
}
else
{
    语句;
}
//第三种
if(表达式)
{
    语句;
}
else if(表达式)
{
    语句;
}
else
{
    语句;
}

switch语句

//例子
int main()
{
    int day = 0;
    switch(day)
    {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        printf("weekday\n");
        break;
    case 6:
    case 7:
        printf("weekend\n");
        break;
    default:    //当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行
        break;
    }
    return 0;
}

循环语句

break:终止本次循环

coutine:跳过本次循环

while(表达式)
    {
    循环语句;
    }

for(表达式1; 表达式2; 表达式3)
    {
    循环语句;
    }
//表达式1进行变量初始化,表达式2进行条件判断,表达式3进行变量调整
//循环语句在表达式2判断为真之后才会执行

*递归

//通过递推实现strlen函数
int newstrlen(char* str)
{
	if (*str != '\0')
		return 1 + newstrlen(str + 1);
	else
		return 0;
}
int main()
{
	char str[] = "string";
	printf("%d\n",newstrlen(str));
	return 0;
}

迭代

 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

算法

//栈判断括号匹配问题
#include <stdio.h>
#include <stdlib.h>
char ch, stack[1000];
int left=0;
void push(void); char pop(void); void check(char left, char right);
int main()
{
	do
	{
		ch = getchar();
		switch (ch)
		{
		case '(':
		case '[':
		case '{':push(); break;
		case ')':check(pop(), '('); break;
		case ']':check(pop(), '['); break;
		case '}':check(pop(), '{'); break;
		}
	} while (ch!='@');
	printf("YES");
	return 0;
}

void push(void)
{
	stack[left++] = ch;
}

char pop(void)
{
	if (left > 0)
		return stack[--left];
	else
	{
		printf("NO");
		exit(0);
	}
}

void check(char left, char right)
{
	if (left != right)
	{
		printf("NO");
		exit(0);
	}
}

*常用ASCII码表

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值