c语言的学习日记--数组篇:

一、一维数组的实现 

1.一维数组的创建和初始化

数组的创建:常见数组时必须定义数组的类型和大小

int a[10]={1,2,3,4,5};        括号内必须是常量,

int a[ ]={1,2,3};  这种也是可以的 

int a[ ]=“fahuif”;

int a[ ]={‘a’,‘46’};

数组的大小不能超过定义数组的大小

char *p="abc"; //这里是把a的 地址放入p里

  在这里插入图片描述

2.一维数组的使用

#include<stdio.h>

int main()
{
	int arr[10] = { 0 };
	int i = 0;
	for (i = 0; i < sizof(arr); i++)//i<11是不可以的,不可以越界访问
	{
		arr[i] = i;
	}

	return 0; 
}

数组是使用下标来进行访问的,下标是从0开始的。

sizeof(arr);  计算数组的大小;

3.一维数组在内存中的储存

    for (int i = 0; i < 4; i++) //i<11是不可以的,不可以越界访问
    {
        printf("%p", &arr[i]);
        a = sizeof(arr[i]);
        printf("数组的大小是%d\n", a);
    }

可以看出数组内的数据在磁盘内是按照顺序连续储存的

4.指针的初步介绍

int *ptr = NULL;//定义一个整型的指针变量,初始化为NULL

char *ptr = NULL;//定义一个字符的指针变量,初始化为NULL

5.一维数组的指针访问

#include<stdio.h>

int main()
{
	int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	printf("%p\n", arr);
	printf("%d\n", *arr);

	return 0; 
}

#include <stdio.h>
int main()
{
    int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    printf("%p\n", arr);
    for (int i = 0; i < sizeof(arr); i++)
    {
        printf("%p\n", arr+i);
    }
 

    return 0;
}

 

6.二维数组的初始化和创建

#include<stdio.h>

int main()
{
	int arr[3][4] = { 1, 2, 3, 4, 5, 6 };
	//int arr[][4] = {{1, 2},{3, 4, 5},{6}};可以
	//arr[3][] = {{1, 2},{3, 4, 5},{6}};是不可以的

	return 0; 
}

数组定义时一定要定义列数,但是可以不用定义行数;

7.二维数组的使用

#include<stdio.h>
int main(){

    int arr[3][5]={0};
    int i=0;
    int j=0;
    for(i=0;i<3;i++){
        for(j=0;j<5;j++){
            arr[i][j]=i*5+j+1;

        }

    }
    for(i=0;i<3;i++){
        for(j=0;j<5;j++){
            printf("%d",arr[i][j]);
            printf(" ");

        }
        printf("\n");

    }

    return 0;
}

如何实现从键盘输入。

8.二维数组在内存中的存储

    for(i=0;i<3;i++){
        for(j=0;j<5;j++){
            printf("&arr[%d][%d]%p\n",i,j,&arr[i]);

        }
        printf("\n");
    }

二维数组的地址实际上是连续的。

9.二维数组的指针访问

#include <stdio.h>
int main()
{
    int arr[2][3] = {0};
    int *p = &arr[0][0];
    for (int i = 0; i < 6; i++)
    {
        *(p + i) = i + 1;
    }
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            printf("%d\n", arr[i][j]);
        }
    }

    return 0;
}

指针也存在类型:

#include<stdio.h>

int main()
{
	int num = 0x11223344;
	int *p = &num;
	*p = 0;

	return 0;
}

指针p为int类型、所以当我们对它进行改变时是改变了4个字节的,如果我们对p进行加1操作,则指针向后跳动四个字节。

#include<stdio.h>

int main()
{
	int num = 0x11223344;
	//int *p = &num;
	//*p = 0;
	char *pc = &num;
	*pc = 0;

	return 0;
}

这里写图片描述

我们可以从内存中观察到,只改变了1个字节的大小,因为pc指针的类型是char。如果我们对pc进行加1操作,指针向后跳1个字节。 

10.数组运算;

#include<stdio.h>

int main()
{
	//一维数组
	int a[] = { 1, 2, 3, 4 };
	printf("%d\n", sizeof(a));//16  
	//1.数组名单独放在sizeof内部,数组名表示整个数组,所以sizeof(数组名)计算的是是数组总大小,单位是字节
	//2.&数组名,数组名表示整个数组,所以&数组名取出的是整个数组的地址
	//3.除此之外,所有的数组名都表示首元素的地址
	printf("%d\n", sizeof(a + 0));//4    a代表首元素地址,a+i代表第i个元素的地址,在32位平台下所有的地址的大小都是4个字节
	printf("%d\n", sizeof(*a));//4       a是首元素地址,*a是首元素--1,int型占4个字节大小
	printf("%d\n", sizeof(a + 1));//4    a是首元素地址,a+1是第二个元素的地址,它还是一个地址
	printf("%d\n", sizeof(a[1]));//4     a[1]--第二个元素
	printf("%d\n", sizeof(&a));//4       &a虽然取出的是整个数组的地址,但它还是一个地址
	printf("%d\n", sizeof(*&a));//16     &a取出的是整个数组的地址,对它进行解引用,就是这个数组,这个数字的大小就是16
	printf("%d\n", sizeof(&a + 1));//4   &a取出的是整个数组的地址,加1跳过了整个数组(16个字节),但它还是一个地址
	printf("%d\n", sizeof(&a[0]));//4    &a[0]取的是第一个元素的地址
	printf("%d\n", sizeof(&a[0] + 1));//4   &a[0] + 1取的是第二个元素的地址

	return 0;
}

 

这里写图片描述

 

#include<stdio.h>

int main()
{
	//字符数组
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	printf("%d\n", sizeof(arr));//6
	printf("%d\n", sizeof(arr + 0));//4        首元素地址
	printf("%d\n", sizeof(*arr));//1           首元素地址解引用是首元素(a),char类型占1个字节
	printf("%d\n", sizeof(arr[1]));//1         首元素
	printf("%d\n", sizeof(&arr));//4           数组的地址
	printf("%d\n", sizeof(&arr + 1));//4       下一个数组的地址,跳过了f
	printf("%d\n", sizeof(&arr[0] + 1));//4    第二个元素的地址

    printf("%d\n", strlen(arr));//随机值       strlen()求的是字符串长度,以'\0'为结束标志,这里并没有'\0',所以会一直往后数
	printf("%d\n", strlen(arr + 0));//随机值   还是从'a'开始数,但没有'\0',所以停不下来
	printf("%d\n", strlen(*arr));//程序会崩掉  strlen()接收的是一个地址,*arr是字符'a',这里把'a'的ASCII码值(97)作为一个地址访问,这一块的地址是不能被访问的
	printf("%d\n", strlen(arr[1]));//错误      传的是'b',和传的是'a'效果一样
	printf("%d\n", strlen(&arr));//随机值      &arr虽然取的是数组的地址,但数组的地址和数组首元素的地址是一样的,也是从‘a'开始数,但并没有'\0'
	printf("%d\n", strlen(&arr + 1));//随机值  但这个随机值和前边的随机值意义不同,它是把'a','b','c','d','e','f'跳过去了,从f后边开始数
	printf("%d\n", strlen(&arr[0] +1));//随机值   这个是从'b'开始往后数的


	return 0;
}

这里写图片描述

 

#include<stdio.h>

int main()
{
    char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7   里边还有'\0',只不过我们看不到而已
	printf("%d\n", sizeof(arr + 0));//4     arr+0---首元素地址
	printf("%d\n", sizeof(*arr));//1   对首元素地址解引用是首元素
	printf("%d\n", sizeof(arr[1]));//1 第二个元素
	printf("%d\n", sizeof(&arr));//4    数组的地址也是地址
	printf("%d\n", sizeof(&arr + 1));//4  也是一个地址,不过这个地址在'\0'后边,跳过了整个数组
	printf("%d\n", sizeof(&arr[0] + 1));//4   从b开始的一个地址



	printf("%d\n", strlen(arr));//6   strlen()以'\0'为结束标志,但不算'\0'
	printf("%d\n", strlen(arr + 0));//6  arr+0与arr都代表首元素地址
	printf("%d\n", strlen(*arr));//错误   这传进来的不是一个地址,而是一个字符
	printf("%d\n", strlen(arr[1]));//错误
	printf("%d\n", strlen(&arr));//6    数组的地址也是首元素地址,地址的位置是一样的
	printf("%d\n", strlen(&arr + 1));//随机值   跳过了'\0',从'\0'往后数,不知道会数到哪里去
	printf("%d\n", strlen(&arr[0] + 1));//5    从第二个元素(b)开始往后数,遇到'\0'结束


	return 0;
}
————————————————
版权声明:本文为CSDN博主「人山人海肉最可爱」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huaijiu123/article/details/79897843

这里写图片描述

#include<stdio.h>

int main()
{
    char *p = "abcdef";
	printf("%d\n", sizeof(p));//4   p是指针变量,里边存的是a的地址
	printf("%d\n", sizeof(p + 1));//4   还是一个地址,不过是指向了b的地址
	printf("%d\n", sizeof(*p));//1      对a的地址解引用就是a
	printf("%d\n", sizeof(p[0]));//1    第一个元素(a)
	printf("%d\n", sizeof(&p));//4      &p取的是p的地址,p是一个指针,指向a的地址,但p的地址是什么并不知道
	printf("%d\n", sizeof(&p + 1));//4  &p+1--跳过了p的一个地址
	printf("%d\n", sizeof(&p[0] + 1));//4   还是一个地址,这个地址指向了b的地址


    printf("%d\n", strlen(p));//6        从a开始向后数
	printf("%d\n", strlen(p + 1));//5    从b开始向后数
	printf("%d\n", strlen(*p));//错误    *p就是a,strlen()要的是一个地址,而不是a的ASCII码值(97)
	printf("%d\n", strlen(p[0]));//错误
	printf("%d\n", strlen(&p));//随机值
	printf("%d\n", strlen(&p + 1));//随机值
	printf("%d\n", strlen(&p[0] + 1));//5    从b开始往后数

	return 0;
}

#include<stdio.h>

//二维数组
int main()
{    
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//48    整个数组有12个元素,每个元素都是int型
	printf("%d\n", sizeof(a[0][0]));//4   代表的是第一行第一列那个元素
	printf("%d\n", sizeof(a[0]));//16   a[0]--第一行数组名,第一行总共有4个元素
	printf("%d\n", sizeof(a[0] + 1));//4   a[0]降级变为a[0][0]的地址,a[0]+1是a[0][1]的地址
	printf("%d\n", sizeof(a + 1));//4    a--首元素(第一行)地址,a+1--第二行地址
	printf("%d\n", sizeof(&a[0] + 1));//4    第二行地址
	printf("%d\n", sizeof(*a));//16   对第一行地址解引用就是第一行元素
	printf("%d\n", sizeof(a[3]));//16    这里有好多人会出错,认为这个数组并没有这么大,只有3行,不能访问第4行,其实这里并没有访问第4行,它只是一个类型(1行的大小)
	return 0;
}

这里写图片描述

11.数组作为函数参数

void bubble(int arr[])
{
    int sz = sizeof(arr)/sizeof(arr[0]);//这是错误的
    ...
}

数组作为函数参数时,不会把整个数组传递过去,实际上只是把数组的首元素地址传递过去了。

 

 

 

 

数组//做仓库,先清空!!,就不理他。一般用来存放程序中自己产生的数据

数组的地址:&array

首元素的地址&array[0]    其他元素地址 &array[1] &array[2] &array[3]

#include<stdio.h>
int main(){

    int a[3];
    a[0]=1;
    printf("%p\t%p\t%p\n",&a,&a[0],a);
    
    printf("%d\n",*a);
    printf("%d\n",a[0]);



    return 0;
}

 可以看出数组地址和数组元素的首地址大小是一样的,存放的值也都是首元素的值,但
是概念不同

#include<stdio.h>
int main(){

    int a[3]={0};
    a[0]=1;
    a[1]=3;
    int *p=a;//定义指针p并指向数组a[]的地址
    printf("%p\t%p\t%p\n",&a,&a[0],a);//打印数组名地址、数组第一个元素地址、数组第一个元素地址
    
    printf("%d\n",*a);//输出数组名地址对应的值
    printf("%d\n",a[0]);//输出数组第一个元素值
    printf("%d\n",*(p+1));//输出指针往后移一个int长度位置地址所对应的值
    printf("%p\n",p+1);//输出指针往后移一个int长度位置地址



    return 0;
}s

可以看出指针p所指向的(里面的值)是地址,所以使用指针所指向参数的值需要用*才可以用 。

 从数组中间分别向右向左输出

#include <stdio.h> //数组先中先又后左运行
#include <stdlib.h>
#include <time.h>
int main()
{
    int b;
    scanf("%d", &b); //定义数组的个数
    int a[b];
    getchar();      //清除回车键缓存
    srand(time(0)); //播种子
    for (int i = 0; i < b; i++)//给数组a赋予随机值
    {
        a[i] = rand() % 10;
    }
    for (int i = 0; i < b; i++)//按顺序打印出数组中的元素
    {
        printf("%d", a[i]);
    }
    printf("\n");
//先从中间向右输出再向左输出
    for (int i = (b - 1) / 2; i >= 0; i--)
    {
        printf("%d", a[i]);
    }
    for (int i = (b - 1) / 2 + 1; i < b; i++)
    {
        printf("%d", a[i]);
    }

    return 0;
}

 

字符数组:

1.满足数组的基本特点

‘2.定义方式(初始化)

3.各个元素的逻辑处理

字符包括:数组字符、标点符号字符、转移字符 (一个字节)、中文编码字符,组成汉字

 

一次性输入输出整个字符串:

scanf("%s",数组名);

printf(“%s”,数组名);

计算字符串长度的函数:strlen () <string.h>

字符串中有一个很重要的元素:结束标识符(系统内部再用 )‘\0’

 

字符数组的初始化

1.char array[10] ={ 'a','d','g','f', };

2.char array[500]="afhaioai"//i后面默认为\0

3.char a[]="hellow";//编译器自动帮你计算长度。

4.char array[10]="\0";/char array[10]={0};//定义了一个空数组

3.如果字符串不是自己初始化,也不是自己输入,不需要预留空位置存放‘\0’

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值