常用的编程技巧 const ,assert

目录

1:使用assert

2:尽量使用const

3:养成良好的编程风格

4:添加必要的注释

5:避免编程陷阱


1:使用assert

当需要判断的时候就可以用assert

为假的时候会返回一个错误

看下面的代码

#include<stdio.h>
#include<assert.h>
int  my_strlen(const char* p) {
	int count = 0;
	assert(p != NULL);
	while (*p++ != '\0') {
		count++;
	}
	return count;
}
int main() {
	char arr[] = "abcdefghijklmnopqrstuvwxyz";
	int ret=my_strlen(arr);
	printf("%d", ret);
}

  这里的返回类型可以使unsigned int =size_t,这样返回值的范围会扩大一倍

#include<stdio.h>
#include<string.h>
int main() {
	if (strlen("abc") - strlen("abcdeft") > 0) {
		//strlen函数的返回值是size_t
		// -3的原反补
		//10000000000000000000000000000101
		//11111111111111111111111111111010
		//11111111111111111111111111111101
		printf("hehe\n");
	}
	else {
		printf("haha\n");
	}
}

 

 

#include<stdio.h>
#include<assert.h>
void my_strcpy(char* des, char* sor) {
	/*if (des == NULL || sor == NULL) {
		return;
	}*/
	assert(des != NULL);//断言,release版本可以优化掉
	assert(sor != NULL);
	while (*des++ = *sor++) {
		;
	}
}
int main() {
	char arr[] = "abcdef";
	char arr2[10];
	my_strcpy(arr2, arr);
	my_strcpy(arr2, NULL);
	printf("%s", arr2);
}

 

 用assert断言(头文件为assert.h)des和sor两个指针不是空,如果是空指针,证明断言为假,就会出现这种情况

2:尽量使用const

const修饰指针的时候,如果放在*的左边,代表所指向的指针所指向对象的内容无法被改变,如果修饰数组指针,那么可以防止数组里面的元素被意外的修改

如果放在*的右边,代表所指向的对象无法被改变

看下面的代码

#include<stdio.h>
int main() {
	//const修饰指针
	//const放在*的左边,限制的是*p,也就是指针所指向的对象的内容
    //int const*p和const int* p是一样的

	int a = 20;
	int b = 10;
	const int* p = &a;
	*p = 10;//错误的
	p = &b;
	int const* pb = &b;
	*pb = 20;//错误的
	pb = &a;

	//const放在*的右边,限制的是p,也就是指针所指向的对象
	int c = 30;
	int d = 40;
	int* const pc = &c;
	pc = &d;//错误的
	*pc = 40;
}

 

3:养成良好的编程风格

下面代码函数的内容有六种写法

 

int main() {
	char arr[] = "abcdef";
	char arr2[10];
	/*char arr6[] = "abcdefghijklmn";
	char arr7[4];*///目的地字符串的空间必须要足够

	//char arr5[] = { 'a','b','c' };//源头字符串必须要有\0

	/*char arr3[] = "ghijk";
	const char* arr4 = "#########";//常量字符串是放在常量区的,是不能修改的
	char* ret = my_strcpy(arr4, arr3);*/

	char*ret=my_strcpy(arr2, arr);
	printf("%s", ret);
}

第一种最简单

第二种将用后置++使代码简洁

第三种通过while()循环自身就带的判断来判断是否遇到\0

第四种使用assert来断言,使当传进来的指针使空指针的时候会报错

第五种使用const修饰指针,防止指针所指向的数组的元素被意外修改,也就是防止传反数组地址

第六种在上面,返回类型为char*,返回一个指针,但是最后des所指向的内容不是其实地址,所以要将他的其实地址存起来

#include<stdio.h>
//版本一
void my_strcpy(char* des, char* sor) {
	while (*sor != '\0') {
		*des = *sor;
		des++;
		sor++;
	}
	*des = *sor;
}
//版本二
void my_strcpy(char* des, char* sor) {
	while (*sor != '\0') {
		*des++ = *sor++;
	}
	*des = *sor;
}
//版本三
void my_strcpy(char* des, char* sor) {
	//1:复制字符
	//2:遇到\0停止
	while (*des++ = *sor++) {
		;//空语句
	}
}
//版本四
#include<assert.h>
void my_strcpy(char* des, char* sor) {
	/*if (des == NULL || sor == NULL) {
		return;
	}*/
	assert(des != NULL);//断言,release版本可以优化掉
	assert(sor != NULL);
	while (*des++ = *sor++) {
		;
	}
}
//版本五
void my_strlen(char* des, const char* sor) {
	//const防止原字符数组被意外修改,也防止将目的地的字符复制到源头的字符数组中
	assert(des != NULL);
	assert(sor != NULL);
	while (*des++ = *sor) {
		;
	}
}
int main() {
	char arr[] = "abcdef";
	char arr2[10];
	my_strcpy(arr2, arr);
	my_strcpy(arr2, NULL);

	printf("%s", arr2);
}

4:添加必要的注释

上面的代码都有注释

5:避免编程陷阱

看积累了

### C++ 模板编程常用技巧和最佳实践 C++ 模板编程是一种强大的工具,它允许程序员创建泛型代码,从而提高代码重用性和效率。以下是关于 C++ 模板编程的一些常见技巧和最佳实践: #### 泛型函数设计 模板可以用于定义适用于多种数据类型的函数。这种技术的核心在于利用编译期多态来实现通用逻辑[^1]。 ```cpp template<typename T> T max(T a, T b) { return (a > b) ? a : b; } ``` 上述代码展示了如何通过模板定义一个 `max` 函数,它可以接受任意具有比较运算符的数据类型作为输入参数。 #### 部分特化与全特化 部分特化是指针对某些特定条件下的模板实例提供专门化的实现方式;而全特化则是完全替换掉默认版本的行为。这有助于解决复杂场景中的特殊需求[^2]。 ```cpp // 原始模板声明 template<class T> class MyClass; // 对指针类型的部分特化 template<class T> class MyClass<T*> { public: void process() { /* 处理指针 */ } }; // 全特化示例 template<> class MyClass<int> { public: void specialProcess() { /* 只针对int类型的操作 */ } }; ``` #### SFINAE 技术应用 SFINAE(Substitution Failure Is Not An Error),即替代失败不是错误原则,在模板元编程中有重要作用。它使得我们可以基于表达式的合法性选择不同的函数重载形式。 ```cpp #include <type_traits> template<typename T> auto addOne(T t) -> typename std::enable_if<std::is_integral<T>::value, T>::type { return t + 1; // 如果T是整数,则执行此操作 } template<typename T> auto addOne(T t) -> typename std::enable_if<!std::is_integral<T>::value, T>::type { return t; // 否则返回原值 } ``` 这里使用了 `std::enable_if` 来控制何时启用某个函数模板。 #### 使用静态断言验证约束 为了增强程序健壮性并给出清晰提示信息给开发者,可以在模板内部加入静态断言语句以确认满足必要的前提假设。 ```cpp template<typename T> void checkType(const T& value){ static_assert(std::is_arithmetic<T>::value,"Template argument must be an arithmetic type."); // 执行其他业务逻辑... } ``` 以上方法会在不符合要求的情况下抛出编译时错误,并附带自定义消息说明原因。 #### 性能考量与内联建议 由于模板会生成大量重复代码副本,因此需要注意其对最终二进制文件大小的影响。适当运用 inline 关键字可以帮助减少冗余复制带来的开销问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值