欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言涉猎笔记(一)

程序员文章站 2022-07-15 10:03:00
...

为安卓的NDK开发基础,所以尝试去学习C和C++语言,把学习笔记代码存着方便以后复习。

C语言的hello,world

// <> 寻找系统的资源
// “” 寻找我们自己写的资源
// .h .hpp(声明文件 头文件)
// .c  .cpp (实现文件)
//C语言的hello,world
#include <stdio.h>

int main(){
    printf("你好,C语言");

    getchar();//阻塞程序
    return  0;
}

基本数据类型和打印

//C语言的基本数据类型
#include <stdio.h>
int main(){
    int i = 100;
    double d = 200.00;
    float f = 300.00f;
    long l = 400;
    short s = 500;
    char c = 'a';
    char * str = "string";
    //C语言没有boolean   判断条件:非0即true

    //打印需要占位
    printf("%d \n", i);//d = 整形
    printf("%lf\n", d);//lf = long float
    printf("%f\n", f);//f = float
    printf("%ld\n", l);//ld = 长整形
    printf("%d\n", s);//d = 整形
    printf("%c\n", c);//c = char
    printf("%s\n", str);//s = string

    getchar();//阻塞程序
    return  0;
}

基本数据类型占用的字节数

//基本类型占用的字节数  sizeof获取字节数
#include <stdio.h>

int main(){
    printf("int size:%d\n", sizeof(int));// 4
    printf("double size:%d\n", sizeof(double));// 8
    printf("char size:%d\n", sizeof(char));// 1
    printf("float size:%d\n", sizeof(float));// 4
    printf("short size:%d\n", sizeof(short));// 2
    printf("long size:%d\n", sizeof(long));// 4

    return 0;
}

指针,地址概念

// 指针,地址概念
// Java 万物皆对象
// C C++(对象) 万物皆指针
// Linux 万物皆文件
#include <stdio.h>

int main(){
    // 指针 == 地址

    // %p == 地址输出的占位
    // &变量 == 取出变量地址   *指针 == 取出指针的值

    int number = 100;
    printf("此number变量的地址是:%p\n", &number); // 地址 == 000000000061FE1C

    int * number_path = &number;
    printf("此number变量的值是:%d\n", *number_path); // 值 == 100

    //通关指针修改变量的值
    *number_path = 200;
    printf("此number变量的值是:%d\n", number); // 值 == 200

    return 0;
}

常规函数

//函数
#include <stdio.h>

// C语言不允许函数重载,    Java可以,C++可以
void change(int * i); //1.先声明(C语言有顺序,想要调用的方法必须写在调用行数上面,所以可以先在上面声明在下面实现)

int main(){
    int i = 100;

    change(&i);

    printf("%d\n", i);
    return 0;
}

//C语言万物皆指针,一般入参都为指针
void change(int * i) {//2.再实现
    *i = 666;
}

C语言练习,交换两个数的值

//使用方法交换两个数的值
#include <stdio.h>

// 由于C语言不支持函数重载,所以声明的函数,不需要写参数
void changeNumber();

int main(){
    int a = 100;
    int b = 200;
    changeNumber(&a, &b);
    printf("交换完成后的效果:%d,%d\n", a, b);
    return  0;
}

//临时变量方式
void changeNumber(int * a, int * b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

//异或运算方式,不推荐
//void changeNumber(int * a, int * b) {
//    *a = *a ^ *b;
//    *b = *a ^ *b;
//    *a = *a ^ *b;
//}

函数入栈

//函数入栈后参数不是地址的话是要开辟新的空间的
#include <stdio.h>

void update(int i) {
    //此处的i的地址不是main函数里面的地址
    printf("%p\n", &i);
    //也就是此时修改i的值不会影响main里面i的值
    i = 200;
}

int main() {
    int i = 100;
    printf("%p\n", &i);
    update(i);
    printf("%d\n", i);
    return 0;
}

多级指针

//多级指针的写法
#include <stdio.h>
int main() {

    int num = 100;
    //定义多级指针
    int * num_p1 = &num;//一级指针
    int ** num_p2 = &num_p1;//二级指针
    int *** num_p3 = &num_p2;//二级指针

    //打印多级指针地址
    printf("%p\n", num_p1);
    printf("%p\n", num_p2);
    printf("%p\n", num_p3);

    //多级指针取值
    printf("%d\n", *num_p1);
    printf("%d\n", **num_p2);
    printf("%d\n", ***num_p3);

    return 0;
}

数组与数组指针

//数组与数组指针
#include <stdio.h>

int main() {
    //定义数组(声明时赋值)
    int arr[] = {1, 2, 3};
    //定义数组(声明时标记数组数量,不赋值)
    int arr2[3];
    arr2[0] = 1;
    arr2[1] = 2;
    arr2[2] = 3;

    //数组指针地址 == 数组第一个元素的地址 == 数组本身(数组本身就是一个地址)
    printf("%p\n", &arr);//000000000061FE10
    printf("%p\n", &arr[0]);//000000000061FE10
    printf("%p\n", arr);//000000000061FE10
    printf("%d\n", *arr);//1

    //数组的指针地址挪动
    //数组是连续的内存空间(没有断层,有规律) 数组
    int * arr_p = arr;//数组本身就是一个地址,不用&
    printf("%d\n", *arr_p);
    //指针自增长
    arr_p++;
    //指针指的值就是数组的下一位
    printf("%d\n", *arr_p);
    //数组指针不会越界,超过定义的值外,指向的是系统值
    arr_p+=10;
    printf("%d\n", *arr_p);


    //通过[]遍历数组 和java一样
    // sizeof arr / sizeof(int)  数组内存长度 / 定义的数组类型内存长度 = 数组元素数量
    for (int i = 0; i < sizeof arr / sizeof(int); ++i) {
        printf("%d\n", arr[i]);
    }
    //通过数组指针遍历数组
    int * arr_p2 = arr;
    for (int i = 0; i < sizeof arr / sizeof(int); ++i) {
//        int * p = arr_p2 + i;
//        printf("%d\n", *p);
        printf("%d\n", *(arr_p2 + i));
    }

    //通过[]给数组元素赋值 和java一样
    arr[0] = 199;
    printf("%d\n", arr[0]);
    //通过数组指针给数组元素赋值
    int * arr_p3 = arr;
    arr_p3++;
    *arr_p3 = 299;
    printf("%d\n", arr[1]);
    return 0;
}

指针长度

//指针的长度
#include <stdio.h>

int main() {
    int * p;
    printf("%d\n", sizeof p);//8
    int i = 100000;
    p = &i;
    //指针长度不会随值改变
    printf("%d\n", sizeof p);//8

    double p_d;
    //指针长度不会随指针类型改变
    printf("%d\n", sizeof p_d);//8

    //指针长度与当前运行的系统有关,一般windows32位操作系统是4位,windows64位操作系统是8位
    return 0;
}

函数指针

//函数指针,方法成入参传入另一个方法
#include <stdio.h>

void add();

// void(*method)(int,int) 函数指针入参声明格式
// void 返回值
// (*method) 函数名
// (int,int) 两个参数
void doAdd(void(*method)(int,int), int num1, int num2) {
//    (*method)(num1, num2);
    method(num1, num2);
    //与main中方法地址相同
    printf("doAdd method : %p\n", method);
}

int main() {
    //1.直接将函数名作为实参传入
    doAdd(add, 2,3);
    //2.先定义出函数指针,再传入
    void (*method) (int, int);
    method = &add;
    doAdd(method, 1, 2);

    //方法和数组一样,本身就是一个地址
    printf("%p, %p\n", add, &add);
}

void add(int a, int b) {
    printf("%d\n", a + b);
}