C语言基础笔记

C 小知识

gcc hello.c -o hello_world  # 编译时指定生成的文件名
int a;  // 定义一个变量但没有赋值,那么它的值是随机的.但是当我们定义一个全局变量并没有初始化,那么它的值是0.
字节: 一个字节 == 8个二进制位
单引号内是字符, 双引号内是字符串(字符串的结尾符是 ‘\0’, 战用1个字节)
  • 基本数据类型, 运算符号, 关键字
int: 整形, 4字节
short: 短整形, 2字节
long: 长整形, 64位unix系统下占用8字节

unsigned int: 无符号整形,效率会高一些,表示范围会大一些,处理非数学运算时使用
unsigned long
unsigned short
unsigned char

float: 小数点后6double: 小数点后16char: 字符类型,使用ASCII编码

&&: 逻辑与
||:逻辑或

sizeof: 返回变量或数据类型占用的内存的长度,以字节位单位

&:取地址符,加在某个变量前面,组合后的符号代表这个变量的地址值

指针: 指针全称是指针变量,其实质是C语言的一种变量。它的值通常是某个变量的地址值(p  = &a), 然后我们可以使用 *p 去间接访问p指向的那个变量

void: 代表任意类型(不是空类型),任意类型的意思不是哪种类型都行,而是说 类型是未知的,还没有指定。
      一个函数的参数列表是void,代表这个函数调用时不需要(不是不能)给它传参
      返回值类型是void, 代表这个函数不会返回一个有意义的返回值

void * : 表示void 类型的指针,void类型指针的含义是,这是一个指针变量,该指针指向一个void类型的数,就是说这个数可能是intfloat等等,但是我当前不知道是哪种类型。
         void类型指针的作用是,程序不是道是哪种类型,但是程序员是知道的(当时赋值的时候是什么类型,现在就还是什么类型)

  • if 选择结构
#include <stdio.h>

int main(void)
{
    int a, b, max;

    a = 33;
    b = 22;

    if (a > b){
        max = a;
    }
    else if (a < b){
        max = b;
    }
    else {
        max = 0;
    }

    printf("max = %d.\n", max);

    return 0;
}
  • switch case 选择结构
int main(void)
{
    int num = 2;

    switch (num){
        case 1:
            printf("1\n");
            break;
        case 2:
            printf("2\n");
            break;
        default:
            printf("default\n");
            break;
    }
}

注意:
    case 中必须是常数,且必须是整形(char 也可以被认为是整形)
    每个case后面都要有一个break
  • for 循环结构
#include <stdio.h>

int main(void)
{
    int sum;

    sum = 0;

    for (int a = 1; a <= 10; a++){
        sum += a;
    }

    printf("sum=%d.\n", sum);
    return 0;
}
  • while 循环结构
int main(void)
{
    int i = 1;
    int sum = 0;

    while (i <= 100){
        sum += i;
        i++;
    }

    printf("sum = %d.\n", sum);
    return 0;
}
  • do while 循环结构
int main(void)
{
    int i = 101;
    int sum = 0;

    do {
        sum += i;
        i++;
    } while (i <= 100);

    printf("sum = %d.\n", sum);
    return 0;
}
  • 函数
#include <stdio.h>

// 函数声明,全称函数原型声明
int add(int a, int b);

int main(void)
{
    int a, b, c;
    a = 1;
    b = 2;

    c = add(a, b);  // 函数调用

    printf("sum=%d.\n", c);
}


// 函数定义
int add(int a, int b){
    return a + b;
}
  • 复合数据类型 – 数组
#include <stdio.h>

int main(void)
{
    int a[4];  // 定义数组
    a[0] = 0;
    a[1] = 1;
    a[2] = 2;

    int b[3] = {0, 1}; // 不完全初始化
    b[2] = 2; // 赋值

    int c[3] = {}; // 不完全初始化,好处是会把元素默认初始化为0

    int g[] = {1, 2, 3};  // 编译器会自动补充初始化的长度

    int d[100] = {[50] = 50};  // 将第51个元素初始化

    printf("a = %d.\n", b[2]);

    char f[4] = {'a', 'b', 'c', 'd'}; // 字符数组
    char g[] = "abcde";  // 字符串方式定义字符数组, 默认包含字符串的结尾符 ‘\0’

    return 0;
}
  • 指针
#include <stdio.h>

int main(void)
{
    int a = 23;
    int *p;  // 定义指针变量p, 该指针指向一个整形数.

    p = &a;  // &是取地址符,将变量a的地址值赋值给p

    *p = 111;

    /*
    a   代表a变量本身
    p   代表指针变量p本身
    &a  代表变量a的地址值
    *p  代表指针变量p指向的那个变量,也就是变量a
    *   指针符号,在指针定义的时候(int *p),*的含义是告诉编译器p是一个指针。在指针操作的时候。*p代表指针变量p指向的那个变量
    */

    printf("a = %d.\n", a);
    printf("a = %p.\n", p);
    return 0;
}
  • 指针与数组初步结合
#include <stdio.h>

int main(void)
{
    int a[5] = {0, 1, 2, 3, 4};
    int *p;

    p = &a;  // 记录  数组  开始的地址,但是这样会出现警告,因为p是int类型,a 是array类型

    p = &a[0];  // 正确,记录了  数组首元素  的地址
    p = a;  // 看着不对,但其实可以。因为数组变量做右值时,表示的是  数组首元素  的首地址

    a[0]; // 访问数组a的第一个元素
    a[1]; // 访问数组a的第二个元素
    *p;   // 访问数组a的第一个元素
    *(p + 1);  // 访问数组a的第一个元素

    printf("a = %d.\n", *(p + 1));
    return 0;
}
  • 指针的 ++ 与 –
#include <stdio.h>

int main(void)
{
    int a[3] = {0, 1, 2};
    int *p;

    p = a;

    p++;  // p 指向的地址自增1

    printf("a = %d.\n", *p);
    printf("a = %d.\n", *p++); // ++ 和 * 的运算优先级一致,运算是从右到左的,但是因为++在变量右边的时候会在运算完成后再自增,所以这里打印出的值是1
    return 0;
}
  • 指针与传参
    传递实参时,实际上是将实参的拷贝传给函数,若想让实参本身参与运算,需要传指针
#include <stdio.h>

int swap(int a, int b);
int swap_pointer(int *p1, int *p2);

int main(void)
{
    int a = 1;
    int b = 2;

    swap(a, b);  // 传的是a和b的拷贝

    printf("a = %d.\n", a);
    printf("b = %d.\n", b);
////////////////////////////////////////////
    swap_pointer(&a, &b);  // 传的是a和b的地址

    printf("a = %d.\n", a);
    printf("b = %d.\n", b);

    return 0;
}

// 交换两个数
int swap(int a, int b){
    int temp;

    temp = a;
    a = b;
    b = temp;

    return 0;
}

int swap_pointer(int *p1, int *p2){
    int temp;

    temp = *p1;
    *p1 = *p2;
    *p2 = temp;

    return 0;
}
  • 结构体 – 用来封装几个不同类型的变量
#include <stdio.h>

// 结构体定义的是一种新的组合数据类型
struct person{
    char name[20];  // char类型的数组
    int age;
    int sex;
};  // 这里要有分号


int main(void)
{
    struct person per1;  // 定义一个结构体变量

    per1.name[0] = 'a';  // 结构体赋值
    per1.name[1] = 'b';
    per1.name[2] = '\0';  // 字符串结束标志
    per1.age = 12;
    per1.sex = 0;

    printf("per1.name = %s.\n", per1.name);

    struct person per2 = {  // 定义时初始化
        "abc",
        1,
        0
    };

    printf("per2.name = %s.\n", per2.name);

    return 0;
}
  • 共用体(联合体, union传)
#include <stdio.h>

union MyUnion{  // 定义共用体,共用体中只有一个对象,这个对象有不同的数据类型的访问形式。通常用在,只需要使用对象中的一个方法,但使用哪个方法不确定。
    int a;
    char b;
    float c;
};

int main(void)
{
    union MyUnion u1;

    // a 和 b 是不同的数据类型,重合的部分是 -128 ~ 127,所以在这个范围内a和b的值是一致的
    u1.a = 1111;

    printf("u1.b = %d.\n", u1.b);

    return 0;
}
  • 宏定义
#include <stdio.h>

#define N1 11111  // 宏定义, 用N 代替 11111, 类似于全局变量吧?
#define N2 1 + 2
#define N3 (265 * 24 * 60 * 60)UL  // 需要类型转换,默认会当做int类型处理

int main(void)
{
    int a;

    a = N1;

    printf("a = %d.\n", a);

    return 0;
}
  • 枚举
#include <stdio.h>

enum week{
    SUN,
    MON,
    TUS,
    WEN,
    THU,
    FRI,
    SAT
};


int main(void)
{
    enum week today;  // 定义一个枚举变量

    today = MON;  // 不能将 today 赋值为比如HUI这种枚举元素之外的值

    switch (today){
        case MON:
            printf("MON.\n");
            break;
        case WEN:
            printf("WEN.\n");
            break;
        default:
            printf("else.\n");
            break;
    }

    return 0;
}
  • 数据类型转换
int main(void)
{
    int a = 3;
    float b = 3.5;

    float c = a + b;  // 隐式转换, C语言默认就会进行,默认向精度更高的方向转换。这里编译器会构造一个临时的float变量,将a的值转成float放进去,a本身不变

    printf("c = %f.\n", c);

    float d;
    printf("d = %lu.\n", sizeof((char) d)); // 强制类型转换

    return 0;
}
  • 静态变量
#include <stdio.h>

void test(void);

int main(void)
{
    test();
    test();
    test();

    return 0;
}


void test(void){
    static int a = 1;  // 静态局部变量,只在第一次调用时才定义和初始化,以后多次调用时,变量的值是上一次执行后的值

    a++;

    printf("a = %d.\n", a);
}
  • 寄存器变量
#include <stdio.h>

void test(void);

int main(void)
{
    test();
    test();
    test();

    return 0;
}


void test(void){
    register int a = 1;  // 寄存器局部变量,直接把变量放到寄存器而不是内存里,这样访问速度就会加快

    a++;

    printf("a = %d.\n", a);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值