C语言初印象(1.2w字粗略讲讲C)

2023-11-09 09:50
文章标签 语言 讲讲 粗略 1.2 印象

本文主要是介绍C语言初印象(1.2w字粗略讲讲C),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

PS

计算机语言

浅谈语言 - 与自然语言的区别

发展历程

C语言简述

c语言的国际标准

c语言的常用编译器

源文件和头文件

 内存单位以及转换

 C语言的数据类型

第一个c语言程序 

 在屏幕上打印hello world!

运行结果

代码分析

转义字符表

\n

\\和\t

 \'和\"

\ddd

进制转换

ASCⅡ码表

\xdd

字符串

\0

常量与变量

定义变量的方法(变量的初始化)

已定义变量的再赋值

变量命名的注意事项

变量的分类

这里为大家列出输入输出(% + 字符)格式及意义

变量使用

变量的作用域和生命周期

作用域

生命周期

常量

字面常量

const 修饰的常变量(这个本质上属于变量,只是拥有常量的属性)

#define的标识符常量

枚举常量

 注释

注释有两种风格:

C语言风格的注释

C++风格的注释(建议使用这个)

选择语句(分支语句)

分类:

if分支语句模板

 循环语句

分类:

while循环模板

函数

函数定义的模板

数组

数组的定义模板

数组的下标

 数据的使用

操作符

算术操作符

/(除号)

% (取模)

移位操作符

位操作符

赋值操作符

单目操作符(后接上一个操作数)

sizeof(用来计算数据类型、变量的大小,计算出来的结果单位是字节byte)

sizeof和strlen的区别

++,--

关系操作符

逻辑操作符

三目操作符

逗号表达式

下标引用、函数调用和结构成员

常见关键字

extern

typedef

static

修饰局部变量

修饰全局变量

修饰函数

#define 定义常量和宏

define定义常量模板

define定义宏

内存

指针变量模板

指针变量的大小

结构体

结构体模板

结构体变量

写在最后


PS

本文是对C语言进行一个大概的描述!!!对相应的知识点并不进行详细的说明和记录,换句话说就是点到为止,讲点武德!详细知识点可见后续已更blog。


计算机语言

浅谈语言 - 与自然语言的区别

自然语言 - 人与人交流的语言 (汉语、英语等)

计算机语言 - 人与计算机交流的语言(c/c++/python等)

发展历程

首先是一开始计算机科学家运用的机械语言,也就是二进制语言,也就是由0和1组成的一串数字。

可以直接被计算机识别,不用进行编译。

接着就是汇编语言 由ADD SUB等助记符组成的语言。

然后就是B语言。

紧接着,我们如今比较常用的一些高级计算机语言,比如 c / c++ /python。

纵观整个计算机语言发展过程,语言都是逐渐地由低级变为高级

语言也越来越接近我们的自然语言。便于我们人和人之间理解和沟通。


C语言简述

C语言是一种高级的计算机语言,广泛应用于底层开发

说到底层不得不提到这张图(拿JAVA和c举例)(分割线往下是底层

 

 

c语言的国际标准

就像国际基本单位一样,在国际单位制中,将单位分成三类:基本单位、导出单位和辅助单位。 7个严格定义的基本单位是:长度(米)、质量(千克)、时间(秒)、电流(安培)、热力学温度(开尔文)、物质的量(摩尔)和发光强度(坎德拉)。有了这些标准,我们人类社会的科学发展才得以顺利进步。

一个好的计算机语言必须有国际标准,这样才便于这种语言的传播,普及,以及程序员之间的合作和交流。目前C语言比较普及的国际标准是C89C90

c语言的常用编译器

编译器是将高级计算机语言转换为二进制语言的工具。

C语言的常见编译器:ClangGCC、MSVC等。


源文件和头文件

.c 后缀的是c的源文件,.h 后缀是头文件。


 内存单位以及转换

一个bit位可以存储一个二进制的数字(一个0或者1)。


 C语言的数据类型

浮点数也就是小数。

整型就是整数。

有如此多数据类型是因为每种数据类型占用计算机的内存不一样,所以可以达到节约内存空间的效果。

具体数据类型所占内存空间如下表(仅供参考,不同的编译环境有可能不同

数据类型所占内存(单位:byte)
char1

short

2
int4
long4
long long8
float4
double8

 c语言规定 long 的所占内存 >= int 的所占内存


第一个c语言程序 

 在屏幕上打印hello world!

#include <stdio.h>
int main()
{printf("hello world!\n");return 0;
}

运行结果

代码分析

#include <stdio.h>

#开头的是预处理指令

这个语句是引用头文件,stdio是standard input output(标准输入输出)英文缩写。

c语言的标准输出函数 就是 printf(), 标准输入函数 就是  scanf() ,如果需要运用到这两个函数必须引用头文件stdio.h。

main是主函数,在一个项目中必须有且仅有一个

{}花括号里面的是函数内容。

一个函数的模板
返回值类型 函数名(函数参数)
{

        函数内容

        return 返回值;

}

 根据这个模板,我们大概能知道,main前面的 int函数返回值类型

return 0;

return后面接与函数返回值类型对应的数值main 函数 一般的函数返回值类型int返回值 一般是0,非0一般表示程序出错。

main函数建议这样写

int main()
{//内容return 0;
}

 main不建议的写法

void main
{//这种写法非常古老
}

\n转义字符的一种,意思是换行。(转义字符一般来说不显示在程序的输出结果


转义字符表

转义字符
释义
\?在书写连续多个问号时使用,防止他们被解析成三字母词
\'用于表示字符常量'
\“用于表示一个字符串内部的双引号
\\用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a警告字符,蜂鸣
\b退格符
\f禁止符
\n换行
\r回车
\t水平制表符
\v垂直制表符
\dddddd表示1~3个八进制的数字。 如: \130 X
\xdd

dd表示2个十六进制数字。 如: \x30 0

\0字符串结束标志

\n

比方说我们将\n放在hello world!的中间看看是否会换行

#include <stdio.h>
int main()
{printf("hello \n world!");return 0;
}

 运行结果

很明显可以看到这句话是被\n换行了的。

\\和\t

假设我们需要在屏幕上打印一个目录D:\test.c

#include <stdio.h>
int main()
{printf("D:\test.c\n");return 0;
}

运行结果 

 

可以看到输出结果并没有和我们想的那样是D:\test.c

为什么呢?因为\和t结合形成一个转义字符\t,其作用是在屏幕上打印一个大空格(TAB键按出的大空格)

那么想要正确的输出D:\test.c,必须在\前面再加上一个\形成一个转义字符\\,其作用是输出一个\。

#include <stdio.h>
int main()
{printf("D:\\test.c\n");return 0;
}

运行结果

 \'和\"

如何在屏幕上输出一个'和"呢?

代码如下

#include <stdio.h>
int main()
{//问题1:在屏幕上打印一个单引号',怎么做?//问题2:在屏幕上打印一个字符串,字符串的内容是一个双引号“,怎么做?printf("%c\n", '\'');printf("%s\n", "\"");return 0; 
}

\ddd

\ddd表示1~3个八进制数字 也就说可以有 \d ,\dd,\ddd。

 

可以看到\130是八进制下的130转换为十进制是88,那为什么\130对应字符X呢?

首先我们先一个一个来,先看看八进制下130如何转换为十进制下88

进制转换

十进制下123为什么就是123呢?

这就要说到权重问题了

个位对应的权重是10^{0},十位对应的权重是10^{1},百位对应的权重是10^{2}

所以十进制下123就是1*10^{2}+2*10^{1}+3*10^{0}=123(十进制)。

八进制下130 = 1*8^{2}+3*8^{1}+0*8^{0}= 88(十进制)。

由此可知

n进制的权重就是n的k次幂,k由位数决定

那为什么十进制的88对应字母X呢?这就要讲到ASCⅡ码表了

ASCⅡ码表

字母还有一些符号都可以转变为十进制数字,而十进制数字又可以转变为二进制数字,便于计算机储存这些字母和符号。

由表可以知道,X对应88。

\xdd

\xdd 中 dd表示2个16进制数字 16进制 和 8进制的差别就在\后面是否有x

可以看见\x30对应十进制数字48,又对应字符0(零)。 

字符串

"hello world!"

这种由双引号(Double Quote)引起来的一串字符称为字符串字面值String Literal),或者简称字符串

注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容

\0

字符串结束符号,输出时计算机找到该符号表示输出的字符串到此结束。

我们用字符数组存放字符串

#include <stdio.h>
//下面代码,打印结果是什么?为什么?(突出'\0'的重要性)
int main()
{char arr1[] = "abc";//双引号引起来的字符串自带\0char arr2[] = { 'a', 'b', 'c' };char arr3[] = { 'a', 'b', 'c', '\0' };printf("%s\n", arr1);printf("%s\n", arr2);printf("%s\n", arr3);return 0;
}

运行结果 

 我们可以看到arr1因为是用双引号初始化的,所以本身自带\0字符串结束符,所以输出结果正常。

arr2和arr3都是字符数组单个单个元素初始化,唯一不同就是arr3有\0,arr2没有。

所以arr2输出结果不正常,arr3输出结果正常。

无论如何输出字符串都需要找到\0,才算作输出字符串的结束。arr2没有\0,所以输出乱码。


常量与变量

生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)
有些值是可变的(比如:年龄,体重,薪资)。
不变的值, C 语言中用 常量 的概念来表示,变的值,C语言中用 变量 来表示。

定义变量的方法(变量的初始化

​变量定义模板
数据类型 变量名 = 变量值;

int age = 20;
float weight = 45.5;
char ch = 'w';

已定义变量的再赋值

对于一个已定义的变量可以修改它的数值的

比如下面这样,我先对变量age初始化为20,后面我可以用下面这个模板把age变量赋值为18.

已定义变量的再赋值模板

已定义变量 = 数值;

int age = 20;//初始化变量age
age = 18;//已定义变量的再赋值

变量命名的注意事项

只能由字母(包括大写和小写)、数字和下划线( _ )组成。
不能以数字开头。
长度不能超过 63 个字符。
变量名中区分大小写的。
变量名不能使用关键字

变量的分类

局部变量
全局变量
#include <stdio.h>
int a = 2019;//全局变量
int main()
{int local = 2018;//局部变量//下面定义的a会不会有问题?int a = 2020;//局部变量printf("a = %d\n", a);return 0; }

运行结果

 可以看见如果有一个全局变量和局部变量名字相同时,引用时优先使用局部变量。(不建议变量重名

printf函数里面的%d将变量值变成十进制数输出

scanfprintf 输入输出变量值,只能通过%+字符的形式进行。

这里为大家列出输入输出(% + 字符)格式及意义

% + 字符意义
%d十进制整数
%ld更大精度的十进制整数
%u无符号的整数
%c一个字符
%s一个字符串
%f浮点数
%lf更大精度的浮点数
%o八进制整数
%x十六进制整数
%e指数

变量使用

#include <stdio.h>
int main()
{int num1 = 0;int num2 = 0;int sum = 0;printf("输入两个操作数:>");scanf("%d %d", &num1, &num2);sum = num1 + num2;printf("sum = %d\n", sum);return 0; }

这里需要注意的是scanf函数中引用的变量需要在变量前面加上取地址符号(&)

%+字符一定要和变量一一对应上,如果有多个变量用逗号隔开。

一定要注意的是scanf函数里面不能有\n转义字符

变量的作用域和生命周期

作用域

作用域( scope )是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效 可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
1. 局部变量的作用域是变量所在的局部范围。
2. 全局变量的作用域是整个工程。

生命周期

变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
2. 全局变量的生命周期是:整个程序的生命周期。

常量

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

1.字面常量
2.const 修饰的常变量(这个本质上属于变量,只是拥有常量的属性)
3.#define 定义的标识符常量
4.枚举常量

字面常量

#include <stdio.h>
int main()
{//字面常量3.14;//浮点数常量2000;//整型常量'c';//字符常量"hello";//字符串常量printf("%f\n", 3.14);printf("%d\n", 2000);printf("%c\n", 'c');printf("%s\n", "hello");return 0;
}

const 修饰的常变量(这个本质上属于变量,只是拥有常量的属性)

它与一般变量最大的不同就是,const 修饰的常变量不能进行再赋值操作

在初始化数组时,它不能作为数组元素的个数去定义数组,所以它是变量。

#define的标识符常量

枚举常量

修改第一个枚举常量后的结果

不论哪种常量都不可以进行再赋值操作,有一些常量需要初始化。


 注释

1. 代码中有不需要的代码可以直接删除,也可以注释掉
2. 代码中有些代码比较难懂,可以加一下注释文字
注意:注释过的代码不会运行!!!

#include <stdio.h>
int Add(int x, int y) {return x+y; }
/*C语言风格注释
int Sub(int x, int y)
{return x-y;
}
*/
int main()
{//C++注释风格//int a = 10;//调用Add函数,完成加法printf("%d\n", Add(1, 2));return 0;
}

注释有两种风格:

C语言风格的注释

/*xxxxxx*/
缺陷:不能嵌套注释

C++风格的注释(建议使用这个)

//xxxxxxxx
可以注释一行也可以注释多行。

选择语句(分支语句)

如果你好好学习,校招时拿一个好 offer ,走上人生巅峰。
如果你不学习,毕业等于失业,回小区当保安。
这就是选择。

分类:

1. if语句
2. switch语句(后面blog会详细讲,浅浅地提一下)

if分支语句模板

//选择语句、分支语句,每个分支都有前提条件,
//符合前提条件进入分支,执行分支内容。
//判断前提条件时,从上往下判断。
//当你列出的前提条件都不满足时,进入else分支。

if (前提条件)
{
    //该分支内容
}
else if (前提条件)
{
    //该分支内容
}
//...
else
{
    //该分支内容
}

第一个分支语句必须是if语句,后面带小括号(),小括号里面是前提条件,后面接花括号{},括号是分支内容

接下来的语句就是else if语句,后面带小括号(),小括号里面是前提条件,后面接花括号{},括号是分支内容。(else if 语句 可缺省

最后就是else语句,没有小括号和前提条件,后面接花括号{},括号是分支内容。(else 语句 可缺省

例子:

#include <stdio.h>
int main()
{int coding = 0;printf("你会去敲代码吗?(选择1 or 0):>");scanf("%d", &coding);if(coding == 1){printf("坚持,你会有好offer\n");}else{printf("放弃,回家卖红薯\n");}return 0; }

结果:


 循环语句

有一些东西是需要我们坚持的,比如敲代码和学习。

分类:

1.while语句

2.for语句(后面blog会详细讲,浅浅地提一下)

3.do while语句(后面blog会详细讲,浅浅地提一下)

while循环模板

先判断是否符合前提条件,符合就循环一次,每次进入循环前,都需要进行判断直到不符合条件为止

while ( 前提条件 )

{

        //循环内容

}

while语句实例

#include <stdio.h>
int main()
{int line = 0;while(line<=20000){line++;printf("我要继续努力敲代码\n");}if(line>20000)printf("好offer\n");return 0; 
}

注意: line++;  相当于  line = line + 1;  


函数

函数定义的模板

返回值类型 函数名(函数参数)
{

        函数内容

        return 返回值;

}

比如我们想让两个整型num1和num2相加赋值给sum,那我们就要写这个语句。

sum = num1 + num2;

完整代码:

#include <stdio.h>
int main()
{int num1 = 0;int num2 = 0;int sum = 0;printf("输入两个操作数:>");scanf("%d %d", &num1, &num2);sum = num1 + num2;printf("sum = %d\n", sum);return 0; 
}

我们也可以写一个相加函数达成这种效果。

#include <stdio.h>
int Add(int x, int y) //函数原型
{int z = x+y;return z; 
}
int main()
{int num1 = 0;int num2 = 0;int sum = 0;printf("输入两个操作数:>");scanf("%d %d", &num1, &num2);sum = Add(num1, num2);//函数调用,函数返回值赋值给sumprintf("sum = %d\n", sum);return 0; 
}

函数可以简化程序,达到代码重复使用的效果。


数组

C语言中给了数组的定义:一组相同类型元素的集合。

数组的定义模板

数据类型 数组名 [数组中元素个数] = { 初始化内容多个元素初始化用逗号隔开 };
例子
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素

数组的下标

C语言规定:数组的每个元素都有一个下标,下标是从0开始的。
数组可以通过下标来访问的。
比如:
int arr[10] = {0};
//如果数组10个元素,下标的范围是0-9

 数据的使用

#include <stdio.h>
int main()
{int i = 0;int arr[10] = {1,2,3,4,5,6,7,8,9,10};for(i=0; i<10; i++){printf("%d ", arr[i]);}printf("\n");return 0; }

运行结果


操作符

算术操作符

+(加) -(减)  *(乘)   /(除)  %(模)

+,-,* 没什么好说的。

/(除号)

如果是两个整型相除,比如7/2,结果并不是3.5,而是3。

因为整型和整型相除只能得到整型,想让除出来的数是小数(浮点数),必须将其中一个数变成浮点数,比如 7.0/2 或者 7/2.0 最后得出的结果才是 3.5 。

% (取模)

如果两个数取模得到的是他们的相除后得到余数。比如 7%2 得到 1。

移位操作符

<< (左移)    >> (右移)

位操作符

&(按位与)           ^(按位异或)            |(按位或)

赋值操作符

=      +=      -=      *=     /=      &=        ^=       |=        >>=       <<=
=(赋值)大家应该都了解,就不多说了。
+= 这个举个例子
n += 10; 相当于 n = n + 10;
+= 后面的符号和 += 类似,就不赘述了。

单目操作符(后接上一个操作数)

!                   逻辑反操作
-                   负值
+                  正值
&                  取地址
sizeof          操作数的类型长度(以字节为单位)
~                  对一个数的二进制按位取反
--                  前置、后置--
++                前置、后置++
*                   间接访问操作符(解引用操作符)
(类型)           强制类型转换

C语言中 0表示假 非0表示真。

//情况1
a = 0;
!a = 1;//情况2
a = -1;
!a = 0;

sizeof(用来计算数据类型、变量的大小,计算出来的结果单位是字节byte)

#include <stdio.h>
int main()
{printf("%d\n", sizeof(int));return 0;
}

sizeof不是函数,是操作符。

sizeof计算数组时,如果括号里放数组名字,算得的是数组的总大小;

括号如果放数组元素,计算的是数组元素的大小。

sizeof和strlen的区别

strlen 是库函数 

strlen 是求字符串长度的,关注字符串中是否有\0,统计\0之前的出现的字符个数。

sizeof是操作符

sizeof只关注占据了多大的内存空间,不关注内存中存放的内容。

sizeof的返回值单位是字节。

++,--

有两种用法前置++,和后置++。

//如果是像这样单独语句,前置和后置没有区别a++;//后置,相当于a = a + 1;
++a;//前置,相当于a = a + 1;a--;//后置,相当于a = a - 1;
--a;//前置,相当于a = a - 1;//如果嵌套在其他语句中,有区别。前置先计算,再使用。后置先使用,再计算。//情况1 前置
int a = 0;
printf("%d\n", ++a);//结果为1
printf("%d\n", a);//结果为1//情况2 后置
int a = 0;
printf("%d\n", a++);//结果为0
printf("%d\n", a);//结果为1

关系操作符

>          大于
>=        大于等于
<          小于
<=        小于等于
!=         不相等
==        相等

逻辑操作符

&&       逻辑与
||          逻辑或

三目操作符

?   :   ;

条件判断? 条件为真的执行内容 : 条件为假的执行内容 ;

例子

m = a > b ? a : b;

如果a>b成立,a就会赋值给m;不成立b赋值给m。

逗号表达式

exp1 , exp2 , exp3 , …expN
逗号表达式从左往右依次计算,但最后一个表达式的计算结果将是整个逗号表达式的结果。

下标引用、函数调用和结构成员

[]  ----下标引用        () ------ 函数调用       .    ------ 结构成员           -> ------- 结构成员

常见关键字

auto  break   case  char  const   continue  default  do   double else  enum  
extern float  for   goto  if   int   long  register    return   short  signed
sizeof   static struct  switch  typedef union  unsigned   void  volatile  while

extern

可以将函数和变量在同一个项目内跨文件使用。

//test1111.c中的代码
int a = 1000;//test.c中的代码
#include <stdio.h>
extern a;
int main()
{printf("%d\n", a);//结果是1000
}

typedef

typedef 顾名思义是类型定义,这里应该理解为类型重命名。(相当于给数据类型起小名)
比如:
//将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
typedef unsigned int uint_32;
int main()
{//观察num1和num2,这两个变量的类型是一样的unsigned int num1 = 0;uint_32 num2 = 0;return 0; }

static

C语言中:
static是用来修饰变量和函数的
1. 修饰局部变量-称为静态局部变量
2. 修饰全局变量-称为静态全局变量
3. 修饰函数-称为静态函数

修饰局部变量

 结论:

static修饰局部变量改变了变量的生命周期

让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。

修饰全局变量

//代码1
//test1111.c中的代码
int a = 1000;//test.c中的代码
#include <stdio.h>
extern a;
int main()
{printf("%d\n", a);//结果是1000
}
//代码2
//test1111.c中的代码
static int a = 1000;//test.c中的代码
#include <stdio.h>
extern a;
int main()
{printf("%d\n", a);//编译出错
}
代码 1 正常,代码 2 在编译的时候会出现连接性错误。
结论:
一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。

修饰函数

//代码1
//test1111.c中的代码
int Add(int x, int y) 
{return x + y;
}//test.c中的代码
#include <stdio.h>
extern Add(int,int);
int main()
{printf("%d\n", Add(2, 3));//结果是5return 0;
}
//代码2
//test1111.c中的代码
static int Add(int x, int y) 
{return x + y;
}//test.c中的代码
#include <stdio.h>
extern Add(int,int);
int main()
{printf("%d\n", Add(2, 3));//编译出错return 0;
}
代码 1 正常,代码 2 在编译的时候会出现连接性错误 .
结论:
一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。  

#define 定义常量和宏

#include #define 预处理指令

define定义常量模板

#define 常量名字 数值

define定义宏

宏是有参数的,和函数很像。

例子

#define ADD(x, y) ((x) + (y))

宏的参数没有数据类型,用宏是一定需要用括号,避免出错。

宏的本质是替换,函数是调用。


内存

为有效使用内存空间,把内存划分为一个个小的内存单元(一个内存单元的大小是一个字节。)

类似于把一栋楼划分为一户户人家。而每个地址都有储存有一个数值。

如果把计算机的内存比作一栋楼的话,每一个内存单元都相当于一户人家,而每户人家都有编号,内存单元的编号就称为地址,而每户人家里面的,就相当于存放的数值

32位机器有32位地址线,状态(1/0)。

可以管理2的32次个内存单元。所以32位机器可以管理 2的32次byte == 4gb的内存空间。

编号 == 地址 == 指针 。

变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。
取出变量地址如下:
#include <stdio.h>
int main()
{    int num = 10;&num;//取出num的地址//注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)printf("%p\n", &num);//打印地址,%p是以地址的形式打印return 0; 
}

对于占多个内存单元的变量,取该变量的地址,是取该变量的首地址。取内存单元的个数由变量的数据类型决定。

那地址如何存储,需要定义指针变量。指针变量可以用来储存地址。

指针变量模板

对应变量数据类型 * 指针变量名 = &对应变量

*说明是指针变量。

1.指针本质是地址。

2.口头语中,说的 “指针” 是 “指针变量”。

指针变量用来存对应变量的首地址,根据其数据类型可以找到对应变量。

int num = 10;
int *p;//p为一个整型指针变量
p = &num;//p指向num

 指针的使用实例:

#include <stdio.h>
int main()
{int num = 10;int *p = &num;*p = 20;//相当于 num = 20;return 0; 
}

 以整形指针举例,可以推广到其他类型,如:

#include <stdio.h>
int main()
{char ch = 'w';char* pc = &ch;*pc = 'q';printf("%c\n", ch);return 0; 
}

指针变量的大小

#include <stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{printf("%zu\n", sizeof(char *));printf("%zu\n", sizeof(short *));printf("%zu\n", sizeof(int *));printf("%zu\n", sizeof(double *));return 0; 
}
注意:%zu专门返回sizeof的返回值。
结论
指针大小在 32 位平台是 4 个字节,64位平台是 8 个字节。
使用指针变量时,一定要给指针变量初始化,这样才有指向对象,才可以调用。

结构体

结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
定义复杂对象时,可以使用结构体。

结构体模板

struct 结构体名字

{

        //结构体成员

        //描述结构体的相关数据

};

结构体变量

struct 结构体名字 结构体变量 //结构体变量的定义

结构体变量.结构体成员  //访问成员

结构体指针变量->结构体成员  //访问成员

比如描述学生,学生包含: 名字+年龄+性别+ 学号 这几项信息。
这里只能使用结构体来描述了。
例如:
struct Stu
{char name[20];//名字int age;      //年龄char sex[5];  //性别char id[15]; //学号
};
结构体的初始化:
//打印结构体信息
struct Stu s = {"张三", 20, "男", "20180101"};
//.为结构成员访问操作符
printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id);
//->操作符
struct Stu *ps = &s;
printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps- >id);

写在最后

有错误的地方希望大家指出,有问题的也可以在评论区讨论。

这篇关于C语言初印象(1.2w字粗略讲讲C)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/375395

相关文章

usaco 1.2 Palindromic Squares(进制转化)

考察进制转化 注意一些细节就可以了 直接上代码: /*ID: who jayLANG: C++TASK: palsquare*/#include<stdio.h>int x[20],xlen,y[20],ylen,B;void change(int n){int m;m=n;xlen=0;while(m){x[++xlen]=m%B;m/=B;}m=n*n;ylen=0;whi

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (

usaco 1.2 Milking Cows(类hash表)

第一种思路被卡了时间 到第二种思路的时候就觉得第一种思路太坑爹了 代码又长又臭还超时!! 第一种思路:我不知道为什么最后一组数据会被卡 超时超了0.2s左右 大概想法是 快排加一个遍历 先将开始时间按升序排好 然后开始遍历比较 1 若 下一个开始beg[i] 小于 tem_end 则说明本组数据与上组数据是在连续的一个区间 取max( ed[i],tem_end ) 2 反之 这个

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

如何确定 Go 语言中 HTTP 连接池的最佳参数?

确定 Go 语言中 HTTP 连接池的最佳参数可以通过以下几种方式: 一、分析应用场景和需求 并发请求量: 确定应用程序在特定时间段内可能同时发起的 HTTP 请求数量。如果并发请求量很高,需要设置较大的连接池参数以满足需求。例如,对于一个高并发的 Web 服务,可能同时有数百个请求在处理,此时需要较大的连接池大小。可以通过压力测试工具模拟高并发场景,观察系统在不同并发请求下的性能表现,从而

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,