C语言学习笔记(三)

2019-08-24  本文已影响0人  皮皮雅_

1. 隐式类型转换---->表达式有无符号的char 和short会被自动转为int。当包含两种的数据类型的表达式计算时,要先转为较高类型的数据再运算。例如:3+3.4,先转为double。注意图中的混合运算间的类型转换关系

隐式类型转换
2.强转指针/地址类型。指针的类型决定指针读写方式(字节数)。内存管理:大小端存储。生活中一般都是小段存储,如何测试?强转和联合。类型重命名typedef
小端存储
大端存储
大小端互转
#include<stdio.h>
//类型重命名
typedef int myint;
typedef myint yourint;
//结构体重命名(也可类似前面的)
typedef struct Node
{
    int a;
}_Node;

//函数重命名
void fun(int a) {};

typedef void(*newFunName)(int);

int main(void)
{
    //int a = 12;
    //double *p = (double)&a;//越界
    //*p = 21.3;
    double a1= 12.36;
    int *p = (int)&a1;//大指针转为小的可以。相同也可以
    *p = 21;//操作前四个字节
    *(p + 1) = 22;//操作后四个字节

    //测试大小端存储
    myint a = 134480385;
    char *p1 = (char*)&a;//吧字节划为单个来取
    printf("%p,%d\n%p,%d\n%p,%d\n%p,%d\n",&p1[0],p1[0], &p1[1], p1[1], &p1[2], p1[2], &p1[3], p1[3]);//1 2 4 8对比图的存储方式
    //转成大端存储就手动转改变即可



     getchar();
     return 0;
}

3. 一般都是大写使用 #define预处理指令。常量宏和参数宏

#include<stdio.h>
//常量宏  宏不加分号结尾(宏理解为替换,若里面有分号,也会被替换进去)
#define ONE 1
//宏不计算,单纯的替换
#define TWO 1*2-3*a

//参数宏,参数可多个
#define PRINTF(x)printf("%d\n",x);
#define SUM(x,y)((x)+(y));//一般加上括号避免优先级产生的读取逻辑错误
//拼接 用'\',拼接换行的,‘\’后不接东西
#define NUM 1+54\
+12+25
//#以字符串输出,##拼接字符串
#define NUM1(x) #x 
#define NUM2(x,y) #x ## #y 
int main(void)
{
    int a = 12;
    printf("%d\n",TWO);

    PRINTF(12*45);
    int b=SUM(45, 45);
    printf("%d\n", b);
    printf("%s\n", NUM2(fscfes,ffe));
    getchar();
    return 0;
}

4.预备役指令--#include

#include详解
<>和""区别
5.头文件相互包含解决:
#ifndef +头文件
//如果没有定义头文件就执行下面这“两行”语句
#define +头文件
#include"XXX"

#end if
总结:结构体不能互相嵌套
6.变量与存储。局部变量一般跟所在的{}共存亡。

静态变量
类型限定词(const(常量修饰符),volatile,restrict)
const修饰指针
volatile和restrict
#include<stdio.h>
int c;
extern int c1=15;//全局的变量,其他文件也可以用(其他文件的函数)。c c1两者一样的效果,作用域是所有的文件(因为他们地址都相同的)
static int s1=12;//静态全局,作用域为所在当前文件(不同地方的地址不同)
void fun()
{
    int c00 = 1;
    static int c11=1;
    c00++;
    c11++;
    printf("%d %d\n", c00, c11);
}
int main(void)
{
    auto int a;//自动变量,存储说明,说明a是栈区变量
    int b=2;//默认前面加了auto,未定义时。不初始化会运行报错,编译不会
    printf("%d %d",c,b);
    extern int c2;
    static int s2;//静态局部变量,生命周期和全局一样和陈序共存亡
    fun();//输出:2 2
    fun();//输出:2 3
    fun();//输出:2 4
    //寄存器存
    register int rl;
    const int b1 = 2;
    const int b11[5] = {0};
    //b1 = 3;//报错
    const int *b2 = &b;//*p不可变,p指向的地址可变
    //*b2 = 12;//报错

    getchar();
    return 0;
}

7.内存分区(5个)

栈区、堆区、静态全局区
字符常量、代码区
8.命令行参数(外部参数)
传参方式
#include<stdio.h>
//命令行参数的写法
int main(int argc, char*argv[])
{
    //将.exe文件拖入cmd中输入参数,记得空格隔开
    printf("%d\n", argc);//参数的个数,自动计算
    printf("%s\n",argv[0]);//文件的路径
    printf("%s\n", argv[1]);
    printf("%s\n", argv[2]);
    getchar();
    return 0;

}

8.随机数,
头文件:stdlib.h;srand(基数)随机数种子(没有默认为1);rand()产生随机数。基数固定,产生的随机数是一样的(解决:使用系统时间为基准数,头文件:time.h;使用time(NULL)即可,强转一下,time()返回64位的),每产生一个随机数,下一个随机数会以上一个随机数为基数产生下一个。

int a = rand()%25;//产生的就是0-24范围的值
int b = rand()%900+100;//产生的就是100-999范围的值
int c[]={4,8,59,5,74,67};//随机产生数组里的数,思路:随机产生他们的下标即可
int arr = rand()%6;

9.位运算 二进制用8421码转其他进制 例如:1011转16,84211011对应位相乘,100转8进制,100421对应位相乘相加为4

位运算
char a = -123;//负数补码,正数的补码:自身,负数的:符号位不变,数据位按位取反再加一(内存中存的就是这个)。负数为1正为0
    char b = ~a;//取反
    printf("%d\n",b);

10.文件操作,读取任意文件传入参数。文件读写有两种模式(文本模式,二进制模式)

文本模式
二进制模式

文件读写具体操作,切记:写入三种模式都可以,但是读取最好取r/r+,只读/读写

操作文件 fwrite()函数
fread()函数

读写结构体,fwrite()和fread()可以读写结构体。


fputs()和fgets()
fseek()和ftell()
#define  _CRT_SECURE_NO_WARNINGS
//防止不安全警告
#include<stdio.h>
#include<stdlib.h>


struct Node
{
    int Num;
    char name[10];
    short age;
};

int main(void)
{
    struct  Node no = {123123,"tzktzk",21};
    {

    };
    int a;
    //读取模式w会把文件内容先清空
    FILE *pFile = fopen("test.txt","r+");//绝对路径反斜杠要两个,相对路径就是在同文件夹下即可。r只读,w可读可写(改变读写模式文本模式或进制模式)
    // fopen_s(&pFile,"test.txt", "r");//参数1.返回文件指针,2.文件名,3.读写方式。外部返回类型(errno_t)错误码,没有为0。返回的值可以在 工具-->错误查找里查看

    //char *str = "\nHello";//文本模式换行\n,进制模式换行\r\n
    //fwrite(str, sizeof(char), strlen(str) + 1, pFile);

    //char str[20] = { 0 };
    ////a为实际读取字节数   。实测vs2015用a模式无法用循环读取txt文件内容.每次读2个,放入2个进入str记录下来
    //while (!feof(pFile))
    //{
    //  //feof(文件指针)文件结束:返回非0值,文件未结束,返回0值
    //  a = fread(str, sizeof(char), 2, pFile);
    //  printf(str);//模式选r才读的出来
    //  printf("%d\n", a);//读取放入数组是从头放的,之前读取的往后推
    //  str[0] = 0;//消除上一次记录下来的值
    //  str[1] = 0;
    //  
    //}

    //读写结构体
    //fwrite(&no, sizeof(no), 1, pFile);
    //fread(&no, sizeof(no), 1, pFile);//每读完指定字节,指针就指向下一个了

    //换行输入输出
    //fputs("\nhello",pFile);//并不能主动换行
    //char str[10] = {0};
    //fgets(str,10,pFile);


    //格式化读和写
    //fprintf(pFile, "%d %s %lf", 12, "Hello824", 12.34);//字符串在中间要用空格,其他的逗号也可以
    /*char str1[20] = { 0 };
    double d = 0.0;
    int a11 = 0;
    fscanf(pFile, "%d,%s,%.2lf", &a11, str, &d);
    printf(a11);*/

    
    int a1 = errno;//errno全局的错误码存储,出错就有
    fclose(pFile);
    system("pause");
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读