C语言知识点

C语言

1.进制转换

十进制(逢10进1):0-9

二进制(逢2进1):0-1

八进制(逢8进1):0-7

十六进制(逢16进1):0-15

注意:为了区分不同进制:八进制前面加0---076

                                           十六进制前面加0x---0x76

转换

1.1其他进制转十进制:对应的数字乘以其他进制的位数次幂

二进制转十进制:1011---->1*2^0+1*2^1+0*2^2+1*2^3    11(1248)

八进制转十进制:076--->6*8^0+7*8^1

十六进制转十进制:0xafc--->12*16^0+15*16^1+10*16^2

1.2十进制转其他进制:除以其他进制倒取余数

1.3二进制转八进制:每一个八进制可以用三位二进制数进行表示(421)

0 --- 000

1 --- 001

2 --- 010

3 --- 011

4 --- 100

5 --- 101

6 --- 110

7 --- 111

1.4 二进制和十六进制的转换:每一个十六进制可以用四位二进制去表示(8421)

0 --- 0000    1 --- 0001   2 --- 0010    3 --- 0011    4 --- 0100    5 --- 0101   6 ---- 0110    7 ---- 0111

8 --- 1000     9 --- 1001   a --- 1010    b --- 1011   c --- 1100    d --- 1101    e ----1110     f --- 1111

2.数据类型以及大小

2.1 long

只有long32位和64位操作系统字节大小不同,其他数据类型均一样

long 32os是4字节

         64os是8字节

2.2 有符号数和无符号数

有符号数:signed ---->正数和负数

符号位:最高位为符号位,0表示正数,1表示负数

10 --- 0000 1010

-10 --- 1000 1010

无符号数:unsigned ---->正数

3 转义字符

转义字符是一种特殊的字符序列

例如:/n   换行

          /t    水平制表

4.变量

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

                                       int            a;

数据类型:决定开辟空间的大小

存储类型:决定开辟的空间在哪个分区

一共有四种存储类型:static auto extern register

static:既可以修饰全局变量,也可以修饰局部变量,修饰的变量放在静态区

auto:默认情况下就是auto,只能用来修饰局部变量,修饰的变量存放在栈区

extern:只能修饰全局变量,修饰的变量存放在静态区

register:只能修饰局部变量,修饰的变量存放在寄存器中

4.1 初始化

定义变量的时候就给变量赋值

int a = 9; //初始化
int b; //定义变量
b = 3; //赋值

注意:1.全局变量未初始化存放在静态区.bss,初始化在存放在静态区.data

           2.局部变量未初始化和初始化都存放在栈区

           3.全局变量不初始化,其值为0;局部变量不初始化,其值为随机值

           4.static修饰全局变量限制作用域,只能在本文件中使用

             static修饰局部变量时延长局部变量的生命周期(延长至从定义开始到整个程序结束),局部变量没有初始化,其值为0,初始化且只能初始化一次

5.数据类型转换

5.1 强制类型转换(自己转)

变量前面加个括号直接转

5.2 隐式类型转换(编译器进行转换)

6.运算符

优先级依次递减:单算移关与,异或逻条赋

6.1单---单目运算符

a++    ++a    --a   a--

6.2算---算数运算符

+    -    *    /    %    ++    --

注意:%---取模运算,求余数   %不能用与浮点数

            /---除法运算,取整

++a;    //先自加再赋值
a++;    //先赋值后自加

6.3移---移位(左移、右移)

位运算符:&    |     ~     <<    >>    ^

~   取反运算符

左移---<<

无符号数(只有正数)---高位丢弃低位补0

有符号数---符号位不变,高位丢弃,低位补0

右移--->>

无符号数---低位丢弃,高位补0

有符号数---符号位不变,低位丢弃,高位补1

6.4关---关系运算符

>    <    >=    <=    ==    != 

关系运算符:比较的结果是真或假

注意:判断相对时,编程习惯将常量放在左边

if(9 == a)

6.5与---与运算符

&

6.6异或---异或运算符

^   异或运算符

相同为0,不同为1

6.7逻---逻辑运算符

&&    ||    !

截断法则

6.9赋---赋值运算符

=

6.10 sizeof运算符

使用方法:

sizeof(数据类型);//用法1
sizeof(变量名);//用法2

作用:求对应数据类型或者变量名所占内存空间的大小

6.11 三目运算符

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

6.12 逗号运算符

(表达式1,表达式2,表达式3,......表达式n)

从左往右依次计算每个表达式的值,将表达式n的值作为整个表达式的值

注意:必须依次计算,防止前面的表达式改变了表达式n中的变量的值

           逗号的优先级最低,因此在使用的时候需要加上括号

7.输入输出

7.1输出printf

整型

%d----以整型形式进行输出

%ld----以long整型形式输出

%lld----以long long整型形式输出

%hd----以short整型形式输出

%u----以无符号整型形式输出

%o----以八进制整型形式输出

%x、%X----以十六进制整型形式输出

#:自动在八进制和十六进制之间加上前缀

字符型

%c----以字符形式输出

浮点型

%f----以浮点形式输出

%lf----以双精度浮点型输出

%g----以指数形式和浮点形式中较短的方式进行输出

%e---以指数的形式进行输出

%.nf----保留小数点n位进行输出

%m.nf

m----指定我们输出的域宽,当m>0,默认右对齐,当m<0,默认左对齐

当m的值大于数据的实际长度时,补空格,m小于数据的实际长度时,原样输出

注意:默认左对齐,加上负号表示右对齐

7.2输入scanf

scanf("%d",&a);

注意

1.scanf格式控制串,不要加修饰语,如果要加,要原样输出

2.如果输入“%d%d”时,要给多个变量进行赋值,在格式控制串中,没有多余的修饰语时,可以以空格,回车,tab键作为第一个变量结束的标志

3.全部输入结束,必须以回车作为结束符

4.如果以“%c%c”输入多个字符时,不能有回车,空格,tab键,因为空格,回车,tab键也是一个字符

解决方法

1.在%c和%c之间加上逗号或者空格

2.加上%*c,*表示抑制符(吃掉一个字符)

3.%*nc---吃掉n个字符

 7.3 字符输入输出函数

字符输入函数

getchar()----返回值输入字符的ascii码值

字符输出函数

putchar()---参数输出的字符的ascii码值

 8.三大结构

8.1 顺序结构

程序中的语句按照一定的先后顺序去运行

8.2 选择结构

选择正确的条件结果再进行运行输出

if else选择结构

单分支结构

双分支结构

多分支结构

switch case结构

switch(表达式)
{
    case 标号1:
         语句1;
    break;
    case 标号2:
         语句2;
    break;
    ......
    case 标号n:
         语句n;
    break;
    default:
         最终语句;
}

 注意:

1.表达式不能为float类型

2.标号必须为常量

 8.3 循环结构

循环三要素:循环的起始条件,循环的终止条件,循环变量的变化

for循环

for(表达式1;表达式2;表达式3)
{
   循环体;
}

 注意:

表达式1:可以省略,但需要在循环体外给循环变量一个初始值

表达式2:可以省略----会导致死循环

表达式3:可以省略,但需要在循环体内实现循环变量的变化

三个表达式都可以省略,但是分号不可以省略

for循环嵌套

 while循环

while(表达式)   //循环终止条件
{
    循环体;
    (包含循环变量的变换)
}

 注意:while循环的循环体包含循环变量的变化

do while循环

do
{
    循环体;
    (包含循环变量的变化)
}while(表达式);

 while和dowhile的区别:

while先执行再判断,循环体最少执行0次

do while先执行再判断,语句至少执行1次

break和continue的区别

二者都是跳出循环的作用

break

跳出switch case语句

跳出循环(离他最近的循环)

continue

跳出本次循环,进入下一次循环

 死循环

while(1)

{

        循环体;

}

for( ;  ;  )

{

     循环体; 

}

 goto语句

无条件跳转语句

标号:

goto 标号;//当执行到这条语句时,程序自动跳转至标号处

 9.数组

9.1 定义数组

概念:一组数据类型相同的元素的集合

<存储类型> 数据类型 数组名[元素个数]
            int    arr[5];
//arr的数据类型是int[5]
//存储类型:auto static extern register

特点:元素的数据类型相同

            地址连续

注意:

打印地址的格式化符---%p

数组的数据类型---去掉变量名,剩下的就是数据类型

 sizeof在64位linux系统下打印时,应使用%ld

数组名的特点:

1.代表数组首元素的地址

2.代表整个数组

注意:数组元素的个数必须是整数型,不能是浮点数。数组元素个数是一个确定的值,不能是一个变量

 9.2 数组初始化

全部初始化

int arr[5] = {1,2,3,4,5};//全部初始化方法一
int brr[] = {1,2,3,4,5};//全部初始化方法二

 在定义数组时,给所有元素赋值

只有在全部初始化的时候,才能省略元素个数,此时元素个数由输入决定

部分初始化

在定义数组时,给部分元素赋值

数组清零

int arr[6] = {0};//清零

 数组的默认值

1.局部变量的数组不初始化,其值为随机值

2.static修饰的局部变量的数组不初始化,其值为0(静态区里的.bss)

3.全局变量的数组不初始化,其值为0

 访问

 9.3. 冒泡排序

从左往右,依次比较,如果前一个元素比后一个元素大,需要互换位置,反之元素位置不变

 

9.4 字符数组

概念:存储元素类型为字符的集合

每一个元素的数据类型为char

<存储类型> 数据类型 数组名[元素个数];
           char    str[5];
//分配5个大小为1字节的空间,给这片空间起名为str

计算字符数组所占空间大小 = sizeof(char)*元素个数

字符数组的本质---字符串

打印字符串的格式化符%s

字符数组清零

char str[5] = {0};
char str[5] = {'\0'};

 9.5 字符串输出函数

puts(参数);
//函数功能:打印输出字符串,遇到'\0'结束打印,并自动换行
//函数参数:需要打印的字符串的起始地址(字符数组名)

 9.6 字符串输入函数

gets(参数);
//函数功能:从键盘得到字符数据存放到字符数组中,并自动'\0'
//函数参数:电脑去保存字符的数组名
//注意:该函数不会进行越界检查,注意访问越界问题

 总结

 gets和scanf对比

1.scanf以回车、空格、tab键作为输入结束符,gets以回车作为结束符

2.scanf输入完成后不会清空缓冲区,里面遗留回车、空格tab键,gets会清空缓冲区

3.gets函数发现缓冲区有数据,会直接拿过来使用,否则,要求键入

4.scanf只能以键入方式输入数据

puts和printf

1.puts函数输出的时候自动换行,printf函数不会自动换行

9.7 字符串处理函数

使用的时候需要引入头文件

#include <string.h> //C库的头文件

 1.求字符串长度

strlen();//求出的值不包含‘\0’

 

 2.字符串拷贝函数

strcpy(str1,str2);//str1的长度要大于str2  遇到'\0'停止拷贝
strncpy(str1,str2,3);//将str2的前三个字符拷贝到str1中 遇到'\0'停止拷贝

3.字符串连接函数

strcat(str1,str2);//str1的空间要足够大
strncat(str1,str2,n);//将str2中的前n位连接到str1

 4.字符串比较函数

strcmp(str1,str2); //比较两个参数的大小
//函数返回值
return value > 0; //参数1 > 参数2
return value < 0; //参数1 < 参数2
return value = 0; //参数1 = 参数2

 9.8 二维数组

二维数组:一组元素集合在一起(元素:一维数组)

本质:元素为一维数组的数据

<存储类型> 数据类型 数组名[行数][列数];
             int    arr[2][3];
//定义了一个二维数组,该数组有2个元素,每一个元素都是一个有3个int类型元素的一维数组
//行数:有几个一维数组(二维数组有几个元素)
//列数:一维数组有几个元素

 二维数组所占内存空间大小 = sizeof(最里面元素的数据类型)*最里面元素

初始化

全部初始化

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

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

注意:行数可以省略,因为确认了一维数组中最里面的元素,所以编译器可以计算出一维数组的个数

列数不可以省略,会产生歧义

部分初始化

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

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

访问

二维字符数组

char str[2][3]

 10.函数

概念:具有一定功能的模块代码

为什么要有函数:提高代码复用率 可以让程序变得模块化

分类

10.1 库函数

使用的时候要加头文件

#include <stdio.h>

#include <string.h>

printf scanf strlen strcpy gets等等

10.2 自定义函数

调用自定义函数

函数名(实参);

注意:1.实参的数据类型和个数必须和形参一一对应(调用的时候将实参的值传给形参)

            2.实参可以是一个变量、常量、表达式,必须是一个确定的值

            3.实参和形参是两片独立的空间

            4.传参实际上是将实参的值拷贝给形参

            5.形参是局部变量,在函数调用的时候被定义(开辟空间),函数调用结束之后释放空间

 

 10.3 函数声明

如果自定义的函数在main函数之后,就需要加上声明

将函数名复制加分号就是函数声明

 

 11.指针

指针是一个数据类型,是一个保存地址的数据类型

指针的大小:32OS 4字节  64OS 8字节

11.1定义指针

<存储类型> 数据类型 指针名;
           int *   p;
//一个指向int类型变量的指针
//编译器分配8字节,起名为p,存放int类型变量的地址

int *p; //p的数据类型是int *

注意:指针变量中只能保存它指向同中数据类型的变量的地址

11.2 野指针

不知道指向的指针(局部指针,未初始化,随机指向)

要避免野指针----先指向NULL,0号地址

11.3 空指针

0号地址:没有指向的指针(NULL)

注意:禁止操作

特点:不读不写(这片空间不能保存别的地址,只能保存NULL,即就是不能指向,但别的指正可以指向它)

实现两数交换

调用函数的时候,需要操作地址里面的值,需要传地址

11.4 二级指针

概念

指针的指针(保存指针的地址)

二级指针的内存空间:用来保存一级指针的地址

int **p;

 

 总结

1.指针指向的数据类型:去掉*和指针名,剩下的就是指向的数据类型

2.指针的数据类型:去掉指针名,剩下的就是指针的数据类型

3.指针所能访问到的空间的大小,由其指定的数据类型决定

11.5 指针与一维数组

指针常量的偏移量取决于指针指向的数据类型的大小

 

 总结:

1.p+n 相当于指针p向地址增大方向移动n个数据(数据大小为sizeof(指向的数据类型))p为指针常量或者指针变量

实际变化:p+sizeof(p指向的数据类型)*n

2. p-n相当于指针p向地址减小方向移动n个数据(数据大小 = sizeof(指向的数据类型)) p为指针常量或者指针变量

实际变化:p+sizeof(p指向的数据类型)*n

3.p++ 指针p向地址增大方向移动1个数据(数据大小为sizeof(指向的数据类型))p为指针变量

4.p--:指针p向地址减小方向移动1个数据(数据大小 = sizeof(指向的数据类型)) p为指针变 量!!

5.p-q:p和q的指针类型要匹配,两个指针之间相差的数据个数(数据大小 = sizeof(指向的数据类型))

(十六进制p-q的差值)/sizeof(指向的数据类型)

 注意:1.指针的算术运算需要操作连续的空间地址才有意义

             2.p是指针变量,可以++或者--(指针常量不可以++或者--)

指针常量与一维数组的关系

指针变量与一维数组的关系 

 

 

 数组在子函数中弱化为指针(数组名---指针常量)

void input(int *p,int m)
void input(int a[],int m)
//可以在子函数中像main函数一样操作数组,操作的是同一片地址

 指针常量与二维数组的关系

 

 总结:

1.a    &a    a[0]    &a[0]    &a[0][0] 都表示首地址,但其意义不同

a  指针常量整个二维数组名

&a 与a含义相同

a[0] 指针常量整个一维数组名

&a[0] 与a[0]含义相同

&a[0][0] 与a[0]含义相同

2.a[0]是int *类型,指向的是一个int类型,不是二级指针

3.a指向a[0],a[0]指向a[0][0]

11.6 数组指针

 指向数组的指针

int (*p)[3];

数组指针p的数据类型:int (*) [3]

数组指针p指向的数据类型:int [3]

数组指针与一维数组的关系

数组指针对其+1,直接移动一整个一维数组,指向数组底部,容易产生数组越界问题,因此一般不使用数组指针操作一维数组。

11.7 数组指针与二维数组的关系

 11.8 指针数组

本质:数组

概念:由指针组合起来的数组,数组中的元素都是指针类型

定义

<存储类型>  数据类型  数组名[元素个数]
              int *  arr[5];
//[]的优先级高于*

 指针数据arr的数据类型:int* [5]

指针数组保存的数据类型:int *

11.9 指针数组与二维数组关系

 

 11.10 const

const修饰变量:只读(不可写)

 

 

 const修饰指针---左数右指

数---数值不可修改

指---指向不可修改

const int *p;常量指针,指向常量的指针,数值不可以改变

int const *p;指针常量,定义一个指针,将该指针定义为常量,指向不可以改变

 const int * const p;

int const *const p;

p指针的指向和数值都不可改变

11.11 main函数传参

 12.GDB调试工具

调试步骤

1.编译的时候加参数

gcc -g error.c -o error

2.设置断点

b main

b 行号

3.gdb加可执行文件

gdb error

4.运行

r  运行

其他参数

n(next)    不进入子函数

s(step)      进入子函数

p(printf)a(要打印的值)    打印出来某一个指定值

c(continue)    可以直接跳出循环,进入下一步

q(quit)     退出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值