c语言学习笔记

基础语法复习

c

数据类型

image
image

  • unsigned取正数,否则是正负参半,0算在正数侧
  • int范围大概到20w
  • sizeof(xxx)获取所占字节数

♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥

输入输出

putchar()和getchar()

putchar
putchar(‘A’); //输出大写字母A
putchar(x); /*输出字符变量x的值*/
putchar(‘\n’); /*换行*/

成功返回ASCII码,失败返回EOF也就是-1

getchar
char c;
c = getchar();

返回读取到的字符

printf()和scanf()

这个人讲的比较全

格式词典
%c
输出一个单一的字符

%hd、%d、%ld
以十进制、有符号的形式输出 short、int、long 类型的整数

%hu、%u、%lu
以十进制、无符号的形式输出 short、int、long 类型的整数

%ho、%o、%lo
以八进制、不带前缀、无符号的形式输出 short、int、long 类型的整数

%#ho、%#o、%#lo
以八进制、带前缀、无符号的形式输出 short、int、long 类型的整数

%hx、%x、%lx
%hX、%X、%lX
以十六进制、不带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字也小写;如果 X 大写,那么输出的十六进制数字也大写。

%#hx、%#x、%#lx
%#hX、%#X、%#lX
以十六进制、带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字和前缀都小写;如果 X 大写,那么输出的十六进制数字和前缀都大写。

%f、%lf
以十进制的形式输出 float、double 类型的小数

%e、%le
%E、%lE
以指数的形式输出 float、double 类型的小数。如果 e 小写,那么输出结果中的 e 也小写;如果 E 大写,那么输出结果中的 E 也大写。

%g、%lg
%G、%lG
以十进制和指数中较短的形式输出 float、double 类型的小数,并且小数部分的最后不会添加多余的 0。如果 g 小写,那么当以指数形式输出时 e 也小写;如果 G 大写,那么当以指数形式输出时 E 也大写。

%s
输出一个字符串
  • 总结
  1. c字符 s字符串 d整数 u无符号 f单精 lf双精 e科学计数
  2. o八进制 x十六进制
  3. 加h为short 加l为long 加#为添加多进制前缀
  4. x和e区分大小写(0x 0X这种)
  5. %5.2f表示输出至少五个位置(物理上,屏幕占的位置)留两位小数,不够的话前面是空白。
    注:不想写5可以省略也可以用*代替,后面多加一个逗号注明
    注:-5代表左对齐
  6. d、s这几个的.2就是实际的保留位数
printf()
int num = 5;
printf("您输入的数字是:%d",num);

返回值是显示的字符个数(在屏幕上占几位),失败返回一个负数

scanf()
int num;
scanf("请输入数字",&num);

返回值是成功读入的项目的个数,错误返回0,文件末尾返回EOF

  • scanf可指定宽度不可指定精度
float ascanf(“%10f”,&a);  //正确
scanf(“%10.2f”,&a);  //错误
  • %*d可以读取后不赋值,比如1,2就可以直接赋给俩变量且能读到’,‘

gets()和puts()

gets()
 char str[100] = "\0";
 gets(str);

  • 优势在于,判断输入结束的标志为回车,因此可以读空格,但scanf读到空格也会终止
  • 新标里被弃用,fgets(str,maxlen,stdin)代替

while (fgets(str, 10, stdin) != NULL){}

返回读取到的字符串的指针,错误返回空指针

puts()
    char str[100] = "www.dotcpp.com";
    puts(str);

> 末尾会有一个\0

拓展

头文件conio.h

  • getch(); 只读取一个字符,输入不显示,不用回车确认!可用于输入密码时
  • getche(); 只读取一个字符,输入显示,不用回车确认!

♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥

内存相关

存储单元分为内存和CPU寄存器

要存储的变量类型有auto extern static register

  • 不专门声明的变量与形参都是auto,存储在动态存储区,函数调用时分配空间,调用结束自动释放。
  • extern外部变量、也就是全局变量。
  • static存储在静态区,仅初始化一次,函数调用完,它的值也不会删掉。
  • register只能是局部变量、形参,不可用&取地址,因为它存储在CPU寄存器

变量的存储方式有静态和动态

数组

展开
int arr1[10];
float arr2[20];
char arr3[30]; //字符数组就是数组,字符串“abcdefg”默认末尾有个\0

  • 二维数组是线性排布的,第一行、第二行。。。以此存储
string.h常用函数
   char string[10];
   char *str1 = "www.dotcpp.com"; //char * 表示指针类型的变量
   //char str1[] = "www.dotcpp.com"也可以,str1是个指针,str1[]是个数组
   
   strcpy(string, str1); //拷贝
   
   strcat(string, str1); //拼接
   //上述两个均在string基础上操作
   
   int flag = strcmp(str1,str2); //从头到尾比较ascii
   //1前面大 0一样 2后面大
   
   char* ret = strchr(str,c); //查找c在str中第一次出现的位置
   //ret等于包含该字母之后的字符串,ret-string以%d输出就是索引
   
   int len = strlen(str);
   //返回字符串长度
   cpy() cmp() cat() 均可以加n,即strncpy...
   

指针与地址

用法

每一个变量占用不同字节,每个字节有一个地址,地址是一个16进制数字

#include<stdio.h>
int main()
{
        int num=2014;
        int *p=&num;   //int*是一种叫指针的数据类型,p是变量名,是一个16进制数 数值上等于num的地址
        printf("num地址=%#x,num=%d\n",&num,num);
        printf("p=%#x,*p=%d\n",p,*p);
        return 0;
}
// num地址= p   num = *p

指针变量32位系统下占4字节,64位系统8字节

数组与指针

数组,&arr[0]表示该数组的地址,arr也代表该数组的地址

int arr[10];
//下面四种都是把arr地址赋给p
int *p = arr; //第一种
int *p = &arr[0];//第二种

int *p; p = arr; //第三种
int *p; p = &arr[0]; //第四种

(p+i)表示数组第i个元素的地址,因此*(p+i) = arr[i];

字符串和字符数组不同
char *arr = "abcdefg";
char arrr[] = "bcdefgh";
printf("%s %s %c",arr,arrr,arr[3]);

arr虽然是个指针变量,但他也可以直接当字符串用,只是不可以给arr[x]赋值

指针可以等于数组(各种数组都可以,区分int *还是char *)首地址、数组名(规定为数组首地址)、字符串常量(char * )

结构体

相当于自定义了一种数据类型

初始化赋值

#include<stdio.h>
struct stu
{
    int age;
    char name[];
};
int main()
{
    struct stu A;
	struct stu B = {18"Tom"};
    A.age = 20;
    //结构体数组赋值,要么直接初始化,要么一个一个赋值,要么strcpy()
    return 0;
}

结构体指针

给结构体初始化时,可以赋多个,比如

struct stu A[3] = {},{},{}
struct stu *p = &A[0];
//p->name访问,注意不是.

共用体

几种不同类型的变量存放在同一内存单元

  • 后存的起作用,之前的失效
  • 不能使用共同体,只能使用共同体里的元素
  • 共用体不可初始化,因为不能对一个内存单元同时赋值

typedef

替换
typedef int A;
A a = 10; //a是int型 值为10
省略struct
typedef struct stu
{
    int age;
    char name[12];
}s;

struct stu A;
s A;//s等价替换了struct stu

枚举类型

简化宏定义
#define MON  1
#define TUE  2
#define WED  3
#define THU  4
#define FRI  5
#define SAT  6
#define SUN  7

enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;

    day = WED;
    printf("%d",day);

预处理

带#的都是预处理,包括头文件、宏定义、条件编译

宏定义

嵌套容易出错!!亲测宏定义max嵌套后功能出错,猜测是因为先替换再计算导致

#define PI 3.14;         可以!
#define A B;              可以!
#define M(x) x+1;         可以!
#define max(a.b) a>b?a:b; 可以!
//相比于函数调用 宏定义效率更高!
//语句可以是多句,逗号隔开!!

包含头文件

<> “”都可以 尖括号从include文件夹查找,双引号从当前源文件查找

条件编译

如果标识符是define,就编译程序段1,否则编译程序段2,其中else可以没有

#ifdef 标识符
程序段 1
#else
程序段 2
#endif    
//ifndef和上述相反
//标识符处可以是常量,判真假决定是否编译

#和##

相当于粘合剂,

#include <stdio.h>

#define v(x) var##x
//把var(x) 转换为varx!!
int main() {
    int var1 = 10;

    printf("%d\n", a(1));

    return 0;
}

printf中,放再多的""也会被合并成一个!但用逗号隔开后,逗号后面的就不会打印了!!

#include<stdio.h>
#define SUM(A, B) printf("A+B=%d\n",(A)+(B))
//#define SUM(A, B) printf(#A "+" #B "=%d\n",(A)+(B))
int main()
{
  SUM(3, 5);
  return 0;
}
//对于这段代码来说,A+B=属于const char*,不会被替换为3+5,只会显示A+B=8,要想替换就要用#
//本质上,预编译阶段会把#A替换为"A"
#include<stdio.h>
#define PrintStr(A) printf(#A)
int main()
{
  PrintStr(你好,C语言\n再见,C语言);
  return 0;
}

强制类型转换

(int)和(int&)强制转换的区别是前者会对数据进行转换,后者是把内存单元的值直接用int型输出

  • char转int(或unsigned int); 正数,高位补0,负数,高位补1;即转换后结果一样;
  • unsigned char 转(int或unsigned int );高位均补0;
  • -int(或 unsigned int ) 转(char或unsigned char); 直接取最低8位
  • 浮点转整型,直接取整数;
  • 整型转浮点,加.0;

细节与技巧

  1. printf("%%")输出一个%
  2. sizeof()是单目运算符,关键字并非函数,可以运算任何数据类型关键字或变量名
  3. while(i++<20){}替换for循环
  4. 嵌套for循环,里面的for条件j<=i省去if判断
  5. continue只能在循环里使用,break还可以在switch中使用
  6. c++的string直接+就可以拼接了!!不用strcat!!
  7. sizeof()一个数组,得到的是strlen()长度+1,因为末位还有个\0
posted @   __Zed  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示