嵌入式c学习六

**c语言的数组:**用户向内核申请一块连续的空间来存储数据,存储数据的类型需要一致,避免二义性Array

**数组的定义:**数据类型 数组名称 [数据个数],内存大小为:数据类型*数据个数------如:int a[3];

**[数据个数]:**是一个表达式,用于制定数组的大小,如果表达式是一个常量,应该是大于0的一个整数

**数组的访问:**访问数组中的元素可以采用E1[E2]结构------>E1是数组对象,E2是一个整数,作为数组的下标,且数组下标从0开始;数组的名称是指向数组对象的指针->数组名表示数组首元素地址

E1[E2] = *(E1+E2)---------> a[3] = *(a+3)---------》E1是数组名,E2是整型常量

***运算符:**①作为二元运算符,表示乘法,需要两个操作对象,遵循左结合性;

②作为一元运算符其操作对象对应的类型应该为地址,遵循右结合性,*操作数 == *地址==可以得到地址下的数据

&取地址运算符: 向右结合性,&操作数 可以得到操作数的地址

*(E1+E2): E1是一个数组对象,即数组名称,c语言规定数组名可以表示数组中第一个元素的地址,就相当于E1数组中第一个元素的地址,E2是一个整数,加上E2表示从E1的地址向后偏移E2个元素(需要考虑元素类型),(E1+E2)还是地址,*(E1+E2)相当于间接访问该地址得到对应的值,即*(E1+E2)==E1[E2]------》E1[E2] == E2[E1],这两种方式都哦可以访问数组中的元素。

复制代码
#include <stdio.h>

int main()
{
    char buf[11];

    buf[0] = 'a';
    buf[1] = 'b';
    buf[2] = 'c';
    buf[3] = 'd';

    4[buf] = 'e';     //E1[E2],E1是数组名,E2是整型常量,E1[E2]------》*(E1+E2)------》E2[E1]
    5[buf] = 'f';
    6[buf] = 'g';
    7[buf] = 'h';
    7[buf] = '\0';

    printf("%s\n", buf);


    return 0; 
}

**&运算符:**①二元运算符------表示按位与

②一元运算符:&操作数,可以得到操作数的地址,遵循右结合性

*&E == E------》&E结合得到E的地址,*(&E)得到地址下的值,变量名E本身就表示地址下的值

复制代码
#include <stdio.h>

int main()
{
    int data;

    data = 10;    //对变量赋值
    printf("data=%d\n", data);

    *&data = 20;   //同样可以赋值
    printf("data=%d\n", data);


    return 0; 
    
}

**数组名的含义:**c标准中说明数组名可以表示数组首元素地址,有两种例外情况,如a是一个数组

**&a:**此时a表示数组本身,&a表示整个数组的地址

复制代码
#include <stdio.h>

int main()
{
    int a[5];

    printf("%p->%p\n", a, &a[0]);    //此时a表示首元素地址

    printf("%p->%p\n", a+1, &a[1]);  // a+1表示数组第二个元素的地址

    printf("%p->%p\n", &a, &a+1);    //&a表示整个数组的地址其值与数组首元素地址相同,&a+1表示以数组本身为单位向后偏移一个数组的大小即4*5=20字节

    return 0; 

}

0x44-0x30 = = 0x14 == 20(字节)

sizeof(a): 当数组名与sizeof()运算符单独运算时,表示数组本身

复制代码
#include <stdio.h>

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

    printf("%d\n", sizeof(a));    //20------>数组a与sizeof()运算符单独使用,a表示数组本身大小为 20字节 

    printf("%d\n", sizeof(a+0));  //8------>未单独使用,a表示首元素地址,a+0为地址偏移量为0,64bit系统中地址为8字节

    printf("%d\n", sizeof(*a));   //4------>a表示首元素地址,*表示取地址里面的数据,整型未4字节

    printf("%d\n", sizeof(a[1])); //4------>a[1]数组第二个元素的值,数据大小4字节

    printf("%d\n", sizeof(&a));   //8------>&a表示数组本身地址-》8字节

    printf("%d\n", sizeof(&a+1)); //8------>地址偏移一个数组单位的字节

    printf("%d\n", sizeof(&a[0]));//8->首元素地址

    printf("%d\n", sizeof(&a[0]+1));//8->首元素地址,偏移单位未数组中的元素类型


    
    char a[5] = {'a', 'b','c','d','e'};

    printf("%d\n", sizeof(a));    //5------>数组a与sizeof()运算符单独使用,a表示数组本身大小为 20字节 

    printf("%d\n", sizeof(a+0));  //8------>未单独使用,a表示首元素地址,a+0为地址偏移量为0,64bit系统中地址为8字节

    printf("%d\n", sizeof(*a));   //1------>a表示首元素地址,*表示取地址里面的数据,整型未4字节

    printf("%d\n", sizeof(a[1])); //1------>a[1]数组第二个元素的值,数据大小4字节

    printf("%d\n", sizeof(&a));   //8------>&a表示数组本身地址-》8字节

    printf("%d\n", sizeof(&a+1)); //8------>地址偏移一个数组单位的字节

    printf("%d\n", sizeof(&a[0]+1));//8->首元素地址,偏移单位未数组中的元素类型
    
    
    return 0; 

}

**数组的初始化:**c语言规定只有在定义数组的同时进行赋值才叫数组初始化,

**格式:**数据类型 数组名[数组容量] = {0}; 如 int a[5] = {0,0,0,0,0};

复制代码
int main()
{
    int a[5] = {1};  // 将数组第一个元素初始化未1,其余元素操作系统默认赋值为0

    a[4] = 10;  //此处是对数组元素进行赋值不叫初始化
    for(int i =0; i<5; i++){
        printf("a[%d]=%d\n", i, a[i]);
    }
  
    
    return 0; 

}

**[数组容量]:**用户在定义时数据此处可以空着不写,一般需要在定义的同时进行初始化,操作系统会直接以用户初始化数据的个数申请内存空间

复制代码
#include <stdio.h>

int main()
{
    int a[] = {1,2,3,4,5,6};  // 将数组初始化未,操作系统将申请6个整型数据的内存

    printf("%d\n", sizeof(a)/sizeof(a[0]));
    
    return 0; 

}

数组元素的清空 :bzero()函数与memset()函数

**bzero():**需要包含头文件<strings.h>,void bzero(void *s, size_t n),将参数s指向的地址区域的前n个字节清0(存的是'\0'的ASCII码),无返回值

**memset():**void *memset(void *s, int c, size_t n),将参数s所指向区域的地址的前n个字节填充为c,返回值为s指向的内存地址

复制代码
#include <stdio.h>
#include <strings.h>
#include <string.h>

int main()
{
	int buf[5] = {1,2,3,4,5};
	
	printf("修改前\n");
	for(int i=0; i<5; i++){
		printf("buf[%d]=%d	", i, buf[i]);
		if(i == 4){
			printf("\n");
		}
	}
	
	memset(buf,0,4);     //将数组中前4个字节设置为0,即数组中第一个元素设置为0 

	printf("修改后\n");
	for(int i=0; i<5; i++){
		printf("buf[%d]=%d	", i, buf[i]);
	}
	printf("\n");
		
	
	
	return 0;
}

数组越界访问,可能会出现段错误------>访问没有权限访问的空间

字符型数组: 字符串末尾需要以'\0'结尾,如char a[5] = "abcde" ------>此处系统为默认在结尾加'\0',已经出现越界访问,因此数组中有效字符串常量,应该小于数组容量

复制代码
#include <stdio.h>

int main()
{
	char a[]="adcd";
	
	//32bit系统寻址能力为4个字节 
	printf("sizeof(a) = %d\n", sizeof(a));	           //5-> a表示整个数组,字符串末尾有\0
	
	printf("sizeof(a+0) = %d\n", sizeof(a+0));         //4-> a表示首元素地址->+0表示偏移0个字符型元素 
	
	printf("sizeof(*a) = %d\n", sizeof(*a));    	   //1-> *a等价与a[0] 
	
	printf("sizeof(a[1]) = %d	*(a+1) = %d\n", 
	        sizeof(a[1]),       sizeof(*(a+1)));	   //1->*(a+1) == a[1]
	        
	printf("sizeof(&a) = %d\n", sizeof(&a));   		   //4-> a表示数组本身,&a表示数组的地址
	 
	printf("sizeof(&a+1) = %d\n", sizeof(&a+1));       //4-> &a+1表示地址向后偏移一个数组的大小 
	
	printf("sizeof(&a[0]+1) = %d\n", sizeof(&a[0]+1)); //4-> &a[0]表示首元素地址,&a[0]+1,地址偏移一个元素(字符型)单位 
	
	printf("sizeof(&a[0]+1) = %d\n", sizeof(&a[0]+1));
	
	return 0;
}

**数组型数组:**多维数组,维度是针对用户而言,内存是线性的不分行和列。

**定义规则:**数组名[元素数量] + 元素类型 如:int a[5]

**二维数组定义规则:**元素类型 数组名称[元素数量] [元素数量] 如:int a[3][2]

可通过下标访问:a[1][2] == *(a+1)[2] == *(*(a+1) +2)

复制代码
#include <stdio.h>

int main()
{
	int a[2][3]={{1,2,3},{4,5,6}};
	
	printf("a[1][2]=%d\n", a[1][2]);    
	
	printf("*(*(a+1)+2)=%d\n", *(*(a+1)+2));    //E1[E2] == *((E1) + (E2))
	
	
	return 0;
}
复制代码
#include <stdio.h>

int main()
{
	int a[3][4] = {0};   //将第一个元素初始化为0,其他元素系统默认置0 
	
	//数组a:        a[0]            a[1]            a[2]
	//         0   0   0   0___0   0   0   0___0   0   0   0  
	//         a[0][0]         a[1][0]         a[2][0]
	       
	printf("sizeof(a)=%d\n", sizeof(a));                 //48:a表示整个数组
	
	printf("sizeof(a[0][0])=%d\n", sizeof(a[0][0]));     //4 :表示第一个元素的值
	 
	printf("sizeof(a[0])=%d\n", sizeof(a[0]));           //16:a[0]表示匿名数组 int [4]
	 
	printf("sizeof(a[0]+1)=%d\n", sizeof(a[0]+1));       //4 :a[0]表示匿名数组int [4]的首元素地址 
	
	printf("sizeof(*(a[0]+1))=%d\n", sizeof(*(a[0]+1))); //4 :*(a[0]+1) == a[0][1] 
	
	printf("sizeof(a+1)=%d\n", sizeof(a+1));             //4 :a表示首元素地址a[0]的地址,a[0]是个数组 
	
	printf("sizeof(*(a+1))=%d\n", sizeof(*(a+1)));       //16:*(a+1) == a[1]
	
	printf("sizeof(&a[0]+1)=%d\n", sizeof(&a[0]+1));     //4 :&a[0]表示a[0]数组的地址+1=&a[1] 
	printf("&a[0]+1=%p	&a[1]=%p\n",&a[0]+1, &a[1]);
	
	printf("sizeof(&a[0]+1)=%d\n", sizeof(*(&a[0]+1)));  //16: *&a[1] == a[1] *与&互相抵消 
	
	printf("sizeof(*a)=%d\n", sizeof(*a));               //16: a表示首元素地址即&a[0], *&a[0]==a[0]
														 //16: *a = *(a+0) = a[0]  
														 
	printf("sizeof(a[3])=%d\n", sizeof(a[3]));           //16:a[3]已经越界,可以保存地址,但不能访问内存 
	
	return 0;
}

**柔性数组:**数组元素的数量用变量来表示,注意数组内存一旦确定就不会因为变量发生变化导致数组长度变化

复制代码
#include <stdio.h>

int main()
{
	int cnt =5;
	
	int a[cnt];
	printf("%d\n", sizeof(a)); 
	
	cnt = 0;
	printf("%d\n", sizeof(a)); 
	
	return 0;
}

**匿名数组:**一般在多为数组中使用。如:int a[3][4]--->数组a[3]中每个元素为int [4],是匿名数组

相关推荐
kaikai_sk9 分钟前
Docker和Dify学习笔记
笔记·学习·docker
阑梦清川15 分钟前
蓝桥杯关于栈这个数据结构的一个算法题目
数据结构·算法·蓝桥杯
面包圈蘸可乐1 小时前
DNA语言模型GROVER学习人类基因组中的序列上下文
人工智能·学习·语言模型
happy_lhz1 小时前
让“树和二叉树”埋在记忆土壤中--性质和概念
数据结构
努力努力再努力wz2 小时前
【Linux内核系列】:动静态库详解
linux·运维·服务器·c语言·开发语言
ん贤2 小时前
单调队列【C/C++】
开发语言·数据结构·c++·算法·单调队列
云上艺旅2 小时前
K8S学习之基础三十六:node-exporter部署
学习·云原生·贪心算法·kubernetes·prometheus
不灭锦鲤2 小时前
c语言 逆序存放并输出的题【基础】
c语言·数据结构·算法
辰辰大美女呀3 小时前
【Zephyr】【二】学习笔记【RTOS系统架构】
笔记·学习·系统架构
ClaNNEd@3 小时前
大话数据结构第一章,数据结构绪论笔记
数据结构·算法·大话数据结构