结构体
数组是用于保存一组相同类型数据的, 而结构体是用于保存一组不同类型数组的
在使用结构体之前必须先定义结构体类型, 因为C语言不知道你的结构体中需要存储哪些类型数据, 我们必须通过定义结构体类型来告诉C语言, 我们的结构体中需要存储哪些类型的数据
struct 结构体名{
类型名1 成员名1;
类型名2 成员名2;
……
类型名n 成员名n;
};
结构体变量占用存储空间大小
结构体的总大小为结构体最宽基本类型元素大小的整数倍
struct Person{
int age;
char ch;
double score;
};
struct Person p;
printf("sizeof = %i\n", sizeof(p));
占用内存最大属性是score, 占8个字节, 所以第一次会分配8个字节
将第一次分配的8个字节分配给age4个,分配给ch1个, 还剩下3个字节
当需要分配给score时, 发现只剩下3个字节, 所以会再次开辟8个字节存储空间
一共开辟了两次8个字节空间, 所以最终p占用16个字节
struct Person{
int age;
double score;
char ch;
};
struct Person p;
printf("sizeof = %i\n", sizeof(p));
占用内存最大属性是score, 占8个字节, 所以第一次会分配8个字节
将第一次分配的8个字节分配给age4个,还剩下4个字节
当需要分配给score时, 发现只剩下4个字节, 所以会再次开辟8个字节存储空间
将新分配的8个字节分配给score, 还剩下0个字节
当需要分配给ch时, 发现上一次分配的已经没有了, 所以会再次开辟8个字节存储空间
一共开辟了3次8个字节空间, 所以最终p占用24个字节
结构体变量的定义
定义结构体变量:struct 结构体名 结构体变量名;
先定义结构体类型,再定义变量:
struct Student {
char *name;
int age;
};
struct Student stu;
定义结构体类型的同时定义变量
struct Student {
char *name;
int age;
} stu;
匿名结构体定义结构体变量
struct {
char *name;
int age;
} stu;
第三种方法与第二种方法的区别在于,第三种方法中省去了结构体类型名称,而直接给出结构变量,
这种结构体最大的问题是结构体类型不能复用。
结构体变量的初始化
定义的同时按顺序初始化
struct Student {
char *name;
int age;
};
struct Student stu = {“cxx", 22};
定义的同时不按顺序初始化
struct Student{
char *name;
int age;
};
struct Student stu = {.age = 22, .name = "cxx" };
先定义后逐个初始化
struct Student{
char *name;
int age;
};
struct Student stu;
stu.age = 22;
stu.name = "cxx" ;
先定义后一次性初始化
struct Student {
char *name;
int age;
};
struct Student stu;
stu2 = (struct Student){"cxx", 22};
结构体指针
一个指针变量当用来指向一个结构体变量时,称之为结构体指针变量
格式:== struct 结构名 *结构指针变量名==
int main(void)
{
struct Student {
char *name;
int age;
};
struct Student stu = {“lnj", 18};
struct Student *p;
p = &stu;
printf("name=%s, age = %d \n", stu.name, stu.age);
printf("name=%s, age = %d \n", (*p).name, (*p).age);
printf("name=%s, age = %d \n", p->name, p->age);
return 0;
}
结构体指针成员访问
通过结构体指针访问结构体成员, 可以通过以下两种方式:
(*结构指针变量).成员名
== 结构指针变量->成员名==
字符串定义、初始化:
char string[]="cxx";
printf("%s\n",string);
char *str = "abc"
for(int i = 0; i < strlen(str);i++){
printf("%c-", *(str+i));
}
char name[9] = "cxx";
char name1[9] = {'c,'x','x','\0'};
char name2[9] = {'c','x','x',0};
char name3[9] = {'c','x','x'};
字符串输出:
如果字符数组中存储的是一个字符串, 那么字符数组的输入输出将变得简单方便。
不必使用循环语句逐个地输入输出每个字符
可以使用printf函数和scanf函数一次性输出输入一个字符数组中的字符串
使用的格式字符串为“%s”,表示输入、输出的是一个字符串
输出%s的本质就是根据传入的name的地址逐个去取数组中的元素然后输出,直到遇到 ‘\0’ 位置结束
char name[]="chenc\0hen";
printf("%s\n",name);
char name[10];
scanf("%s",name);
字符串长度计算:
sizeof关键字:
因为字符串在内存中是逐个字符存储的,一个字符占用一个字节,所以字符串的结束符长度也是占用的内存单元的字节数。
char name[] = "it666";
int size = sizeof(name);
printf("size = %d\n", size);
strlen函数:
测字符串的实际长度(不含字符串结束标志‘\0’)并作为函数返回值。
char name[] = "it666";
size_t len = strlen(name2);
printf("len = %lu\n", len);
以“\0”为字符串结束条件进行统计
int myStrlen2(char str[])
{
int length = 0;
while (str[length] != '\0')
{
length++;
}
return length;
}
int myStrlen(char str[], int count)
{
int length = 0;
for (int i = 0; i < count; i++) {
if (str[i] == '\0') {
return length;
}
length++;
}
return length;
}
字符串连接函数:strcat
格式: strcat(字符数组名1,字符数组名2)
功能:把字符数组2中的字符串连接到字符数组1 中字符串的后面,并删去字符串1后的串标志 “\0”。本函数返回值是字符数组1的首地址。
char oldStr[100] = "welcome to";
char newStr[20] = " cxx";
strcat(oldStr, newStr);
puts(oldStr);
本程序把初始化赋值的字符数组与动态赋值的字符串连接起来。
要注意的是,字符数组1应定义足 够的长度,否则不能全部装入被连接的字符串。
字符串拷贝函数:strcpy
格式: strcpy(字符数组名1,字符数组名2)
功能:把字符数组2中的字符串拷贝到字符数组1中。串结束标志“\0”也一同拷贝。字符数名2, 也可以是一个字符串常量。这时相当于把一个字符串赋予一个字符数组。
char oldStr[100] = "welcome to";
char newStr[50] = " cxx";
strcpy(oldStr, newStr);
puts(oldStr);
本函数要求字符数组1应有足够的长度,否则不能全部装入所拷贝的字符串。
字符串比较函数:strcmp
格式: strcmp(字符数组名1,字符数组名2)
功能:按照ASCII码顺序比较两个数组中的字符串,并由函数返回值返回比较结果。
字符串1=字符串2,返回值=0;
字符串1>字符串2,返回值>0;
字符串1<字符串2,返回值<0。
char oldStr[100] = "0";
char newStr[50] = "1";
printf("%d", strcmp(oldStr, newStr));
char oldStr[100] = "1";
char newStr[50] = "1";
printf("%d", strcmp(oldStr, newStr));
char oldStr[100] = "1";
char newStr[50] = "0";
printf("%d", strcmp(oldStr, newStr));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)