默认计划
491人加入学习
(0人评价)
【研发工程师】C语言程序设计
价格 ¥ 970.00
该课程属于 名企研发核心能力课 请加入后再学习

数组的代码演示:

数组作为函数参数会退化为指针

#include <stdio.h>

void func(int* num) {
    printf("func: ");
    printf("sizeof(num) = %lu\n", sizeof(num));
    return ;
}

int main() {
    int arr[100] = {}, n;
    printf("sizeof(arr) = %lu\n", sizeof(arr));
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", arr + i);
    }
    func(arr);
    return 0;
}

函数里接收的数组,与原数组不是同一个东西,函数里的形参本质上是一个指针

 

二维数组传参:

void func(int **num) { // int **num是错误的

}

void func(int num[100][20]) {

}

void func(int num[][20]) {

}

void func(int (*num)[20]) {
    // int * 指向一个 int [20]
}

int main() {
    int arr[100][20] = {};
    func(arr);
    return 0;
}

 

int **num = arr; 报警告是因为地址的类型不匹配。

 

因为:

int arr[100][20] = {0};

int **num = (int **)arr;

arr[%p]与arr+1[%p]相差20*4B的大小,但是

num[%p]与num[%p]相差8B,地址的大小。

因为int *(*num)是跟着类型的。

外在表现形式是不同的。

 

三维数组传参:

void func(int ***num) { // int ***num是错误的

}

void func(int num[100][20][10]) {

}

void func(int num[][20][10]) {

}

void func(int (*num)[20][10]) {
    // int * 指向一个 int [20][10]
    // 最常用
}

int main() {
    int arr[100][20][10] = {};
    func(arr);
    return 0;
}

维度至多只能省略第一个维度

--------------------------------------------

宏作用:文本替换,不做计算

定义符号常量:

#define PI 3.1415926
#define MAX_N 10000

定义傻瓜表达式:不需要加 { }

#define MAX(a, b) (a) > (b) ? (a) : (b)
#define S(a, b) a * b

定义代码段:需要加 { }

#define P(a) { \
    printf("%d\n", a); \
}

 

定义代码段时,如果{}外面加了(),即({}),

小括号的作用是:变成表达式,获取返回值

 

C语言预定义的宏:

__DATA__  替换成编译时的日期:Mmm dd yyyy。

__TIME__  替换成编译时的时间:hh:mm:ss

__LINE__  替换当前代码的行号

__FILE__  替换成当前.c的文件名

打印函数信息的宏:(以下3个是非标准宏,所有OS并非通用)

__func__   linux标准

__FUNC__  windows标准

__PRETTY_FUNCTION__  

 

还有很多其他的预定义宏需要自己学习提升

------------------------------------------------

条件式编译:(用于代码剪裁,增加可移植性)

#ifdef DEBUG   是否 定义了 DEBUG宏

#ifndef DEBUG 是否 没定义 DEBUG宏

 

// 用于版本号之类的

#if MAX_N == 5 宏MAX_N是否等于5

#elif MAX_N == 4 否则宏MAX_N是否等于4

#else

 

#endif 使用条件式编译,末尾必须加#endif

 

编译期检查:语法分析、词法分析、语义分析

链接:将所有的.o文件整合成a.out

 

工业开发:多文件“链编”

 

随堂练习:实现没有BUG版的MAX(a, b)宏返回a b二者中的最大值,需要通过如下测试:

MAX(2, 3)  3

5 + MAX(2, 3)  8

MAX(2, MAX(3, 4))  4

MAX(2, 3 > 4 ? 3 : 4)  4

MAX(a++, 6) // a的初始值为7,函数返回值为7,a的值变为8

#include <cstdio>

#define MAX(a, b) ({ \
	__typeof(a) x, y; \
	x = a; y = b; \
	(x) > (y) ? x : y; \
})

//#func表示将读入的MAX(2,3)字符串化
#define P(func) { \
	printf("%s = %d\n", #func, func); \
}

int main() {
	int a = 7;
	P(MAX(2, 3));
	P(5 + MAX(2, 3));
	P(MAX(2, MAX(3, 4)));
	P(MAX(2, 3 > 4 ? 3 : 4));
	P(MAX(a++, 6));
	P(a);
	
	return 0;
}

 

vim矩形删除:先两下esc 然后Ctrl+V,上下左右选中,最后 dd 删除

vim批量行添加:Ctrl+V,上下左右选中插入的行,然后按大写的I,进行输入,输入结束两下esc

 

-----------------------------------------------

宏定义其他冷门、重点知识

#define Conn(x,y) x##y

#define ToChar(x) #@x

#define ToString(x) #x

x##y表示什么?表示x连接y,举例说:

int n = Conn(123,456); 结果就是n=123456;

char* str = Conn("asdf","adf")结果就是 str = "asdfadf";

#@x,其实就是给x加上单引号,结果返回是一个constchar。

举例说:

char a = ToChar(1);结果就是a='1';

做个越界试验char a = ToChar(123);结果是a='3';

但是如果你的参数超过四个字符,编译器就给给你报错了!error C2015:too many characters in constant :P

#x是给x加双引号

char* str = ToString(123132);就成了str="123132";

如果有#define FUN(a,b) vo##a##b()那么FUN(idma,in)会被替换成void main()

[展开全文]

预处理命令:

    函数内部: 系统栈区(8M, 2M)主动定义赋值; 

num指针变量与数组表现形式一样

#include<stdio.h>

// num 为指针变量与arr不同
void func(int *num, int n) {
    printf("func : \n");
    printf("sizeof(num) = %lu\n", sizeof(num));
    printf("num = %p, num + 1 = %p\n", num, num + 1);
    return;
}

int main() {
    int arr[100] = {0}, n;
    
    // arr 为数组
    printf("sizeof(arr) = %lu\n", sizeof(arr));
    printf(arr = %p, &arr[0] = %p\n", arr, &arr[0]);
    printf("arr + 1 = %p\n", arr + 1);
    func(arr, n);
    return 0;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", arr + i);
    }
    func(arr, n);
    return 0;
}

高维数组传参:一个指针类型的大小64位8字节

#include<stdio.h>

// num 为指针变量与arr不同
void func(int num[100][20], int n) {
// 或者 void func(int num[][20], int n) {
// 或者 void func(int (*num)[20], int n) {
    printf("func : \n");
    printf("sizeof(num) = %lu\n", sizeof(num));
    printf("num = %p, num + 1 = %p\n", num, num + 1);
    return;
}

int main() {
    int arr[100][20] = {0}, n;
    
    // arr 为数组
    printf("sizeof(arr) = %lu\n", sizeof(arr));
    printf(arr = %p, &arr[0] = %p\n", arr, &arr[0]);
    printf("arr + 1 = %p\n", arr + 1);
    
    return 0;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", arr + i);
    }
    func(arr, n);
    return 0;
}

预处理命令-宏定义

   定义符号常量: #define PI 3.1415926

   定义傻瓜表达式:#define MAX(a, b) (a) > (b) ? (a) : (b)

   #define S(a, b) a * b

  定义代码段:

         #define P(a) { \

               printf("%d\n",a); \

        }

   预定义的宏

      __DATE__         // 日期:M mm dd yyy

      __TIME__        // 时间:  hh:mm:ss

      __LINE__         //行号

      __FILE__       // 文件名

       __func__       // 函数名

      __FUNC         //

       __PRETTY_FUNCTION__     // 更详细函数信息

   条件式编译:

       函数:  #ifdef DEBUG       // 是否定义了

                   #ifndef DEBUG     // 

                   #if MAX_N == 5   //  宏MAX_N是否

                 #elif MAX_N == 5

                   #else

                 #endif

      1: 54:50       预处理命令

      2:14:30     歌曲

gcc -E xxx.c

#define MAX(a, b) ({ \
    __typeof(a) _a = (a); \
    __typeof(b) _b = (b); \
    _a > _b ? _a : _b; \
})


#define P(func) {\           
    printf("%s = %d\n", #func, func);\
}

int main() {

    int a = 7;   
    P(MAX(2, 3));
    P(5 + MAX(2, 3));
    P(MAX(2, MAX(3, 4)));
    P(MAX(2, 3 > 4 ? 3 : 4));
    P(MAX(a++, 6));
    P(a);
    return 0;
}

 

[展开全文]

授课教师

C++算法工程师

课程特色

视频(31)