C语言使用注意点

1. 函数参数为一级指针,函数内部参数的指针改变并不影响原来传入指针本身的值。

void ptr_mdy(void *ptr)
{
	ptr = malloc(100);
	assert(ptr);
	printf("In the func: %x\n", (unsigned int)ptr);
}

int main()
{
	void * ptr = malloc(100);
	assert(ptr);
	printf("Former: %x\n", (unsigned int)ptr);

	ptr_mdy(ptr);
	printf("Out of func: %x\n", (unsigned int)ptr);

	return 0;
}
ptr的值未被改变。

如果要修改ptr的值,那么要用二级指针, 修改如下

void ptr_mdy(void **ptr)
{
	*ptr = malloc(100);
	assert(*ptr);
	printf("In the func: %x\n", (unsigned int)*ptr);
}

int main()
{
	void * ptr = malloc(100);
	assert(ptr);
	printf("Former: %x\n", (unsigned int)ptr);

	ptr_mdy(&ptr);
	printf("Out of func: %x\n", (unsigned int)ptr);

	return 0;
}

2. 函数返回局部变量数组,局部结构体指针(非malloc分配的)错误。因为函数返回,栈上内容被回收。

int *ptr_ret()
{
	int ptr[100] = {0};
	return ptr;
}

int main()
{
	int * ptr = ptr_ret();
	return 0;
}
函数返回后,ptr成为野指针。


3. 如果两个结构体相互包含,至少一方为指针,然后把指针对象的结构体声明放在前面,具体声明放到后面。不能两个相互包含的结构体都是普通变量类型(就是非指针类型)。即:

struct b;
struct a{
	struct b * test;
};

struct b{
	struct a test;
};

4. 结构体内部不能包含该结构体变量(非指针), 因为永远递归而不知该结构体大小。

struct a{
	struct a test;
};


5. 变量不要定义在头文件里,如果有两个c文件以上包含该头文件,则会造成该变量混乱使用。

6. 指针类型的内容不能直接赋值,要通过内存拷贝的方式。比如字符串,结构体。

7. 对于strlen、strcmp等函数需要检查参数是否为NULL,否则容易一不小心而挂掉,因为内部需要访问参数地址的内容, 使用strnlen, strncmp会更加安全,防止没有字符串结束符。

8. sizeof是c 编译器的一个关键字,用于静态检测分配的内存。

9. char **argv != char copy[a][b]; 不可以直接赋值,因为argv[]是指向字符串的指针,而copy[]是指向间距为b的空间,内存布局不一样。常见错误

int callback(char **argv, int argc)
{
	int i;
	for (i = 0; i < argc; i++)
		printf("argv[%d]: %s\n", i, argv[i]);
}

int main()
{
	char copy [100][10];
	memcpy(copy[1], "1", 1);
	memcpy(copy[2], "2", 1);
	memcpy(copy[3], "3", 1);

	callback(&copy[2], 2);

	return 0;
}
把char *argv[] 改为 char argv[][10] 即可。


10. 数据类型转换。

比如 

int i = 16384. 

char j = i;

这时,因为16384 = 0x4000, 所以 j = 0;这就可能导致整个系统逻辑不对了。


11. int data;

int data = 10;

printf("%s\n", data);

这样就挂了


你可能感兴趣的:(C语言使用注意点)