C 学习(1)

人生漫长。开始学就行,慢慢就越学越好。这是一个学习log,可能错误很多,请谨慎辨别

目录

#include 

#define

struct 

百度百科:

函数

for 循环

变量

typedef

#include 

 #include是一个预处理命令,用于包含或插入指定头文件的内容到当前位置。这个命令 告诉编译器在实际编译之前需要做的工作。使用#include可以将头文件的内容插入到源文件中,使得函数声明或宏定义可以在多个文件之间共享。

  • #include <stdio.h>
  • #include "myHeader.h"

在上述代码中,<stdio.h>是标准输入输出头文件,而"myHeader.h"是用户自定义的头文件。使用尖括号<>和双引号""有不同的搜索路径。尖括号告诉编译器在系统路径下查找头文件,而双引号则首先在当前目录下查找,如果未找到,再在系统路径下查找1

#define

在C语言中,#define指令是一种预处理命令,用于创建宏定义。这些宏定义可以是常量、表达式、代码片段甚至是基于条件的编译指令。

宏的主要作用包括自动化频繁使用的序列、提供抽象能力以及方便代码的复用和维护。

的主要优点是它不占用内存空间,因为它只是一个临时的符号,预编译后这个符号就不存在了。

#define的基本语法如下:

#define 标识符  常量(宏定义的内容) 

                                这里的标识符是宏的名称,常量可以是数字、表达式或一段代码。例如:

#define PI 3.14159  //定义一个表示圆周率的宏

#define MAX(a, b) ((a) > (b) ? (a) : (b))

float radius = 5.0f;

float area = PI * radius * radius; //代码中使用宏

在例子中,PI是一个代表圆周率的宏。如果你在代码中使用PI,预处理器会将其替换为3.14159。而MAX是一个带参数的宏,用于计算两个值中的最大值。

宏展开:预处理器会在编译过程中将宏展开成其定义时的文本内容。宏的主要作用包括自动化频繁使用的序列、提供抽象能力以及方便代码的复用和维护。

宏与函数的区别,虽然宏可以像函数一样使用,但它们之间有几个关键区别:

  • 宏在每次使用时都会在程序中插入一份代码,这可能会增加程序的长度。

  • 宏不进行类型检查,因此它们是类型无关的,可以用于任何合法的参数类型。

  • 宏可能会引起运算符优先级的问题,因此建议在宏定义中多使用括号。

struct 

参考链接:struct 结构 - 《阮一峰《C 语言教程》》 - 书栈网 · BookStack

允许自定义复合数据类型,将不同类型的值组合在一起。这样不仅为编程提供方便,也有利于增强代码的可读性。C 语言没有其他语言的对象(object)和类(class)的概念,struct 结构很大程度上提供了对象和类的功能。

下面是struct自定义数据类型的一个例子,然后声明该类型的变量。

声明了一个struct fraction类型的变量f1,这时编译器就会为f1分配内存,接着就可以为f1的不同属性赋值。

  1. struct fraction {
  2. int numerator;
  3. int denominator;
  4. };
  1. struct fraction f1;   声明
  2. f1.numerator = 22;   赋值。
  3. f1.denominator = 7;   赋值。

struct 的数据类型声明语句与变量的声明语句,可以合并为一个语句。

  1. struct book { 
  2. char title[500];
  3. char author[100];
  4. float value;
  5. } b1; 

上面的语句同时声明了数据类型book和该类型的变量b1。如果类型标识符book只用在这一个地方,后面不再用到,这里可以将类型名省略。

指针变量也可以指向struct结构。

  1. // 常写成两个语句
  2. struct book {
  3. char title[500];
  4. char author[100];
  5. float value;
  6. };
  7. struct book* b1;

上面示例中,变量b1是一个指针,指向的数据是struct book类型的实例。

百度百科:

一个指针当用来指向一个结构体、对象时,称之为结构体指针或对象指针

struct  结构体类型名  *指针名;    //结构体指针

#include <iostream>
#include <string>
using namespace std;
class C
{
public:
    int num;
    string name;
};
int main(void)
{
    C obj;
    C *p = &obj;
    p->num = 5;
    p->name = "Tony";
    cout << p->num << p->name << endl;
    return 0;
}

- > 是C语言和C++语言的一个运算符,叫做指向结构体成员运算符,用处是使用一个指向结构体或对象的指针访问其内成员。

- > 和 . 的区别

1、指向不同

一般情况下用“.”,只需要声明一个结构体。格式是,结构体类型名+结构体名。然后用结构体名加“.”加域名就可以引用域 了。因为自动分配了结构体的内存。如同 int a;一样。

而用“->”,则要声明一个结构体的指针,还要手动开辟一个该结构体的内存,然后把返回的指针给声明的结构体指针,才能用“->”正确引用。
typedef struct AWB   这个例子是我自己编的,气死!时隔几个月返回来看,发现还编错了。
{
  float rg;
  float bg;
}awb;

struct AWB *ctx = (struct AWB *)malloc(sizeof(struct AWB));
                      --------将malloc()返回的 void 指针,强制转换成了结构体指针
if (ctx == NULL) {   ------检查分配内存是否成功
        return NULL;
}
memset(ctx, 0, sizeof(struct AWB));   -----内存初始化为0

sub1 = ctx->rg;
sub2 = awb.bg;

free(ctx); -------释放内存

否则内存中只分配了指针的内存,没有分配结构体的内存,导致想要的结构体实际上是不存在。这时候用“->”引用自然出错了,因为没有结构体,自然没有结构体的域了。

2、读法不同

(*a).b 等价于 a->b。"."一般情况下读作"的”。

“->”一般读作"指向的结构体的"。

3、作用的不同
在“结构”一单元中出现的->运算符成为“右箭头选择”,在使用中可以用new_node->value = 10;来代替(*new_code).value = 10;

也就是说在结构中,运算符->是运算符*和运算符.的结合,在上述语句中,他先对new_node间接寻址以定位所指向的结构,然后再选择结构的成员value。

函数

函数是一段可以重复执行的代码。它可以接受不同的参数,完成对应的操作。下面的例子就是一个函数。

  1. int plus_one(int n) {
  2. return n + 1;
  3. }

上面的代码声明了一个函数plus_one()

函数声明的语法有以下几点,需要注意。

(1)返回值类型。函数声明时,首先需要给出返回值的类型,上例是int,表示函数plus_one()返回一个整数。

(2)参数。函数名后面的圆括号里面,需要声明参数的类型和参数名,plus_one(int n)表示这个函数有一个整数参数 

(3)函数体。函数体要写在大括号里面,后面(即大括号外面)不需要加分号。大括号的起始位置,可以跟函数名在同一行,也可以另起一行,本书采用同一行的写法。

(4)return语句。return语句给出函数的返回值,程序运行到这一行,就会跳出函数体,结束函数的调用。如果函数没有返回值,可以省略return语句,或者写成return;

调用函数时,只要在函数名后面加上圆括号就可以了,实际的参数放在圆括号里面,就像下面这样。

  1. int a = plus_one(13);
  2. // a 等于 14

for 循环

for语句是最常用的循环结构,通常用于精确控制循环次数。

1.一般形式为:

for(单次表达式;条件表达式;末尾循环体

{

中间循环体;

}

  1. for (initialization; continuation; action)
  2. statement;

上面代码中,for语句的条件部分(即圆括号里面的部分)有三个表达式。

  • initialization:初始化表达式,用于初始化循环变量,只执行一次。
  • continuation:判断表达式,只要为true,就会不断执行循环体。
  • action:循环变量处理表达式,每轮循环结束后执行,使得循环变量发生变化。

循环体部分的statement可以是一条语句,也可以是放在大括号里面的复合语句。下面是一个例子。

  1. for (int i = 10; i > 0; i--)
  2. printf("i is %d\n", i);-------一条语句

执行过程为:

  1. 求解表达式1;
  2. 求解表达式2。若其值为真,则执行 for 语句中指定的内嵌语句,然后执行第3步;若表达式2值为假,则结束循环,转到第5步;
  3. 求解表达式3;
  4. 转回上面第2步继续执行;
  5. 循环结束,执行 for 语句下面的语句。

执行过程中,“表达式1”只执行一次,循环是在“表达式2”“表达式3”和“内嵌语句”之间进行的。

变量

变量名区分大小写,starStarSTAR都是不同的变量。

有些词在 C 语言里面有特殊含义(比如int),另一些词是命令(比如continue),它们都称为关键字,不能用作变量名。

C 语言的变量,必须先声明后使用。声明变量时,必须把变量的类型告诉编译器。

  1. int height;

上面代码声明了变量height,并且指定类型为int(整数)。

  1. int num = 42;  //变量的声明和赋值,写在一行。
  2. int x = 1, y = 2;  //多个相同类型变量的赋值,可以写在同一行。

不能用变量声明之前定义的常量。

#define a 120    //define 常量

int a;  //这是错误的

变量的作用域

作用域(scope)指的是变量生效的范围

C 语言的变量作用域主要有两种:文件作用域(file scope)和块作用域(block scope)。

文件作用域(file scope)指的是,在源码文件 .c (C 语言的源代码文件,通常以后缀名.c结尾)顶层声明的变量,从声明的位置到文件结束都有效。------全局变量

  1. int x = 1;
  2. int main(void) {
  3. printf("%i\n", x);
  4. }

上面示例中,变量x在文件顶层声明的,从声明位置开始的整个当前文件都是它的作用域,可以在这个范围的任何地方读取这个变量,比如函数main()内部就可以读取这个变量。其它函数也可以

块作用域(block scope)指的是由大括号{}组成的代码块,它形成一个单独的作用域。凡是在块作用域里面声明的变量,只在当前代码块有效,代码块外部不可见。---------局部变量

  1. int a = 12;
  2. if (a == 12) {
  3.   int b = 99;
  4. printf("%d %d\n", a, b); // 12 99
  5. }
  6. printf("%d\n", a); // 12
  7. printf("%d\n", b); // 出错

上面例子中,变量b是在if代码块里面声明的,所以对于大括号外面的代码,这个变量是不存在。

如果同一个名字,既在全局声明了变量,又在函数块里声明了变量,那以最小作用域为准。

全局变量: 在所有函数的外部声明的变量,包括main 函数以外。

静态变量

static 变量为静态变量,当某一个静态变量声明在函数内部时,其初始化只在第一次执行时起作用,随后的执行过程中,变量值将保持上一次执行后的值。

typedef

typedef命令用来为某个类型起别名。

  1. typedef type name;
  2.  typedef  float      float32_t; 

 float类型占用4个字节(32位),其中8位存放指数的值和符号,剩下24位存放小数的值和符号。

上面代码中,type代表类型名,name代表别名。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

search7

请为我点赞!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值