【重学C语言】第四章:指针与数组

一、地址

在这里插入图片描述
在这里插入图片描述

(重点)可以发现,对应字节的地址,他是连续起来的;所以可以之后得到了,变量的起始地址,也可以获得后面字节的地址;

代码理解:

#include<stdio.h>

int main() {
   
    int a = 1;
    //%p是地址的格式占位符
    //&a就是对变量a进行取地址
    //取的地址也是对应字节的起始地址
    printf("&a = %p\n", &a);
    return 0;
}

执行结果:

这里的结果一般来说是不一样的,但是只要是0x开头的16进制就说明没有问题

在这里插入图片描述

16进制

在这里插入图片描述

在程序中十六进制的表示,以及使用:

#include <stdio.h>
#include <limits.h>
int main() {
   
    //如果要用十六进制对变量赋值
    //需要在赋值前加上0x
    int a = 0x6f;
    //打印a变量对应10进制的值
    printf("a(10) = %d\n", a);
    //打印a变量对应16进制的值
    //%x是十六进制对应的格式占位符
    printf("a(16) = %x\n", a);
    //打印a变量对应16进制的值
    //%X是十六进制对应的格式占位符
    //但是对应小写和大写的作用是
    //打印时十六进制不是会有字母吗
    //然后这里的大小写对应就是把那些字母规定打印时是小写还是大写
    printf("a(16) = %X\n", a);
    //用16进制表示整形最大值和最小值
    printf("MAX_INT = %d\n", INT_MAX);
    printf("MIN_INT = %d\n", INT_MIN);
    int max_int = 0x7fffffff;
    int min_int = 0x80000000;
    printf("max_int = %d\n", max_int);
    printf("min_int = %d\n", min_int);
    return 0;
}

执行结果:

在这里插入图片描述

对应的最大值2进制转换的十六进制0x7fffffff如何来的:

在这里插入图片描述

通过这张图,也可以推出0x80000000如何来的

地址是一个几位二进制数据

先看一段程序:

#include<stdio.h>

int main() {
   
    int a;
    double b;
    char c;
    //获取每个类型的地址长度
    //sizeof获取参数的对应字节长度
    printf("sizeof(int &) = %lu\n", sizeof(&a));
    printf("sizeof(double &) = %lu\n", sizeof(&b));
    printf("sizeof(char &) = %lu\n", sizeof(&c));
    return 0;
}

执行结果:

在这里插入图片描述

可以发现每个类型对应的地址都是8位,那么一定就是每个类型对应的地址都是8位吗?

来看32位操作系统和64位操作系统

在这里插入图片描述

通过对32位和64系统的理解后,可以发现地址不应的是8位的,要看操作系统是多少位有关系的。

二、数组

定义和使用

在这里插入图片描述

程序中如何使用数组,以及概念对应的代码:

#include<stdio.h>
 
//数组定义和使用
void test1() {
   
    int a[5] = {
   0};
    for (int i = 0; i < 5; i++) {
   
        //a[i] 就可以访问数组对应下标为i的位置
        //也可以进行赋值
        a[i] = 2 * i;
    }
    for (int i = 0; i < 5; i++) {
   
        printf("a[%d] = %d\n", i, a[i]);
    }
    return ;
}
 
//动态数组的定义和使用
void test2() {
   
    //通过执行程序时来定义数组想要的大小
    int n;
    scanf("%d", &n);
    //动态数组是无法初始化的
    int a[2 * n];
    for (int i = 0; i < 2 * n; i++) {
   
        a[i] = i * i;
    }
    for (int i = 0; i < 2 * n; i++) {
   
        printf("a[%d] = %d\n", i, a[i]) ;
    }
    return ;
}
//初始化进行对数组赋值
void test3() {
   
    // int a[5] = {0}; 这种初始化是将每个位置初始化为0
    int a[5] = {
   1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i++)  {
   
        printf("a[%d] = %d\n", i, a[i]);
    }
    return ;
}
//数组定义时不在[]中输入大小
void test4() {
   
    int a[] = {
   1, 2, 3, 4, 5, 6, 7};
    //sizeof(a)获取数组字节大小
    //sizeof(int)获取int类型字节大小
    //相除就可以得到数组元素的个数
    int len = sizeof(a) / sizeof(int);
    printf("sizeof(a) / sizeof(int) = %d\n", len);
    for (int i = 0; i < len; i++) {
   
        printf("a[%d] = %d\n", i, a[i]);
    }
    return ;
}
//数组的地址理解
void test5() {
   
    int a[5] = {
   1, 2, 3, 4, 5};
    printf("a = %p\n", a);
    for (int i = 0; i < 5; i++) {
   
        printf("&a[%d] = %p\n", i, &a[i]);
    }
    return ;
}
 
int main() {
   
    printf("test1()\n");
    test1();
    printf("test2()\n");
    test2();
    printf("test3()\n");
    test3();
    printf("test4()\n");
    test4();
    printf("test5()\n");
    test5();
    return 0;
}

执行结果:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

通过test5()发现数组的地址也不是连续的啊,但是对于数组a的类型是整形,整形对应的字节是4字节,对于变量的地址就是他的起始地址,所以相差为4刚好满足连续条件,所以数组的元素是连续的。

素数筛

在这里插入图片描述

在这里插入图片描述

代码实现:

#include<stdio.h>

int prime[100] = {
   0};

void init_prime(int n) {
   
    //初始化0和1不是素数
    prime[0] = prime[1] = 1;
    for (int i = 2; i <= n; i++) {
   
        if (prime[i]) continue;//如果被标记了,说明不是素数,就不用再去标记
        for (int j = 2 * i; j <= n; j += i) {
   
            prime[j] = 1;//标记当前数为合数
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值