C语言中的数组(含指针)

什么是数组

  • 数组是 C 语言中的一种数据结构,用于存储一组具有相同数据类型的数据。
  • 数组中的每个元素可以通过一个索引(下标)来访问,索引从 0 开始,最大值为数组长度减 1。

数组

数组的使用

  • 定义语法格式
    类型 数组名[元素个数];
    int arr[5];
    • 数组名不能与其它变量名相同,同一作用域内是唯一的

    • 其下标从0开始计算,因此5个元素分别为arr[0],arr[1],arr[2],arr[3],arr[4]

#include <stdio.h>

int main() {
    // 定义了一个数组,名字叫a,有10个成员,每个成员都是int类型
    int a[10]; 
    // a[0]…… a[9],没有a[10]
    // 没有a这个变量,a是数组的名字,但不是变量名,它是常量
    a[0] = 0;
    // ……
    a[9] = 9;
    // 数据越界,超出范围,错误
    // a[10] = 10;  // err

    for (int i = 0; i < 10; i++) {
        a[i] = i; // 给数组赋值
    }

    // 遍历数组,并输出每个成员的值
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}

 数组的初始化

  • 在定义数组的同时进行赋值,称为初始化
  • 全局数组若不初始化,编译器将其初始化为零
  • 局部数组若不初始化,内容为随机值
	int a1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 定义一个数组,同时初始化所有成员变量
	int a2[10] = { 1, 2, 3 }; // 初始化前三个成员,后面所有元素都设置为0
	int a3[10] = { 0 }; // 所有的成员都设置为0

	 // []中不定义元素个数,定义时必须初始化
	int a4[] = { 1, 2, 3, 4, 5 }; // 定义了一个数组,有5个成员

 数组名

  • 数组名是一个地址的常量,代表数组中首元素的地址
#include <stdio.h>

int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 

    // 数组名是一个地址的常量,代表数组中首元素的地址
    printf("a = %p\n", a);
    printf("&a[0] = %p\n", &a[0]);

    int n = sizeof(a);     // 数组占用内存的大小,10个int类型,10 * 4  = 40
    int n0 = sizeof(a[0]); // 数组第0个元素占用内存大小,第0个元素为int,4
    int num = n / n0;      // 元素个数
    printf("n = %d, n0 = %d, num = %d\n", n, n0, num);

    return 0;
}

数组案例

一维数组的最大值

#include <stdio.h>

int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[] = {1, -2, 3, -4, 5, -6, 7, -8, -9, 10};

    // 假设第0个元素就是最大值
    int temp = a[0];
    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
        // 如果有元素比临时的最大值大,就交换值
        if (a[i] > temp) {
            temp = a[i];
        }
    }
    printf("数组中最大值为:%d\n", temp);

    return 0;
}

一维数组的逆置

#include <stdio.h>

int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 

    int i = 0;  // 首元素下标
    int j = sizeof(a) / sizeof(a[0]) - 1;   // 尾元素下标
    int temp;

    while (i < j) {
        // 元素交换值
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
        // 位置移动
        i++;
        j--;
    }

    for (i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
        printf("%d, ", a[i]);
    }

    return 0;
}

数组和指针

通过指针操作数组元素

  • 数组名字是数组的首元素地址,但它是一个常量
  • * 和 [] 效果一样,都是操作指针所指向的内存
    #include <stdio.h>
    
    int main() {
        int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        int i = 0;
        int n = sizeof(a) / sizeof(a[0]);
    
        for (i = 0; i < n; i++) {
            // * 和 [] 效果一样,都是操作指针所指向的内存
            // printf("%d, ", a[i]);
            printf("%d, ", *(a + i));
        }
        printf("\n");
    
        // 定义一个指针变量保存a的地址
        int *p = a; 
        for (i = 0; i < n; i++) {
            // printf("%d, ", p[i]);
            printf("%d, ", *(p + i));
        }
        printf("\n");
    
        return 0;
    }

指针数组

  • 指针数组,它是数组,数组的每个元素都是指针类型
    #include <stdio.h>
    
    int main() {
        // 指针数组
        int *p[3];
        int a = 1;
        int b = 2;
        int c = 3;
    
        // 指针变量赋值
        p[0] = &a;
        p[1] = &b;
        p[2] = &c;
    
        for (int i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
            printf("%d, ", *(*(p + i)));
            // printf("%d, ", *(p[i]));
        }
        printf("\n");
    
        return 0;
    }

 数组名做函数参数

  • 数组名做函数参数,函数的形参本质上就是指针
    #include <stdio.h>
    
    // 下面3种写法完全等价
    // void print_arr(int a[10], int n)
    // void print_arr(int a[], int n)
    void print_arr(int *a, int n) {
        int i = 0;
        for (i = 0; i < n; i++) {
            printf("%d, ", a[i]);
        }
        printf("\n");
    }
    
    int main() {
        int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        int n = sizeof(a) / sizeof(a[0]);
    
        // 数组名做函数参数
        print_arr(a, n);
    
        return 0;
    }

字符数组与字符串 

字符数组与字符串区别

  • C语言中没有字符串这种数据类型,可以通过char的数组来替代
  • 数字0(和字符 '\0' 等价)结尾的char数组就是一个字符串,字符串是一种特殊的char的数组
  • 如果char数组没有以数字0结尾,那么就不是一个字符串,只是普通字符数组
    #include <stdio.h>
    
    int main() {
        char c1[] = {'c', ' ', 'p', 'r', 'o', 'g'}; // 普通字符数组
        printf("c1 = %s\n", c1);                    // 有可能乱码,因为没有'\0'结束符
    
        // 以'\0'('\0'就是数字0)结尾的字符数组是字符串
        char c2[] = {'c', ' ', 'p', 'r', 'o', 'g', '\0'};
        printf("c2 = %s\n", c2);
    
        // 字符串处理以'\0'(数字0)作为结束符,后面的'h', 'l', 'l', 'e', 'o'不会输出
        char c3[] = {'c', ' ', 'p', 'r', 'o', 'g', '\0', 'h', 'l', 'l', 'e', 'o', '\0'};
        printf("c3 = %s\n", c3);
    
        // 使用字符串初始化,编译器自动在后面补0,常用
    	char c4[] = "c prog";
        printf("c4 = %s\n", c4);
    
        return 0;
    }

字符串的输入输出

  • 由于字符串采用了'\0'标志,字符串的输入输出将变得简单方便
    #include <stdio.h>
    
    int main()
    {
        char str[100];
    
        printf("input string1: ");
        // scanf("%s",str) 默认以空格分隔
        // 可以输入空格
        gets(str);
        printf("output: %s\n", str);
    
        return 0;
    }

字符指针 

  • 字符指针可直接赋值为字符串,保存的实际上是字符串的首地址
    • 这时候,字符串指针所指向的内存不能修改,指针变量本身可以修改
      #include <stdio.h>
      
      int main() {
          char *p = "hello";  // 和 const char *p = 'hello' 等价,有没有const都一样
          // 指针变量所指向的内存不能修改
          // *p = 'a';    // err
          printf("p = %s\n", p);
      
          // 指针变量可以修改
          p = "world";
          printf("p = %s\n", p);
      
          return 0;
      }

字符串常用库函数

strlen

函数说明:

#include <string.h>
size_t strlen(const char *s);
功能:计算指定指定字符串s的长度,不包含字符串结束符‘\0’
参数:
	s:字符串首地址
返回值:字符串s的长度,size_t为unsigned int类型,不同平台会不一样

 示例代码:

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "abcdefg";
    int n = strlen(str);
    printf("n = %d\n", n);

    return 0;
}

运行结果:

n = 7

strcpy

函数说明:

#include <string.h>
char *strcpy(char *dest, const char *src);
功能:把src所指向的字符串复制到dest所指向的空间中,'\0'也会拷贝过去
参数:
	dest:目的字符串首地址,如果参数dest所指的内存空间不够大,可能会造成缓冲溢出的错误情况
	src:源字符首地址
返回值:
	成功:返回dest字符串的首地址
	失败:NULL

示例代码:

#include <stdio.h>
#include <string.h>

int main() {
    char dest[20] = "123456789";
    char src[] = "hello world";
    strcpy(dest, src);
    printf("%s\n", dest);

    return 0;
}

运行结果:

hello world

strcat

函数说明:

#include <string.h>
char *strcat(char *dest, const char *src);
功能:将src字符串连接到dest的尾部,‘\0’也会追加过去
参数:
	dest:目的字符串首地址
	src:源字符首地址
返回值:
	成功:返回dest字符串的首地址
	失败:NULL

示例代码:

#include <stdio.h>
#include <string.h>

int main() {
    char str[20] = "123";
    char *src = "hello world";
    strcat(str, src);
    printf("%s\n", str);

    return 0;
}

运行结果:

123hello world

strcmp

函数说明:

#include <string.h>
int strcmp(const char *s1, const char *s2);
功能:比较 s1 和 s2 的大小,比较的是字符ASCII码大小。
参数:
	s1:字符串1首地址
	s2:字符串2首地址
返回值:
	相等:0
	大于:>0
	小于:<0

示例代码:
 

#include <stdio.h>
#include <string.h>

int main() {
    char *str1 = "hello world";
    char *str2 = "hello mike";

    if (strcmp(str1, str2) == 0) {
        printf("str1==str2\n");
    } else if (strcmp(str1, str2) > 0) {
        printf("str1>str2\n");
    } else {
        printf("str1<str2\n");
    }

    return 0;
}

运行结果:

str1>str2

字符串案例

  • 需求:自定义一个函数my_strlen(),实现的功能和strlen一样
  • 示例代码:
    #include <stdio.h>
    
    // 函数定义
    int my_strlen(char * temp) {
        // 定义一个累加个数的变量,初始值为0
        int i = 0;
        // 循环遍历每一个字符,如果是'\0'跳出循环
        while (temp[i] != '\0') {
            // 下标累加
            i++;
        }
    
        return i;
    }
    
    int main() {
        char *p = "hello";
        // 函数调用
        int n = my_strlen(p);
        printf("n = %d\n", n);
    
        return 0;
    }

  • 51
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值