复习
int a; 整型变量
int a[10]; 整型数组10个元素
int *a; 整型指针
int *a[10]; 整型指针的数组,数组中的元素是10个整型的指针
int (*a)[10]; 数组指针,指向的是由10个int类型元素组成的数组, 用来指向二维数组
int (*a[3])[10]; 指针类型的数组,3个元素,每个元素都是指向10个int类型元素的数组
int *a(int); 函数,是指针函数,返回值是int类型指针的函数,参数是int类型
int (*a)(int); 函数指针,指向参数是int,返回值是int的函数。
int *(*a)(int); 函数指针,指向参数是int,返回值是int*的函数。
int (*a[2])(int); 指针数组,2个元素,元素值函数指针,函数参数int,返回值是int。
作业:
选择题
- [单选题-C语言]
关于if语句,下面哪一种说法是错误的 ( D ) (牛客网)
A: 一个if只能有一个else与之配对
B: if语句中可以有多个else if子句
C: if语句中可以包含循环语句
D: if语句中不能包含switch语句
- [单选题-位运算]
下面关于位运算符的叙述,正确的是?( ) (牛客网)
A: #表示"按位异或"的运算
B: &表示"按位或"的运算
C: ~表示"按位取反"的运算
D: ||表示"按位或"的运算
3.[单选题-C语言]
下面哪个语句无法通过编译? ( B ) (牛客网)
A: if (x>y);
B: if (x=y) && (x!=0) x+= y;
C: if (x!=y) scanf("%d",&x); else scanf("%d",&y);
D: if (x<y) {x++; y++;}
- [单选-linux]
若基于Linux操作系统所开发的ARM应用程序源文件名为test.c,
那么要生成该程序代码的调试信息,编译时使用的GCC命令正确的是? ( D ) (阿里巴巴)
A: arm-linux-gcc -c -o test.o test.c
B: arm-linux-gcc -S -o test.o test.c
C: arm-linux-gcc -o test test.c
D: arm-linux-gcc -g -o test test.c
- [单选-C]
若整型变量a、b、c、d中的值依次为:1、4、3、2。则条件表达式a<b?a:c<d?c:d的值 ( A ) 。(牛客网)
A: 1
B: 2
C: 3
D: 4
6.[单选题-优先级]
已知int i=1, j=2;,则表达式i+++j的值为( C )。
A: 1
B: 2
C: 3
D: 4
- [单选题]
在软件生命周期中,( B )阶段负责“写出正确、易懂,容易维护的程序模块”。
A: 详细设计
B: 编码和单元测试
C: 确认测试
D: 总体设计
- [单选题]
break和continue两个都是( A ) (美行科技)
(A)控制循环指令 (B) 数据结构
© 相等的判断 (D) 不包含在C++中
- [单选题]
有以下程序
main()
{ int a=666,b=888;
printf("%d\n",a,b);
}
程序运行后的输出结果是( B )。
A: 错误信息
B: 666
C: 888
D: 666,888
编程题:
编写函数,[采用递归方法]实现将输入的字符串按反序输出。(北京麦邦)
函数自己调用自己
并没有改变字符串,仅仅是反着输出 “abc” 输出"cba"
void out_char(char *p)
{
}
#include <stdio.h>
void out_char(char* p)
{
if(*p == '\0')
{
return;
}
out_char(p+1);
printf("%c", *p);
}
int main()
{
char* p = "hello world";
out_char(p);
printf("\n");
return 0;
}
一、const
作用: 使变量常量化
两种情况:
1、常量没有名字,给常量起名字,这个时候如果使用宏,全局有效。如果只在一个小作用域内使用常量,我们可以使用const定义一个变量,就相当于给常量起名字。
2、函数传参数,有一些不想被改变的参数,这个时候会使用const来定义,比如:
字符串操作函数
int strcmp(const char* s1, const char* s2);
在函数内部不可以对这两个参数修改。
两种使用情况都是为了防止我们无意间修改了不想修改的变量。
示例1:
int main()
{
const int a = 10;//还可以等价的写成 int const a = 10;
a = 20;//任何尝试去修改变量a的操作,都是语法错误
return 0;
}
linux@ubuntu:~/809$ gcc test.c -o test
test.c: In function ‘main’:
test.c:7:2: error: assignment of read-only variable ‘a’
示例2:
#include <stdio.h>
int main()
{
int a = 100, b = 20;
int * const p = &b;//使用const修饰指针变量
p = &a;//改变指针变量p的指向 语法错误
*p=11;//通过指针变量改变指向的变量的值
printf("%d\n", *p);
}
#include <stdio.h>
int main()
{
int a = 100, b = 20;
int const* p = &b;//可以等价写成const int* p = &b;
p = &a;
*p = 11;
printf("%d\n", b);
return 0;
}
重点:
const修饰指针变量,const可能出现在*的左边也可能出现在*的右边;出现在*的左边,修饰*p(不能通过指针去修改指针指向的变量);出现在*右边,修饰p(不能修改指针的指向)。
const出现在*左边,叫 常量指针
const出现在*右边,叫 指针常量
被const修饰的变量必须初始化。
示例3:
#include <stdio.h>
int main()
{
int a = 100;
const int *p = &a;
a = 80;
*p = 60;
printf("%d\n", a);
return 0;
}
二、数据存储类型
4种。 自动(auto)、寄存器(register)、静态存储(static)、外部存储(extern)
auto就是我们在栈空间定义的局部变量
register针对硬件编程才能用到,就是硬件中的寄存器
1. extern
静态外部链接
示例4:
/// a.c
int a = 200;//全局变量
/// b.c
#include <stdio.h>
extern int a;//使用在其他文件中定义的全局变量a, a.c和b.c中的a是同一个变量
int main()
{
printf("a = %d\n", a);
return 0;
}
执行过程: gcc a.c b.c
2. static
修饰静态
1)static 修饰全局变量:
如果全局变量被 static 修饰,则该全局变量只能在当前文件中使用,不能被外部使用。
一个文件中的函数一般都是具有相关逻辑的,有时候同文件的函数之间需要定义全局变量,但是这个全局变量的逻辑仅仅是当前文件中的函数可以使用。这个时候要把全局变量定义层静态全局变量。
示例5:
/ a.c
static int a = 200; //static修饰全局变量a,那么这个a只能在a.c文件中被使用
/// b.c
#include <stdio.h>
extern int a;
int main()
{
printf("a = %d\n", a);
return 0;
}
编译报错,因为static修饰全局变量,只能在定义它的文件中使用这个全局变量。
2)static 修饰局部变量
普通的局部变量被定义在内存什么空间?栈,函数开始执行变量被创建,函数执行完毕变量删除。
static修饰局部变量,将局部变量定义在静态空间。
被修饰的局部变量,只初始化一次。生命周期,从进程开始到结束,作用域:就在原来的作用域内。
示例6:
#include <stdio.h>
void fun()
{
static int a = 90; //静态局部变量,是在程序开始运行的时候创建的,作用域只能在定义它的{}里使用
//这段代码 a只能在fun中使用
printf(" %d \n", a);
a++;
}
int main()
{
fun();
//printf(" a = %d\n",a );//语法错误,因为a的作用域只在fun函数中
fun();
fun();
return 0;
}
执行结果: 90 91 92
3)static 修饰函数: 被修饰的函数,限定在当前文件内使用。
示例7:
/a.c///
static void fun()//static修饰fun函数,fun函数只能在a.c中调用
{
printf(“hello world\n”);
}
/b.c///
void fun();
int main()
{
fun();
return 0;
}
编译报错
小总结:
static和const经常在面试中被一起问到,但是他俩又没有任何关系。
static修饰局部变量 生命周期变得和程序一样长,但是作用域不变
static修饰全局变量 缩小了全局变量的访问范围,只能在定义全局变量的文件中使用全局变量,生命周期没有改变
static修饰函数 缩小了函数的访问范围,只能在定义函数的文件中使用
const 将变量修饰成只读的。
常量指针 指向常量的指针,*p不能变。 const在*左边
指针常量 不能改变指向的指针,p不能变。const在*右边
三、带参宏
#define HEIGHT 21
#define WIDTH 12
宏的特点:
1) 宏是在预处理阶段完成的事,完成了用宏值把宏名替换掉。
2) 宏值是没有类型的。 宏只是简单的符号替换。无脑替。
3) 宏名字一般用大写。为了和变量做以区分。
错误范例:
//宏值后面有; 是错误,在for循环中替换宏名的时候,会把;也替换过去
#define NUM 10;
int main()
{
int i;
for(i = 0;i < NUM;i++)
{
printf("hello\n");
}
return 0;
}
宏的优势:
-
一改全改
-
使得常量有意义
示例8:
#include <stdio.h>
//x就是带参宏的参数
#define EXPAND(x) (10*(x))
int main()
{
//替换后(10*(2))
//printf(" %d \n", EXPAND(2));
//#define EXPAND(x) (10*x) 替换后 10*2+1
printf(" %d \n", EXPAND(2+1));
return 0;
}
不写括号的错误范例
#define EXPAND(X) 10*X
int main()
{
printf("%d\n", EXPAND(2+3));
return 0;
}
练习1:
使用带参宏实现功能: 求一个整数的平方
#include <stdio.h>
#define POW(a) ((a)*(a))
int main()
{
printf("%d\n", POW(1+1));
return 0;
}
带参宏 和 函数调用的区别
带参宏 : 在预处理阶段就完成了 宏值替换掉宏名。 运行效率高。在预处理阶段就替换好了要运行的代码,省去了函数的调用过程。
带参宏因为只是替换,所以要考虑作用域命名冲突的问题。
带参宏不会对参数类型进行检查。
带参宏不能定义返回值。
带参宏不具备函数调用的灵活性。
函数调用: 在程序执行之后才进行函数调用。 运行效率没有带参宏的效率高。因为执行阶段才调用。有类型检查,有作用域,有生命周期。
四、条件编译
1. #ifdef
if如果 def define 定义
如果有宏定义,就进行以下的编译
条件编译有什么用?
可以帮助我们自动不编译一些调试输出。
跨平台开发,针对不同的平台可能代码会有微调。
比如WIN,就是windows下逻辑;LINUX就是linux下的逻辑
示例9:
#include <stdio.h>
int main()
{
//如果定义过宏名 DEBUG 才会编译printf("hello world\n"); 这行代码
#ifdef DEBUG
printf("hello world\n");
//ifdef的控制范围到endif结束
#endif
printf("hello farsight\n");
return 0;
}
条件编译不是选择性的执行代码,而是选择性的编译代码,并不是代码的执行逻辑。
2. #else #elif
示例10:
#include <stdio.h>
#define TEST
int main()
{
#ifdef DEBUG
printf("hello world\n");
printf("hello farsight\n");
#else
printf("hello test\n");
#endif
return 0;
}
#include <stdio.h>
#define TEST 2
int main()
{
#if TEST == 1
printf("hello world\n");
#elif TEST == 2
printf("hello test\n");
#endif
printf("hello farsight\n");
return 0;
}
3. #ifndef
if not define
一般的使用在头文件中,防止头文件中定义的结构体、枚举、联合等类型重复定义。
C++的每个头文件都要加#ifndef
示例11:
///person.h
#ifndef PERSON_H
#define PERSON_H
struct Person
{
char name[20];
int age;
};
#endif
在不加条件编译的情况下,多个.c文件包含person.h头文件,会编译出错,提示Person结构体重复定义。
#ifndef PERSON_H这个条件编译,是为了避免头文件中的内容被重复定义。
五、linux标准main函数
格式:
//argv不是数组指针,它就是一个二级指针
int main(int argc, const char *argv[]) //int main(int argc, const char **argv)
{
return 0;
}
参数 argc : argument count 运行程序时的参数个数 touch a.c b.c
参数 argv : argument value 运行程序是参数的值
在函数的形参列表中,参数的类型用[]修饰,和用*修饰是一个意思,之所以可以将*换成[]是为了增强程序可读性。
void fun(int* p)
{
}
void fun2(int p[])
{
}
/*
fun中的p和fun2中的p语法是一样的!fun2中的p给人传达的信息是指针p是专门用来指向数组的。此时[]中不必写数字,就算写了也是白写。
*/
示例12:
#include <stdio.h>
//标准main函数的两个参数,就是传了一个字符指针数组。
int main(int argc, const char *argv[])
{
if( argc < 4 )
{
return -1;
}
printf("argc : %d\n", argc);
printf("argv[0]: %s\n", argv[0]);
printf("argv[1]: %s\n", argv[1]);
printf("argv[2]: %s\n", argv[2]);
printf("argv[3]: %s\n", argv[3]);
return 0;
}
linux@ubuntu:~/22011$ ./test hehe haha enen
argc : 4
argv[0]: ./test
argv[1]: hehe
argv[2]: haha
argv[3]: enen
六、函数的递归调用
自己调用自己,叫做函数的递归调用。
示例13:
调用形式:
void fun()
{
fun();
}
示例14:
求阶乘 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1
n = 1 num(n) = 1
n > 1 num(n) = n * num(n-1)
#include <stdio.h>
//求n的阶乘
int mul(int n)
{
if( n == 1 )//当递归到1的时候,不再递归,返回1的阶乘1
{
return 1;
}
int num = n * mul(n-1);//n的阶乘就是n乘以n-1的阶乘
return num;
}
int main()
{
printf("%d\n", mul(6));
}
要成功使用递归函数,需要注意的是:
一定要写明结束条件。 在满足结束条件后就不再递归了。
递归的结束条件,有时可以作为思考递归的一个逻辑入口。
七、字节序:
1. 分类
大端字节序: 高地址存低位数据,低地址保存高位数据,就是大端序。
小端字节序: 高地址存高位数据,低。。。。低。。。,就是小端序。
了解:
主机字节序: 大部分都是小端序,也有大端序。
网络字节序: 大端字节序。
2. 字节序的检测
当一个变量有多个字节组成时,最低位的地址代表这个变量的地址。
示例15:
#include <stdio.h>
int main()
{
int a = 0x12345678;
//强制类型转换,当赋值运算符左右两边的类型不一样,需要进行强制类型转换。
//强制类型转换要十分小心,很可能数据本身不支持这样的转换。
//&a 是int* 类型 p是char*类型
char *p = (char *)&a;//指针p指向的是变量a的最低位的地址,指针定义成char类型,就是为了取一个字节的数据
printf("%x\n", *p);
return 0;
}
结果:0x78 说明我们的ubuntu系统是小端字节序
八、位运算
位运算有什么用?
±*/
char 1byte 8bit
只对变量中我们想操作的位进行操作,而不是对整个变量操作。
1. 按位与 & 二元运算
真值表:
a & b 结果
-------------------
0 0 0
1 0 0
0 1 0
1 1 1
示例: 14 && 24 = 1 (真)
14 & 24
0000 1110
& 0001 1000
-------------------
0000 1000
2. 按位或 |
真值表:
a | b 结果
-------------------
0 0 0
1 0 1
0 1 1
1 1 1
示例: 14 || 24 = 1 (真)
14 | 24
0000 1110
| 0001 1000
0001 1110
3. 按位异或 ^
真值表:
a ^ b 结果 (相同为0,不同为1)
-------------------
0 0 0
1 0 1
0 1 1
1 1 0
示例:
14 ^ 24
0000 1110
^ 0001 1000
-------------
0001 0110
4. 按位取反
真值表:
a ~a
---------
0 1
1 0
示例: !100 = 0 (假)
~100
~ 0110 0100
1001 1011
5.左移右移
左移,向数据高位移,和内存没关系。
每一位都向高位移动,低位补0,高位溢出。
8 << 2
0000 1000
<<2 0010 0000
右移,向数据低位移,和内存没关系。
每一位都向低位移动,低位溢出,高位补(无符号数补0,有符号数补符号位),位运算时
绝大部分情况下都是无符号。
有符号数
1 最高位 0
-1 最高位 1
无符号
8 >> 3
0000 1000
>>2 0000 0001
有符号,最高位是符号位,正数符号位0,负数符号位是1
-8 >>2
1000 1000
>>2 1110 0010
注意:
使用位运算不要计算变量的值是多少,不是不能算,因为没意义。如果在意变量的值是多少,说明根本就不需要位运算。
这道题出的本身就有问题,只是在强调位运算的数学规律,并不是位运算的目的。
经过位运算的某一位或者某些位的值是0还是1。
6. 运用
按位与: 置0 或者 读取值
按位或: 置1
异或: 取反
置零
unsigned char x;
x = x&~(1<<n); 将变量x的n位置0
假设x 的二进制值 0000 1010
假设n的值是3
1 ------ 0000 0001
1<<3 ------0000 1000
~(1<<3)—1111 0111
0000 1010
& 1111 0111
0000 0010 结果是将x3号位的1变成了0,其他位都没变
置1
unsigned char x;
x = x|1<<n; 将变量x的n位置1
假设x 的二进制值 0000 1010
假设n的值是2
1 ------ 0000 0001
1<<2 ------0000 0100
0000 1010
| 0000 0100
0000 1110 结果,把x的2号位值置1,其他位没变
int status = 0;
0 位表示中毒
1 位表示冰冻
2 位表示残废
3 位表示眩晕
status | 1<<1;
status | 1<<2;
status | 1<<3;
status | 1<<0;
读取
unsigned char x;
if( (x&1<<n) == 0)
{
//结果位真说明x的n位是0
}
else
{
//结果位假,说明x的n位是1
}
假设x 的二进制值 0000 1010
假设n的值是2
1 -------- 0000 0001
1<<2-------- 0000 0100
0000 1010
& 0000 0100
0000 0000 结果是0,说明x的2号位是0
假设x 的二进制值 0000 1010
假设n的值是3
1 -------- 0000 0001
1<<3-------- 0000 1000
0000 1010
& 0000 1000
0000 1000 结果不为0,所以x的3号位是1
取反
unsigned char x;
x = x^1<<n; 将变量x的n位取反,和不一样,是把所有的位取反
假设x 的二进制值 0000 1010
假设n的值是3
0000 0010 0000 1010
^ 0000 1000 0000 1000
0000 1010 0000 0010 结果是将x的3号位取反。
九、数据类型:
基本数据类型: char int short long float double
构造数据类型: 指针。 数组。 结构体。 共用体。 枚举。
空类型: void
1. 枚举 enum
switch(score)
front 0
mid 1
back 2
Z轴
(1)定义:
enum TimeofDay
{
morning,
afternoon,
evening
};
(2)注意要点:
1)枚举类型中,声明的第一个枚举成员默认值为0
2)以后每个枚举成员值将是前一个枚举成员的值加1得到的。
3)定义枚举类型时,可以为枚举成员显示赋值。允许多个枚举成员有相同的值。
4)没有显示赋值的枚举成员的值,总是前一个枚举成员的值+1
(3) 使用示例:
枚举的使用,一般不会定义枚举类型变量,因为没有意义,枚举的每个成员都是常量。
enum TimeofToday
{
morning,
halfmorninig = 0, //强制让halfmorninig是0
afternoon,
halfafternoon = 0, //强制让halfafternoon是0
evening, //枚举的最后一个成员后面有没有逗号都无所谓
};
int main(int argc, const char** argv)
{
printf("%d %d %d %d %d\n", morning, afternoon, evening, halfmorninig, halfafternoon);
}
(4) 为什么使用枚举
枚举中每个成员都是常量,当定义好枚举之后,成员的值不能改变。
使用枚举的场合:当我们需要很多变量,不在乎值是多少,只在乎他们的值没有重复,最好还有大小关系,这时会将这些变量定义成枚举。
我们不会去定义枚举变量,枚举里的成员都是当作常量直接使用的。
2. 共用体 union
也叫联合体
(1)定义
union data
{
int a;
char b;
};
(2)要点:
-> 使用内存的方式,与结构体不同。
-> 共用体的各个成员共用内存,各个成员的起始地址是相同的。(占内存小的成员,是在大成员的低位地址)
-> 整个共用体占用的存储空间以长度最大的成员为准。
-> 一个共用体变量,如果对多个成员赋值,会覆盖掉其他成员的数据。
(3) 代码示例: 测试主机序。
#include <stdio.h>
union data
{
int a;
char c;
};
int main()
{
union data x;
x.a = 0x12345678;
printf("%x\n", x.c);
return 0;
}
(4)共用体的作用
1.作为数据泛型,一个共用体变量可以表示多种类型的数据。
2.实现巧妙的数据转换,比如将成员a转换为成员b。
(5) 共用体对比结构体
结构体每个成员都有独立的内存,而共用体所有成员共用同一段内存。
3. 位域
有时用一个字节去存储信息,还是会很浪费内存,此时就可以使用位域。使用位域的目的是为了节省内存。
(1) 定义:
struct data
{
unsigned int a : 2; //a占了int类型的前0位和1位
unsigned int b : 4; //b 占了int类型的 2 3 4 5位
unsigned int : 0; /* 空域 *///占了int类型剩下的所有位6~31位
unsigned int c : 3; //c占了另一个int的0 1 2位
};
//占8字节 a b 空域 占一个int c独占一个int
struct data
{
unsigned int a:2; //int 0 1
unsigned int b:4; //int 2 3 4 5
unsigned int c:3; //int 6 7 8
unsigned int:0; //空域 9~31
};
//占4字节
(2) 注意要点:
1)各位域必须存储在同一个类型长度中,不能跨两个类型长度。
2)位域占用的位数,不能超过类型长度。
3)允许位域无域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。
作业:
选择题
1.若数组名作实参而指针变量作形参,函数调用实参传给形参的是 ( )
A.数组的长度
B.数组第一个元素的值
C.数组所有元素的值
D.数组第一个元素的地址
2.变量的指针含意是指变量的 ( )
A.值 B.地址 C.存储 D.名字
3.某文件中定义的静态全局变量(或称静态外部变量)其作用域是 ( )
A.只限某个函数 B.本文件 C.跨文件 D.不限制作用域
4.以下对结构体类型变量的定义中,不正确的是( )。
A: typedef struct aa
{
int n;
float m;
} AA;
AA td1;
B: #define AA struct aa
AA {
int n;
float m;
} td1;
C: struct
{
int n;
float m;
} aa;
stuct aa td1;
D: struct
{
int n;
float m;
} td1;
5.short a[100],sizeof(a)返回? ( ) (百度笔试)
A 2 B 4 C 100 D 200 E 400
- 以下代码执行后,val的值是( )
unsigned long val = 0;
char a = 0x48;
char b = 0x52;
val = b << 8 | a;
A 20992 B 21064 C 72 D 0
简答题
- 为什么在头文件的最前面都会看到这样的代码 ?
#ifndef STDIO_H
#define STDIO_H
2.局部变量和全局变量是否能重名,简述一下当两者同时存在是会有什么结果?
编程1:
已知 strcpy 函数的原型是
void strcpy(char *strDest, const char *strSrc);
其中 strDest 是目的字符串,strSrc是源字符串。
不调用 C++/C 的字符串库函数,请编写 函数 strcpy。(注意检查参数的有效性) (东软汽车电子)
编程2:
编写一个函数 taxis()实现数组的升序排序,在函数中调用 带参宏swap()实现两个数的交换。
打印出排序结果
; //c占了另一个int的0 1 2位
};
//占8字节 a b 空域 占一个int c独占一个int
```C
struct data
{
unsigned int a:2; //int 0 1
unsigned int b:4; //int 2 3 4 5
unsigned int c:3; //int 6 7 8
unsigned int:0; //空域 9~31
};
//占4字节
(2) 注意要点:
1)各位域必须存储在同一个类型长度中,不能跨两个类型长度。
2)位域占用的位数,不能超过类型长度。
3)允许位域无域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。
作业:
选择题
1.若数组名作实参而指针变量作形参,函数调用实参传给形参的是 ( )
A.数组的长度
B.数组第一个元素的值
C.数组所有元素的值
D.数组第一个元素的地址
2.变量的指针含意是指变量的 ( )
A.值 B.地址 C.存储 D.名字
3.某文件中定义的静态全局变量(或称静态外部变量)其作用域是 ( )
A.只限某个函数 B.本文件 C.跨文件 D.不限制作用域
4.以下对结构体类型变量的定义中,不正确的是( )。
A: typedef struct aa
{
int n;
float m;
} AA;
AA td1;
B: #define AA struct aa
AA {
int n;
float m;
} td1;
C: struct
{
int n;
float m;
} aa;
stuct aa td1;
D: struct
{
int n;
float m;
} td1;
5.short a[100],sizeof(a)返回? ( ) (百度笔试)
A 2 B 4 C 100 D 200 E 400
- 以下代码执行后,val的值是( )
unsigned long val = 0;
char a = 0x48;
char b = 0x52;
val = b << 8 | a;
A 20992 B 21064 C 72 D 0
简答题
- 为什么在头文件的最前面都会看到这样的代码 ?
#ifndef STDIO_H
#define STDIO_H
2.局部变量和全局变量是否能重名,简述一下当两者同时存在是会有什么结果?
编程1:
已知 strcpy 函数的原型是
void strcpy(char *strDest, const char *strSrc);
其中 strDest 是目的字符串,strSrc是源字符串。
不调用 C++/C 的字符串库函数,请编写 函数 strcpy。(注意检查参数的有效性) (东软汽车电子)
编程2:
编写一个函数 taxis()实现数组的升序排序,在函数中调用 带参宏swap()实现两个数的交换。
打印出排序结果