c语言 面试前必备基础知识

2023-05-16

目录

      • c语言 数据类型
      • c语言 数据类型打印格式 %c %s %d %f %lf %p %x %o %lu %lld
      • c语言 格式化输出
        • %md
        • %0md
        • %m.nf
      • c语言 常用字符的ASCII值
      • c语言 变量 常量
        • c语言 变量
          • c语言 变量命名规范
          • c语言 变量存储类型 auto static extern register
          • c语言:局部变量 全局变量
        • c语言 常量
      • c语言 字符串
        • 常见字符串定义的两种方式
        • 常见字符串函数
          • 1. strlen
          • 2. strcpy
          • 3. strcat
          • 4. strcmp
          • 5. strstr
      • c语言 转义字符
      • c语言 操作符
        • 1、算术操作符 + - * / %
        • 2、移位操作符 >> <<
        • 3、位操作符 & ^ |
        • 4、赋值操作符 = += -= *= /=
        • 5、单目操作符
          • 前置++和后置++的区别
          • 【\*p++ |*(p++) | *++p | (*p)++ | ++(*p) 区别】
        • 7、关系操作符
        • 8、逻辑操作符 && ||
      • c语言 原码、反码、补码
      • c语言 常见函数
        • scanf
        • getc 和putc
        • getchar和putchar
        • fgetc和fputc
        • gets 和puts
        • fgets和fputs
        • fprintf和fscanf
        • sprintf和sscanf
        • fwrite和fread
        • fseek
        • feof
      • c语言 数组
        • c语言 一维数组
        • c语言 数组名(arr) 和 &数组名(&arr) 的区别
          • 相同点
          • 不同点
        • c语言 二维数组
      • c语言 结构体
        • c语言 简单结构体 定义 初始化 访问
        • c语言 typedef关键字
        • c语言 复杂结构体 初始化 访问
        • c语言 匿名结构体类型
        • c语言 结构的自引用 链表
        • c语言 结构体内存对齐
          • c语言 结构体的对齐规则

c语言 数组指针/c语言 指针数组

c语言 数据类型

c语言 数据类型的转换优先级: char-->float-->short-->int-->double

char //字符数据类型 1个字节
short int //短整型 2个字节 [int 可以省略]
int //整形 4个字节
long int //长整型 32位OS 4个字节(64位OS 8个字节) [int 可以省略]
long long int //更长的整形 8个字节 [int 可以省略]
float //单精度浮点数 4个字节 eg:定义一个 float 型变量 float x = 3.4f (如果不加f,计算机默认为双精度浮点数)
double //双精度浮点数 8个字节 eg:定义一个 double 型变量 double y = 9.79
整数后加u或U 明确说明为无符号整型数 eg 38u
整数后加l或L 明确说明为长整型数 eg 38L
38lu:无符号长整形数

有了以下知识,就可以理解上述数据类型的字节了。

1、c语言规定了存储 0 或 1 的最小单位叫做比特 bit

2、c语言规又定了 1 个字节 (byte) 为8个 bit。

那么这里我们就明白了:为什么64位的操作系统存储"long类型"需要64/8=8个字节 ;32位的OS存储"long类型"需要32/8=4个字节

3、我们知道计算机只认识 0,1 两种数字(0代表负电,1代表正电),所以只能存储 0 或 1。即64位操作系统(OS)中的每一位有2种存储选择,可以存放0或 1。那么总共就有了2^64 种存储方案

二进制十进制
00000
00011
00102
00113
01004
01015
64个12^64-1

c语言 数据类型打印格式 %c %s %d %f %lf %p %x %o %lu %lld

%c		打印字符类型
%s		打印字符串类型
%d		打印整形
%f		打印单精度浮点型(float)
%lf 	打印双精度浮点型(double)
%p		以地址的形式打印
%x      打印16进制数
%o		打印8进制数
%lu		long int 简写[long]
%lld	    long long int	简写[long long]

在这里插入图片描述

小练习1

1、下面程序的输出正确的是__。

#include<stdio.h>

void main()
{
	int k = 11;
	printf("k=%d,k=%o,k=%x\n", k, k, k);
}
A) k=11,k=12,k=11           B) k=11,k=13,k=13
C) k=11,k=013,k=0xb         D) k=11,k=13,k=b

答案:D

c语言 格式化输出

注意:格式化输出涉及太多零碎知识,这里我们只给出常用的格式化。

%md

使不足m位的int型变量以m位进行右对齐输出,高位用空格补齐。如果本身超过m位,则保持原样

#include<stdio.h>

int main(){
	int a = 123, b = 1234567;
	printf("%2d\n", a);
	printf("%5d\n", a);
	printf("%5d\n", b);
	return 0;
} 

在这里插入图片描述

%0md

当变量不足m位时,在前面补0

#include<stdio.h>

int main(){
	int a = 123, b = 1234567;
	printf("%05d\n", a);
	printf("%05d\n", b);
	return 0;
}

在这里插入图片描述

%m.nf

#include <stdio.h>

int main() {
    float y = 12.345;
    // %m.nf:m为指定的输出字段的宽度,n为小数点后保留n位

    printf("x=%5.2f\n", y); // 输出结果:x=12.35
    /*
    解释:
        1. n为2,则小数点后保留2位,故【.34】
        2. m为5,字段宽度为5,向前在补2位,故【12.34】(小数点也占字段宽度)
        3. 由于四舍五入,故【12.35】

    */
    return 0;
}

必看

#include <stdio.h>

int main() {
    float y = 12.345;
    // %m.nf:m为指定的输出字段的宽度,n为小数点后保留n位

    printf("x=%0.2f\n", y); // 输出结果:x=12.35
    printf("x=%1.2f\n", y); // 输出结果:x=12.35
    printf("x=%2.2f\n", y); // 输出结果:x=12.35
    printf("x=%3.2f\n", y); // 输出结果:x=12.35
    printf("x=%4.2f\n", y); // 输出结果:x=12.35
    printf("x=%5.2f\n", y); // 输出结果:x=12.35
    printf("x=%6.2f\n", y); // 输出结果:x= 12.35 注意有空格
    /*
    解释:
        1. n为2,则小数点后保留2位,故【.34】
        2. 由于四舍五入,故【.35】
        3. 由于编译器需要保证这个整数的实际意义,所以它会自动把整数部分补齐。故【.35】(只要字段宽度<=5,即m<=5)
        4. 当m>5时,如m=6,加上整数部分,字段长度不足6位,所以最左端用空格补齐
        5. 当m=7时,最左端补2个空格,依此类推

    */
    return 0;
}

小练习1

#include<stdio.h>

int main()
{
	int a = 2008, b = 8;
	float f = 1.1;
	double d = 1.21;
	float x = 361.568, y = -123.456;
	char ilc[] = { "I love China!" }; //字符串长度为13
	printf("%f\n",f);//输出结果为:1.100000
	printf("%lf\n",d);//输出结果为:1.210000
	printf("%2d,%2d\n", a, b); //输出结果为:2008, 空格8
	printf("%8.3f-%8.3f=%8.2f\n", x, y, x-y);//输出结果为:空格361.568--123.456=空格空格485.02
	printf("%16s\n", ilc);//输出结果为:空格空格I love China!
	printf("%5s\n", ilc);//输出结果为:I love China!
	return 0;
}

在这里插入图片描述

c语言 常用字符的ASCII值

字符ASCII值
A65
a97
空格32
换行10
数字048
数字132

c语言 变量 常量

化分依据:值是否会变化

c语言 变量

c语言 变量命名规范

(1)只能由字母、数字、下划线构成

(2)开头只能由字母、下划线构成

(3)关键字不能作为标识符

c语言 变量存储类型 auto static extern register

自动(auto)、静态(static)、外部(extern)、寄存器 (register)

这些存储类型的具体意义

c语言:局部变量 全局变量

c语言根据变量作用域将变量分为:局部变量 全局变量

人话:是否在大括号{}的内部或外部, 在{}内:叫做局部变量

注意:C语言语法规定,变量要定义在当前代码块的最前面

#include<stdio.h>

int num1 = 77; //全局变量定义在大括号{}外
int main()
{
	int num2 = 99; //局部变量定义在大括号{}内
	{
		int num = 100; //局部变量定义在大括号{}内
	}
	//以下可以写业务逻辑代码(变量必须定义在业务逻辑代码的上边)
	return 0;
}

c语言 常量

C语言中的常量分为以下以下几种:

  1. 整形常量

  2. 浮点常量

  3. 字符常量

  4. 字符串常量

  5. 枚举常量

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

// 枚举关键字 enum
enum Sex {
	MALE, // 枚举常量
	FEMALE // 枚举常量
};

int main()
{
	//打印枚举常量的初始值
	printf("%d\n", MALE);
	printf("%d\n", FEMALE);
	return 0;
}

在这里插入图片描述

c语言 字符串

  • 常见字符串定义的两种方式

在这里插入图片描述

  • 常见字符串函数

我们知道,字符串的结束标志为 \0,那么可以做一下以下题目

1. strlen

该函数不会返回负数

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<string.h>

// 判读字段串的长度
int main()
{
	char arr1[] = { 'a', 'b', 'c',0 };
	char arr2[] = { 'a', 'b', 'c','\0' };
	char arr3[] = { 'a', 'b' };
	printf("%d\n", strlen(arr1));
	printf("%d\n", strlen(arr2));
	printf("%d\n", strlen(arr3));
	return 0;
}

在这里插入图片描述

解释:

1、arr3,没有字符串结束标志,所以abc后边跟的是随机值,统计的是 abc + 随机值的长度

2、arr2,有字符串结束,所以统计的是 abc 的长度

3、我们知道计算机是不认识字母和某些数字的(除了 1 or 0外)。那么计算机存储字母 a 时,就必须转换为 0 或 1。所以国际语言标准就为每个字母,数字,或符号都赋了一个特定的数值,例如 a 为 97,然后计算机就可以将十进制的 97 转换为了二进制的 1100001。那么同理,字符串结束标志 \0 也有一个特定的值 0,那么c语言编译器扫描到 0 时,会认为是字符串的结束标志。看到这里我们就能明白 arr1 长度也是 3 了。

转义字符 \0 十进制值为 0

字符 0 十进制值为 48

2. strcpy

字符串拷贝函数

  • 源字符串必须以’\0’结束。
  • 会将源字符串中的’\0’拷贝到目标空间。
#include<stdio.h>
#include<string.h>

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "xyz";
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

  • 目标空间必须足够大,以确保能存放源字符串。目标空间必须可变。
#include<stdio.h>
#include<string.h>

int main()
{
	char arr1[] = "abcdef"; 
	char arr2[] = "xyz"; // arr2空间必须足够大
	strcpy(arr2, arr1); // 错误写法 arr2空间不足
	return 0;
}
3. strcat

字符串追加函数

#include<stdio.h>
#include<string.h>

int main()
{
	char arr1[44] = "abcdef"; // arr1空间必须足够大
	char arr2[] = "xyz";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	return 0;
}

在这里插入图片描述

4. strcmp

字符串比较函数

#include<stdio.h>
#include<string.h>

int main()
{
	char *p1 = "awbc";
	char *p2 = "abyz"; // 比较规则:a和a比较 w和b进行比较,b和y进行比较,依次类推
	printf("%d\n", strcmp(p1, p2)); // p1>p2 返回大于0的数 p1=p2 返回0 p1<p2 返回小于0的数 
	
	return 0;
}

在这里插入图片描述

5. strstr

查找字符串

#include<stdio.h>
#include<string.h>

int main()
{
	char *p1 = "abcdefabcdef";
	char *p2 = "def";
	char *ret = strstr(p1, p2);
	if(ret == NULL){
		printf("子串不存在!\n");
	}else{
		printf("%s\n",ret); // 若存在,返回第一次出现位置后的所有字符串
	}
	
	return 0;
}

在这里插入图片描述

c语言 转义字符

语句中只要有\就表示转义

问题: 小明多年前在电脑中的某个位置(C:\users\xxx.mp4)存了一部岛国电影,现在忘记了。所以请你把电影的存储路径打印给他

因为路径中有\,所以默认情况下会进行转义。若想把影片路径中的\打印出来,在加一个\,表示在转义
在这里插入图片描述

打印输出 单引号,双引号

在这里插入图片描述

c语言 操作符

1、算术操作符 + - * / %

+ - * / %

% 为求余运算符,该运算符只能对整型数据进行运算。且符号与被模数相同。5%2=1;5%-2=1;-5%2= -1;(-5)%(-2)= -1;

/ 为求商运算符,该运算符能够对整型、字符、浮点等类型的数据进行运算

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int main()
{
	int a = 5;
	//整除
	printf("%d\n", (a / 2));
	//取余
	printf("%d\n", (a % 2));
	return 0;
}

在这里插入图片描述

小练习2

在这里插入图片描述

(1)相同数据类型的元素进行数学运算(+、-、*、/)得到结果还保持原数据类型。

(2)不同数据类型的元素进行数学运算,先要统一数据类型,统一的标准是低精度类型转换为高精度的数据类型。

选项A,11与3为两个整形,11/3结果的数据类型也应为整形,因此将3.666666的小数部分全部舍掉,仅保留整数,因此11/3=3。

选项B,11.0为实型,3为整形,因此首先要统一数据类型,将整型数据3转换为3.0,转换后数据类型统一为实型数据,选项B变为11.0/3.0,结果的数据类型也应为实型数据,因此选项B11.0/3=3.666666。

选项C,先将整数11强制类型转换,转换为实型11.0,因此选项C变为11.0/3,其后计算过程、结果与选项B同。

2、移位操作符 >> <<

>> <<

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int main()
{
	int a = 5;
	//向左移动2位
	printf("%d\n", (a << 2));
	//向右移动2位
	printf("%d\n", (a >> 2));
	return 0;
}

在这里插入图片描述

3、位操作符 & ^ |

& ^ |

在这里插入图片描述

4、赋值操作符 = += -= *= /=

= += -= *= /= 

小练习1

8、设 int a=12,则执行完语句a+=a-=a*a后,a的值是___.
A) 552        B) 264      C) 144        D) -264

答案:D 从右到左,依次计算即可

  1. a*a=144
  2. a=a-144=-132
  3. a=a+(-132)=-264

小练习2

22、已知a=12,则表达式a+=a-=a*=a的结果是___.
A) 0         B) 144        C) 12        D) -264

答案:A 从右到左,依次计算即可

小练习3

以下答案正确的是___。
#include<stdio.h>

int main()
{
	int x = 10;
	x *= 3 + (x % 3);
	printf("%d\n", x);
	return 0;
}

A. 31 	B. 40

答案:B

  1. 赋值运算符的优先级最低
  2. x%3 = 1
  3. 3+1 =4
  4. x = 10*4

5、单目操作符

!           逻辑反操作
-           负值
+           正值
&           取地址
sizeof      操作数的类型长度(以字节为单位)
~           对一个数的二进制按位取反
--          --在前,先----在后,算完其它后,在--
++          
*           间接访问操作符(解引用操作符)
(类型)       强制类型转换
  • 前置++和后置++的区别
#include<stdio.h>

int main()
{
	int a = 1, b = 8,x,y;
	x = ++a; // ++在前,先++,在赋值给x x=2
	y = b++; // ++在后,先赋值给y,然后在++ y=8
	printf("%d\n",b); // 9
	return 0;
}

c语言中,除了数字0,其它一切非0值都为1。 eg: -7 ,7, 3.3, 4.42 类型的 都是 1

小练习1

小练习2

运算符号的优先级想要搞懂,必须做题,这里给一个小栗子

在这里插入图片描述
答案:B

  1. !x=0
  2. 0||y
  3. x=2
  4. y =0

在这里插入图片描述

小练习3

前置++
在这里插入图片描述
注意:这里的 ! 优先级 比前置 ++ 的低,先计算 ++x

  • 【*p++ |*(p++) | *++p | (*p)++ | ++(*p) 区别】

*p++:等同于:*p; p += 1;

#include<stdio.h>

int main() {
    char s[99] = {"hello"};
    char *q = s;
    while (*q++) {
        printf("%c", *q); 
    }
    return 0;
}

在这里插入图片描述

  1. while->先计算*p=h 然后再++
  2. while循环体内 再计算*p

错误理解:由于 * 和 ++ 的运算优先级一样,在优先级相同时,遵循自右向左结合的规则。p先与++结合,然后p++整体再与*结合

正确写法

#include<stdio.h>

int main() {
    char s[99] = {"hello"};
    char *q = s;
    while (*q) {
        printf("%c", *q); 
		q++;
	}
    return 0;
}

在这里插入图片描述

* p++ 与*(p++)无区别

#include<stdio.h>

int main() {
	// 拷贝str1中的defgh
	char str1[]={"abcdefgh"};
	char str2[99];
	char *p =str1+3,*q=str2,*t=str2;
	while(*p){
		*(q++)=*p++; // 这里可以证明2者无区别
		// 详细步骤:*q=*p; p++;q++;
	}
	*q='\0';
	printf("%s\n",t);

}

在这里插入图片描述

*++p:等同于 p += 1; *p;

(*p)++,使用()强制将*与p结合,只能先计算*p,然后对*p整体的值++

++(*p),先*p取值,再前置++,[该值+1后]作为整个表达式的值

7、关系操作符

>
>=
<
<=
!=      用于测试“不相等”
==      用于测试“相等”

小练习1

26、下面程序的输出结果是____.
#include<stdio.h>
void main()
{
  int a=5,b=3;
  float x=3.14, y=6.5;
  printf("%d,%d\n",a+b!=a-b,x<=(y-=6.1));
}

A) 1,0        B) 0,1      C) 1,1        D) 0,0

答案:A

  1. a+b=8
  2. a-b=2
  3. 8!=2
  4. y=y-6.1=0.4
  5. x<=0.4

8、逻辑操作符 && ||

&&     逻辑与 只有两个为真时,才为1
||     逻辑或 任意一个为真,才为1
真:除0以外所有的数都为真,包括负数,小数

必看
在这里插入图片描述
解释:&&的左边,只要为假,&&右边的优先级无论多高,计算机都不会在计算,直接返回0

小练习1

25、下面程序的输出结果是______.
#include<stdio.h>
void  main() 
{
 int a=-1, b=4, k;
 k=(++a<=0)&&(b--<=0);
 printf("%d,%d,%d\n",k,a,b);
}

A) 1,1,2      B) 1,0,3    C) 0,1,2      D) 0,0,3

答案:D

  1. ++a=0
  2. 0<=0
  3. b<=0 结果为0
  4. 1&&0 结果为0
  5. k=0
  6. b=3

c语言 原码、反码、补码

在这里插入图片描述

  1. 对于整形来说,计算机内存存储的是补码
  2. debug时,编译器呈现给我们的是16进制数据。

c语言 常见函数

  • scanf

#include<stdio.h>

int main()
{
	char ch;
	scanf("%3c", &ch);
	printf("%c", ch);
	return 0;
}
如果从键盘上输入
    abc<回车>
则程序的运行结果是___.
A) a        B) b        C) c    D) 程序语法出错

答案:A

解析:如果从键盘上连续输入3个字符abc,由于ch只能容纳一个字符,系统就把第一个字符‘a’赋给字符变量ch。3为指定的输入字段的宽度。如果数据的位数小于3,则等待直到满足3字符长度(如果有回车,则包含回车符),若大于3,则截断后输出前3字符。

  • getc 和putc

getc :从流中读取单个字符
putc :从流中输出单个字符
流:可以是 控制台(黑窗口cmd),也可以是文本文件等
在这里插入图片描述

  • getchar和putchar

getchar:读取用户从键盘输入的单个字符
putchar:向终端输出一个字符
在这里插入图片描述

  • fgetc和fputc

fetc:一次从文件流中读取一个字符
在这里插入图片描述
fputc:向文件流中一次写一个字符
在这里插入图片描述

  • gets 和puts

gets:从流中读取一行字符串 知道遇到换行,才停止读取
puts:简单来说是,输出字符串
在这里插入图片描述

  • fgets和fputs

fets: 从流中读取一行字符串
在这里插入图片描述

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(){
	FILE *pf = fopen("e:\\input\\hello.txt","r");
	char str[55]={0};
	if(pf==NULL){ // 读文件出错时,控制台打印出错信息
		printf("%s\n",strerror(errno));
		return 0;
	}
	// 读文件 
	// 将从文件中读取到的一行字符串,暂时放到缓冲区,缓冲区大小为1024个字符
	fgets(str,1024,pf);
	printf("%s\n",str);
	//关闭文件
	fclose(pf);
	return 0;
}

在这里插入图片描述
fputs: 向文件中写入字符串

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(){
	FILE *pf = fopen("e:\\input\\wold.txt","w");
	
	if(pf==NULL){ // 读文件出错时,控制台打印出错信息
		printf("%s\n",strerror(errno));
		return 0;
	}
	// 写文件 
	fputs("b b",pf);
	fputs("c c",pf);
	//关闭文件
	fclose(pf);
	return 0;
}

在这里插入图片描述

  • fprintf和fscanf

在这里插入图片描述

fprintf:本例向文件中格式化输出学生信息

#include <stdio.h>
#include <errno.h>
#include <string.h>

typedef struct stu {
    int on;
    float height;
    char hobby[10];
} Stu;

int main() {
    Stu s = {10086, 1.78f, "sing"};
    FILE *pf = fopen("e:\\input\\info.txt", "w");

    if (pf == NULL) { // 文件出错时,控制台打印出错信息
        printf("%s\n", strerror(errno));
        return 0;
    }
    // 写文件 
    fprintf(pf, "%d %f %s", s.on, s.height, s.hobby);
    //关闭文件
    fclose(pf);
    return 0;
}

在这里插入图片描述
fscanf:本例从文件中格式化读取学生信息,并输出到控制台

#include <stdio.h>
#include <errno.h>
#include <string.h>

typedef struct stu {
    int on;
    float height;
    char hobby[10];
} Stu;

int main() {
    Stu s = {0};
    FILE *pf = fopen("e:\\input\\info.txt", "r");

    if (pf == NULL) { // 文件出错时,控制台打印出错信息
        printf("%s\n", strerror(errno));
        return 0;
    }
    // 从文件中读取结构化数据 
    fscanf(pf, "%d %f %s", &s.on, &s.height, &s.hobby);
    printf("%d %f %s", s.on, s.height, s.hobby);
    //关闭文件
    fclose(pf);
    return 0;
}

在这里插入图片描述

  • sprintf和sscanf

#include <stdio.h>

typedef struct stu {
    int on;
    float height;
    char hobby[10];
} Stu;

int main() {
    Stu s1 = {10086, 175, "sing"};
    Stu s2 = {0};
    char buf[1024] = {0};

    // 把格式化数据存储到字符串
    sprintf(buf, "%d %f %s", s1.on, s1.height, s1.hobby);
    printf("%d %f %s\n", s1.on, s1.height, s1.hobby);

    printf("**************************\n");

    // 从字符串中读取格式化数据
    sscanf(buf, "%d %f %s", &s2.on, &s2.height, &s2.hobby);
    printf("%d %f %s\n", s2.on, s2.height, s2.hobby);

    return 0;
}

在这里插入图片描述

  • fwrite和fread

fwrite:将数据以二进制的形式写入文件

#include <stdio.h>

struct S {
    char name[20];
    int age;
    double score;
};

int main() {
    struct S s = {"老王", 22, 88.4};
    FILE *pf = fopen("e:\\input\\info.txt", "wb");
    if (pf == NULL) {
        return 0;
    }
    // 二进制的形式写文件
    //fwrite(被写进去元素的地址,单个元素的大小,要写进去多少个这样的元素,写到哪里去);
    fwrite(&s, sizeof(struct S), 1, pf);
    fclose(pf);
    pf = NULL;
    return 0;

}

在这里插入图片描述
fread: 读取二进制文件

#include <stdio.h>

struct S {
    char name[20];
    int age;
    double score;
};

int main() {
    struct S b = {0};
    FILE *pf = fopen("e:\\input\\info.txt", "rb");
    if (pf == NULL) {
        return 0;
    }
    // 二进制的形式读文件
    //fread(读取到的数据被放在哪里,单个元素的大小,读取多少个这样的元素,从哪里读文件);
    fread(&b, sizeof(struct S), 1, pf);
    printf("%s %d %lf\n", b.name, b.age, b.score);
    fclose(pf);
    pf = NULL;
    return 0;

}

在这里插入图片描述

  • fseek

fseek:指定位置读写
在这里插入图片描述

#include <stdio.h>

int main() {
    FILE *pf = fopen("e:\\input\\hello.txt", "r");
    if (pf == NULL) {
        return 0;
    }
    // 1. 定位文件指针
    // fseek(从哪里读取文件,指针偏移几个字节,文件指针初始位置)
    fseek(pf, 4, SEEK_CUR);
    // 2. 读取文件
    int ch = fgetc(pf);
    printf("%c\n", ch);

    fclose(pf);
    pf = NULL;
    return 0;

}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • feof

feof:该函数用来判断系统读取文件时,是否正常结束

系统读取文件完毕时,会返回EOF(-1)。但是我们无法知道,是正常读取完毕后,还是读取异常后,返回的EOF,所以我们要用feof函数进行判断,如果feof函数返回真,表示正常读取完毕

#include <stdio.h>

int main() {
    FILE *pf = fopen("e:\\input\\hello.txt", "r");
    if (pf == NULL) {
        return 0;
    }
    int ch = 0;
    while ((ch = fgetc(pf)) != EOF) {
        putchar(ch);
    }
    if (ferror(pf)) {
        printf("读取错误,非正常结束!\n");
    }
    if (feof(pf)) {
        printf("读取正常结束!\n");
    }
    fclose(pf);
    pf = NULL;
    return 0;

}

c语言 数组

c语言 一维数组

判读以下数组的声明是否正确:

int a[ ];

答案:错

解析:只有在对数组初始化(即赋值)的时候才可以省略数组的长度,即int a[] = {1, 2, 3}

c语言 数组名(arr) 和 &数组名(&arr) 的区别

在这里插入图片描述

相同点

都可以表示数组首元素的地址

不同点

1、arr + 1:表示向后移动一个元素,即4个字节(移动一个int类型)

2、&arr + 1: 表示向后移动整个数组的长度,即40个字节

c语言 二维数组

1、二维数组的一维大小,即指二维数组的行数

2、一维数组初始化时可以省略数组长度

3、二维数组初始化时可以省略行数,但不能省略列数

# 判读题
A. int a[][]={1,2,3,4,5,6};(错,不能省略列数)
B. int a[2][]={1,2,3,4,5,6};(错,不能省略列数)
C. int a[][3]={1,2,3,4,5,6};()

c语言 结构体

c语言 简单结构体 定义 初始化 访问


#include<stdio.h>
/*
struct是自定义结构体类型的关键字
struct student 是用户定义的结构体类型
num,name,score都是结构体成员名
stu1是声明的全局变量(不推荐使用)也是结构体类型名
stu2是声明的局部变量
*/

struct student
{
	int num;//结构体成员名
	char name[10];//结构体成员名
	float score;//结构体成员名
}stu1;  // 全局变量 


int main()
{
	// 局部变量初始化
	struct student stu2 = { 86,"lisi" ,66 }; // stu2 局部变量
	printf("%d\n", stu2.num); //输出结果86
	return 0;
}

问题1,全局变量怎么赋初值?

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
/*
struct是结构体类型的关键字
struct student 是用户定义的结构体类型
num,score都是结构体成员名
stu1是声明的全局变量(不推荐使用)
stu2是声明的局部变量
*/

struct student
{
	int num;//结构体成员名
	char name[10];//结构体成员名
	float score;//结构体成员名
}stu1 = { 87,"zhangsan" ,55 };  // 全局变量


int main()
{
	struct student stu2 = { 87,"lisi" ,66 }; // stu2 局部变量
	return 0;
}

c语言 typedef关键字

问题2:可以把 用户定义的结构体类型 struct student,用简洁的形式代替吗?

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

// typedef:自定义类型关键字
typedef struct student
{
	int num;//结构体成员名
	char name[10];//结构体成员名
	float score;//结构体成员名
}Stu; // 自定义的类型(相当于域名)


int main()
{
	//用自定义的类型声明一个局部变量
	Stu stu2 = { 88,"wangwu" ,77 };
	return 0;
}

c语言 复杂结构体 初始化 访问


#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

struct S
{
	int a;
	char c;
	char arr[20];
	double d;
};

struct T
{
	char ch[10];
	struct S s;
	char* pc;
};


int main()
{
	char arr1[] = "hello c";
	struct T t = { "hihi",{100, 'w',"hello world",3.14}, arr1 };
	printf("%s\n", t.ch); // hihi
	printf("%s\n", t.s.arr); // hello world
	printf("%lf\n", t.s.d); // 3.140000
	return 0;
}

c语言 匿名结构体类型

省略了结构体类型

struct
{
    int a;
    char b;
    float c;
}x;

c语言 结构的自引用 链表

struct Node
{
    int data; // 数据域
    // eg:一个节点想要找到另一个节点,可以存另一个节点的地址。那么要存储存储地址就需要指针,且这个指针类型需要和下一个节点的类型一致。
    struct Node* next; // 指针域 
};

使用typedef关键字

可以看以上 c语言 typedef关键字

typedef struct Node1
{
    int data;
    struct Node1* next;
}Node;

c语言 结构体内存对齐

即计算结构体的大小 这里我用的编译器 vs2019

c语言 结构体的对齐规则

1、第一个结构体成员距离结构体变量偏移量为0的地址处对齐。

2、其他结构体成员成员要对齐到,某个对齐数的整数倍处

对齐数 = 编译器默认对齐数 与 该结构体成员大小 的较小值

vs中默认的对齐数为8

linux中默认对齐数为4

3.、结构体总大小为最大对齐数(每个结构体成员都有一个对齐数)的整数倍。

4、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

#include <stdio.h>

struct S1
{
	char c1;
	int i;
	char c2;
};

int main() {
	// 初始化
	struct S1 s1 = { 0 };
	printf("%d\n", sizeof(struct S1)); // 12

	return 0;
}

在这里插入图片描述

struct S3
{
    double d;
    char c;
    int i;
};

在这里插入图片描述

struct S4
{
    char c1;
    struct S3 s3;
    double d;
};

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c语言 面试前必备基础知识 的相关文章

  • Django查询、删除、更新数据

    查询数据 查询无疑是数据库表中使用频率最高的操作 table object get 方法用于从数据库表中取得一条匹配的结果 xff0c 返回一个对象 xff0c 如果记录不存在的话 xff0c 那么它会报DoesNotExist类型错误 通
  • static 静态方法可以直接调用,不用创建对象

    static 静态方法可以直接调用 xff0c 不用创建对象
  • Java歌手评分系统

    有五个评委 xff0c 对一个歌手唱歌打分 xff0c 最终得分要求去掉最高分去掉最低分 xff0c 求平均分 注意要求的格式为 xff1a 输入第1个评委给分 97 1 输入第2个评委给分 89 2 输入第3个评委给分 88 6 输入第4
  • python3环境下使用cv_bridge

    环境 ubuntu18 04 ros melodic 由于ros自带的python版本是2 7 系统中的cv bridge是用python2编译的 xff0c 如果在python3环境中使用cv bridge xff0c 会报以下错误 xf
  • 运行VINS-MONO报的错

    刚刚安装完环境 xff0c 已经可以跑通Euroc数据集 xff0c 回忆一下值得记下来的注意事项 环境配置 我的电脑 xff1a Ubuntu18 04 ROS melodic Opencv3 4 3 首先 xff1a GitHub上的代
  • TX2安装realsense SDK和librealsense

    官网https github com IntelRealSense librealsense安装很简单 xff0c 一定要对应好SDK与ros包 realsense固件的版本 https github com IntelRealSense
  • VINS-Fusion轨迹评估

    代码轨迹输出修改 visualization cpp VINS Fusion master vins estimator src utility visualization cpp的150行左右 xff1a span class token
  • antd4中Form组件initialValues设置初始值无效,使用setFieldsValue动态赋值,getFieldsValus动态获取值

    首先说明initialValues这个属性 xff0c 这个属性antd官方给的是设置Form组件初始值 xff0c 但是有个问题如果值从后端请求那么initialValues可能会设置不上 xff0c 如果说用匿名组件的话 xff0c 修
  • 一个存放论文、笔记等的github仓库

    link xff1a PaperNote如果好用 xff0c 请给个star哦
  • 关于C++ Overload、Override、hide的一些总结

    一 override和overload区别 当需要一些相同的函数名接受不同的参数实现不同的功能时 xff0c 可以是运用函数重载来实现 但是 xff0c 函数的重载必须要在同一个作用域内重载 xff0c 才叫做重载 在不同作用域的两个同名函
  • C++多态的个人总结

    多态 多态分为运行时多态和编译期多态 xff0c 也被称作动态绑定和静态绑定或者晚绑定和早绑定 一 编译期多态 编译期多态主要是通过函数重载 xff0c 运算符重载还有模板函数 xff0c 模板类来是实现的 函数重载和运算符重载 xff0c
  • 嵌入式linux截图工具gsnap移植到OK6410 TX2416开发板

    交叉编译器版本 xff1a arm linux gcc 4 3 2 操作系统平台 xff1a Ubuntu 11 04 开发板平台 xff1a Tx2416 OK6410开发板 需要以下两个源文件 jpegsrc v6b tar gz gs
  • C++四种类型转换运算符的个人总结

    在这四种类型转换符包括static cast dynamic cast reinterpret cast const cast其中使用比较多的是dynamic cast和static cast 我们就从这两种类型转换符开始谈起 一 stat
  • 什么是系统调用?

    01 系统调用是什么 系统内核通过包装一些能够实现特定功能的特殊硬件指令和硬件状态 xff0c 即为内核函数 xff0c 通过一组称为系统调用 xff08 system call 的接口呈现给用户 xff0c 为系统调用而封装出来的API也
  • js中函数内部可以访问外部的变量

  • 视觉SLAM——小觅相机实测vins-mono步骤

    文章目录 step1 相机对应驱动 ubuntu SDK源码安装step2 相机测试 标定参数获取step3 安装vins并建立启动文件step4 开启相机节点并运行vins 使用的是双目深度板小觅相机 xff0c 只需要使用相机左摄像头和
  • ROS自定义消息类型 发布与订阅

    1 自定义消息类型与编译 1 在功能包里面创建一个msg文件夹 添加文档 文档名字为生成的头文件名和消息类型名 功能包名为消息类型的作用域 在msg文件夹下创建一个Person msg文件 xff0c 将下列代码复制进去 xff1a str
  • ROS的launch文件创建

    1 使用launch文件 Launch文件是ROS提供的 xff0c 可以同时运行多个nodes的文件 Launch文件以一种特殊的XML格式编写 xff0c 在ROS packages中使用广泛 创建launch功能包 首先在工作空间sr
  • ROS+UR机械臂+Moveit+ 仿真与实体机械臂的使用+realsense相机+eye_handeye手眼标定(亲测有效)上

    Universal Robots xff08 优傲机器人 xff09 公司是一家引领协作机器人全新细分市场的先驱企业 xff0c 该公司成立于2005年 xff0c 关注机器人的用户可操作性和灵活度 xff0c 总部位于丹麦的欧登塞市 xf

随机推荐

  • ROS+UR机械臂+Moveit+ 仿真与实体机械臂的使用+realsense相机+eye_handeye手眼标定(亲测有效)下

    1参考链接 1 UR5 realsense手眼标定 2 优遨机器人UR5与RealSense深度摄像头D435的手眼标定 3 UR5 realsense手眼标定 4 标定所需二维码 5 ROS下UR5 usb cam单目外参标定 xff08
  • 链表的头节点理解

    不管带不带头节点 xff0c 头指针始终指向第一个结点 xff0c 头指针始终指向第一个结点 xff0c 而头节点是带头结点的链表的第一个结点 xff0c 结点内通常不存储信息 图示如下 xff1a 2 在建立链表时 xff0c 如果是不带
  • 汇编语言学习04之X86计算机组件

    X86计算机组件 本文首先通过检查典型主板配置以及围绕 CPU 的芯片组来了解 x86 如何与其他组件的集成 然后讨论内存 I O 端口和通用设备接口 最后说明汇编语言程序怎样利用系统硬件 固件 xff0c 并调用操作系统函数来实现不同访问
  • 【翻译】服务器后端的编程语言

    对于那些需要web服务的初创公司里的大型新项目 xff0c 我会选择何种后端编程语言呢 xff1f 在客户端侧有CSS html和javascript xff08 包括CoffeeScript和TypeScript这类衍生语言 xff09
  • ubuntu换内核的方法适用于16-18系统

    2080ti的卡兼容18 04的5 0 0 37 generic内核驱动需要用418 56 ubuntu内核突然变了 导致nvidia显卡驱动用不了 进行内核降级 解决方法 查找可用的内核版本 grep menuentry boot gru
  • 统计信号估计 (二) 最小方差无偏估计量(MUV)的线性模型

    MVU表示最小方差无偏估计 xff0c 下面将推导一个线性模型的MVUE xff0c 即最小方差无偏估计量 线性模型可以表示为 xff1a x 61 H 43 w
  • python二级考试-每日刷题7

    知识导图 文件 文件的类型 文件的打开和关闭 文件的读写
  • 树莓派入门(笔记本当显示屏)

    树莓派入门 笔记本当显示屏 your elephant的博客 CSDN博客 树莓派连接笔记本屏幕
  • python-sklearn实现神经网络(数据量小的情况)

    以下内容笔记出自 跟着迪哥学python数据分析与机器学习实战 xff0c 外加个人整理添加 xff0c 仅供个人复习使用 神经网络 xff08 neural network 模块重要的有两个类 xff0c MLPClassifier 分类
  • 想免像控?RTK/PPK无人机 vs GCP 测绘精度对比

    无人机航拍测绘具有精度高 作业效率高 数据分析能力强的特点 xff0c 很大程度上解决了人工测绘的痛点 因此 xff0c 无人机在测绘工程中的应用越来越广泛 精度对于测绘从业人员来说精度至关重要 xff0c 针对RTK PPK 无人机和使用
  • ROS的GPS驱动包

    ROS WiKi地址 http wiki ros org nmea gps driver ROS功能包 xff1a nmea gps driver Package to parse NMEA strings and publish a ve
  • 【操作系统】进程切换到底是怎么个过程?

    首先 xff0c 我们要了解 xff0c 进程切换是个什么过程 xff1f 进程切换概念 其实很简单 xff0c 进程切换就是从正在运行的进程中 xff0c 收回CPU的使用权利 xff0c 交给下一个要运行的进程 实际上 xff0c 因为
  • docker设置多个环境变量

    在命令行直接使用 e或 env xff0c env file xff0c 每个变量写一次 e 2 在dockerfile里设置 这里键值是以空格分开的
  • 一些好用的c++ STL库函数

    stl可以说是懒癌患者福利了 持续更新 xff08 随缘更新 xff09 全排列函数next permutation 今天在洛谷做题的时候发现一个题简直是这个函数的完美应用 题目链接 xff1a 洛谷P1088 火星人 头文件 xff1a
  • 【FreeRTOS】中断机制

    FreeRTOS 之中断机制 在FreeRTOS中 xff0c 中断是实现实时性必要的操作 一款芯片的中断涉及到硬件触发 xff0c 软件触发 xff0c 软件中断处理 所以FreeRTOS的中断机制其实不好单独拿出来看 FreeRTOS关
  • 【VSPD虚拟串口】【Modbus Poll】【Modbus Slave】仿真工具的学习过程

    学习想法 xff1a 通信是工控行业内采集仪器仪表等设备信息的重要途径 xff0c 同时可以通过通信访问设备的工作状况对设备进行监控 xff0c 也可以通过通信对设备进行参数修改以及控制设备运行 xff0c 所以掌握通信是工控行业人员比不可
  • 【RISC-V】Trap和Exception

    文章目录 控制流 xff08 Control Flow xff09 和TrapRISC V Trap处理中涉及的寄存器mtvec Machine Trap Vector Base Address mepc Machine Exception
  • @TableId(type = IdType.AUTO)不生效问题

    随手记录一下 64 TableId type 61 IdType AUTO private Long id Cause java sql SQLException Field 39 id 39 doesn 39 t have a defau
  • Docker apt-get update报错

    在Docker改apt源出现问题 root 64 1ad3e492d821 etc apt apt get update Ign 1 http mirrors 163 com debian stretch InReleaseGet 2 ht
  • c语言 面试前必备基础知识

    目录 c语言 数据类型c语言 数据类型打印格式 c s d f lf p x o lu lldc语言 格式化输出 md 0md m nf c语言 常用字符的ASCII值c语言 变量 常量c语言 变量c语言 变量命名规范c语言 变量存储类型