C 查漏补缺(三)

  • main函数传参数
#include <stdio.h>

int main(int argc, char **argv)
{
    int i;
    printf("program name = %s\n", argv[0]);
    for (i = 1; argv[i] != NULL; i++)
    {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
    return 0;
}

image
- 指针数组

char *p[3] = {"abc", "defg"};//sizeof(p) = 3*4 = 12   p 为数组名代表整个数组
p[1] = "abcd";//不可以 *p[1] = "abcd",*p[1]指向字符串常量不能改变,只能改变p[1]即指针地址
  • 数组指针
#include <stdio.h>

int main()
{
    int *q;
    int num[2][4];
    //数组名num指向第一个元素,num[0]指向“{num[0][0],num[0][1],num[0][2],num[0][3]}”,num[1]同理
    //num == num[0] == &num[0][0]; num+1 == num[1] == &num[1][0];*num+1 == num[0]+1 == &num[0][1]
    //num == &num(指向整个数组的指针);num+1 != &num+1;
    //二维数组名可以看作一个指向指针数组的指针,“num-->{num[0],num[1]}-->{num[0][0]......};”
    int (*p)[4];//p是指向一个数组一行元素的整体的指针
    p = num[0];
    //p == num[0],p+1 == num[1];*p+1 == &num[0][1];
    //sizeof(p) == 4;sizeof(*p) == 4*4;sizeof(num) = 2*4*4 = 32; 
    q = (int *)p;//对数组每个元素进行读写,需要强制类型转换,把指向4int的指针转换为一个指向1int的指针
    *q = 1;//不可以 *p = 1
    printf("%d\n", num[0][0]);//输出1
    return 0;
}
  • strlen和sizeof
    • sizeof与strlen有着本质的区别,sizeof是求数据类型所占的空间大小,而strlen是求字符串的长度,字符串以’\0’结尾
char *c = "abcdef";//sizeof(c) = 4; strlen(c) = 6
char d[] = "abcdef";//sizeof(d) = 7 字符数组以字符串的形式赋值,字符串末位有'\0',所以共7个字节, strlen(d) = 6;
char e[] = {'a','b','c','d','e','f'};//sizeof(d) = 6 字符数组以单个元素的形式赋值,末位没有'\0',strlen(d) 为不确定的值
  • 内存
    • 内存分配了不释放是内存泄漏
      • malloc 、new 没有 free 、delete
    • 写多了是缓冲区溢出
    • Linux可以通过valgrind跑一遍
  • 野指针
    • 野指针不是NULL指针,是指向“垃圾”内存的指针。
    • 野指针的成因:
      • 指针变量没有被初始化
      • 指针p被free或者delete之后,没有置为NULL
  • 指针和数组
    • 数组名对应着一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。
    • 指针可以随时指向任意类型的内存块。
    • 内容复制与比较:
//数组
char a[] = "hello";
char b[10];
strcpy(b, a);//不能 b = a
if (0 == strcmp(b, a));//不能 if(b == a)
//指针
int len = strlen(a);
char *p = (char *)malloc(sizeof(char)*(len+1));//+1 是'\0'
strcpy(p, a);// p = a 只是把a的地址赋给了p
if (0 == strcmp(p, a))//不要用if (p == a)
#include <stdio.h>
#include <string.h>

void func(char str_arg[2])//形参可以是 char *str_arg || char str_arg[9999] 
{                           //数组作为函数参数被弱化成指针
    int m = sizeof(str_arg);//str_arg为char *类型 4
    int n = strlen(str_arg);//输出字符串长度5
    printf("%d %d\n", m, n);//输出4 5
}
int main()
{
    char str[] = "Hello";
    func(str);
    return 0;
}
  • 文件包含
#include <stdio.h>//使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的),而不再源文件目录中查找
#include "myHead.h"//首先在当前的源文件目录中查找,若未找到才到包含目录中去查找。
  • 函数声明
#include <stdio.h>
#include <string.h>

int main()
{
    int a = 1;
    int func(int a);//声明,不能在main函数里面再定义函数
    printf("%d %d\n", a, func(a));//输出 1 2
    return 0;
}

int func(int a)
{                           
    return ++a;
}
  • 如何编写有多个返回值的C语言函数
    • 利用全局变量
    • 传递数组指针
    • 传递结构体指针
  • 回调函数
    • 将函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,这个函数就是回调函数
NODE *Search_List(NODE *node, int (*compare)(void const *, void const *), void const *value){}
  • 变参函数
    • int printf(const char * format, …);
      • C语言中定义了一个头文件专门用来对付可变参数列表,它包含了一组宏和一个va_list的typedef声明。
  • 运行时才确定的参数
    • int main(int argc, char *argv[]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值