c语言笔记

c语言笔记

第一个程序(梦开始的地方)

#include<stdio.h>//头文件
int main()
{
 	printf("hello word")//打印hello word
}

//变量 一个存储数据的;

//定义变量 变量类型 变量名;

//作用域 变量的作用域在把它包含在{}里面最近的;

//生命周期 重调用时就是生命开始到结束;

//五则运算 + - * / % 前面4个和我们学的一样,后面的%是取模也叫取余;

//单目运算 ++ – 使变量加1或者减1 注:i++ 是先用后加,而++i是先加后用;


作业:查找一下**%c %s %o %x %f %p %u** //百分号什么是控制我们输出的格式

//& :取地址符 把变量的内存地址取出来

// :解地址符 把变量的内存地址里面存的东西解出来*

%c:输出字符
%s :输出字符串
%o:输出无符号以八进制表示整数
%x:输出无符号以十六进制表示的整数
%f: 输出浮点数
%p: 输出指针值
%u:十进制无符号整

进制转换

数据存储是以字节(byte)为单位

数据传输是以位(bit)为单位 //一字节等于八

小白用法欸
10进制转16,先转二进制,再隔4个转16,比如 97=0110 0001=61
10进制转8,先转二进制,再隔3个转8进制,比如97=  001=1 100=4 001=1
10进制转210进制除以2,
比如
97/2=48....1
48/2=24....0
24/2=12....0
12/2=6.....0
6/2=3......0
3/2=1......1一直算到1然后把最后的1也加上从后先前记110 0001。
正经的用法
10进制转16
97/16=97-16*6=1(这边加上16乘以的数就好,再加上1,就是6110进制转8
97/8=97-8*12=1
12/8=12-8=4			(算到比8小的就可以不用算了,加上一就好,141).

数据类型

基本数据类型
int 		//整型		 //4字节
char		//字符型		//1字节
short		//短整型		//2字节
long		//长整型		//4字节
float		//单精度浮点数  //4字节
double		//双精度浮点数  //8字节
注:以上是在32位的系统下的字节

在计算机里是用补码+1表示负数

要得到补码先取反,比如1,二进制就是0000 0001,取反1111 1110,加1,1111 1111,这就是补码;

逻辑判断

&&		//逻辑与	必须2个都是真才真,否则为假
||		//逻辑或	有一个为真就是真,2个假为假
!		//非	 真的变假的,假的变真的 非零的数和零,真和假,不管什么数只要不是0,就是真,是零就是假
!=		//不等于	不相等
==		//等于	等于

位运算

&		//按位与		必须2个都是1才是1,否则为0
|		//按位或		有一个为1就是,就为1
~		//按位取反	~1111 等于0000			若n为任何一个十进制的数则:“~n+n=-1” ~1+1=-2
^		//异或		 相同为0,不同为1
>>		/*右移		 二进制向右移动,比如a=4=0100,a>>1(让a向右移动一位),然后a=2=0010	对于无符号的int和char型数据,右移时左端补零,对于有符号int和char型数据,空出来补符号位
    	比如-3 是先3取反1100(原码0011),然后加上1变成补码1101,这就是-3,然后正常来说位移是0110,但是它是有符号的所以要加上前面加上1,也加上1110,然后就位移成了-1(这是通俗易懂的)。
    	然后就是正常来说int 是4字节,每个字节8位,也就是3的源码是00000000 00000000 00000000 00000011
    	那取反后就是11111111 11111111 11111111 11111100,
    	补码是11111111 11111111 11111111 11111101
    	然后位移>>就是01111111 11111111 11111111 11111110,
    	但是要补上符号位所以就是11111111 11111111 11111111 11111111,也就是-1.
    	*/
<<		//左移		 二进制向左移动,比如a=4=0100,a<<1(让a向左移动一位),然后a=8=1000	
x|=1<<y)	//将x的第y位置为1
x&=~1<<y)	//将x的第y位清零

内存图

32位的操作系统,为我们分配了4g的内存 32g=2^32

指针是一个特殊的变量,它存储的是内存里的地址.32位的系统,无论是什么指针都是4字节(sizeof()可以用尝试一下),因为指针本身只有4字节
在定义指针的时候“*”只有在定义指针的时候才表示是指针,其他任何时都不表示是指针。
n级指针用来存储n-1的指针,比如
int a=10*p=&a;
**p1=&p;(一级指针解一次,二级解两次)
大小端
在小端是高地址存高位,低地址存低位,大端是高地址存低位,低地址存高位。

程序结构

顺序结构(从上往下顺序执行的程序)
#include<stdio.h>
int main()
{
 	int i=5;
 	int j=4;
 	int sum=i+j;
}
分支结构
if分支
#include<stdio.h>
int main()
{
 	int i=5;
 	int j=4;
 	int sum=i+j;
 	if(i>5)
 	{
 		printf("hello ");
 	}
    else		//else 是否则,有if可以没有else,但是else 前面必须有if
    {
        printf("word");
    }	
}
/********************************************************************************************************************************/
#include<stdio.h>
int main()
{
 	int i=5;
 	int j=4;
 	int sum=i+j;
 	if(i>5)
 	{
 		printf("hello ");
 	}
    else if()		//else if 是多一个判断,也可以不加,下面的else{}就只判断if
    {
        printf("word");
    }	
}
/********************************************************************************************************************************/
#include<stdio.h>//这是if嵌套
int main()
{
 	int i=92;
 	int j=3;
 	if(i>=90)
 	{
 		printf("KFC\n ");
        if(j<=5)
        {
            printf("200\n");
        }
 	}
    else
    {
        printf("NULL\n");
    }
	
}
switch()分支
switch()//填写变量
{
    case 1:
        printf("hello\n");
        break;
    case 2:
         printf("hello123\n");
        break;				//break这是结束,在结束离它最近的{}
    default:				//这也是结束,是标记switch的末尾。
        printf("hh");			
}
三目运算

条件 ? 结果1:结果2

#include<stdio.h>//这是if嵌套
int main()
{
    int i=5,j=9;
	printf("%d",(i>j)?i:j);
}
循环结构
for循环
int sum;
for(int i=0(初始化条件);i=<10(退出条件);i++(循环控制条件))		 //i可以在for前面定义初始化,但是不能在for后面,
{														//循环体
	sum+=i;
}
while循环
while()	//逻辑判断,为真就循环,为假退出,非零死循环,零是不运行
{						//循环体
	
}
do…while循环
do								//先运行后判断,只是少运行一次
{								//循环体
	
}while;							 //do while最后必须加;
go to循环
xuedao:							//标签名加:
	int i=1;
    if(i<10)						//条件用if跳转
    {
        i++;
    }
	else
    {
        goto exit
    }
exit:
	return 0;					 //返回值
循环控制
break;						//跳出整个循环
continue;					//跳出单次循环
循环嵌套
for(int i=1;i=<9;i++)		//九九乘法表就是基础嵌套;
{
    for(int j=1;j=<i;j++)
        printf("%d*%d=%d\t",j,i,i*j);
    printf("\n");
}

数组

一维数组

一维数组(可以看出excel的一行或一列表格)

数组就是相同数据的数据集合

数组名代表首地址

内存是从上往下分配的,但是数组是从下至上的

//可以把一维数组想象成一行,或者一列的表格
#include<stdio.h>
//数据类型 数组名[元素个数]
int main()
{
	int a[10];
     printf("%d",*a);//获取首地址
     printf("%d",*(a+1))//获取首地址的下一个元素的地址
}
//sizeof计算内存大小,可以用来算数组大小
二维数组

二维数组可以看成一个面(也可以看出excel的整个表)

#include<stdio.h>
int main()
{
	int a[2][3];
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<3;j++)
        {
            printf("%d",a[i][j])//变量二维数组
            printf("%d",*(*a+0) )	//获取二维数组的第0行第0个数
            printf("%d",*(*(a+0)+0) )	//获取二维数组的第0行第0个数
            printf("%d ",*(*(a+2)+1));	 //第3行第2列 二维数组需要解两次才能用
            printf("%d",*(*(a+i)+j) )//获取二维数组的第j行第i个数。
        }
    }
}

指针

指针是变量,地址是常量

#include <stdio.h>
//
int main()
{
 int i = 8;
 int *p  =&i;
 int **p1 = &p;
 printf("&i = %p\n",&i);//变量i的地址
 printf("&p = %p\n",&p);//变量本身p的地址
 printf("*p = %p\n",*p);//*p == *(&i)
 printf("*p1 = %p\n",*p1);//*p1 == &i !=&p
 printf("**p1 = %p\n",**P1);//8
}
#include<stdio.h>
#include<stdlio.h>
int main()
{
int *p=malloc(sizeof(int)*4)//向系统要内存空间malloc(大小),它返回的是指针;
*p=10;
*p=20;
free(p);//释放内存
p=NULL//必须置空,预防野指针;
}
int *p;//就是int类型
指针的类型决定了访问内存大小,和指针+1加多少
char *p[];//在只读区,不能修改而且要取首地址要解2次才可以
数组指针
int brr[2][3];
int (*p)[3];		//只有多维数组才可以用数组指针
解开和解数组是一样的
printf("%d",*(*(a+i)+j) )

查找

#include<stdio.h>//二分法查找(必须是有序)
int sea(int a[] ,int len,int n)//传入数组,数组长度,查找的位置
{
    
    int left= 0;            //左边
    int right= len-1;         //右边
    while (left<=right)     //当左变小于等于右边时结束,就是说前面的加到超过了right就结束,代表没有这个数
   {    
        int middle =left+((right-left)/2);//用必定最大的左边减右边,除以2,
        if(a[middle]>n)             //判断中间的是否大于n
        {
            right=middle-1;     //缩小范围
        }else if(a[middle]<n)   //判断中间的值是否小于n
        {
            left=middle+1;      //缩小范围
        }else{
            return middle;      //查找到后,返回中间值
        }
   }
   return -1;					//返回值为-1
}
int main()
{
    int len=15,n=5;
    int a[15];
    for(int i=1;i<1;i++)
    {
        a[i]=i;
    }
    if(sea(a,len,n)==-1)
    {
        printf("NULL");
    } else
    {
        printf("下标是%d",sea(a,len,n));
    }
   
   
}

排序

 for (int  i = 0; i <len; i++)//冒泡
    {
        for(int j=i+1;j<len;j++)
        {
            if(a[i]<a[j])
            {
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
    }
for (int  i = 0; i <len; i++)//选择
    {   
        mid=i;
        for(int j=i+1;j<len;j++)
        {
            if(a[mid]>a[j])
            {
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
    }
void cr(int arr[],int len)
{
    int key;
    for(int i=1;i<len;i++)
    {
        key=arr[i];
        j=i-1;
        while((j>=0) && (arr[j]>key))
        {
            arr[j+1]=arr[j];
            j--;
        }
        arr[j+1]=key;
    }
}

字符、字符串、字符数组

字符‘a’ ‘b’ ‘\n’

字符串 “hh" “hello”

字符串默认以‘\0’结尾

%s是输出一个字符串,给它一个地址,然后解开地址,并打印输出地址里面的值

假如有指针指向了一个字符串,用%s的时候就,不需要解地址

指针可以直接存储字符串,但是指针的存储的字符串在只读区域,不能修改;

可以用循环输出指针存的字符串,

#include<stdio.h>
int main()
{
	while(*p)
	{
		printf("%s",p);
		*p++;
	}
}

内存分段

堆内存(heap),栈内存(stack)
数据段分为 未初始化的全局变量(bss)、全局变量(global)、静态变量区(static)、只读区(readonly) 
代码段(code)
//程序分为5个阶段编辑、预处理、编译、链接、执行
//预处理把原代码分为语法单元,去掉注释,同时把#define与#include等预处理指令定义和包含的内容展开;
//编译器检测分析源代码的语法单元,检测源代码的有效性,检查成功则产出对应的机器码,符号
//链接器分析对外部变量和函数引用,找到符号(有且唯一),确定数据段与代码段地址,并产生可执行程序,在一个程序中,一定不能重复定义外部变量和函数

函数

//封装调用代码
//函数的作用是将代码模块化

#include<stdio.h>
//函数是由返回值 函数名 参数列表;
//传参 值传递 地址传递
int test(int a,int * b)//子函数,int是返回值类型、函数是test、int是参数列表	如果前面的int 是void是返回值为空,也就是没有返回值,
// 返回值类型 函数名(参数列表)
{
    a++;			//值转递不改变主函数的变量
    (*b)++;			//地址传递改变了主函数的变量
    printf("%d" ,a);
    printf("%d" ,b);
    return	a,b;	//返回值必须和函数名前面的返回值类型一致,返回值返回了直接结束当前函数
}
int main()//主函数
{
    int a=5,b=5;
	test(a,&b);		//调用函数,a是值传递,而b是地址传递给函数
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值