数据结构中的C语言编程基础_编写数据结构的格式c语言-程序员宅基地

技术标签: c语言  数据结构  

​ 在学习数据结构时,需要我们编写许多的程序,对于一些变量的定义、结构体的声明、指针的使用,需要有一个统一的标准,这样才能方便我们使用、并简化记忆难度。

​ 本文结合自身的编程经验和高分笔记中对考研数据结构编程的一些建议,整理出这么一篇C语言编程入门基础,主要面向数据结构中数据类型的定义,希望能对你有所帮助。

1.Hello World示例

#include <stdio.h>
 
int main()
{
    
   /* 我的第一个 C 程序 */
   printf("Hello, World! \n");
   
   return 0;
}

​ 上面就是编程语言学习的’创世之光’–Hello World!,只要他执行成功了,那么我们就算是一只脚踏进了圈子。

资源分配图

​ 一个基础的C程序,主要包含五个部分:预处理器指令(include加载的头文件)、函数、变量、语句&表达式、注释。

2.C基础语法

​ C语言的基础语法,不在本文赘述,可以参考下面文章进行学习或复习。

C语言教程

3.输入与输出

​ 当我们提到输入时,这意味着要向程序填充一些数据。输入可以是以文件的形式或从命令行中进行。C 语言提供了一系列内置的函数来读取给定的输入,并根据需要填充到程序中。

​ 当我们提到输出时,这意味着要在屏幕上、打印机上或任意文件中显示一些数据。C 语言提供了一系列内置的函数来输出数据到计算机屏幕上和保存数据到文本文件或二进制文件中。

​ 当然,我们在基本的编程练习时,不需要涉及到文件的操作,只需要通过键盘、屏幕进行数据的输入与输出。在本文中,我们主要讲下scanf() 和 printf() 函数。

3.1输入

​ scanf函数的声明如下:

int scanf(const char *format, ...);

​ 使用C的输入输出函数,有一点比较让初学者头疼,就是较为繁多的%s、%d等等。不过了解了之后,还是很方便使用的。

资源分配图
#include <stdio.h>

int main(void)
{
    
    int a,b,c;
    printf("请输入三个数字:");
    scanf("%d%d%d",&a,&b,&c);
    printf("%d,%d,%d\n",a,b,c);
    printf("请再输入三个数字:");
    scanf("%d, %d, %d",&a,&b,&c);
    printf("%d,%d,%d\n",a,b,c);
    return 0;
}

​ 执行结果如下图所示,一定要注意,scanf中的format不要有过多的修饰,比如:scanf(“please input three numbers:%d%d%d”,&a,&b,&c),因为format决定了你输入数据时的结构。如scanf("%d%d%d",&a,&b,&c),几个输入之间可以使用空格分隔,而scanf("%d, %d, %d",&a,&b,&c),必须使用’,‘分隔,且’,'前不能有空格。

资源分配图

3.2输出

​ 输出的函数printf的声明如下:

int printf(const char *format, ...);

​ 其中的参数format是字符串,包含了要被写入到标准输出 stdout 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是 %[flags][width][.precision][length]specifier,具体讲解如下:

资源分配图

​ 其余更细致的文档说明,可以参考这篇文档

#include <stdio.h>
int main()
{
    
   char ch = 'A';
   char str[20] = "lizishudd.blog.csdn.net";
   float flt = 10.234;
   int no = 150;
   double dbl = 20.123456;
   printf("字符为 %c \n", ch);
   printf("字符串为 %s \n" , str);
   printf("浮点数为 %f \n", flt);
   printf("整数为 %d\n" , no);
   printf("双精度值为 %lf \n", dbl);
   printf("八进制值为 %o \n", no);
   printf("十六进制值为 %x \n", no);
   return 0;
}

​ 执行结果如下图所示:

资源分配图

4.数组

4.1一维数组

​ 数组由多个相同数据类型的变量组合起来的,数组的声明方式如下,其中type为变量类型。

#define arraySize = 5
//arraySize为已经定义的常量
type arrayName [ arraySize ];
//for example
int a[5];

​ 数组的初始化,可以通过定义时初始化或通过键盘输入初始化。主要代码如下:

#include <stdio.h>
#define arraySize 5

int main(int argc, const char * argv[]) {
    
    //arraySize为已经定义的常量
    int a[arraySize];
    //定义时初始化
    //如果b[]中不限制长度,则数组的长度由{}中的元素个数觉得
    int b[5] = {
    1, 3, 5, 7, 9};
    printf("请输入数组中的值:");
    for(int i = 0; i<arraySize; i++){
    
        scanf("%d", &a[i]);
    }
    printf("数组A中的值:");
  	//通过输入初始化数组
    for(int i = 0; i<arraySize; i++){
    
        printf("%d ", a[i]);
    }
    printf("\n");
    printf("数组B中的值:");
    for(int i = 0; i<sizeof(b)/sizeof(int); i++){
    
        printf("%d ", b[i]);
    }
    printf("\n");
    return 0;
}

​ 执行结果如下:

资源分配图

4.2二维数组

​ C 语言支持多维数组。多维数组声明的一般形式如下:

type name[size1][size2]...[sizeN];
//for example
int threeDim[5][10][4];

​ 一般我们只会用到二维数组,更高维度的数组理论上都是相同的。一个二维数组可以认为是带有x行、y列的表格,如int x[3][4],他是一个包含三行、四列的二维数组。

资源分配图

二维数组的初始化和一维数组类似,可参考下面代码:

int a[3][4] = {
      
 {
    0, 1, 2, 3} ,   /*  初始化索引号为 0 的行 */
 {
    4, 5, 6, 7} ,   /*  初始化索引号为 1 的行 */
 {
    8, 9, 10, 11}   /*  初始化索引号为 2 的行 */
};
//内部嵌套的括号是可选的,下面的初始化与上面是等同的:
int a[3][4] = {
    0,1,2,3,4,5,6,7,8,9,10,11};
//也可以通过键盘输入来初始化
for(i = 0; i < 3; i++){
    
  printf("请输入%d行的数据:", i+1);
  for(j = 0; j < 4; j++){
    
    scanf("%d", &a[i][j]);
  }
  printf("\n");
}

​ 当数组作为函数的参数是,函数的定义应当如何写?

//void 参数都是可调的
//一维数组作为参数的函数定义方法如下
void f(int x[], int n){
    
  //insert code here ...
}
//二维数组作为参数的函数定义方法如下
//不需要传入行数,必须传入列数,且传入的数组的第二维度的长度必须是maxSize
void f(int x[][maxSize], int n){
    
  //insert code here ...
}

5.指针

​ 指针一直是让人恐惧的知识点,但是在数据结构中,指针是你无法逃避的。不过指针的学习既简单又有趣,需要我们去正确的面对。通过指针,可以简化一些编程任务的执行。还有一些任务,如动态内存分配,没有指针是无法执行的。

​ 对于其他类型的变量,变量里装的是数据元素的内容,而指针变量里装的是变量的地址,通过它可以找出这个变量在内存中的位置,就像一个指示方向的指针,指出某个变量的位置。

​ 对于每种变量,指针的定义方法都有相似的规则,如以下语句:

//int型变量的定义语句,int a
int *a;
char *b;
float *a;
//结构体,参考第6节的内容
TypeA *d;

​ 与其他变量的定义相对比,指针型变量的定义只是在变量名之前多一个’*’。对于指针地址、变量的解释,可以参考下图:

资源分配图

​ 指针使用的案例如下所示,更详细的用法还需要读者自行探索。

#include <stdio.h>

int main(int argc, const char * argv[]) {
    
    int  var = 20;   /* 实际变量的声明 */
    /*
     指针变量的声明
     如果无明确的指向,赋值为NULL
     */
    int  *ip = NULL;
    /* 在指针变量中存储 var 的地址 */
    ip = &var;
    printf("var 变量的地址: %p\n", &var);
    /* 在指针变量中存储的地址 */
    printf("ip 变量存储的地址: %p\n", ip);
    /* 使用指针访问值 */
    printf("*ip 变量的值: %d\n", *ip);
    return 0;
}

6.结构体

​ 了解结构体前,需要知道typedeftypedef可以理解为给现有的数据类型起一个新名字,如:

typedef struct {
    ...} TypeA

​ 新定义的结构体没有名字,因此用typedef给他起个名字是有必要的。

结构体就是系统提供给程序员制作新的数据类型的一种机制,即可以用系统已有数据类型(int,char,float…)或用户定义的结构型为原料,组合成用户需要的复杂数据类型。(可以理解成面向对象编程中的类)

​ 一般而言,可以在创建结构体时定义变量,但是为了书写统一,我们先通过typedef定义新类型,在创建新的变量。

//用typedef创建新类型
typedef struct
{
    
    int a;
    char b;
    double c; 
} TypeA;
//现在可以用TypeA作为类型声明新的结构体变量
TypeA a, a1[20], *a2;

​ 可以看到,结构体定义后,可以和int、char等基本数据类型一样使用,用于定义数组、指针等。当需要访问数组中的数据时,可以通过a1[index].a来访问。示例如下所示:

#include <stdio.h>

typedef struct
{
    
    int a;
    char b;
    double c;
} TypeA;

int main() {
    
    //现在可以用TypeA作为类型声明新的结构体变量
    TypeA a = {
    1, 'a', 12};
    printf("a中的值为:%d,%c,%f\n", a.a, a.b, a.c);
    TypeA *a2 = &a;
  	//需注意,a2->a或(*a2).b
    printf("a2中的值为:%d,%c,%f\n", a2->a, (*a2).b, a2->c);
    TypeA a3[2];
    a3[0] = a;
    a3[1] = a;
    printf("a3[0]中的值为:%d,%c,%f\n", a3[0].a, a3[0].b, a3[0].c);
    printf("a3[1]中的值为:%d,%c,%f\n", a3[1].a, a3[1].b, a3[1].c);
    return 0;
}

​ 在数据结构中,结构体更常见的应用,是和指针结合起来构造结点(链表的结点、二叉树的结点等)。下面我们来一起看下常用结点的"构造"。

6.1链表结点

​ 链表结点有两个域:一个是数据域,用于存放数据;另一个是指针域(指针域可以有多个,如双向链表结点),用于存放下一个结点的位置,链表结点的结构型定义如下:

typedef struct Node{
    
  //这里默认是int型,如其他类型可以修改
  int a;
  //指向Node型变量的指针
  struct Node *next;
}Node;

注意:凡是结构型内部含有指向和自己相同类型的指针,即Node结点中有指向Node结点的指针变量,则在定义Node的语句后,需要加上Node这个结构型的名字,如typedef struct Node。读者可以自己对比下上面定义和上一小节中TypeA定义的区别。

6.2二叉树结点

​ 二叉树结点的构造,也是由链表结点引申出来的,其余类型的结点也都可以类似的进行扩展。二叉树结点的结构型如下:

typedef struct BTNode{
    
  //这里默认是int型,如其他类型可以修改
  int data;
  //指向左孩子结点的指针
  struct Node *lchild;
  //指向右孩子结点的指针
  struct Node *rchild;
}BTNode;

6.3创建新结点

​ 通过上面讲解,我们也基本知道了结构型结点的定义方法,定义方法还有其他的不同写法,不过我们不用关心太多,以增加记忆负担和理解难度。结构型定义好后,就要用它来制作新结点了。

​ 以二叉树结点为例,创建结点有以下两种写法:

//1
BTNode aNode;
//2
BTNode *bNode;
bNode = (BTBode *) malloc(sizeof(BTNode));

​ 其中,1理解起来比较容易;对于2,分为了两步,首先定义一个结点的指针bNode,然后通过malloc()来申请一个节点的内存空间,最后让指针bNode指向这片内存空间。

​ 其中malloc()函数很重要,需要掌握,以后所有的内存分配基本都可使用malloc()来完成。malloc()的函数声明如下:

void *malloc(size_t size)

​ 通过malloc()申请空间的通用公式如下,其中①、②处填写你所定义的结构型名称,p为指针、指向新创建的结点,sizeof()函数用于测算所需要申请的空间大小。

p = (*)malloc(sizeof()) 

​ 我们还可以通过malloc()来动态的申请数组空间,相对于上面的申请方法,可以认为动态申请了一组空间,语法如下,可以通过p[1]来取第二个元素。

int *p;
p = (int *) malloc(n * sizeof(int));

​ 使用示例如下:

#include <stdlib.h>

    //可以将代码放入第六节中的测试代码中
    //...
		TypeA *node;
    node = (TypeA *)malloc(sizeof(TypeA));
    node->a = 2;
    node->b = 'A';
    node->c = 13;
    printf("node中的值为:%d,%c,%f\n", node->a, node->b, (*node).c);
		//return 0;

参考资料:

1.菜鸟教程–C 语言教程

2.数据结构高分笔记


​ 又到了分隔线以下,本文到此就结束了,本文内容全部都是由博主根据自身理解与对考研资料进行的整理,仅作为参考,大佬有什么问题,可以评论区留言,如果有什么错误,还请批评指正。

​ 本专栏为数据结构知识,喜欢的话可以持续关注,如果本文对你有所帮助,还请还请点赞、评论加关注

​ 有任何疑问,可以评论区留言。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34666857/article/details/119987034

智能推荐

js 字符串转换成数字的三种方法_autojs字符转数字-程序员宅基地

文章浏览阅读3.9k次。随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)、博主微信(guyun297890152)、QQ技术交流群(183198395)。from:https://www.cnblogs.com/zfyouxi/p/4348280.html在js读取文本框或者其他表单数据的时候获得的值是字符串类型的,比如两个文本框a和b,假设获得a的value值..._autojs字符转数字

linux延时函数及头文件,linux延时函数-程序员宅基地

文章浏览阅读1.4k次。应用程序的延时函数:头文件: #include 函数:unsigned int sleep (unsigned int seconds);//n秒此外:int usleep (useconds_t usec);//n微秒实际上用select不错的选择,如下:#include#includevoid Sleep(int seconds,int useconds){struct timeval tim..._linux 用户层ms延时需要引入那个头文件

pytorch和tensorflow有什么区别?_pytorch和tensorflow的区别-程序员宅基地

文章浏览阅读4.2w次,点赞27次,收藏227次。PyTorch 是一种用于构建深度学习模型的功能完备框架,同时tensorflow也是常用的框架之一。大家在学习的时候,尝尝会用来做比较。那么pytorch和tensorflow有什么区别?大家所关心的问题,解答来了。pytorch和tensorflow有什么区别?创建和运行计算图可能是两个框架最不同的地方。在PyTorch中,图结构是动态的,这意味着图在运行时构建。而在TensorFlow中,图结构是静态的,这意味着图先被“编译”然后再运行。举一个简单的例子,在PyTorch中你可以用标准的Python语_pytorch和tensorflow的区别

docker 常见问题_backing file system is unsupported for this graph -程序员宅基地

文章浏览阅读379次。容器不停 restartingdocker logs [container_id] 查看日志_backing file system is unsupported for this graph driver

eclipse反编译离线安装_eclipse反编译插件离线安装-程序员宅基地

文章浏览阅读435次。反编译安装步骤_eclipse反编译插件离线安装

11-标志寄存器+adc/sbb+cmp+条件转移指令-程序员宅基地

文章浏览阅读1.1k次。CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有以下三种作用:用来存储相关指令的某些执行结果用来为CPU执行相关指令提供行为依据用来控制CPU的相关工作方式这种特殊的寄存器在8086CPU中,被称为标志寄存器。8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW)。在后面我们将标志寄存器简称为flag。flag和其他寄存器不一样,其他寄存器都是用来存放数据的,都是整个寄存器具有一个含义。而flag寄存器是按位起作用的,也就是说,,_cmp+

随便推点

论文笔记:A Lip Sync Expert Is All You Need for Speech to Lip Generation In The Wild-程序员宅基地

文章浏览阅读1.9k次,点赞6次,收藏8次。论文笔记:A Lip Sync Expert Is All You Need for Speech to Lip Generation In The Wild_a lip sync expert is all you need for speech to lip generation in the wild

解决Android Studio 不自动提示问题_android studio 没有提示-程序员宅基地

文章浏览阅读4.2k次,点赞6次,收藏10次。解决Android Studio 不自动提示问题第一种 :一般是由于Android ButterKnife Zelezny插件导致的,在Settings=>Plugins里卸载掉后File---restart IDE 解决!_android studio 没有提示

HBase中Java操作数据库增删改查——删除数据/删除数据表_删除表的流程代码如下: hbaseadmin admin = new hbaseadmin(cfg)-程序员宅基地

文章浏览阅读1.8k次。已经创建了一个学生宿舍管理系统数据表表名:student_info列族1:students列族2:dormitorys列族3:staff_members例如:删除数据表中行键为001的数据:package myhbase;import java.io.IOException;import java.util.ArrayList;import org.apache..._删除表的流程代码如下: hbaseadmin admin = new hbaseadmin(cfg); if (admin.

【ClickHouse 极简教程-图文详解原理系列】ClickHouse 主键索引的存储结构与查询性能优化..._nodejs操作clickhouse-程序员宅基地

文章浏览阅读1w次。概述这是 Alexey Milovidov(ClickHouse 的创建者)给出的关于复合主键的答案的翻译。原文: https://groups.google.com/g/clickhouse/c/eUrsP30VtSU/m/p4-pxgdXAgAJ问题:主键可以有多少列?存储驱动器上的数据布局是什么?有任何理论/实践限制吗?某些行缺少数据的列可以成为主键的一部分吗?This is......_nodejs操作clickhouse

用unittest做单元测试,编写测试用例详细操作步骤-程序员宅基地

文章浏览阅读3.9k次,点赞5次,收藏13次。废话不多说,具体如下:一、什么是unittest?unittest模块是python自带的一个单元测试模块,我们可以用来做单元测试。unittest模板包含了如下几个子模块:测试用例:TestCase测试集:TestSuit加载用例:TestLoader执行用例:TextTestRunner这四个都是unittest模块中的类,整个单元测试的工作模块,就是这几大类。二、了解了什么是unittest,来编写自己的第一个测试类eg:编写一个数学方法类,类里面有加法以及减法两个函数。代码如

Anaconda 换国内源_conda 换源-程序员宅基地

文章浏览阅读7.4w次,点赞46次,收藏189次。由于国外下载速度太慢,这里就有了国内的一些镜像源进行下载Anaconda 换源清华源在cmd 命令行中,输入添加以下命令(前提是要安装了Anaconda包管理工具)conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda_conda 换源

推荐文章

热门文章

相关标签