linux学习笔记和demo 7.4-7.17

linux学习笔记

头文件防止定义多个

#pragma once

#ifdef _MAIN_H

#define _MAIN_H

#endif

地址的存储,32位编译器用32位存地址,64位编译器使用64位存地址

野指针:存着没有意义地址的指针

注意传的时候要把长度也传进去,因为是不可知的

对编译器而言,int a[1000], int a[], int *a对于编译器而言,没有任何区别,都是当做int *处理

二维数组不是二级指针,

打印字符串传入参数为%s, 传入第一个值的地址,然后继续寻找直到结束符号,不然就会乱码

static修饰的变量在编译阶段就进行初始化

static 修饰的局部变量初始化只会执行一次,可以赋值多次

static 修饰的局部变量只能用常量进行初始化,因为他会先初始化,这时候局部变量还没有入栈,所以只能使用常量进行初始化

static修饰的变量只有在整个程序结束才会进行初始化

普通的全局变量:

在{}函数外面定义的全局变量称之为全局变量,只有外面定义了全局变量,任何地方都能用到,

如果使用之前还没有定义,需要声明,

如果定义一个全局变量,没有初始化,这个肯定是定义,

定义全局变量初始化,声明全局变量就使用extern

全局变量分文件:

头文件只使用头文件做声明extern

static全局变量:

一个文件只能有一个static全局变量的定义,一个文件不能出现多个

static全局变量相对于普通全局变量只能在本文件中使用

普通全局变量:外部连接

static全局变量:内部连接

全局变量的寻找:就近原则

 

程序没有运行之前内存分区已经确定,虽然分区确定,但是没有加载内存,程序只有在运行的时候才能加载内存

text(代码区):只读,函数

data:初始化的数据,全局变量,static变量,文字常量区(只读)

bss:没有初始化的数据,全局变量,static变量

当程序运行时,加载内存,首先根据前面确定的内存分区(text,data,bss)先加载,然后额外加载2个区

stack(栈区):普通局部变量,自动管理内存,先进后出

heap(堆区):手动申请空间,手动释放,整个程序结束,系统也会自动回收

使用size a.out查看程序的各个部分的占比

ulimit查看栈的大小有多大

内存使用的几个函数

memset

将内存区域的前几个字符以..的方式填写,中间参数是以字符处理.

优越性:当改变了字符数组的时候,如果不用这个办法,就需要获取长度,循环赋值0

memcpy

相对于strcpy,全部拷贝,而不是像str遇到\0就结束拷贝

此函数的使用不要出现内存重叠

memmove

如果出现内存重叠,就使用这个函数

memcmp

为什么和str*系列区分:因为str遇到\0就会结束,mem使用范围更广泛

free的使用和判空进行使用,避免重复释放问题

if(NULL != p)

{

free(p);

p = NULL;

}

高位放高地址,低位放低地址,叫做小端,指针总是从低地址向高地址进行存储

typedef 起别名

文件操作流程:

  1. 打开文件fopen
  2. 读写文件
  1. 按照字符读写fgetc(), fputc()
  2. 按照字符串行读取文件 fgets() fputs()
  3. 按照文件结尾符号 feof
  1. 关闭文件 fclose()

fopen 的选项,如果r,文件不存在,打开就会失败,”w”如果文件不存在就会新建,存在就会清空内容打开,”a”文件不存在,新建,如果文件存在,光标放在文件末尾

linux相对路径是对于可执行程序,相对路径

VS , 编译同时运行程序,相对于.vcxproj所在的路径

如果直接运行程序,就是相对于可执行程序

/*
c demo

*/

//常用的头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
/*
56 34 12 00
^
|
p
指针指向这个位置
指针步长demo
*/
void demo1()
{
    int i = 0;
    int a = 0x00123456;
    void *p = &a;
    printf("%x\n", *(char *)p);
    char *tmp = (char *)p;
    for (i = 0; i < 4; i++)
    {
        printf("%x\n", *tmp);
        tmp = tmp + 1;
    }
}
/*
const修饰指针
*/
void demo2()
{
    int a = 1;
    int *const p = &a;
    //编译失败,表示p(保存地址)无法被更改,只能指向这个地址
    // p = NULL;
    int const *p1 = &a;
    const int *p2 = &a;
    a = 2;
    p1 = NULL;
    p2 = NULL;
}
/*
指针操作数组
*/
void demo3()
{
    int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *p = a;
    int len = sizeof(a) / sizeof(*a);
    int i = 0;
    for (i = 0; i < len; i++)
    {
        printf("%d\n", *p);
        p++;
    }
    printf("\n\n");
    p = &a[len - 1];
    for (i = 0; i < len; i++)
    {
        printf("%d\n", *p);
        p--;
    }
}
/*
指针数组:是数组,每个元素都是指针
数组指针:指向数组的指针
*/
void demo4()
{
    int a[3] = {0, 1, 2};
    int *p[3];
    // p[0] = &a[0]
    p[0] = a;
    // p[1] = a+1;
    p[1] = &a[1];
    // p[2] = a+2;
    p[2] = &a[2];

    int len = sizeof(a) / sizeof(*a);

    int i = 0;
    for (i = 0; i < len; i++)
    {
        printf("%d\n", *p[i]);
    }
}

/*
值传递,指针传递
不要被c++的引用混淆了
c没有引用
*/
void swap(int a, int b)
{
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}
void swap2(int *a, int *b)
{
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}
void demo5()
{
    int a = 10;
    int b = 20;
    swap2(&a, &b);
    printf("%d\n", a);
    printf("%d\n", b);
}

/*
形参中的数组demo
注意传的时候要把长度也传进去,因为是不可知的
对编译器而言,int a[1000], int a[], int *a对于编译器而言,没有任何区别,都是当做int *处理

*/
void sort(int *a, int len)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < len - 1; i++)
    {
        for (j = 0; j < len - 1 - i; j++)
        {
            if (a[j] > a[j + 1])
            {
                swap2(&a[j], &a[j + 1]);
            }
        }
    }
}
void demo6()
{
    int a[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
    int len = sizeof(a) / sizeof(*a);

    sort(a, len);
    int i;
    for (i = 0; i < len; i++)
    {
        printf("%d--", a[i]);
    }
    printf("\n");
    int *p;
    printf("%d\n", sizeof(p));
}
/*
字符串拼接
*/
int demo7()
{
    char str[] = "hello";
    char str2[] = "world";
    strcat(str, str2);
    printf("str is %s \n", str);
}

/*
字符串打印的乱码测试
*/
void demo8()
{
    char a[] = {'a', 'b'};
    int i;
    char *p = a;
    for (i = 0; i < 4; i++)
    {
        printf("char is %d \n", *p);
        p++;
    }
    printf("%s\n", a);
}

/*
字符串使用const修饰
整个字符串都会被赋予只读
*/
void demo9()
{
    char a[] = {'a', 'b'};
    const char *p = a;
    //*p = 'k'; err
    p++;
    //*p = 'k'; err
}

/*
字符串常量地址
存放在data区域,不可以修改
*/
void printStr()
{
    printf("%p\n", "helloworld");
}
void demo10()
{
    printf("%s\n", "helloworld");
    printf("%p\n", "helloworld");
    printf("%s\n", "helloworld" + 1);
    printStr();
    char *p = "helloworld";
    printf("%s\n", p);
    //*(++p) = 'a'; err
}

/*
main函数的参数意义
*/
// void fun1(int a[10])
// void fun1(int a[])
// void fun1(int *a) 都是一样的
void printArray(char **p, int n)
{
    int i;
    for (i = 0; i < n; i++)
    {
        printf("the %dth is %s\n", i, p[i]);
    }
}
void demo11()
{
    char *p1 = "hello";
    char *p2 = "world";
    char *p3 = "lx";

    char *p[] = {p1, p2, p3};
    int n = sizeof(p) / sizeof(p[0]);
    int i;
    for (i = 0; i < n; i++)
    {
        printf("%s\n", p[i]);
    }
}

/*
二维数组的使用方式
*/
void printfArray2(char **a, int n)
{
    int i;
    for (i = 0; i < n; i++)
    {
        printf("%s\n", a[i]);
    }
    printf("\n");
}
void demo12()
{
    char *a[] = {"aa", "bb", "cc", "dd"};
    int n = sizeof(a) / sizeof(*a);
    printfArray2((char **)a, n);
}

/*
查找字符串匹配次数的方式
*/
void demo13()
{
    char *p = "11abc33333abc55555abc1111abc666";
    int i = 0;
    char *tmp = NULL;
    while (1)
    {
        tmp = strstr(p, "abc");
        if (NULL == tmp)
        {
            break;
        }
        else
        {
            printf("%s\n", tmp);
            p = tmp + strlen("abc");
        }
    }
}

/*
二维数组的赋值操作
*/
void demo14()
{
    int a, b, c;
    int *p12[] = {&a, &b, &c};

    //表现1
    char *str1 = "abc";
    char *str2 = "hello";
    char *str3 = "mike";
    char *p[] = {str1, str2, str3};
    //表现2
    char *p1[] = {"abc", "hello", "mike"};
    //表现3
    char *p2[3];
    p2[0] = "abc";
    p2[1] = "hello";
    p2[2] = "mike";
    printfArray2(p, 3);
    printfArray2(p1, 3);
    printfArray2(p2, 3);
}

/*
static demo
static 修饰的局部变量初始化只会执行一次,可以赋值多次
static 修饰的局部变量只能用常量进行初始化,因为他会先初始化,这时候局部变量还没有入栈,所以只能使用常量进行初始化
*/
void static_func()
{
    static int i = 0;
    i++;
    printf("static_func i = %d\n", i);
}
void demo15()
{
    static_func();
    static_func();
    static_func();
}

/*
memset
memcpy demo
*/
void demo16()
{
    char p[] = "hello\0mike";
    char buf[100];
    printf("sizeof(p) = %lu\n", sizeof(p));
    strncpy(buf, p, sizeof(p));
    printf("buf1 = %s\n", buf);
    printf("buf2 = %s\n", buf+strlen("hello")+1);
    memset(buf, 0, sizeof(buf));
    memcpy(buf, p, sizeof(p));
    printf("buf1 = %s\n", buf);
    printf("buf2 = %s\n", buf+strlen("hello")+1);
}

/*
memcpy 常用
*/
void demo17()
{
    char a[] = {1,2,3,4,5,6,7,8,9};
    char b[9];
    memcpy(b, a, sizeof(a));
    //or memcpy(b, a, sizeof(int)*9);

    //内存重叠:不可以出现
    memcpy(&a[2], a, 5*sizeof(int));
}

/*
memmove 常用
*/
void demo18()
{
    int a[] = {1,2,3,4,5,6,7,8,9};

    memmove(&a[2], a, 5*sizeof(int));
    int len = sizeof(a)/sizeof(a[0]);
    printf("len is %d\n", len);
    int i;
    for(i=0;i<len;i++)
    {
        printf("%d\n", a[i]);
    }
}

/*
stack demo
*/
void demo19()
{
    int *p;
    int a;
    p = &a;
    *p = 10;
    printf("*p = %d\n", *p);
}

/*
内存对齐
*/
struct Stu
{
    char ID;
    int age;
    short k;
};
typedef struct Stu1
{
    char ID;
    int age;
    int k;
}STU;
void demo20()
{
    printf("the size of the struct is %d\n",sizeof(char)+sizeof(int)+sizeof(short));
    printf("the size of the struct is %d\n", sizeof(struct Stu1));
}

/*
完全相同的结构体可以赋值
*/
void demo21()
{
    struct Stu stu1 = {1,2,3};
    struct Stu  stu2 = stu1;
}

/*
union demo
*/
union Tea
{
    unsigned char ID;
    unsigned int a;
};
void demo22()
{
    union Tea tea;
    tea.ID = 'a';
    printf("the size of the struct is %d\n", sizeof(union Tea));
     
}

/*
typedef demo
*/
void demo23()
{
    STU student;
    student.age = 12;
}

/*
文件描述符的使用,印证按照顺序寻找空闲fd
*/
void demo24()
{
    close(1);
    int fd = open("01.txt", O_RDWR|O_CREAT, 0777);
    printf("today i am so happy\n");
    printf("today i am so happy\n");
    printf("today i am so happy\n");
    printf("today i am so happy\n");
}

/*
文件读写
*/
void demo25()
{
    FILE *fp = NULL;
    fp = fopen("./01.txt", "rw");
    if(NULL == fp)
    {
        perror("fopen");
        return;
    }

}

/*
fputc的使用
*/
void demo26()
{
    FILE* fp = NULL;
    fp = fopen("./02.txt", "w");
    if(NULL == fp)
    {
        perror("open");
        return -1;
    }
    char buf[] = "hello world\n";
    int len = strlen(buf);
    int i;
    for(i=0;i<len;i++)
    {
        fputc(buf[i], fp);
    }

    fclose(fp);

}

int main(int argc, char *argv[])
{
    demo26();

#if 0
    printArray(argv, argc);
#endif

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值