- 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;
}
- 指针数组
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;//对数组每个元素进行读写,需要强制类型转换,把指向4个int的指针转换为一个指向1个int的指针
*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 printf(const char * format, …);
- 运行时才确定的参数
- int main(int argc, char *argv[]);