C语言基础知识

一、在计算机中数据的表现形式

  1. 二进制:逢二进一

  1. 八进制:逢八进一

  1. 十进制:逢十进一

  1. 十六进制:逢十六进一

一般计算机都是二进制语言

二、数制之间的转换

    • 二进制转八进制:

三位二进制为一位八进制数

    • 十进制转二进制

运用短除法取余来转换

    • 二进制转十六进制

四位二进制数为一位十六进制数

三、C语言的编程规范

所有的c程序都是从主函数开始到主函数结束

在c语言中{ }表示一个模块,模块之间要注意缩进

;(分号)代表一条语句的结束

return:遇到return关键字代表程序结束

四、C语言中的词法符号

    • 标识符

标识符是程序员按照命名规则自定义的词法符号

标识符的命名规则
  1. 由数字、字母、下划线组成

  1. 不能以数字开头

  1. 不能与关键字重名

C语言的32个关键字
存储类型:

auto,register,static,const,volatile,extern

数据类型

char,short,int,float,long,double,signed,unsigned

结构体类型

struct,union,enum

语句类型:

if,else,switch,case,break,default,while,do,for,continue,goto,return

空类型:

void

重命名:

typedef

求字节:

sizeof

在C语言当中要严格区分大小写

    • 运算符

赋值预算符

+=,-=,/=,*=

算术运算符

+,-,*,/,

++,--

前++:先取值再自增

后++:先自增再取值

位运算符

~:位非,按位取反

&(与):位与,按位比较

|(或):位或

^(异或):相同为0,不同为1

<<(右移):

表达式1)<<(表达式2)

正数:高位舍去,低位补0

负数:高位舍去,低位补0,最后最高位置1

>>(左移):

(表达式1)>>(表达式2)

正数:低位舍去,高位补0

负数:低位舍去,高位补1(用补码运算)

关系运算符

>,<,==,<=,>=,!=(不等)

逻辑运算符

&&: 逻辑与,全1为1,有0则0

| | :逻辑或,全0为0,有1则1

!:逻辑非

短路法则:

逻辑与:如果前一个表达式为假,则不运行下一个表达式,运行结果为0

逻辑或::如果前一个表达式为真,则不进行下一个表达式,运行结果为1

逗号运算符

以逗号最右边的作为运算结果

三目运算符

(表达式1)?(表达式2):(表达式3)

符号含义:如果表达式1为真则表达式2为运算结果,如果为假,则表达式3为运算结果

求字节

sizeof:求数据类型或变量的字节

原码,补码,反码

对于一个有符号的机器码来说,第一位为数字的符号位,1为负,0为正

原码:机器码

反码:

正数:原码

负数:符号位不变,其他位按位取反

补码:

正数:原码

负数:反码加一

注意:计算机中存储的数据都是存的数据的补码

运算符的优先级:

五、C语言中数据的表现形式

    • 常量

程序运行中不能被修改的数据

整形常量
实型常量:

十进制小数形式

指数形式:

3.14e1

规范化指数形式:小数点前一位为0,小数点后第一位不为0

字符型常量:

''括起来的单个字符,'a'

转义字符:

\n换行 \t--tab

字符串常量:

" "括起来的字符串

符号常量:

#define N 100//放在程序的开头 宏定义

    • 变量

程序运行过程中能被改变的数据--保存数据

定义变量的一般形式:

<存储类型><数据类型>变量名:

存储类型:
auto:自动存储类型

在定义局部变量时,用auto显示声明代表该变量在栈区(先入后出的一种存储方式)随机分配一片存储空间。如果在定义变量是缺省存储类型,改变变量默认为auto类型

register:寄存器类型

声明的变量在程序运行时直接加载到寄存器上,但是计算机上寄存器有限,可能加载失败,失败后自动转为auto类型

extern:引用类型

该变量不能初始化,代表该变量在别处定义,要在此处使用

1.在一个文件中扩张全局变量的作用范围。

2.在一个源程序中扩展一个全局变量的范围

static:静态类型

1.修饰全局变量,限制全局变量只能在本文中使用

2.修饰局部变量,将局部变量的生命周期延长到整个程序结束,并且该变量只会被定义一次

const:修饰只读

const 修饰的变量,只能读不能写(不能被改变)变量常量化

该变量不能作为等号左值

数据类型:
整型:

char 字符型 一个字节

unsigned:0-255

signed:-128~127

char C;//不说明默认为有符号数

short:短整型 两个字节

int:整型 四个字节

long:长整型 八个字节

浮点型:

flaot :单精度浮点型 四个字节

精确度:小数点后6-7位

double:双精度浮点型 八个字节

精确度:小数点后15-16位

变量名:标识符

命名规则:

1.由字母、数字、下划线组成

2. 不能以数字开头

3. 不能与关键字重名

变量的初始化

在定义的时候赋值

例:int a=10;

int a,b,c,d=10

变量的赋值

例:int a,b,c,d;

char c;

a=10;

c= 'a';

全局变量,局部变量
全局变量:

定义位置:定义在所有模块({})之外的变量

生命周期:从定义开始,到程序结束

使用范围:整个源文件

没有初始化:默认为0

局部变量:

定义位置:定义在所有模块({})之内的变量

生命周期:从定义开始,到模块结束

作用范围:在定义它的模块中

没有初始化:默认为随机值

六、C语言的输入输出

    • 格式控制字符串

格式控制符+其他字符

%d--按十进制有符号整数格式输出

%u--按十进制无符号整数格式输出

%md--指定占m域宽,默认右对齐

%-md--默认左对齐

%ld--按十进制有符号长整型格式输出

%o--按八进制无符号整数格式输出

%#o--带前缀

%x--按十六进制无符号整数格式输出

%p--输出一个地址

%f--输出单精度浮点型数据--隐含六位小数

%.nf-输出单精度浮点型数据--指定保留n位有效数据

%lf--输出双精度浮点型数据

%c--输出单个字符

%s--输出一个字符串

%.ns--输出字符串的前n个字符

%%--输出一个%

    • scanf--标准输入函数

scanf(“格式控制字符串”,地址列表)

int a=10;

scanf("%d",&a);

格式控制字符串:

格式控制符+其他字符

其他字符:按照原样输入

地址列表:&变量

注意1:在输入数值型数据时,空格、回车、tab都属于无效字符相当于输入结束

注意2:在输入字符型数据时,空格、回车、tab都算是有效字符--脏字符

消除脏字符:%*c

getchar()

返回值:为按照格式正确输入的个数

    • printf--标准输出函数

printf(“格式控制字符串”,输出列表)

输出列表:从左到右与控制符一一对应,用逗号隔开

4.getchar--字符输入函数

char ch=0;

ch=getchar();

可以用来消除脏字符

5.putchar--字符输出函数

char ch ='x'

putchar(ch);

putchar('x');

    • gets--字符串输入函数

char a[20];

gets(a);

7.puts--字符串输出函数

char strp[20]="hello world";

puts(strp);

注意:打印完字符串之后会自动换行

七、数据类型转换

    • 自动类型转换

1.当用一种数据类型的数据,给另一种数据类型的变量赋值时会发生自动类型转换

int a=3.14;//最后输出a=3

2.C语言当中两个整数的数据相除,结果还是一个整数。

3.当多种数据类型的数据发生混合运算时

转换规则:数据会向精确度增加的方向转换

float f=5/2+3.14; //最后f=5.14

float f2=5.0/2+3.14//最后f2=5.64

2.强制类型转换

(数据类型)数据://将数据转换成()里指定的数据类型

int a=5;

int b=2;

float f= (float)a/b;

八、C语言的语句结构

    • 顺序结构

C语言按照顺序执行

    • 选择结构

1)if语句

if(表达式)

{

语句块1;

}

else

{

语句块2;

}

注意1:如果if或者else后面只有一条语句,{}可以省略

2)switch语句

switch(表达式)

{

case 表达式1:

语句块1;

break;

case 表达式2:

语句块2;

break;

……

case 表达式n;

break;

default:

语句块n+1

}

表达式:整型表达式

表达式1-n:整型的常量表达式

step:表达式1-n哪一个与表达式相等,如果相等则执行表达式n后面的语句块,如果遇到break则停止,没有遇到break关键字则顺序执行后面的语句

    • 循环结构

1)while循环--当型循环

while(表达式)

{

语句块;

}

step:判断表达式,如果表达式为真,则执行语句块,然后继续判断表达,如果表达式为真则继续执行语句块,否则结束循环。

2)do {}while()循环--直到型循环

do

{

语句块;

}while(表达式);

step:执行语句块,然后判断表达式,如果表达式为真则继续执行语句块,否则结束循环。

break:

1.在switch语句中遇到break关键字,结束switch语句。

2.结束当前循环

continue:跳过本此循环,执行下一次循环。

3)for循环

for(表达式1;表达式2;表达式3)//三个表达式用分号隔开

{

语句块;

}

表达式1:一般是循环变量的初始化,只会在第一次进入循环时执行一次

表达式2:循环结束的条件

表达式3:一般是循环变量的自增或自减

4)goto--无条件跳转语句

goto 标签;

标签:标识符

step:当程序执行过程中,遇到goto关键字,自动跳转到标签处,继续执行下面的操作

goto后面的标志不能放在定义语句的前面

九、数组

同种数据类型数据的有序集合

    • 数据定义的一般形式

<存储类型><数据类型>数组名[元素个数];

数组名:

1.标识符。

2.是整片数组空间的起始地址,代表了整片数组空间

注意:数组名是一个地址常量

long len =sizeof(a);

元素的个数:整型的常量

[ ]:

1.在定义变量[]代表定义是一个数组

2.对于地址来说,偏移并引用

取数组元素:a[下标]--下标从0开始

int a[5];//a[0]--a[4]

数组的清零:memset(数组名,想要清零的样式,想要清零的空间)

2.数组的初始化

1)完全初始化

有多少个元素,就赋多少个初值

int a[5]={11,22,33,44,55}

2)部分初始化

前面依次赋 值,后面没有赋值的自动补0

int a[6]={11,2,3}//给前三个元素初始化,没有初始化的元素默认为0

3)省略初始化

省略的是下标,计算机根据数组后面初始化赋值的个数来开辟对应的空间地址

int a[]={3,3,4,42,4}

3.数组元素的赋值

int a[10]=|{1,2,3};

int b[10];

b=a;//error

-------

int a[5];

a[5]={2,3,4,4,5};//error

-----------

注意:在数组定义之后,只能逐个给每个数组元素赋值

int a[3]={0};

a[0]=11;

a[1]=1;

a[2]=6;

十、字符数组

1.字符数组的初始化

1)完全初始化

char str[5] ={'h','e','l','l','o','\0'};在用%s打印的时候要用\0或者0来结束

printf ("%s\n",str);

字符串常量:" "括起来的一串字符,所有的""括起来的字符串后都有一个隐藏的'\0'

注意:在c语言当中可以用字符串常量来给字符数组初始化

char str[6]="hello";//要开辟足够的空间来保存'\0'

2)部分初始化

char str[10]={'h','e'};

="he";//未定义的默认为'\0'

3)省略初始化

char str[]="hello";

2.字符串操作函数

1)strcpy
头文件:

#include <string.h>

函数的原型:

char *strcpy(char *dest,const char *src);

描述:

将src所指向的字符串,复制到dest所指的数组。

参数:

dest:接收被复制字符的数组

src:字符串的首地址

char str[10];

strcpy(str,"hello");

返回值:

返回dest

2)strlen
头文件:

#include<string.h>

函数的原型:

size_t strlen(const char *s);

描述:

计算s所指向字符串的有效长度。不包括'/0'

参数:

s指向的字符串的首地址

返回值:

s所指向字符串的有效字节数

注意:strlen计算字符串有效长度,只要遇到'\0'就停止计算

3)strcmp
头文件:

#include<string.h>

函数的原型:

int strcmp(const char *s1, const char *s2);

描述:

判断两个字符串是否相同

比较规则:对位比较

参数:

s1:字符串

s2:字符串

返回值:

如果s1>s2,但会大于0的整数

s1<s2,返回小于零的整数

s1==s2,返回值为0

4)strcat
头文件:

#include<string.h>

函数的原型

char *strcat(char *dest, const char *src);

描述:

将src所指向的字符串拼接到dest所指向的数组后面

参数:

src--字符串的首地址

dest--字符数组名

返回值:

dest

5)strstr
头文件:

#include<string.h>

函数的原型

char *strstr(const char *haystack, const char *needle);

描述:

在haystack中所指向的字符串中,找needle所指向的字符串第一次出现的位置

参数:

haystack--字符串

needle--字符串

返回值:

如果找到则返回第一次出现位置(地址)

十一、二维数组

1.二维数组的定义

<存储类型><数据类型> 二维数组名[行号][列号];

int a[1][2];

二维数组名:是整个二维数组的首行地址,代表了整片数组空间

行号,列号:整型的常量

[]:对地址来说,偏移并引用

注意二维数组名还是一个地址常量

去二维数组的元素:a[行号][列号]--行号,列号都从零开始

2.二维数组的初始化

1)完全初始化

int a[2][3]={1,2,3,4,5,6}

={1,2,3,},{4,5,6}

2)部分初始化

int a[2][3]={1,2,3};//给第一行的三个元素赋值,其余的剩下默认为0

int a[2][3]={{1},{2}};

3)省略初始化

注意:行号可以省略,但是列号不能省略。

int a[][3]={1,2,3,4,5,6};

十二、指针

指针就是地址,地址就是指针

地址--内存单元的编号(一般用十六进制的帧数表示)

指针、地址、指针变量。

指针变量用来保存地址(指针)

1.指针变量的定义

<存储类型><数据类型> *指针变量名;

<数据类型>+* --构成了一个新的数据类型--指针类型

存储类型是指针的存储类型

在64位操作系统中,所有的指针变量都占8个字节

*和&互为逆运算

int a=10;

int *p=&a;

char ch ='a';

char *q=&ch;

存储类型是指针的存储类型,数据类型是指针指向对象的数据类型,指针的大小和数据类型没有关系,32位是4,64的大小8

2.指针的运算符

&:取地址符--取变量的地址。

[]:

1.在定义变量时代表的是一个数组

2.偏移并引用。

*:1.定义变量时代表定义的是一个指针变量

2.取(引用)地址下的内容

int a =10;

int *p=&a;

p[0]=123;

printf("%d\n",a);//通过指针间接访问a所占的内存空间

*p=666;//通过指针间接访问a所占的内存空间

printf("%d\n",a);

3.指针变量的初始化

int a=0x11223344;

int *p=&a;

char ch = 'x';

char *q =&ch;

int a[5] ={1,2,3,4,5,};

int *p=a;

注意:在给指针变量初始化时,一定要类型匹配

小端存储:数据的低位,存储到地址低位

4.指针的赋值

1、把已知变量的地址赋给指针

int a=4; 12 int *p=&a;

2、把已知数组的首地址赋给指针

int a【5】={1,2,3,4,5};

int *p=a;====int *p=&a[0];

*和【】可以互换

指针变量名和数组名可以互换,注意,数组名是一个常量,指针是一个变量

3、指针赋值给指针

同级指针

4、把NULL赋值指针

相当于指针的初始化为0x00000000

5.指针的偏移

nt a[5];

int *p=a;

p++;

p++ ---指针向高地址偏移一个数据类型单位。

p-- ---指针向高地址偏移一个数据类型单位。

p+N ---指针向高地址偏移N个数据类型单位--N为一个整数

p-N ---指针向低地址偏移N个数据类型单位

p-q ---两个指针相减表示两指针之间相差多少个数据类型单位

注意:在c语言中同种类型的指针才能运算

6.特殊指针

野指针:

没有指向的指针,比较危险,在定义指针变量时没有初始化,里面保存的是随机的地址。

int *p;

char *p;

避免野指针的出现

int *p=NULL;

注意:如果暂时不知道指针指向,尽量初始化为NULL.

空指针:

NULL--代表0地址空间,不允许访问,一旦访问直接报段错误(非法访问内存)

空类型的指针:

使用空类型指针时必须强制类型转换。

void *p;//p为空类型的指针

int a=10;

void *p=(void *)&a;

*(int*p)

7.多级指针

指针的迭代,一级一级指向

二级指针--指向指针变量的指针

inta=10;

int*p=&a;

int**pp=&p;//指向p指针的指针

8.const修饰指针

const修饰*p

不能通过该指针修饰所指向的内容。

const char *p; char const *p;

const修饰p

这种类型的指针指向不能被改变

char *const p;

即修饰p也修饰*p

const char * const p;

这种类型的指针,既不能修改指针的指向,也不能修改指针所指向的内存空间里面的内容。

十二、数组指针--行指针

本质是一个指针,指向数组一行

1.数组指针定义的一般形式

<存储类型><数据类型>(*数组指针变量名)[N]

N:所指向数组一行有几个元素,是一个整型的常量。

intarr[3][4];

int (*p)[4]=arr;

p[i][j]

=(*(p+i))[j]

=*(*(p+i)+j)

十三、指针数组

同种数据类型指针的集合

1.指针数组定义的一般形式

<存储类型><数据类型>*指针数组名[N]

int*parr[5];

2.指针数组的初始化

inta[3][4]={1,2,3,4,5,6,,7,8,9,10,11,12}

int*p[3]={a[0],a[1],a[2];

for(inti=0;i<3;i++)

{

for(intj=0;j<4;j++)

{

printf("%3d",*(p[i]+j));

}

}

注意1:指针数组名,是整个数组空间的起始地址,代表了整片数组空间

longlen=sizeof(arr);//len = 16;

注意2:指针数组名,是一个地址常量,不能做等号左值。

十二、函数

能够实现特定功能的代码模块的封装

1.函数的作用

  • 提高代码的复用率

  • 增加了代码的可读性

  • 增加代码的逻辑性

2.函数的定义

<返回值类型>函数名(形式参数)

{

函数体;

return返回值;

}

返回值: charshortintlongfloatdoublevoid

函数名:

1.标识符

2.整个函数的入口地址

形式参数:是各种类型变量,可以多个可以没有

函数体:

代码模块->函数功能的具体实现过程。

return:函数调用过程中,程序执行时,遇到return关键字代表整个函数结束,后面可以跟一个返回值,代表整个函数的运行结果。

注意:如果是void类型的函数,则没有返回值。

返回值:

函数只能有一个返回值,高返回值必须与函数的返回值类型对应

函数的三要素:

返回值,形式参数,函数体

3.函数的声明

  • 告诉编译器,该函数是在别处定义,要在后续的程序中使用

  • 声明方式

<返回值类型>函数名(形式参数);

voidPrint(intn);

声明位置:

1.放在调用之前--头文件之后,主函数之前。

2.放在.h文件之中

4.函数的调用

  • 函数调用的一般形式

函数名(实际参数);

实际参数:与函数的形式参数一一对应,每一个实际参数之间用逗号隔开

  • 作为语句调用

intn=0;

scanf("%d",&n);

Print(n);

  • 作为表达式调用

char*p="hello world"

5.函数的传参方式

值传递:

传递数值

地址传递:

利用指针传递地址

数组传递

数组传数组

#include<stdio.h>

intswap(intb[32])

{

printf("b[3]=%d\n",b[3]);

}

intmain(intargc, char*argv[])

{

inta[32]={1,2,3,4};

swap(a);

return0;

}

数组传指针

#include<stdio.h>

intswap(int*b)

{

printf("b[3]=%d\n",b[3]);

}

intmain(intargc, char*argv[])

{

inta[32]={1,2,3,4};

swap(a);

return0;

}

6.static修饰函数

  • 限制该函数只能在本文件中使用,其他文件调用该函数

  • 同一源程序的其他文件可以定义同名的函数。

7.指针函数

本质上还是一个函数,只不过返回值是一个指针。

<返回值类型>*函数名(形式参数)//形式参数不要初始化

{

函数体;

return返回值;

}

<返回值类型>*:char*,int*....

void*:代表该函数返回值是一个空类型指针

注意:在定义指针函数时,不能返回一个内部局部变量的地址。

8.递归函数:

直接或者间接调用函数本身

#include <stdio.h>

int sum=0;

int digui(int n)

{

sum += n;

n++;

if(n<=100)

{

digui(n);

}

return sum;

}

int main(int argc, char *argv[])

{

int n=1;

printf("sum=%d\n",digui(n));

return 0;

}

9.回调函数:

以函数作为参数用函数指针接收传输

#include <stdio.h>

int callback()

{

printf("hello world\n");

}

int callback2()

{

printf("zhangcheng\n");

}

int zhangcheng(int (*zc)())

{

zc();

}

int main(int argc, char *argv[])

{

zhangcheng(callback);

return 0;

}

11.malloc函数:

在堆区申请一片空间

堆区:内存上的一片区域,是程序员手动开辟,手动释放

void*malloc(size_t size);

size:传一个整型的数据,代表申请多少个字节的空间。

返回值:如果申请成功,则返回一个空类型的指针,指向这片空间的其实地址,失败返回NULL。

释放堆区申请的空间

voidfree (void*p);

11.typedef:重命名已知数据类型

12.define:宏定义

define定义出来的是一个常量不可以修改

13.结构体:

可以存放任意数据类型的元素集合

struct(关键字)结构体名

{

数据类型 成员1;

数据类型 成员2;

数据类型 成员3;

。。。。

};//这里的分不能省略

结构体的初始化,按照定义的结构体的成员顺序依次赋值

结构体的调用,变量名.成员

1)结构体的赋值

字符串的赋值只能用strcpy函数赋值。

2)结构体的嵌套

#include <stdio.h>

#include <string.h>

typedef struct student{

int age;

char name[32];

int id;

char sex[32];

}STU;//结构体的定义

typedef struct teacher{

int age;

char name[32];

char sex[32];

STU zhangcheng;

}TEA;

int main(int argc, char *argv[])

{

/* STU zhangcheng;//结构体的初始化

zhangcheng.age = 18;

strcpy(zhangcheng.name,"zhancgheng");

zhangcheng.id=520;

strcpy(zhangcheng.sex,"man");*/

TEA zc = {20,"zc","man",{18,"zhangcheng",520,"man"}};

// printf("name=%s----age=%d\n",zhangcheng.name,zhangcheng.age);//结构体的成员调用

printf("name=%s----age=%d\n",zc.zhangcheng.name,zc.zhangcheng.age);//结构体的成员调用

return 0;

}

3)结构体数组
4)结构体指针
5)结构体的大小

字节序对齐,如果是成员最大的大小大于等于8,按照8字节对齐,如果最大的大小小于8,按照最大的数据类型字节对齐

偶数地址存储

验证方式:结构体的字节数是最大数据类型的倍数

14.共用体:union

和结构体的区别;

1.大小不一样,结构体计算每一个成员,按照字节序对齐方式存储,共用体计算最大成员的大小,字节对齐方式存储

2.存储方式不同,结构体所有成员分别存储不同的空间地址,共用体共用一个空间,只能一个一个存储。

15.枚举型:enum

#include <stdio.h>

int main(int argc, char *argv[])

{

enum week {

monday=3,tuesday,wednesday,thursday,friday,saturday,sunday};

printf("wesday=%d\n",wednesday);

return 0;

}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值