复杂结构与指针
一、字符串
定义字符数组:char str[size];
初始化字符数组:
char str[] = “hello world”; // sizeof(str)为12
char str[size] = {‘h’, ‘e’, ‘l’, ‘l’, ‘o’};
字符串数组的大小需要比字符串大小大1,因为最后以为需要存储字符‘\0’;
‘a’ —> 97, ‘A’ —> 65, ‘0’ —> 48, ‘\0’ —> 0
二、字符串相关操作
头文件:string.h
函数 | 说明 |
---|---|
strlen(str) | 计算字符串长度,以 \0 作为结束符 |
strcmp(str1, str2); | 字符串比较 |
strcpy(dest, src); | 字符串拷贝 |
strncmp(str1, str2, n); | 安全的字符串比较 |
strncpy(str1, str2, n); | 安全的字符串拷贝 |
memcpy(str1, str2, n); | 内存拷贝 |
memcmp(str1, str2, n); | 内存比较 |
memset(str1, c, n); | 内存设置 |
strcmp 的返回值:当 str1 = str2 时,返回值为0;str1 > str2,返回值为出现不同位置的字符的ASCII码的差值。
strncpy中的n代表最多拷贝n个字符,防止引发相关不安全的问题。
memset 是将 str1 的每一位设置为 c,最多设置 n 字节。
头文件:stdio.h
函数 | 说明 |
---|---|
sscanf(str1, format, …) | 从字符串str1读入内容 |
sprintf(str1, format, …) | 将内容输出到str1中 |
这两个函数能解决字符串拼接的问题。
随堂练习-1
请使用字符串相关操作方法,计算一个整型16进制表示的位数。
#include <stdio.h> #include <string.h> int main() { char str[11]; int n; while (scanf("%d", &n) != EOF) { sprintf(str, "%X", n); printf("%d(%s) has %lu digits\n", n, str, strlen(str)); } return 0; }
三、结构体
struct person {
char name[20];
int age;
char gender;
float height;
};
结构体的本质是类型。
结构体的组成:关键字 struct, 结构体名 (可以没有名字,称为匿名结构体),及结构体相关字段。
访问方式:1. 通过.字段名 访问(直接引用)2. 通过 地址->字段名(间接引用)
结构体申请内存时默认采用类型最大的字段进行对齐。所以建议在定义将相同类型的字段放在一起去定义,这样可以节约一部分内存。
四、共用体
union register {
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes;
unsigned int number;
}
共用体结构反映了在结构内部各个字段是共用一片存储空间的。
访问方式与结构体的访问方式相似。
随堂练习
请使用共用体,实现 ip 转整数的功能。
#include <stdio.h> union IP { struct { unsigned char a1; unsigned char a2; unsigned char a3; unsigned char a4; } ip; unsigned int num; }; int main() { union IP p; char str[100] = {0}; int arr[4]; while (~scanf("%s", str)) { sscanf(str, "%d.%d.%d.%d", arr, arr + 1, arr + 2, arr + 3); p.ip.a1 = arr[3]; p.ip.a2 = arr[2]; p.ip.a3 = arr[1]; p.ip.a4 = arr[0]; printf("%u\n", p.num); } return 0; }
五、变量的地址
int a;
int *p = &a;
变量是用来存值的,不同类型的变量存不同的值,指针变量也是变量。
当前的变量p是一个int类型的指针变量,指向的是存储整型类型的变量的地址,* 是取值符,*p是取当前指针变量的值。
在64位操作系统中, 指针变量占8个字节,在32位操作系统中,指针变量占4个字节。
int **q = &p;
定义一个指针变量 q (表示为*q)指向的是存储类型为 int * 的指针的地址。
六、等价形式转换
*p <=> a (原始变量)
p + 1 <=> &p[1]
p->filed <=> (*p).filed <=> a.filed