字符串+sizeof/strlen+typedef+结构体对齐访问(全面解析)

字符串解析:
C语言中没有原生字符串类型,定义字符串时可以通过字符串指针来间接实现。char *p=“linux”,此时p就代表一个字符串。
字符串在内存中是多个字节连续分布的。
在C语言中用一个指针指向字符串头;以’\0’结尾;中间的有效字符连续连接。
存储多个字符的两种方式:字符串和字符数组
字符数组自身有内存可以出字符,字符串一定需要额外的内存来存字符,字符串本身只存真正的那些字符所在内存空间的首地址。
sizeof/strlen解析:
sizeof是一个运算符(关键字),无原型;
strlen的原型:size_t strlen(const char *s);
sizeof(类型或变量名),用来返回一个类型或变量所占内存的字节数。
strlen(一个字符串的指针),用来返回字符串的长度(用字节表示,不包括’\0’)。
char *p=“linux”; sizeof( p )=4; strlen( p )=5;
typedef:
举例说明:

typedef struct teacher
{
	char name[10];
	int age;
}T1;

代码释义:将类型strutc teacher重命名为T1,T1是一个类型名不是变量。

struct teacher
{
	char name[10];
	int age;
}T1;

代码释义:T1是一个变量,类型为strutc teacher。
结构体的对齐访问:

struct teacher
{
	char name[10];
	int age;
	int *p;
}T1,*T2;

C语言中用结构体变量来访问元素用.;T1.name=“he”
用结构体变量的指针来访问元素有->; T2->p
用指针访问结构体变量代码说明:

#include <stdio.h>
struct s
{
	char c;			// 1  c实际占4字节,而不是1字节
	int b;			// 4
};
int main(void)
{
	printf("sizeof(struct s) = %d.\n", sizeof(struct s));	//  5 or 8? 结果是8
	struct s s1;
	s1.c = 't';
	s1.b = 12;
	//用指针访问结构体变量
	char *p1 = (char *)(&s1);
	printf("*p1 = %c.\n", *p1);			// t
	int *p2 = (int *)((int)&s1 + 1);		
	printf("*p2 = %d.\n", *p2);			// 201852036(为一个随机的数).
	int *p3 = (int *)((int)&s1 + 4);	//因为对齐访问的原因	
	printf("*p3 = %d.\n", *p3);			// 12.
	return 0;
}

在32位编译器中,默认字节对齐方式是4字节对齐
可以用一下几种方式来自定义对齐方式:
1、#pragma pack(n)与#pragma pack()搭配使用,在两者包含区域是以n字节对齐。
2、__ attribute__((packed)),放在要进行内存对齐的类型定义后面,取消对齐访问(也就是恢复编译器默认的对齐访问)。
3、__ attribute__((aligned(n))),放在要进行内存对齐的类型定义后面,让整个结构体变量整体(不是结构体里面的元素)进行n字节对齐。
利用代码说明:

#include <stdio.h>

//#pragma pack(128)

struct mystruct1
{					// 1字节对齐	4字节对齐
    int a;			// 4			4
    char b;			// 1			2(1+1)
    short c;		// 2			2
};

struct mystruct11
{					// 1字节对齐	4字节对齐
    int a;			// 4			4
    char b;			// 1			2(1+1)
    short c;		// 2			2
}__attribute__((packed)); //加上__attribute__((packed))表示取消了结构体中
                           //元素的对齐(就是按照编译器默认对的对齐方式来访问)

typedef struct mystruct111
{					// 1字节对齐	4字节对齐		2字节对齐
    int a;			// 4			4				4
    char b;			// 1			2(1+1)			2
    short c;		// 2			2				2
	short d;		// 2			4(2+2)			2
}__attribute__((aligned(1024))) My111;  //它的作用是让strutc mystrutc111整个结构体变量进行n字节的对齐

typedef struct mystruct2
{					// 1字节对齐	4字节对齐
    char a;			// 1			4(1+3)
    int b;			// 4			4
    short c;		// 2			4(2+2)
}MyS2;

struct mystruct21
{					// 1字节对齐	4字节对齐
    char a;			// 1			4(1+3)
    int b;			// 4			4
    short c;		// 2			4(2+2)
} __attribute__((packed));


typedef struct myStruct5
{							// 1字节对齐	4字节对齐
    int a;					// 4			4
    struct mystruct1 s1;	// 7			8
    double b;				// 8			8
    int c;					// 4			4	
}MyS5;

struct stu
{							// 1字节对齐	4字节对齐
	char sex;				// 1			4(1+3)
	int length;				// 4			4
	char name[10];			// 10			12(10+2)
};

//#pragma pack() (在#pragma pack(n)与#pragma pack()之间的数据都是以n字节对齐)

int main(void)
{
	printf("sizeof(struct mystruct1) = %d.\n", sizeof(struct mystruct1)); //8
	printf("sizeof(struct mystruct2) = %d.\n", sizeof(struct mystruct2)); //12
	printf("sizeof(struct mystruct5) = %d.\n", sizeof(MyS5)); //24
	printf("sizeof(struct stu) = %d.\n", sizeof(struct stu)); //20
	printf("sizeof(struct mystruct11) = %d.\n", sizeof(struct mystruct11)); //7
	printf("sizeof(struct mystruct21) = %d.\n", sizeof(struct mystruct21)); //12
	printf("sizeof(struct mystruct111) = %d.\n", sizeof(My111)); //1024
	return 0
发布了19 篇原创文章 · 获赞 11 · 访问量 3396

猜你喜欢

转载自blog.csdn.net/m0_46204326/article/details/104270799