c语言入门高级教学(下)

前言

此文章为c语言高级教学续作,有需要可以直接去结语找上部分。由于是初学,很多内容都是点到为止。难免有错误,请各位读者指正。

1.数组

1.1数组的定义

要存储1-10的数字,怎么存储?
C语言中给了数组的定义:一组相同类型元素的集合

int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素

这里我们定义了一个数组,数组名是arr, [10]里面的是元素的个数,int是数组元素的类型。

1.2数组的下标

C语言规定:数组的每个元素都有一个下标,下标是从0开始的。
数组可以通过下标来访问的。

int arr[10] = {0};
//如果数组10个元素,下标的范围是0-9
int arr0000000000
下标0123456789

小插曲之for循环语句讲解

在此之前,我们先讲一下for循环,有助于理解下面的代码。

1.for循环的语法

for(表达式1; 表达式2; 表达式3)
  循环语句;
  • 表达式1
    表达式1为初始化部分,用于初始化循环变量的。
  • 表达式2
    表达式2为条件判断部分,用于判断循环时候终止。
  • 表达式3
    表达式3为调整部分,用于循环条件的调整。

这样不太好理解,我们看一个实际的问题:
请用for循环 在屏幕上打印1-10的数字。

#include <stdio.h>
int main()
{
	int i = 0;
	//for(i=1/*初始化*/; i<=10/*判断部分*/; i++/*调整部分*/)
	for(i=1; i<=10; i++)
	{
		printf("%d ", i);
	}
    return 0;
} 

2.for循环的执行流程

i=1
i<=10
%d , i
i++

1.3数组的使用

#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;
}

1.3变长数组

int main()
{
    int arr1[10] = {0};
    int arr2[2 + 8] = {0};
    //上述了两个数组的定义均正确
    //在C89标准中数组元素个数的定义必须为常量表达式
    int n = 10;
    int arr3[n];
    //上述了这个数组的定义正确
    //在C99标准中支持了变长数组,数组的元素可以是变量,在C99标准中arr3,arr2,arr1的定义都是没有问题的
    //int arr3[n] = {0};对变长数组进行初始化,是不正确的
    return 0;
}

注意:这个变长数组是不能初始化的,而且由于VS对C99语法的支持较差,所以这个代码在VS上编译会报错。

2.操作符

2.1算术操作符

  • 加 - 减 * 乘 / 除 % 取余
#include<stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    printf("%d %d %d %d %d\n",a + b,a - b,a * b,a / b,a % b,b / a);//30,-10,200,0,10,2
    a += b;//a = a + b
    a -= b;
    a *= b;
    a /= b;
    a %= b;
    printf("%d %d %d %d %d\n",a,a,a,a,a);//30,-10,200,0;10
    int c = 9 / 2;//4
    float c = 9 / 2;//4.000000
    float d = 9.0 / 2;//4.500000
    float d = 9 / 2.0;//4.500000
    return 0;
}

1.+,-,*,/应该不用说了,就和我们现实中一样使用。但是这里要注意一点,因为a,b都是整形数,所以a / b的结果也是整型数,但是a / b是小数,只能舍弃小数,结果就是0,但是b / a的结果是整数,就保留。如果两个数相除,结果为小数,保留整数,舍弃小数。
2.%是取余的意思,意思是a / b剩余的余数,%是双目操作符,要求运算的数字必须是整数,上面的a / b = 0,余数是0。
3.当我们进行小数运算时,需要除号两边的数字其一为浮点数即可。其中浮点数默认为double类型!
4.还有一点,a += b等价于a = a + b, + - * /都可以这样,这是为了简化书写。

小插曲之二进制

需要明白二进制才能看懂后面的操作符,给大家推荐一个还不错的文章,讲二进制的!

https://blog.csdn.net/weixin_43314519/article/details/107443049?utm_source=app&app_version=5.3.0&code=app_1562916241&uLinkId=usr1mkqgl919blen

2.2移位操作符

<< >>

int main()
{
    int a = 39;
    int b = a << 1;
    int c = a >> 1;
    printf("%d%d\n",b,c);//78 19
	return 0;
}

image-20220418232835256

2.3位操作符

& ^ |

int main()
{
    int a = 3;
    int b = 5;
    int c = a & b;
    int d = a | b;
    int e = a ^ b;
    printf("%d\n%d\n%d\n",c,d,e);
	return 0;    
}

2.4赋值操作符

= += -= *= /= &= ^= |= >>= <<=

一样的套路,这里咱就不废话了。

2.5单目操作符

逻辑反操作 !

负值 -

正值 +

二进制按位取反 ~

取地址 &

解引用操作符 *

sizeof 操作数的类型长度(以字节为单位)
– 前置、后置–
++ 前置、后置++

间接访问操作符(解引用操作符)*
(类型) 强制类型转换

这个不太好说,我们结合代码看看。

1.逻辑反操作!

//注意:在c语言中,0表示假,非0表示真(一般取1为真)    
    int flag = 5;
		if(!flag)
        {
			prinf("haha\n");
        }

2 负值 - 正值 +

int a = -12;
int b = -a;//12
printf("%d\n",b);
int c = +a;//-12 //负数前面加一个+,仍然是负数
printf("%d\n",c);

3 ~二进制按位取反

int main()
{
    int a = 1;
    int b = ~a;
    //先将a转为二进制数,再将符号位和数字为全部取反。
    //通俗的说,就是把1全部变成0,把0全部变成1。
    return 0;
}

不懂没关系,有个印象就可以了,以后再细说。

4 取地址 & 解引用操作符 *(先不讲,指针后面会讲)

5 前置,后置++ 前置,后置–

int a = 12;
int b = a++;//后置++,先赋值,在自增
//先赋值b = a,再自增a = a + 1 
b = 12,a = 13
-----------------------------
int a = 10    
int b = ++a;//前置++,先自增,在赋值
//先自增a = a + 1,再赋值b = a
b = 11,a = 11
-----------------------------
/,后置-- 用法一样
int c = 15;
int d = c--;//d = 15,c = 14
int e = 11;
int f = --e;//f = 10,e = 10  sizeof 操作数的类型长度(以字节为单位)

6 强制类型转化 ()
c int a = (int) 2.31; //()把浮点数2.31强制转化为整形数2,转化的过程中会发生数据截断,0.31被截断丢弃 //浮点数一般不标识数据结构,字面浮点数默认为double类型

7 sizeof 操作数的类型长度(以字节为单位)

  int a = 0;
      //%zu是标准用于计算sizeof
      printf("%d\n",sizeof(a));//4
      printf("%zu\n",sizeof(int));//4 
      //当sizeof后面跟数据类型时,打印的是此类型的字节长度,()不可与省略,
      printf("%zu\n",sizeof a);//4 
      //后面是变量,()可省略不写,同时说明sizeof不是一个函数
      ---------------------------
      int arr[10] = {0};
      printf("%d\n",sizeof(arr));//40 
      //此时计算的是整个数组的大小,单位是字节
      printf("%d\n",sizeof(arr[0]));//4 
      //此时计算的是数组第一个元素的大小 
      printf("%d\n",sizeof(arr) /sizeof(arr[0]));//10
      //此时计算的数组的个数

2.6关系操作符

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

这个没什么好讲的

大于 >= 大于等于 < 小于 <= 小于等于
/这里重点强调一下 c语言中等号是== ,=是赋值的意思,初学者容易混淆,我曾经就犯过这种错误

2.7逻辑操作符

&&  逻辑与(也叫短路与) 
||  逻辑或(也叫短路或)
int a = 0;
int b = 0;
int c = 1;
int d = 2;
if(a && b)//a,b均为假,条件为假,不打印
{
    printf("假");
}
if(a || b)//a,b均为假,条件为假,不打印
{
    printf("假");
}
if(a || c)//a,c一真一假,条件为真,打印
{
	printf("真");
}
if(a && d)//a,d均为真,条件为真,打印
{
    printf("真");
}
if(a && c)//a,c一真一假,条件为假,不打印
if(c || d)//a,d均为真,条件为真,打印

&& 必须是两边的条件均为真,才执行
|| 当两边的条件有一个为真,就执行
为什么又叫短路与和短路或呢?
&& 第一个条件为假时,后面的就不用判断了,语句为假
|| 第一个条件为真时,后面的就不用判断了,语句为真

2.8条件操作符

exp1 ? exp2 : exp3
//三目操作符 
//当exp1为真时,执行exp2,当exp1为假时,执行exp3
int a = 34;
int b = 23;
int c = a > b? a : b//求a,b的最大值

2.9逗号表达式

exp1, exp2, exp3, …expN
//逗号表达式就是用逗号隔开的一串表达式
//特点是:从左到右依次计算各个表达式,
//整个逗号表达式的结果是最后一个表达式的结果
#include<stdio.h>
int main()
{
    int a = 12;
    int b = 25;
    int c = 23;//a = 8 b = 33 c = 19 a = 22
    int ret = (a -= 4,b += a,c -=4,a = a + b - c)
    printf("%d\n",ret);//22
    return 0;
}

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

[] () . ->

先讲一下前两个,后两个会在结构体中讲到

下标引用操作符 []

int arr[10] = {1,2,3,4,5,6,7,8,9,10};
arr[1] = 23; 
//[]就是下标引用操作符,arr和[]就是操作数
//我们可以通过下标访问数组中的元素

函数调用操作符()

int Add(int x,int y)//()就是函数调用操作符
{
	return x + y;
}
int main()
{
    int sum = Add(3,7)//Add,3,7都是()的操作符
//这里的()不能省略,我们之前说过,sizeof可以省略(),也说明sizeof不是函数
    return 0;
}

3.常见关键字

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

关键字关键字作用
char声明字符型变量或函数
float声明单精度浮点型变量或函数
int声明整型变量或函数
double声明双精度浮点型变量或函数
void声明函数无返回值或无参数,声明无类型指针
short声明短整型变量或函数
long声明长整型变量或函数
signed声明有符号类型变量或函数
unsigned声明无符号类型变量或函数
union声明联合数据类型类型
sizeof计算数据类型所占内存空间大小
typedef数据类型重命名(定义)
struct声明结构体类型变量或函数
enum声明枚举类型
auto声明自动类型变量,缺省时,编译器一般默认为auto型
static声明静态变量或指定函数是静态函数
extern声明变量是全局变量,在其它文件中声明(声明外部变量或函数)
const(ant)声明只读变量,其修饰的只读变量必须在定义的同时初始化
register声明寄存器变量
volatile说明变量在程序执行中可被隐含的改变
break跳出当前循环,表示终止本层循环
continue结束当前循环,开始下一次循环
goto无条件跳转语句
return子程序返回语句,终止一个函数并返回值
if条件语句
else条件语句否定分支
switch用于开关变量
case用于语句分支(后跟整形或字符型常量)
default开关语句中的其他分支
for一种循环语句
dowhile循环语句的循环体
whilewhile循环语句的循环体条件

变量的命名规则

  1. 变量名只能由字母,数字,下划线组成,不能有特别字符,且不能以数字开头。

  2. 建议使用见名知意的名字,可以使用英文字母驼峰模式或加下划线的方式,尽量不要使用汉语拼音。

  3. 变量名不能是关键字

    C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。 这里我们先讲几个不常见的,长长见识。

3.1关键字 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;
}

总结下来就是,如果一个类型很复杂,我们可以个他取个简单的别名,偷偷懒了!!!

3.2关键字register

int main()
{
    register int num = 100;//声明寄存器变量
    //建议把频繁使用的数据放到寄存器中
	return 0;
}

CPU – 中央处理器,早期的计算机处理数据从内存中去拿,随着技术的发展,CPU的速度越来越快,但是内存的读写速度跟不上,所以CPU经常处于闲置状态,不能充分运用,于是有人想出在内存之上提供一个高速缓存区,在高速缓存区之上提供一个寄存器空间,把那些频繁处理的数据,放在高速缓存区或寄存器中,提高数据处理速度。

3.3关键字static

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

3.3.1修饰局部变量

//代码1
#include <stdio.h>
void test()
{
	int i = 0;
	i++;
	printf("%d ", i);
}
int main()
{
	int i = 0;
	for(i=0; i<10; i++)
	{
		test();
	}
	return 0;
}//结果是2 2 2 2 2 2 2 2 2 2
//代码2
#include <stdio.h>
void test()
{
//static修饰局部变量
	static int i = 0;
	i++;
	printf("%d ", i);
}
int main()
{
	int i = 0;
	for(i=0; i<10; i++)
	{
		test();
	}
	return 0;
//结果是2 3 4 5 6 7 8 9 10 11

对比代码1和代码2的效果理解static修饰局部变量的意义。

结论:

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

3.3.2修饰全局变量

//代码1
//add.c
int year = 2022;
//test.c
int main()
{
	printf("%d\n", year);
	return 0;
}
//代码2
//add.c
static int year = 2022;
//test.c
int main()
{
	printf("%d\n", year);
	return 0;
}

代码1正常,代码2在编译的时候会出现连接性错误。
结论:

一个全局变量被static修饰,使得这个全局变量只能在本源文件(test.c)内使用,不能在其他源文件内使用。

全局变量,在其他源文件内部可以使用,是因为全局变量具有外部连接属性,但是被static修饰之后,就变成了内部链接属性,其他源文件就不能链接到这个静态的全局变量。

3.3.3修饰函数

//代码1
//add.c
int Add(int x, int y)
{
	return x+y;
}
//test.c
int main()
{
	printf("%d\n", Add(2, 3));
	return 0;
}
//代码2
//add.c
static int Add(int x, int y)
{
	return x+y;
}
//test.c
int main()
{
	printf("%d\n", Add(2, 3));
	return 0;
}

代码1正常,代码2在编译的时候会出现连接性错误.
结论:

一个函数被static修饰,使得这个函数只能在自己所在的源文件内部使用,不能再其他源文件内部使用。

本质:static是将函数的外部链接属性变成内部链接属性!(和static修饰全局变量一样!)

4.define定义常量和宏

define是一个预处理指令,他并不是c语言的关键字

4.1define定义标识符常量

#define MAX 100
int main()
{
    printf("%d",MAX);//100
}

4.2define定义宏

#define Add(X,Y) X+Y
 int main()
 {
     printf("%d\n",Add(3,6));//9
     printf("%d\n",4 * Add(3,6));//18
    //有的小伙伴有疑问了,不是4 * (3 + 6)吗?往下看
     return 0;
 }

这是因为编译器执行的是:4 * 3 + 5。define定义宏中,我们不应该把参数X和参数Y当成一个普通的变量,他横可能是表达式。

#define Add(X,Y) ((X) + (Y))

所以我们平时初始化时,应该把参数括起来,再把宏体括起来。

5.指针

终于来啦,那个被誉为c语言的灵魂的指针他来了!我们总是听老师,学长学姐们说指针很难,大家先不要害怕,其实他也没那么难。

5.1指针的概念及内存

首先,我们要知道程序都是在内存中运行的,内存是计算机中特别重要的存储器,早期的科学家为了有效地使用内存,就把内存划分为了一个个小小的内存单元,每个内存单元的大小都是一个字节,每个内存单元都有一个独特的编号,这个编号叫做这个内存单元的地址。编号可以暂时理解为指针。

举个例子来说,就比如我们把内存比作一个大酒店,内存中每个小小的内存单元就好似酒店中一个个房间,每个内存单元都有一个独特的编号就好似每个酒店房间都有一个门牌号。

我们分析一下,我们可以在内存中可以看到地址,内存中的数据和内存数据的文本解析(内容不定,没什么用)。我们知道整形在内存中分配了4个字节的空间,我们看a的地址和她下面的地址相差4(16进制),因为int类型的数据占了4个字节。a =10,用二进制来表示就是

0000 0000 0000 0000 0000 0000 0000 1010,转化为二进制就是00 00 00 0a,但是我们发现a的数据是倒置的,其实这是小端存储方式,这里就先不介绍了。

5.2地址的生成

但是内存单元是如何编号的?以早期的32位电脑为例,他有32根地址线,每根地址线可以产生1/0两种电信号,每个地址线组合起来就会有许多不同的排列方式。

一共有2的32次方种排序方式,(2^32 = 4294967296),内存中就有这么多字节的空间。通过下图的转换,我们发现,在早期的32位电脑内存中一共有4GB的内存空间。也就是说计算机总共可以管理分配4GB的内存。现在我们身边的电脑大多是64位的,可以容纳16GB,32GB的内存。

5.3变量与地址

5.3.1变量的指针和指针变量

变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。
取出变量地址如下:

#include <stdio.h>
int main()
{
int num = 10;
&num;//取出num的地址
//注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
printf("%p\n", &num);//打印地址,%p是以地址的形式打印
return 0;
}

那地址如何存储,需要定义指针变量。指针的使用实例:

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

总结:变量的指针就是变量的存储地址,指针变量就是存储指针的变量。

5.3.2指针变量的使用

  • 取地址运算符&:单目运算符&是用来取操作对象的地址。例:&i 为取变量 i 的地址。对于常量表达式、寄存器变量不能取地址(因为它们存储在存储器中,没有地址)。

  • 解引用操作符(间接寻址符) *:与&为逆运算,作用是通过操作对象的地址,获取存储的内容。例如:x = &i,x 为 i 的地址,

    *x 则为通过 i 的地址,获取 i 的内容。


#include <stdio.h>
int main()
{
int num = 10;
int *p = &num;//这个*说明p是一个指针变量
*p = 20;//与上面的*不同,这个*是解引用操作符
return 0;
}

我们来分析一下上述过程,加强大家对解引用操作符的理解,int是整形数据结构,占4个字节,所以num占4个字节的内存,存入了整型数10,&num取出了num的第一个地址(通过第一个地址向上继续访问)存入了指针变量p中,p指向num,p指向的类型为int类型,所以*p前面类型为int,这个int指的是p指向的类型。对指针变量解引用,发现了num的地址,通过p中的地址指向了num,并把num中的值改为了20。

解引用操作符 *:就比如有一个包裹,我们解引用一下,打开了这个包裹把里面的东西拿过来引用一下。解引用p就等于打开p的空间,取出地址,通过地址找到num的内存,并获取num中的值。

5.3.3“&” 和“*”结合方向

“&” 和“*”结合方向都是左结合(编译器喜欢),其实左右都可以。假设有变量x = 10,则 *&x的含义是,先获取变量x的地址,再获取地址中的内容。因为“&”和“ *”互为逆运算,所以x = *&x。

int main()
{
    int* p = &a;
    int *p = &a;
    //以上均可
    //但是在连续定义是会有区别
    int* p1,p2,p3 =&a;
    //这个定义有问题,只有p1是指针,p2,p3是整形变量
    int *P1,*p2,*p3;
    //这个也有问题,往下看
	return 0;
}

5.3.4其他指针

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

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

5.3.5指针变量的初始化

指针变量与其它变量一样,在定义时可以赋值,即初始化。也可以赋值“NULL”或“0”,如果赋值“0”,此时的“0”含义并不是数字“0”,而是 NULL 的字符码值。注意一定要初始化,否则就是野指针,我们也不知道他会指向哪里。

int x;
int *px = &x;
//错误的定义方法,这是个野指针
int *P1;
//正确的定义指针变量的方法
int *p2 = NULL,int *p3 = 0;

5.3.6指针变量的大小

#include <stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(short *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(double *));
return 0;

结论:指针大小在32位平台是4个字节,64位平台是8个字节。

6.结构体.

6.1.结构体是什么

结构体可以说是人为构造的数据类型,它使c语言有能力描述复杂的数据类型。比如在程序中描述一本书的价格,一个人的身高,人的姓名等等,可以用char型,int型数据类型。但是要是需要描述一个学生,一个学生包含了:姓名+年龄+性别+电话

我们用基本的数据类型无法描述这种复杂的对象,这里我们就可以使用结构体来描述它,结构体可以让c语言创建出新的类型出来。

//创建一个学生类型
struct Stu
{
    //成员变量
	char name[20];//姓名
    int age;//年龄
    char sex[10];//性别
    char tele[12];//电话
}; //;是结束标志

6.2结构体的使用

void print(struct Stu* ps)//用结构体变量接收
{
    //ps指向s的地址,*解引用一下,找到s中的值
    printf("%s %d %s %s\n",(*ps).name,(*ps).age,(*ps).sex,(*ps).tele);
    //->  结构体指针变量->成员变量名
    //通过ps找到结构体对象,然后通过->找到他里面的成员变量
    printf("%s %d %s %s\n",ps->name,ps->age,ps->sex,ps->tele);
}
int main()
{
    				//注意:一定要一一对应
    struct Stu s = {"张三"20"男""13573282919"};//结构体的创建和初始化
    //结构体对象.成员变量名
    printf("%s %d %s %s\n",s.name,s.age,s.sex,s.tele); 
    //这里用到了一个.操作符,找到结构体成员并访问它用.操作符
    struct Stu *ps = &s;
    //结构体类型的指针,把s的地址存到结构体指针中去
    print(&s);//将结构体指针传入函数
    return 0;
}

结语

各位小伙伴们,祝贺你们终于学完了初识c语言,相信大家应该对c语言有个大致的了解,但是这些知识还还远远不够,以后将会更详细的讲解新的知识,你们准备好了吗,让我们一起扬帆起航!!!

如果各位小伙伴们觉得我写得不错,或者看完后有所收获,麻烦大家给个三连(关注,点赞,评论),你们的支持就是我最大的动力!!!1650297500985

为帮助大家理清脉络,把c语言上部分放到下面!!!(点link)

link

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
很多同学对咱们C语言的课程、学习存在着很多误解,而且很多同学还不知道《C语言高级教程》后面的课程安排是什么,因此这里一并做一个说明。有同学问“别人都说开发数据库系统、Web系统还是Java、C#等最流行,咱们用C语言学了开发也不是浪费吗?”、“C语言不是做嵌入式开发、操作系统等底层的东西吗?”、“我们为什么不讲C语言的嵌入式开发?”、“人家都学Web开发,咱们这学C语言开发C/S的程序不是落伍了吗?”。 确实在实际工作中,由于C语言的门槛比较高,很少有实际项目用C语言进行数据库系统、Web系统等的开发的。但是我不止一次强调“学习时学东西和工作时学东西是不一样的”。 工作以后选用的技术、语言一定是选择做合适、最方便做所从事方面的,比如开发Web程序肯定首选PHP、Java、.net,开发底层系统肯定首选C/C++,开发桌面系统肯定首选VB、Delphi,也就是“用合适的语言做合适的事情”; 但是对于在校生来说则是“用最熟悉的语言做所有事情”。初学编程的人最容易在语言的表层陷入 太长时间,如果要学数据库开发了就要去学Delphi、PB,又要学Web开发了就又去学Java、.net,又要学底层开发了就又去学C/C++, 可是每门语言都没深入,最后真正要学的数据库开发、Web开发、底层 开发等等没怎么学会,倒是把大量的时间浪费在学这些基础语法上,浪费了宝贵的时间, 这也是我痛 恨目前很多大学课程安排的一个原因。因此我的倡导就是对于在校生来说则是“用最熟悉的语言做所 有事情”,我甚至建议大学只学一门C语言就够了,然后就教大家用C语言做所有的方面。
高级进阶c语言教程 目录 1. C 语言中的指针和内存泄漏 5 2. C语言难点分析整理 10 3. C语言难点 18 4. C/C++实现冒泡排序算法 32 5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46 12. 浮点数的存储格式: 50 13. 位域 58 14. C语言函数二维数组传递方法 64 15. C语言复杂表达式的执行步骤 66 16. C语言字符串函数大全 68 17. C语言宏定义技巧 89 18. C语言实现动态数组 100 19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效编程秘籍 128 26. C运算符优先级口诀 133 27. do/while(0)的妙用 134 28. exit()和return()的区别 140 29. exit子程序终止函数与return的差别 141 30. extern与static存储空间矛盾 145 31. PC-Lint与C\C++代码质量 147 32. spirntf函数使用大全 158 33. 二叉树的数据结构 167 34. 位运算应用口诀和实例 170 35. 内存对齐与ANSI C中struct内存布局 173 36. 冒泡和选择排序实现 180 37. 函数指针数组与返回数组指针的函数 186 38. 右左法则- 复杂指针解析 189 39. 回车和换行的区别 192 40. 堆和堆栈的区别 194 41. 堆和堆栈的区别 198 42. 如何写出专业的C头文件 202 43. 打造最快的Hash表 207 44. 指针与数组学习笔记 222 45. 数组不是指针 224 46. 标准C中字符串分割的方法 228 47. 汉诺塔源码 231 48. 洗牌算法 234 49. 深入理解C语言指针的奥秘 236 50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66. 关于指向指针的指针 368 67. C/C++ 误区一:void main() 373 68. C/C++ 误区二:fflush(stdin) 376 69. C/C++ 误区三:强制转换 malloc() 的返回值 380 70. C/C++ 误区四:char c = getchar(); 381 71. C/C++ 误区五:检查 new 的返回值 383 72. C 是 C++ 的子集吗? 384 73. C和C++的区别是什么? 387 74. 无条件循环 388 75. 产生随机数的方法 389 76. 顺序表及其操作 390 77. 单链表的实现及其操作 391 78. 双向链表 395 79. 程序员数据结构笔记 399 80. Hashtable和HashMap的区别 408 81. hash 表学习笔记 410 82. C程序设计常用算法源代码 412 83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用宏定义 450
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值