c语言知识点总结(摘自head first c)

gcc name.c -o name;   ./name或者gcc name.c -o name &&  ./name;同时执行
关键字:void sizeof(运算符,它能告诉你某样东西在储存器中占多少字节。例:sizeof(int)返回4,sizeof("Turtles!")返回9,其中包含8个字符外加\0结束字符。)
1.puts可以输出,与printf用法类似。
==========================
2.scanf输入。例:
 /*假设人名小于20个字符*/
char ex[];
puts("输入男友的名字:");
scanf("%19s", ex);
printf("亲爱的%s,我们分手吧。\n", ex );
========================

3.switch。。。case选择的一种用法。
     例:

 char suit = 'H';
switch (suit) {
case 'C':
puts("梅花(Clubs)");
break;
case 'D':
puts("方块(Diamonds)");
break;
case 'H':
puts("红心(Hearts)");
break;
default:
puts("黑桃(Spades)");
}
==================
5. c程序结构:
 /*
这里写注释
*/
#include <stdio.h> //包含的外部代码。
int main()
{
int decks;
puts("输入有几副牌");
scanf("%i", &decks);
if (decks <){
puts("无效的副数");
return ;
}
printf("一共有%i张牌\n", (decks * ));
return ;
}
=================
6.main()函数
  main()函数的返回类型是int。当计算机在运行程序时,它需要一些方法来判断程序是否运行成功,计算机正是通过监察main()函数得返回值来做到这一点。如果让main()函数当回0,就表明程序运行成功;如果让它返回其他值,就表示程序再运行时出了问题。
================
6.5  c语言中,几乎每样东西都有返回值,不仅仅是函数调用,就连赋值表达式也有返回值。
  例如下面这条语句:    x = 4;他
把数字4赋值给变量。有趣的是表达式“x = 4”
本身也有一个值。为什么说这个东西很有用呢?因为你可以用它来做一些很酷的事情,比如你把多条赋值语句链在一起写: y=(x =
4);这行代码同时将x和y的值设为了4。事实上,可以去掉括号,缩短代码的长度:y = x = 4;      
你经常会在需要给多个变量赋相同的值的代码中看到链式赋值。
=================
7.c语言中没有string类型变量,要使用数组来描述字符串。
================
8.printf()函数用于显示格式化输出,它用变量的值来替换格式符,像这样:
  printf("%s说计数是%i","阿星",21);
 !当调用printf()时,可以包含任意数量的参数,但确保每个参数都要有一个对应的%格式符。
=================
9.atoi()方法:把字符数组转化为数字。
==================
10.为什么我在linux和mac中运行程序时必须在程序前加上./?
  因为在类linux操作系统中,运行程序必须指定程序所在的目录,除非程序的目录已经列在了PATH环境变量中。
=====================
11.c数组的大小
  在如今的很多语言中,计算机会时刻记录数组的大小,但C语言比大多数语言更底层,它无法确切地知道数组有多长,如果C语言想在屏幕上显示字符串,它就需要知道什么时候会到达字符串的尾部,为此C语言加入了哨兵字符\0,字符串数组需要比实际大小多出一个用来存放\0。
=====================
12.为什么字符要从0开始编号?为什么不是1?  
  字符的索引值是一个偏移量:它表示当前要引用的这个字符到数组中第一个字符之间有多少个字符。
=======================
13.单双引号有区别吗?  
  有区别,单引号通常用来表示单个字符,而双引号通常用来表示字符串。
========================
14.我应该用双引号定义字符串,还是以显示字符数组的形式定义字符串?
  通常应该用双引号来定义字符串。用双引号定义的字符串叫字符串字面量(string literal),比起字符数组,它输入起来也更方便。
=========
15.字符串字面值和字符数组有没有区别?//p12
  只有一个区别:字符串字面值是常量。这些字符一旦创建完毕,就不能在修改它们。如果我改了会怎么样?这取决于编译器,gcc通常会显示总线错误(bus error)。总线错误?那是什么东西?C语言采取不同的方式在存储器中保存字符串字面值。总线错误意味着程序无法更新那一块储存器空间。
====================
16.=号的多用。
  在C语言中,“等号”(=)用来赋值(assignment),而“双等号”用来检查两个值是否相等。例:teeth = 4; teeth ==4;检查teeth的值是不是4如果想要增加或减少变量的值,可以用+=和-=这两个赋值运算符,它们让代码看起来更简短。例:teeth += 2; teeth加2   teeth -= 2; teeth减2最后,如果想要对变量的值加1或减1,可以用++和--。例:teeth++; 加1 teeth--;减-1
==============
17.布尔运算
只有当给出的两个条件同时为真时,与运算(&&)的结果才为真。例:
  if((dealer_up_card == ) && (hard == ))
与运算的效率很高,因为如果第一个条件为假,计算机就不会自寻烦恼地去计算第二个条件,因为它知道如果第一个条件为假,那么整个条件也一定为假。
两个条件中只要有一个为真时,或运算(||)的结果就是真。
 if (cupcakes_in_fridge || chips_on_table)
eat_food();

如果第一个条件为真,计算机就不会自找麻烦地去计算第二个条件,因为它知道只要第一个条件为真,整个条件也一定为真。

 
!非运算,它将一个条件的值取反。
   if(!brad_on_phone)
answer_phone();

!在C语言中,布尔值是用数字表示的。对C语言来讲,数字0代表假的值。那什么数字代表真呢?任何不等于0的数字都将被当成真处理,因此下面的C代码也没有错。c99中允许程序使用true和false关键字,但编译器还是会把他们当作1和0这两个值来处理。

事实上,C程序常用它作为“检查某个变量不为0”的简写。
 int people_moshing = ;
if (people_moshing)
take_off_glasses();

====================================

18.为什么不能只写一个|和&?
也不是不行。&和|操作符总是计算两个条件,而&&和||可以跳过第二个条件。
19.那还要|和&干什么呢?
对逻辑表达式求值只是他们的一个用处,他们还能对数字的某一位进行布尔运算。
20.那是什么意思?

6 & 4 等于4,是因为当对6(二进制数110) 和 4 (二进制数100) 的每个二进制位布尔与时,就会得到4 (二进制数100).
21.找错:
c语言知识点总结(摘自head first c)
 A:
#include <stdio.h> int main()
{
int card = ;
if (card >)
card = card - ;
if (card < )
puts("小牌");
else {
puts("Ace!");
}
retutn ;
} B:
#include <stdio.h> int main()
{
int card = ;
if (card >){
card = card - ;
if(card < )
puts("小牌");
else
puts("Ace!");
}
return ;
}
C:
#include <stdio.h> int main()
{
int card = ;
if(card > ){
card = card - ;
if (card < )
puts("小牌");
} else
puts("Ace!");
return ;
} D:
#include <stdio.h> int main()
{
int card = ;
if(card > ){
card = card - ;
if (card < )
puts("小牌");
else
puts("Ace!");
return ;
}

A:编译成功。程序显示“小牌”,但程序不能正确工作,因为else匹配了错误的if.
B: 编译成功。程序什么也没有显示,它不能正确工作,因为else匹配了错误的if.
C:编译成功。程序显示“Ace!”,正确!
D:编译失败。因为花括号不匹配。

===============================================
22.switch语句只能检查变量吗?它能检查值吗?
能,switch语句仅仅检查两个值是否相等。
===============
23. 我能在switch语句中检查字符串吗?
=============================
不能用switch语句检查字符串或任何形式的数组,switch语句只能检查值。
24.do while
while循环还有一种形式,它总是在循环体运行后才检查循环的条件,也就是说循环体至少会被执行一次,我们叫它do ...while循环。例:
 do{
/*买彩票 */
} while(have_not_won);

======================================

25.所有循环的结构都相同。
首先为循环准备变量,其次在每一轮的循环前检查条件,最后在循环末尾更新计数器或实现类似功能。
例:

 int counter = ;  //这是循环启动代码
while (counter < ) { //循环条件
printf("%i个枣\n", counter);
counter++; //这是循环更新代码,它用来在循环体的末尾更新计数器。
}

==========================================

26.因为这个模式是通用的,C语言的设计者就创造了for循环。例:

 int counter;
for (counter = ; counter < ; counter++) {
printf("%i 个枣\n", counter);
} // 循环体中只有一行代码,可以去掉花括号。
for循环可以减少代码的行数

===============================

27.用break语句退出循环
例:

 while (feeling_hungry){
eat_cake();
if (feeling_queasy){
/* 从while循环中跳出 */
break;
}
drink_coffee();
}

!break语句可以直接退出当前循环,跳过循环体中break之后的所有语句。 break非常有用,因为它有时是结束循环最简单有效的方法,但应该避免滥用break,因为他们会降低代码的可读性。!break语句可以用来退出循环语句和switch语句。使用break时看清你在哪里,并不是所有地方都能够使用break。

======================
28.用continue继续循环
如果想跳过循环体的其余部分,然后回到循环的开始,那么continue语句就是你的最佳伴侣。例:
 while (feeling_hungry) {
if (not_lunch_ye) {
/* 回到循环条件 */
continue; //"continue" 带你回到循环的条件
}
eat_cake ();
}

break 不能从if语句中退出。
1990
年1月15日,AT&T的长途电话系统死机,造成6万人无法使用电话服务。起因是一个负责写电路交换部分C代码的开发人员企图用break从if
语句中退出,但break不能从if语句中退出。相反,程序跳过了诊断代码,引起了这个bug,令7千万次电话呼叫在9个多小时内无法接通。。。

=================
29.如果我创建了一个void函数,是否就意味着它一定不能有return语句?
你还是可以包含return语句,但编译器很可能会产生一条警告消息。在void函数中的return语句有时可以用来提前退出函数。
===============
30.链式赋值:

C语言中,几乎每样东西都有返回值。例如下面这条语句:x = 4; 他把数字4赋值给变量。有趣的是表达式“x = 4
”本身也有一个值,这个值是4,即赋给x的值。为什么说这个东西很有用呢?因为你可以用它来做一些很酷的事情,比如把多条赋值语句链在一起写:y =
(x = 4); 这行代码同时将x和y的值设为了4。事实上,可以去掉括号,缩短代码的长度:y = x = 4;
你经常会在需要给多个变量赋相同值的代码中看到链式赋值。
=================
31.块语句被{和}包围
32.count++表示技术加1,count--表示计数减1
 
========================
=======================
 
========================
 

储存器和指针:
1.指针就是储存器中某条数据的地址。
2.指针做了两件事:避免副本和共享数据。
3.如果在函数中声明变量,计算机会把它保存在一个叫栈的储存器区段中;如果你在函数以外的地方声明变量,计算机则会把它保存在储存器的全局变量段。
4.航行问题:
例:

 #include <stdio.h>

 void go_south_east(int lat, int lon)
{
lat = lat - ; //纬度减小
lon = lon + ; //经度增加
} int main()
{
int latitude = ;
int longitude = -;
go_south_east (latitude,longitude);
printf("停!当前位置:[%i, %i]\n", latitude, longitude);
return ;
}

  程序开始时船的位置是【32,-64】,如果它向东南方向航行,船的新坐标将是【31,-63】,前提是代码正确工作。。。
!c语言传递参数的值
c语言调用函数的方式是导致这段代码不能正确工作的原因。
a.一开始,main()函数有一个叫longitude的局部变量,它的值是32.
b. 但计算机调用go_south_east()函数时,他将变量longitude的值赋值给了参数lon,这只是一个赋值的过程,从变量longitude到变量lon。也就是说,当你调用函数时,作为参数传递的不是变量,而只是变量得值。
c.但go_south_east()函数修改了lon的值时,函数只是修改了本地的副本,也就是说程序返回mian()函数时,变量longitude中保存的还是它原来的值32.

===================================
5。得到了变量的地址,就需要把它保存在某个地方。为此,需要指针变量。
====================
6.指针只是一个保存储存器地址的变量。
=================
7.&运算符可以找到变量的地址。
=================
8.*运算符可以读取储存器地址中的内容。*运算符还可以设置储存器地址中的内容。
=============
9.数组变量:
char
quote[] = "Cookie make you fat";
quote是数组变量,计算机会为字符串的每一个字符以及结束字符\0在栈上分配空间,并把首字符的地址和quote变量关联起来,代码中只要出现这个
quote变量,计算机就会把它替换成字符串首字符的地址。
===================
10.通过函数传递参数,函数只能接受传递过来参数的副本。
11.为什么指针有类型?
因为指针可以运算,对char指针加1,指针会指向储存器中下一个地址,因为char就占1字节。如果int指针加1,int通常占4字节,编译后的代码就会对储存地址加4.指针之所以有类型,是因为编译器在指针算术运算时需要知道加几。
================
12.一次scanf输入多个参数,例:scanf("%19s %19s", first_name, last_name);
===============
13.scanf()会导致缓存区溢出
例:
 char food[];
printf("Enter favorite food:");
scanf("%s",food);
printf("Favorite food: %s\n", food);

  程 序运行崩溃,因为scanf()在写数据时超过了food数组的尾部。如果忘了限制scanf()读取字符串的长度,用户就可以输入远远超出程序空间的数 据,多余的数据会嗅到计算机还没有分配好的储存器中。如果运气好,数据部但能保存,而且不会有任何问题。但缓存溢出很有可能会导致程序出错,这种情况通常 被称为段错误或abort trap,不管出现什么错误信息,程序都会崩溃。

========================
14.除了scanf()还可以用fgets()
 char food[];
printf("Enter favorite food:");
fgets(food,sizeof(food),stdin);
   //首先,它就手指向缓存区的指针。其次,它就首字符串(包括“\o”)的最大长度。stdin表示数据将来自键盘。注意,fgets()缓冲区大小吧 \0字符也算了进去,所以不必像scanf()那样把常年高度减1
============================
15.找错,例:“三猜一”游戏,某人不停的交换三张牌的位置,你必须摒息凝视,指出Q去了哪儿。
 #include <stdio.h>

 int main()
{
char *cards = "JQK";
char a_card = cards[];
cards[] = cards[];
cards[] = cards[];
cards[] = cards[];
cards[] = cards[];
cards[] = a_card;
puts(cards);
return ;
}

  字符串字面值不能更新,指向字符串字面值的指针变量不能用用来修改字符串的内容:
char *cards = "JQK";    //不能用这个变量修改这个字符串。
也不能用 card = "JQK"去修改,原因在上一张15点。
但你可以用字符串字面值创建一个数组,就可以修改了:
char cards[] = "JQK"; 或 card = { "J","Q","K"};
这是有C语言使用储存器的方式决定的  //P73

======================
16.cards[]还是*cards?  //p74也可以不立即赋值,但要写出数组的大小,例:char cards[5];cards就是一个数组。
17.p75
18.
为了从此避免这个错误,可以不再将char指针设置为字符串字面值,像这样:char *s = "Some
string";但是把指针设为字符串字面值又没有错,问题出在你试图修改字符串字面值。如果你想把指针射程字符串字面值,必须确保使用了const关键
字:
const char *s = "some string";这样一来,如果编译器发现有代码试图修改字符串,就会提示编译错误:
s[0] = 'S';
monte.c:7: error: assignment of read-only location
==========================
19.const到底是什么意思?他能让字符串变成只读吗?
  加不加const,字符串字面值都是只读的,const修饰符表示,一旦你试图用const 修饰过的变量去修改数组,编译器就会报错。
===================
20.我还是不理解,为什么数组变量不保存在储存器中?既然它存在,就应该在某个地方,不是吗?
  程序在编译期间,会把所有对数组变量的引用替换成数组的地址。也就是说在最后的可执行未见中,数组变量并不存在。既然数组变量从来不需要指向其他地方,有何没有其实都一样。
====================
21.每当我把一个新数组设为字符串字面值,程序实际上会复制字符串字面值的内容吗?
  这取决于编译器,最后的机器代码既有可能吧整个字符串字面值的内容复制到数组,也有可能程序会根据生命设置每个字符的值。
==============
22.你老是在说 “声明”,他是什么意思?
  声明是一段代码,他是称某样东西(变量或函数)存在;而定义说明他是什么东西。如果在声明了变量的同时将其设为某个值(例如 int x = 4;),这段代码即是声明又是定义。
========================
23.为什么scanf()要被称为scanf()?
  scanf()其实表示“scan formatted”,它用来扫描带格式的输入。
22.P80
====================
========================
=========================
字符串
1.string.h库中的函数:
  strchr() 在字符串中查找字符;strcmp() 比较字符串;strstr()在字符串中查找字符串;strcpy()复制字符串;strlen()返回字符串的长度;strcat() 连接字符串
=================
2.如果使用mac或linux的计算机,可以在命令行中查看string.h中每一函数的详细介绍,假如想查看strstr()函数,可以输入:  man strstr
==============
3.为什么要把数组定义成tracks[][80]而不是tracks[5][80]?
  也可以这样定义,但编译器知道列表有5项,所以你可以省略5,写成[]。
===================
4.既然如此,为什么不直接写tracks[][]?
  每首歌的名字不一样长,为了放下最长的歌名,需要让编译器分配足够大的空间。
5。为什么我一定要把find_track()放在main()之前?
  在调用函数前,编译器需要知道两件事,函数就首什么参数以及函数的返回类型是什么。
6.如果我把main()放到前面会怎么样?
  你会得到几个警告。
7.能够倒过来显示字符串的函数://P97
8.重点:指针的数组。
结构、联合、位置段
1.const char *表述传递字符串字面值。
2.struct是structured data type(结构化数据类型)的缩写。例:
 struct fish {
const char *name
const char *speces;
int teeth;
int age;
}

======================

3.fish结构会保存字符串吗?
  在这个例子中不会,这里的fish结构中只保存了字符串指针,也就是字符串的地址,字符串保存在储存器中其他位置。
4.但还是可以把整个字符串保存在结构中吧?
  对,只要把字符串定义成字符数组就行了,像这样char name[20];.
5.既然snappy是数组指针,就可以像这样访问它的第一个字段:
例:

 struct fish snappy = {"snappy","piranha",,};
printf("Name = %s\n",snappy[]);

  如果想访问数组元素那样读取结构字段,会得到编译错误,不可以这样做。尽管结构可以向数组那样在结构中保存字段,但读取时只能按名访问。可以使用“.”运算符访问结构字段。
6.数组变量就是一个指向数组的指针,那么结构变量是一个指向结构的指针吗?
  不是,结构变量是结构本身的名字。
7.但我定义结构时,必须使用struct关键字,定义变量时还要再用一遍,有什么更简单的方法吗?
  用typedef为结构命名:
当创建内置数据类型变量时,只要写int 或double就行了,但每次创建结构变量时,不得不加上struct关键字。
在c语言中可以为结构创建别名,你只要在struct关键字前加上typedef,并在右花括号后写上类型名,就可以在任何地方使用这种新类型。例:

 typedef struct cell_phone {
int cell_no;
const char *wallpaper;
float minutes_of_charge;
} phone;
...
puone p = {, "sinatra.png",1.35};

=======================

8.什么是匿名结构?

  匿名结构就是没有名字的结构,typedef struct { ... } spider_man;有一个叫spider_man的别名,但没有结构名。很多时候,如果创建了别名,也就不需要结构名了。
9.(*t).age和*t.age是完全是两个不同的表达式。
================
10.(*t).age 和 t->age这两个表达式含义相同。
===========
11.当调用函数时,计算机会把值复制给形参变量。
  可以像创建其他类型的指针那样创建结构指针。
===============
12.同一类事物,不同数据类型:假如想记录某样东西的“量”,既可以用个数,也可以用重量,或者用容积。如果能够定义一种加“量”的数据类型,然后根据特定的数据决定要保存个数、重量还是容积。在c语言中,可以用联合做到这点。例:
 typedef union {
short count;
float weight;
float volume;
} quantity;

  联合看起来很像结构,但用的是union关键字。所有字段将保存在同一个地方。数据类型不同,但都表示“量”。

================
13.使用联合:声明联合变量后,有很多方法设置它的值。
  a.C89方式:如果联合要保存第一个字段的值,就可以用C89表示法,只要用花括号把值括起来,就可以把值赋给联合中第一个字段。例:quantity q = {4}
b.指定初始化器:指定初始化器(designated initializer)按名设置联合字段的值:quantity q = { .weight = 1.5 };
c.“点”表示法:第三种设置联合值的方法是在第一行创建变量,然后在第二行设置字段的值:
 quantity q;
q.volume = 3.7;

====================

14."指定初始化器"也可以用来设置结构字段的初值。如果结构有很多字段,但你只想为其中某些字段设初值,“指定初始化器”就非常有用。同时它还能够提高代码的可读性:例:

 typedef struct {
const char *color;
int gears;
int height;
} bike;
bike b = {.height=, .gears=}; 将设置height和gear字段,但不设置color字段。

=====================

15.你可以在联合中保存任何字段的值,这些不同类型的值保存在储存器中相同的位置。。。既然如此,你怎么知道我保存的是float还是short?要是我保存了float字段,却读取了short字段呢?
  好问题:可以在联合中保存各种可能的值,但保存以后,就无法知道它的类型。编译器不会记录你在联合中设置或读取过那些字段。我们完全可以设置一个字段,读取另一个字段,但有时这会造成很严重的后果。

==========================
16.你需要某种方法记录我们在联合中保存了什么值。C 程序员常用觉得一种技巧是创建枚举。
17.枚举变量保存符号:
  有时你不想保存数字或文本,而是想保存一组符号。如果你想记录一周中的某一天,只想保存MONDAY,TUESDAY,WEDNESDAY...这些符号。你不需要保存文本,因为一共只有7种不同的取值。这就是为什么要发明枚举的原因。定义例子:
enum colors { RED, GREEN, PUCE };
enum colors favorite = PUCE;
enum colors 类型定义的变量只能设为列表中的某个关键字

==========================

18.位置段:例:

 typedef struct {
unsigned int low_pass_vcf:;
unsigned int filter_coupler:;
unsigned int reverb:;
unsigned int sequential:;
...
} synth;
  每个字段必须是unsigned int。表示该字段只能使用1储存空间。
19.为什么C语言不支持二进制字面值?
  因为二进制字面值占了很大空间,而且十六进制通常写起来更快。
=================
20.位置段就是为了节省空间吗?
  不仅仅是为了节省空间,如果需要读取底层的二进制信息,位字段就会非常有用。
21.枚举保存符号而不是字符串。
=============
=============
===========
数据结构与动态储存
1.为了保存可变数量的数据,需要一样比数组更灵活的东西,即链表。
2.链表是一种抽象数据结构。链表是通用的,可以用来保存很多不同类型的数据,所以被称之为抽象数据结构。
3.链表中的每个结构都需要与下一个结构相连。如果一个结构包含一个链向同种结构的连接,那么这个结构就被称为递归结构。
===========
4.链表:例
 typedef struct island {
char *name;
char *open;
char *closes;
struct island *next; //在结构中保存了一个指针,指向下一座岛。
} island;
  !递归结构要有名字。当用typedef命令定义结构时可以跳过为结构起名字这步,但在递归结构中,需要包含一个相同类型的指针,c 语言的语法不允许用typedef别名来声明它,因此必须为结构起一个名字。这就是为什么这里的结构叫struct 
island.
5.在C语言中,null的值实际上为0,null专门用来把某个指针设为0.
6.其他语言,比如java,有内置链表,C语言有内置数据结构吗?
  c语言没有内置数据结构,你必须自己创建它们。
7.如果我想快速地插入数据,就需要链表,但如果我想直接访问元素,就应该用数组。
8.P276 为什么要用动态储存。
9.malloc()
获取空间,free()释放储存器。申请储存器的函数叫:malloc(),是memory
allocation(存储器分配)的意思。malloc()接收一个参数:所需要的字节数。通常你不知道确切的字节数,因此malloc()经常与
sizeof运算符一起使用,像这样:malloc(sizeof(island));
10.P285 strdup()函数
11.p286 中的“这里没有蠢问题”
12.exit()系统调用是结束程序的最快方式。完全不用操心怎么返回主函数,直接调用exit(),你的程序就会灰飞烟灭。exit()括号中的数字是返回主函数的状态码。
============
===========
=============
 

高级函数
1.void *指针可以指向任何数据类型。
2.int a = * (int *)score_b; (int *) 把void指针转化为整形指针。
3.char ** P331页
4.重复利用函数中的公共部分,使用函数指针可以实现。
使用宏可以创造出可变参数的函数,可以解决一些难题。
5.#defined 宏定义的使用,可以看看二级c参考资料中的使用。

==================
==============
==========
进程与系统调用
1.system()函数会编译到我的程序中吗?
  答:不会,和所有系统调用一样,system()函数不在你的程序里,而在操作系统中。
2.system()
函数会带来很多安全问题;当调用system()函数时,操作系统必须解释命令字符串,然后决定那些运行程序和怎样运行。问题就在“操作系统需要解释字符
串”上,你已经看到这有多么容易出错。要想解决这个问题就必须消除歧义,明确告诉操作系统你想运行哪个程序,这就是exec()函数的用处。
3.exec()函数;替换当前进程。你可以告诉exec()函数要使用哪些命令行参数和环境变量。新城需启动后PID和老程序一样,就像两个程序接力跑,你的程序吧进程交给了新程序。
上一篇:webapi swagger自定义 HTTP Header验证用户


下一篇:牛客小白月赛13 小A买彩票 (记忆化搜索)