c程序语言数组教学(c-柔性数组学习)
c程序语言数组教学(c-柔性数组学习)来看例子 int main() { /** * 柔性数组可以理解为非定长数组,实际的长度是动态的 * 1、必须要声明在结构体的结尾 * 2、不占用内存 * 3、使用内存缓冲区 * 4、自动扩容 */ struct User { int age; int stuID; char address[]; // 结构体结尾 }; // 8 两个int 4 4 // char address[] 不占内存 printf("size of user %lu \n" sizeof(struct User)); struct User jack; // address赋值 jack.addre
在学习PHP的字符串时,我们知道存储在zend_string中,来看一下
struct _zend_string {
zend_refcounted_h gc;
zend_ulong h; /* hash value */
size_t len;
char val[1];
};
这里 char val[1] 只占一个字节内存,我们可能会感到奇怪,长度为1的数组如何存的下大于1长度的字符串呢,其实这里利用了C的柔性数组。
柔性数组可以认为是边长数组,只能出现在结构体的最后一个成员位置,它可以自动扩容。
上面是柔性数组的一种形式,柔性数组还有一种形式 char val[] 这是由于遵循的标准不一样。
来看例子
int main()
{
/**
* 柔性数组可以理解为非定长数组,实际的长度是动态的
* 1、必须要声明在结构体的结尾
* 2、不占用内存
* 3、使用内存缓冲区
* 4、自动扩容
*/
struct User
{
int age;
int stuID;
char address[]; // 结构体结尾
};
// 8 两个int 4 4
// char address[] 不占内存
printf("size of user %lu \n" sizeof(struct User));
struct User jack;
// address赋值
jack.address[0] = 'b';
jack.address[1] = 'e';
jack.address[2] = 'i';
jack.address[3] = 'j';
jack.address[4] = 'i';
jack.address[5] = 'n';
jack.address[6] = 'g';
jack.stuID = 1;
// 8 说明 address并没有占用内存
printf("size of jack %lu \n" sizeof(jack));
// beijing
printf("address is %s \n" jack.address);
printf("*************下面使用指针来************ \n");
struct Stu
{
int age;
int stdID;
char *address;
};
// 16 int int char的指针 4 4 8
// 明显指针是占用内存的
printf("size of std %lu \n" sizeof(struct Stu));
char myAddress[7];
myAddress[0] = 't';
myAddress[1] = 'i';
myAddress[2] = 'a';
myAddress[3] = 'n';
myAddress[4] = 'j';
myAddress[5] = 'i';
myAddress[6] = 'n';
struct Stu rose;
rose.address = myAddress;
rose.stdID = 2;
printf("size of rose %lu \n" sizeof(rose));
printf("address is %p \n" rose.address);
printf("address[0] is %c \n" *(rose.address));
printf("address[1] is %c \n" *(rose.address 1));
printf("*************柔性数组的第二种方式************ \n");
struct zend_string
{
int refcount;
int len;
char val[1];
};
// 12 字节 int int char内存对齐 4*3
printf("size of zend_string %lu \n" sizeof(struct zend_string));
struct zend_string str1;
str1.len = 5;
str1.val[0] = 'h';
str1.val[1] = 'e';
str1.val[2] = 'l';
str1.val[3] = 'l';
str1.val[4] = 'o';
// 12 val赋值之后仍然内存空间没有变化
printf("size of zend_string %lu \n" sizeof(str1));
// hello
printf("size of zend_string.val %s \n" str1.val);
/**
* struct _zend_string {
* zend_refcounted_h gc;
* zend_ulong h;
* size_t len;
* char val[1];
* };
*
*
*
*
*
*/
/**
* val[] 与 val[1] 两种实现方式不太一样,因为标准不一样
* c99 标准中允许 char val[] 这种定义作为柔性(不定长)数组出现,他不占用内存空间
* c99之前只支持 char val[1]这种格式,占用1个字节
*/
return 0;
}
总结:
柔性数组可以理解为非定长数组,实际的长度是动态的
- 必须要声明在结构体的结尾
- 不占用内存
- 使用内存缓冲区
- 自动扩容