C基础
结构体
定义
- 结构体类型声明 注意最后一定要加分号
- 如果结构体变量已经定义,可以对每个成员单独赋值,如
s.num = 1003;
struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}; // 结构体类型声明 注意最后一定要加分号
赋值
struct student s = {1, "小红", 'F', 19, 99.0, "BEIJING"};
输出
- 结构体输出不能直接输出需要每一个字段单独输出
printf("%d %s %c %d %f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);
结构体数组
struct student sarr[3]; // 定义一个结构体数组
for (int i = 0; i < 3; i++)
{
scanf("%d %s %c %d %f %s", &sarr[i].num, sarr[i].name, &sarr[i].sex, &sarr[i].age, &sarr[i].score, sarr[i].addr);
}
for (int i = 0; i < 3; i++)
{
printf("%d %s %c %d %f %s\n", sarr[i].num, sarr[i].name, sarr[i].sex, sarr[i].age, sarr[i].score, sarr[i].addr);
}
完整代码:
#include <stdio.h>
struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}; // 结构体类型声明 注意最后一定要加分号
int main()
{
struct student s = {1, "小红", 'F', 19, 99.0, "BEIJING"};
printf("%d %s %c %d %f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);
printf("------------------------------------------------------------------\n");
int num_of_values_read = scanf("%d %s %c %d %f %s", &s.num, s.name, &s.sex, &s.age, &s.score, s.addr);
printf("num_of_values_read:%d\n", num_of_values_read);
if (num_of_values_read == 6) printf("Input successful!\n");
else printf("Input error! Please enter valid data.\n");
printf("%d %s %c %d %f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);
struct student sarr[3]; // 定义一个结构体数组
for (int i = 0; i < 3; i++)
{
scanf("%d %s %c %d %f %s", &sarr[i].num, sarr[i].name, &sarr[i].sex, &sarr[i].age, &sarr[i].score, sarr[i].addr);
}
for (int i = 0; i < 3; i++)
{
printf("%d %s %c %d %f %s\n", sarr[i].num, sarr[i].name, sarr[i].sex, sarr[i].age, sarr[i].score, sarr[i].addr);
}
}
结构体对齐
- 结构体的大小必须是其最大成员的整数倍
- 结构体对齐是为了CPU能够更高效的去取数据
struct MyStruct1
{
int a;
char b;
short c;
};
char
和short
加起来占用3个字节,不够4个,所以char
和short
一起占用四个字节,这个结构体一共占用8个字节
struct MyStruct2
{
int a; // 4
char c[20]; // 20
char b; // 4
};
- 上面结构体一共占用28个字节
结构体指针
一个结构体变量的指针就是该变量所占据的内存段的起始地址。
- 指针访问结构体变量用的是
->
(推荐),也可以使用(*p).属性
的方式,但不推荐
struct MyStruct1
{
int a;
char b;
short c;
};
struct MyStruct1* p;
printf("p:%zu\n", sizeof(p)); // 所有指针大小都是4个字节(32位操作系统)
p = &s1;
printf("%d %c %hd\n", s1.a, s1.b, s1.c);
printf("%d %c %hd\n", (*p).a, (*p).b, (*p).c); // 第一种访问方式
printf("%d %c %hd\n", p->a, p->b, p->c); // 第二种访问方式
结构体指针数组
struct MyStruct1 sarr[3] = {1, 'a', 1, 2, 'b', 2 , 3, 'c', 3 };
p = sarr;
printf("%d %c %hd\n", p->a, p->b, p->c);
printf("%d %c %hd\n", sarr[0].a, sarr->b, sarr->c);
p = sarr;
相当于将sarr的首地址赋值给p,所以打印结果是:1 a 1
- 上面两句打印结果相同
typedef - 作用:起别名
typedef struct MyStruct2
{
int a;
char c[20];
char b;
}stu, *pstu;
上面代码相当于typedef struct MyStruct2 stu; typedef struct MyStruct2* pstu;
初级
%p、size_t、%zd、%llu、sizeof
%p
用于输出地址,HWND
类型的也可以使用%p
输出size_t
:C语言源代码:typedef unsigned __int64 size_t;
- sizeof 返回值是
size_t
类型,打印的时候不能使用%d
,应该使用%zu
修改窗口标题
#include <stdio.h>
#include <Windows.h>
#include <locale.h>
int main()
{
HWND hWnd = FindWindowA(NULL, "微信"); // 获取窗口句柄
if (NULL == hWnd)
{
printf("错误代码:%d", GetLastError());
return 0;
}
printf("窗口句柄:0x%p\n", hWnd);
printf("初始化本地环境:%s\n", setlocale(NULL, ""));
WCHAR lpString[255];
printf("请输入需要设置的窗口标题:");
wscanf_s(L"%254ls", lpString, (unsigned)_countof(lpString));
wprintf(L"新窗口标题:%ls\n", lpString);
if (SetWindowText(hWnd, lpString))
{
printf("修改成功!\n");
}
}
FindWindowA
函数用于获取窗口句柄,还可以使用FindWindow和FindWindowW,FindWindow
与FindWindowW
是一样的,需要传入宽字符。SetWindowText
函数一共两个参数,第一个参数是窗口句柄,第二个参数是需要设置的新的窗口名字,是宽字符。
在C++中使用宽字符
printf("初始化本地环境:%s\n", setlocale(NULL, ""));
WCHAR lpString[255];
printf("请输入需要设置的窗口标题:");
wscanf_s(L"%254ls", lpString, (unsigned)_countof(lpString));
wprintf(L"新窗口标题:%ls\n", lpString);
使用宽字符需要先初始化本地环境使用setlocale
函数,包含在locale.h
头文件中,然后需要使用wscanf_s
函数来接收输入字符串,使用wprintf
函数进行打印。
获取进程PID
#include <Windows.h>
#include <stdio.h>
/*
获取进程PID TID
GetWindowThreadProcessId
hWnd 窗口句柄
lpdwProcessId 一个DWORD类型的指针
*/
int main()
{
HWND hWnd = FindWindowA(NULL, "微信");
if (NULL == hWnd)
{
return 0;
}
printf("获取到的窗口句柄:0x%p\n", hWnd);
DWORD dwProcessId;
// GetWindowThreadProcessId((HWND)0x3F05E2, &dwProcessId); // 这样直接写窗口句柄也是可以的 不过需要强制类型转换
GetWindowThreadProcessId(hWnd, &dwProcessId);
printf("获取到的进程PID:0x%lX", dwProcessId);
}