初识c语言(2)

·用小乌龟上传文件到gitee时,如果add以后又更改了文件,那文件的图标会变红色,此时 就不用add了 直接commit就可以

常量

常量是不变的量。

  • 字面常量
    • 20;
    • 3.14;
    • ‘a’;字符常量
    • “abcdefh”;字符串常量
  • const修饰的常变量
    • const是c语言的一个关键字,用const修饰后的变量则不能被修改了。如下是不能修改成20的。语法不允许修改。
    • const修饰后,本质上还是变量。所以不能使用中数组定义时,指定大小。
const int num=10;
num=20;
  • #define定义的标识符常量
    • #define m 100
  • 枚举常量
    • enum是关键字
enum Sex
{ MALE, //默认是0
  FEMALE //默认是1  这俩就是枚举常量
};

int main(){
enum Sex s=MALE;
return 0;
}


字符串+转义字符+注释

字符串:

"hello\n"

这种由双引号引起的一串字符成为字符串字面值String Literal 或者简称字符串

·注:字符串的结束标志是一个\0的转义字符。在计算字符串长度的时候\0是结束标志,不算字符串的内容。例:

char arr1[]="abc";
char arr2[]={ 'a','b','c'};

printf("%s\n",arr1);
printf("%s\n",arr2);

此时显示的arr1是abc 而arr2则是abc后面跟着随机的内容。

因为arr1是有""的字符串,所以中"abc"实际是"abc\0" 但‘a’这些后面没有\0,会顺着内存里面的往后随机读取,直到读到\0才停止。

·strlen-库函数,用来求字符串的长度。需要#include<string.h>

求的是\0之前出现的字符的个数。

转义字符:如\n \0 转变原来的意思。 是一个字符。

  • \? 以前有三字母词,如??)等于]
    • 所以以前如果有 printf("(are you ok??)")就会把??)变成一个小方块
    • 所以这时候加上\就不会被识别为三字母词了。printf("(are you ok\?\?)")
  • \'
    • printf("%c",'a')是打印一个字符a
    • printf("%c",''')如果想打印一个' 那程序这里会把前面两个''理解为' '空的字符,然后后面又有一个' 就无法识别了。
    • printf("%c",'\'')这样就会打印出来一个'
  • \"" 同上
  • \\
    • printf("c:\text\text.c");
    • 这里的两个\t \t都会被识别为\t的转义字符
    • 所以c:\\test\\test.c就正常了
    • 一般写路径都要加上\\
  • \ddd -ddd表示1-3个八进制的数字 
    • printf("%c",'\130')显示的是X
    • a--97
    • A--65
    • @--...
    • 把这些字符都编号,即ascii编码。上面,左边是字符,右边是ASCII码的值。(有一个ASCII表可以查询)
    • 8进制的130转化成十进制是88
    • *8进制是0 1 2 3 4 5 6 7,没有8 9
      • \t代表一个字符
      • 1*8^2+3*8^1+0*8^0=1*64+3*8+0=88
    • 88对应的字符就是X
  • \xdd-dd表示两个十六进制数字
    • printf("%c",'\x31');
    • 31这个16进制转化成10进制:
      • 3*16^1+1*16^0=3*16+1*1=48+1=49
    • 49作为ASCII码代表的值,即 1

注释:

快捷键: ctrl k c
                ctrl k u

1、注释是用来解释代码的 非常重要

2、注释可以注释掉一些不需要的代码

        ①c语言的注释方法:

                /*

                */

        缺陷:不支持嵌套

        ②c++的注释方法: //


选择语句 if switch

if(a==1)
{
    printf("yes");
}

if(a==2)
{
    printf("no");
}

循环语句 while   for   do while

while(line<=20000)
{
    line++;
}

函数

int Add(int x,int y){
    int z=0;
    z=x+y;
    return z;

}

数组

能够存放一组相同类型的元素,每个数组的元素都有一个下标。下标从0开始。

arr[8]即第9个元素

注意,int arr[ n]其中的n最好不要是变量,在某些编译器里可以,但某些是不行的。

int arr[10]={1,2,3,4,5,6,7,8,9,10};

操作符

  • 算术操作符
    • + - * / %
      • /的两端如果是整数,那结果也是整数 如7/3
      • 7.0/3
      • 7/3.0 这样有一段是小数,那就是小数除法,结果是2.33333
      • %是取余数 7除以3是商2余1,那结果就是1
  • 移位操作符(移动的是二进制位)
    • >>         <<
  • 位操作符(二进制的)
    • &  ^  |
  • 赋值操作符
    • =  +=  -=  *=  ^=  |=  >>=  <<=
    • a=a+10  也就是 a+=10
  • 单目操作符(a+3 这里的a是双目操作符)​​​​​​​
  • c语言中,0表示假,非0表示真
    • (类型)强制类型转换
      • int a=(int)3.14
    • * 间接访问操作符(解引用操作符)
    • ++ 前置、后置++
      • int a=10
      • b=++a;先加加后使用 ++a的结果是11 所以b也是11
        • a=a+1,b=a;
      • b=a++;先使用后加加 a++的结果是11 但b还是10(a都会改变,b不一样)
        • b=a++    拆封即    int b=a ,a=a+1;
    • -- 前置、后置--
    • ~对一个数的二进制按位取反
    • sizeof 不是函数,是操作符。和+—*/一样操作数的类型长度(以字节为单位)(变量也可以算)
      • int a=10,sizeof(a)和sizeof(int)结果一样,都是4,算的是int 这个类型的长度
    • &取地址
    • +正值
    • -负值
    • !        逻辑反操作
  • 关系操作符
    • >  >=  <  <=  !=  ==
  • 条件操作符(三目操作符)
    • exp1  ? exp2:exp3
    • int a=3;
      int b=5;
      int m=0;
      m=(a>b)?(a):(b);

  • 逻辑操作符
    • &&  逻辑与
    • ||      逻辑或
      • 只关注真和假
      • int a=3; int b=5;
        if((a==3)&&(b==5))
        { printf("hehe"); }

  • 逗号表达式
    • exp1,exp2,exp3,。。。expN
    • int a=3;
      int b=4;
      int c=5;
      int d=(a -=3,b +=a, c =a-b, b=a-4);

      逗号表达式,表达式会从左向右,依次计算

    • 整个表达式的结果是最后一个表达式的结果。

  • 下标引用操作符、函数调用操作符
    • [ ]数组名,下标;是个操作符,和+-*/一样的操作符
    • ( ) 函数调用操作符
    • .
    • ->

常见关键字

是c语言本身提供给我们的;用户自己不能创造关键字。

创建变量的名字不能用关键字。

  • auto 自动; --所有的局部变量前 本质上都有auto的,代表到这里自动创建一个变量,结束后自动取消这个变量。只是平时省略了而已;如 auto int a =5;
  • register 寄存器
    • 电脑的存储区:(从上到下,速度越来越快,空间越来越大)
      • 寄存器(集成到cpu上的,速度快->造价高->空间小)
      • 高级缓存
      • 内存
      • 硬盘
      • 网盘
      • 平时cpu直接从内存中读取数据,但随着发展cpu更牛了,光用内存太大材小用,就开始向高级缓存和寄存器中拿数据,这样效率就上升了。注意这里只是建议,具体放不放看编译器。
      • int num=10; //4个字节
        register int num2=20; //建议将20放在寄存器中
  • break用在Switch 和循环中(for  while  do,while)
  • case用在switch里
  • char
  • short
  • int
  • long
  • float
  • double
  • const
  • continue用在循环中,继续
  • enum 枚举关键字
  • extern声明外部符号
    • 一个工程里创建了两个源文件test.c 此时第二个。c文件想用第一个文件里面的某个变量,第二个要在前面先声明,如:
    • extern int gg;
    • extern int add(int x,int y);//声明来自外部的函数
  • signed有符号的
  • unsigned无符号的
  • static静态的
    • 是用来修饰变量和函数的
      • 1 修饰局部变量 成为静态局部变量
        • 内存 划分为栈区 堆区 静态区,局部变量一般放在栈区,当用static修饰时,放到静态区了;实际改变的是变量的存储位置。
        • 静态区还有全局变量。生命周期比较长。(作用域没有变化,还是原来的作用域)
        • 静态区的生命周期和程序的生命周期一致。
        • 程序结束,静态数据也就结束。
      • 2 修饰全局变量 称为静态全局变量
        • 全局变量本来是有外部链接属性的,但是被static修饰后,外部链接属性就变成了内部链接属性
        • 只能在自己所在的源文件内部使用,不能在其他文件内使用了。用extern声明也不行。
          • 使用上感觉作用域变小了。(有啥用呢?能让别人看不到你的代码)
      • 3 修饰函数 称为静态函数
        • 函数本身有外部链接属性,如果创建函数时候加上了static就没有外部属性了,只能在自己所在的源文件内部使用,无法被其他源文件使用(和全局变量的情况差不多)
      • 局部变量:
        void test()
        { 
        int a=5;
        a++;
        printf("%d",a);
        }
        
        
        int main()
        {
         
        int I=0;
        while(I<10)
        {test();  I++;}
        return 0;
        
        }
        // 此时结果是 6 6 6 6 6 6 6 6 6 6
        
        如果 int a=5变成 static int a=5
        那结果就变成 6 7 8 9 10 11 12 13 14 15
        
        即a在出其局部范围时,不会被销毁;下一次进入此函数时依然存在。(存在静态区)

  • struct-结构体
  • typedef类型重命名
    • unsigned int num=10;
      typedef unsigned int uint;
      uint num2=10;
      //和第一行效果一样

  • union联合体(共用体)
  • void 无/空
  • volatile 体现c语言段位;c++的linux学

#define定义常量

test.c 源文件 经过【预编译 编译 汇编 链接 运行】,才形成一个test.exe开始运行

#define MAX=1000

int main()
{
    int m=MAX;
    printf("%d",MAX);

return 0;
}

这里在预编译的时候,会把MAX统统变成1000;即define定义的常量都会在预编译的时候进行替换。

define定义宏

宏的名字一般都是全大写的,习惯;

宏内的变量尽量都用()括起来,因为你不知道这个传过来的x会不会是一长串,那就容易乱

#define MAX(x,y) (x>y?x:y)

宏不用返回,不用输入变量类型;也是在预处理阶段进行处理的

ve


多组输入:

·scanf函数调用成功会返回一个1,调用失败会返回EOF(end of file 文件结束的标志,本质的定义是-1)

int iq=0;
while(scanf("%d",&iq)!=EOF)
{
    if(iq>=140)
    { printf("Genius!!!")}
}

·水平制表符 =按键Tab


杂七杂八

计算机要不要考证?

--考试得到的证书无法证明自己的能力。会做题才有意义。

--talk is cheap,show me the code

蓝桥杯和acm?

--蓝桥杯适合普通大众,获奖率比较高,简单些。

--acm比较难,都是校队,大家都是炮灰。这俩都是算法竞赛。有实力可以两个都参加,技术弱参加蓝桥杯就好了。不要把所有时间放上去,企业的招聘要求:1计算机语言,c C++ java 2算法和数据结构 3操作系统和系统编程 4计算机网络+网络编程 5数据库 6实战项目

英语重要吗?

非常重要,但年薪40w前不会成为门槛,长远来看非常重要。

不能证明自己能力的考证基本上都没啥用。


初识指针

要讲清指针必须讲内存。

内存

把内存理解成一个个的小格子,每个格子都有一个自己的编号,相当于我们的地址;

因为地址-->房间

所以有编号(地址)就可以找到这个内存单元(房间);

  • 那一个内存单元有多大?
    • 一个内存单元=一个字节byte(如果是bit就太小了,比如送快递送到你家就行,不用到你家厕所)
  • 内存单元的编号怎么产生?
    • 我们有32 、64位的机器
      • 32位就代表有32根地址线/数据线
      • 地址线--就是物理上的电线--通电--电信号---转化成数字信号,即1/0
      • 每根都通电,那就是从0000000000000到111111111111的序列
      • (都是32个,一根可以是0可以是1)
      • 一共有[2的32次方] 种排列组合;即有[2^32]个序列
      • 序列就可以用来当地址;
      • 内存单元是有编号的,编号就是内存单元的地址;理论上地址数不超过2的32次方
      • 总共可以管理2^32个byte 字节。2^32byte=4294967296byte/1024=4194304kb/1024=4096mb/1024=4gb
    • 所以32位实际能管理4gb的内存
    • 当我们写int a=10,int是四个字节,所以a就向内存申请了4个字节的地方;
  • %p 地址的打印
  • &取地址操作符
    • printf("%p",&a)这里拿到的地址是a的第一个字节的地址
  • 内存单元都有编号,这个编号就是地址(一个数字),地址也叫指针
    • int a=10    int* pa=&a
  • pa是用来存放地址的,所以我们把pa叫指针变量。
    • 这个*的意义就是告诉我们,这是个指针
    • int告诉我们,pa指向的对象的类型是int类型
      • 用的时候:*pa //这个*是解引用操作符 意思是,通过pa中存放的地址,找到pa指向的内容
      • *pa=q;就是a=q

指针变量的大小,取决于地址的大小

地址的具体值不一样,但不管是谁的地址,都是一串数字,32个比特位,也就是四个字节;

所以这里的 指针变量 的大小:

32平台上,不管什么类型都是4字节;

64平台上,不管什么类型都是8字节;


结构体

当c语言描述复杂对象时候,比如学生,名字 年龄 性别 学号几项信息

这里只能用结构体来描述了。

//结构体

struct Stu         //创建结构体
{
char name[20];
int age;
char sex[5];
char id[20];
}
//地址应该放到结构体的指针里面去,如int* pa=&a;
//前面的变量&s2就是取地址,而s2的类型不是int,是 struct Stu;所以这里就变成
//struct Stu* 然后要放到指针里面,再加上个ps;这里即ps这个指针里面,存的是s2的地址。
//即现在拿不到s2,因为s2作为结构体有很多数据,没法像int a=2这样直接拿过来用,所以用地址代表s2
//而main函数想用s2这个变量,那作为输入时候,给的就是s2的地址
//print函数里,接收到的输入就是s2的地址,但没法直接 int a=s2的地址,因为地址需要用指针存放,所以必须用一个指针 ()*ps =s2  而()里的类型要和s2一致,所以就是struct Stu* ps
//注意,这个ps只是自己命名了一下,和int a=b 这里的a一样,叫啥都行的

void print(struct Stu* ps){
printf("%s %d %s %s",(*ps).name,(*ps).age,(*ps).sex,(*ps).id);

printf("%s %d %s %s",ps->name, ps->age, ps->sex, ps->id);
}

//上面两个printf是一样的效果
//->:   结构体成员访问操作符,结构体指针->结构体成员

int main()
{

struct Stu s1={"张三",18,"男","202011000"};

struct Stu s2={"如花",444,"女","202011000"};

printf("%s %d %s %s\n",s1.name, s1.age, s1.sex, s1.id);

print(&s2);

return 0;

}

//.  :结构体成员访问操作符,结构体变量.结构体成员

void不需要return

当scanf的时候,数组本身就是地址,所以不需要取地址;其他需要

如上面的例子中,scanf("%s %d %s %s",s1.name, &(s1.age), s1.sex, s1.id );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值