C进阶-遗忘知识点
Posted 程序彤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C进阶-遗忘知识点相关的知识,希望对你有一定的参考价值。
sizeof(arr),数组名表示整个数组
&arr,数组名表示整个数组
sizeof(&arr),取出整个数组地址,地址大小就为4/8。
除此之外所有数组名 表示首元素地址。
int main()
int a[] = 1,2,3,4;
printf("%d\\n", sizeof(a)); // 16
printf("%d\\n", sizeof(a+0));
printf("%d\\n", sizeof(*a)); // 4 数组名表示首元素地址,*a就是数组首元素,int类型4个字节。
printf("%d\\n", sizeof(a+1));
printf("%d\\n", sizeof(a[1])); // 4
printf("%d\\n", sizeof(&a)); // 8
printf("%d\\n", sizeof(*&a)); // 16 整个数组的地址解引用为整个数组的大学,等同于sizeof(a)
printf("%d\\n", sizeof(&a+1));
printf("%d\\n", sizeof(&a[0]));
printf("%d\\n", sizeof(&a[0]+1)); // 第二个元素的地址就是4/8
return 0;
一、构造类型(自定义类型)
数组类型
结构体类型struct
枚举类型enum
联合类型union
指针类型
意义:决定了指针解引用操作符能访问内存中几个字节,char* p;*p访问1一个字节。而int星p访问4个字节。
字符指针
指针数组
int* p[10] = arr; 存放多个指针(地址)的数组。
数组指针
int (*p)[10]=&arr;&arr是整个数组的地址,即指向数组的指针,即存放数组的地址。
数组传参和指针传参
函数指针
存放函数地址的指针
函数指针数组
将函数存放在指针数组中,如下:
int main()
int input = 0;
int x = 0, y = 0;
// 定义函数指针数组
int (*pArr[])(int, int) = 0, Add, Sub, Mul, Div, XoR;
do
menu();
printf("请选择:>");
scanf("%d", &input);
if (input >= 1 && input <= 5)
printf("请输入两个数:>");
scanf("%d%d", &x, &y);
int ret = pArr[input](x, y);
printf("%d\\n", ret);
else if (input == 0)
printf("退出\\n");
else
printf("选择错误\\n");
while (input);
return 0;
指向函数指针数组的指针
指向 【函数指针数组】的指针
int(*(*ppfArr[4])(int,int) = &pfArr
回调函数
空类型
空类型指针如同垃圾桶,不可进行指针解引用和加减整数的操作。因为根本不知道操作几个字节(char1int4double8)
1.整型在内存中如何存储??
正整数在内存中,原码、反码、补码相同。
负整数在内存中,原码最高符号位为1,对符号位不变的原码取反为反码,补码为对反码+1。
在内存中,整数存放的是十六进制补码。
大小端字节序存储模式:
小端模式:数据的低位存在内存的低地址位置,数据的高位存在内存的高地址位置。
如0x11223344在内存中以44332211存储,44的低位44存在低地址44位置。0x从大到小,内存中从小到大44332211。
有符号字符和无符号字符char
有符号字char范围为-128~127,unsigned char范围是0-255。
有符号和无符号数进行加法运算时,无符号数易导致死循环。
2.浮点型在内存中如何存储??
IEEE规定,S M E,二进制十六进制科学技术法。
二、字符函数与内存函数
strlen、strcpy、strcat、strncpy、strncat、strncmp与memcpy、memmove、memcmp,多n和mem通常会设比较字节的个数。
memset
三、C通讯录实现
- contact.c文件,注意包含文件的逻辑。
#include "contact.h"
//#include <stdio.h>
// 抽取查找函数,必须事先声明
static int FindByName(struct Contact *ps, char name[MAX_NAME])
int i = 0;
for (i = 0; i < ps->size; ++i)
if (0 == strcmp(ps->data[i].name, name))
return i; // 找到了,抓取当前i值
return -1;
void InitContact(struct Contact *ps)
memset(ps->data, 0, sizeof(ps->data));
ps->size = 0;
void AddContact(struct Contact *ps)
if (ps->size == MAX)
// printf("通讯录已满,无法增加\\n");
return;
else
printf("请输入名字:>");
scanf("%s", ps->data[ps->size].name);
printf("请输入年龄:>");
scanf("%d", &(ps->data[ps->size].age));
printf("请输入性别:>");
scanf("%s", ps->data[ps->size].sex);
printf("请输入电话:>");
scanf("%s", ps->data[ps->size].tele);
printf("请输入地址:>");
scanf("%s", ps->data[ps->size].addr);
ps->size++;
printf("!!!添加成功!!!\\n");
void ShowContact(const struct Contact *ps)
if (ps->size == 0)
printf("通讯录为空\\n");
// return;
else
printf("%20s\\t%4s\\t%5s\\t%12s\\t%20s\\n", "名字", "年龄", "性别", "电话", "地址");
for (int i = 0; i < ps->size; ++i)
printf("%20s\\t%4d\\t%5s\\t%12s\\t%20s\\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele,
ps->data[i].addr);
void DelContact(struct Contact *ps)
printf("请输入要删除的人名-联系人:>");
char name[MAX_NAME];
int i = 0;
scanf("%s", name);
// for (i = 0; i < ps->size; ++i)
// if (0 == strcmp(ps->data[i].name, name))
// break; // 找到了,抓取当前i值
//
//
int pos = FindByName(ps, name); // 找到返回下标,找不到-1
// if (i == ps->size)
if (pos == -1)
printf("要删除的人不存在\\n");
else
int j = 0;
for (j = pos; j < ps->size - 1; j++)
ps->data[j] = ps->data[j + 1];
ps->size--;
printf("删除成功\\n");
void SelectContact(const struct Contact *ps)
printf("请输入要查的人名:>");
char name[MAX_NAME];
scanf("%s", name);
int pos = FindByName(ps, name);
if (pos == -1)
printf("要查找的人不存在\\n");
else
printf("%20s\\t%4s\\t%5s\\t%12s\\t%20s\\n", "名字", "年龄", "性别", "电话", "地址");
printf("%20s\\t%4d\\t%5s\\t%12s\\t%20s\\n", ps->data[pos].name, ps->data[pos].age, ps->data[pos].sex,
ps->data[pos].tele,
ps->data[pos].addr);
void UpdateContact(struct Contact* ps)
printf("请输入要修改的人名:>");
char name[MAX_NAME];
scanf("%s", name);
int pos = FindByName(ps,name);
if(pos == -1)
printf("要修改的人不存在\\n");
else
printf("请输入名字:>");
scanf("%s", ps->data[pos].name);
printf("请输入年龄:>");
scanf("%d", &(ps->data[pos].age));
printf("请输入性别:>");
scanf("%s", ps->data[pos].sex);
printf("请输入电话:>");
scanf("%s", ps->data[pos].tele);
printf("请输入地址:>");
scanf("%s", ps->data[pos].addr);
printf("!!!修改成功!!!\\n");
- contact.h文件
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
#include <stdio.h>
#include <string.h>
struct PeoInfo
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
;
struct Contact
struct PeoInfo data[MAX];
int size; // 当前已有条数
;
enum Option
EXIT,ADD,DEL,SELECT,UPDATE,SHOW,SORT
;
void InitContact(struct Contact* ps);
void AddContact(struct Contact* ps);
void ShowContact(const struct Contact *ps);
void DelContact(struct Contact *ps); // 删除指定条目
void SelectContact(const struct Contact* ps);
//int FindByName(struct Contact* ps,char name[MAX_NAME]); //不需要在这声明,加上static不向外暴露
void UpdateContact(struct Contact* ps);
- main.c文件,启动入口
#include <stdio.h>
#include "contact.c" // main.c引入contact.c,contact.c引入contact.h。
void menu()
printf("***************\\n");
printf("**1、add****2、delete***\\n");
printf("**3、select**4、update*****\\n");
printf("**5、show***6、sort******\\n");
printf("****0、exit*******\\n");
printf("***************\\n");
int main()
int input = 0;
// 创建通讯录
struct Contact con;
// 初始化通讯录
InitContact(&con);
do
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case SELECT:
SelectContact(&con);
break;
case UPDATE:
UpdateContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case SORT:
break;
case EXIT:
printf("退出通讯录\\n");
break;
default:
printf("选择错误\\n");
break;
while (input);
return 0;
文件
scanf/printf是针对 标准 输入流/标准输出流的 格式化输入/输出语句
fscanf/fprintf是针对 所有 输入流/所有输出流的 格式化输入/输出语句
sscanf/sprintf
以上是关于C进阶-遗忘知识点的主要内容,如果未能解决你的问题,请参考以下文章