C 斯特伦并不总是一个好主意
我不确定我是否选择了正确的标题,但今天我发现(作为C语言的初学者),对于我来说,斯特伦并不总是在我需要它的时候做出正确的决定 因此,我尝试了以下方法:C 斯特伦并不总是一个好主意,c,C,我不确定我是否选择了正确的标题,但今天我发现(作为C语言的初学者),对于我来说,斯特伦并不总是在我需要它的时候做出正确的决定 因此,我尝试了以下方法: #include<stdio.h> #include<string.h> int foo(char *s){ int len = strlen(s); /* code here */ return len; } int main(void){ char *name = "Mich
#include<stdio.h>
#include<string.h>
int foo(char *s){
int len = strlen(s);
/* code here */
return len;
}
int main(void){
char *name = "Michi";
int len = foo(name);
int a = 20, b = 10, c = a - b;
if(c < len){
printf("True: C(%d) < Len(%d)\n",c,len);
}else{
printf("False: C(%d) > Len(%d)\n",c,len);
}
return 0;
}
#include<stdio.h>
#include<string.h>
unsigned int size(char *s){
unsigned int len;
/* code here */
len = (unsigned int)strlen(s);
return len;
}
int main(void){
char *name = "Michi";
unsigned int len = size(name);
int a = 20, b = 10, c = a - b;
if(c < (signed int)len){
printf("True: C(%d) < Len(%d)\n",c,len);
}else{
printf("False: C(%d) > Len(%d)\n",c,len);
}
return 0;
}
一个快速解决方案是施特伦:
int len = (int)strlen(s);
但我不同意,所以我决定我真的需要其他东西,也许另一种方法?
我尝试了以下方法:
#include<stdio.h>
#include<string.h>
int foo(char *s){
int len = strlen(s);
/* code here */
return len;
}
int main(void){
char *name = "Michi";
int len = foo(name);
int a = 20, b = 10, c = a - b;
if(c < len){
printf("True: C(%d) < Len(%d)\n",c,len);
}else{
printf("False: C(%d) > Len(%d)\n",c,len);
}
return 0;
}
#include<stdio.h>
#include<string.h>
unsigned int size(char *s){
unsigned int len;
/* code here */
len = (unsigned int)strlen(s);
return len;
}
int main(void){
char *name = "Michi";
unsigned int len = size(name);
int a = 20, b = 10, c = a - b;
if(c < (signed int)len){
printf("True: C(%d) < Len(%d)\n",c,len);
}else{
printf("False: C(%d) > Len(%d)\n",c,len);
}
return 0;
}
#包括
#包括
无符号整数大小(字符*s){
无符号整数len;
/*代码在这里*/
len=(无符号整数)strlen(s);
回程透镜;
}
内部主(空){
char*name=“Michi”;
无符号整数长度=大小(名称);
INTA=20,b=10,c=a-b;
如果(c<(签名整数)len){
printf(“True:C(%d)Len(%d)\n”,C,Len);
}
返回0;
}
但是我仍然需要强制转换strlen,因为它的返回类型(size\t,我知道它是无符号类型(typedef long unsigned int size\t;))
最后,我决定采用另一种方法,创建我自己的函数,使事情变得更简单,未来可能出现的问题更少,我得到:
#include<stdio.h>
long int stringLEN(char *s){
int i = 0;
long int len = 0;
while (s[i] != '\0'){
len++;
i++;
}
return len;
}
long int foo(char *s){
long int len = stringLEN(s);
/* code here */
return len;
}
int main(void){
char *name = "Michi";
long int len = foo(name);
int a = 20, b = 10, c = a - b;
if(c < len){
printf("True: C(%d) < Len(%ld)\n",c,len);
}else{
printf("False: C(%d) > Len(%ld)\n",c,len);
}
return 0;
}
#包括
长整型字符串(字符*s){
int i=0;
长整数len=0;
而(s[i]!='\0'){
len++;
i++;
}
回程透镜;
}
长整型foo(字符*s){
长整数长度=长整数长度;
/*代码在这里*/
回程透镜;
}
内部主(空){
char*name=“Michi”;
long int len=foo(名称);
INTA=20,b=10,c=a-b;
if(cLen(%ld)\n”,C,Len);
}
返回0;
}
不再需要石膏的地方
所以我的问题是:
这(对我来说)是更好的方法吗?
如果不是,我需要一些解释,我的书(我有3本)并没有以我能理解的方式来解释我
我只知道在某个时刻,演员阵容可能会成为一个大问题
编辑:
此代码也不会使用-Wconversion编译:
#include<stdio.h>
#include<string.h>
size_t foo(char *s){
size_t len = strlen(s);
/* code here */
return len;
}
int main(void){
char *name = "Michi";
size_t len = foo(name);
int a = 20, b = 10, c = a - b;
if(c < len){
printf("True: C(%d) < Len(%zu)\n",c,len);
}else{
printf("False: C(%d) > Len(%zu)\n",c,len);
}
return 0;
}
#包括
#包括
大小\u t foo(字符*s){
尺寸长度=标准长度;
/*代码在这里*/
回程透镜;
}
内部主(空){
char*name=“Michi”;
大小\u t len=foo(名称);
INTA=20,b=10,c=a-b;
if(cLen(%zu)\n”,C,Len);
}
返回0;
}
输出:
错误:有符号和无符号整数表达式之间的比较[-Werror=符号比较]|
但是如果我投下的话,len会起作用。我意识到,如果大小大于int,它将永远不适合。解决这个问题的正常方法是使用键入的变量
size\u t
,并选择适当的格式来打印它们。那么就不需要石膏了。有关printf,请参见以下内容:
size\u t
的值范围不同于int
,如果将size\u t
的某些正值转换为int
,则将被视为负值。更好的选择是让返回类型与函数匹配,在本例中,让foo
返回一个size\t
-您很快就会看到数据类型将允许大部分代码,并留下一些其他可能会做奇怪事情的异常(size\t-size\t
可能会下溢…)我认为不同的编译器之间一定存在差异……因为我在在线编译器上尝试了它,但没有显示任何警告 有两个问题:
strlen()
返回类型size\t
size\u t
是一些无符号整数类型,可能与int
一样宽或更宽。它依赖于编译器/平台int
到size\u t
。由于size\u t
是无符号的,为了防止出现有符号/无符号混合比较的警告,请将int
显式更改为无符号整数。要将非负的int
更改为无符号整数,请强制转换为(无符号)
c
是否为负值,如果不是,则直接将(无符号)c
与len
进行比较。编译器将根据需要转换类型,并生成算术正确的答案
size\u t len=strlen(“SomeString”);
int c=20;//一些智力
如果(c<0 | |(无符号)c=len”);
这将在没有警告的情况下编译:
#include<stdio.h>
#include<string.h>
size_t foo(char *s){
size_t len = strlen(s);
/* code here */
return len;
}
int main(void){
char *name = "Michi";
size_t len = foo(name);
size_t a = 20, b = 10, c = a - b;
if(c < len){
printf("True: C(%zu) < Len(%zu)\n",c,len);
} else {
printf("False: C(%zu) > Len(%zu)\n",c,len);
}
return 0;
}
#包括
#包括
大小\u t foo(字符*s){
尺寸长度=标准长度;
/*代码在这里*/
回程透镜;
}
内部主(空){
char*name=“Michi”;
大小\u t len=foo(名称);
尺寸a=20,b=10,c=a-b;
if(cLen(%zu)\n”,C,Len);
}
返回0;
}
正如@thomasdickey、@rolandshaw、@andreaghidini、@olaf、@juanchopanza和其他人在回答和评论中所解释的那样
你真的采取了更好的方法吗?否:为什么stringlen函数要返回可能为负值的值?不存在大小为负的字符串
标准strlen函数已经存在,效率更高,能够处理最大大小为stringLEN处理的最大大小两倍的字符串,并且对返回类型有更精确的定义。仔细研究所有其他答案,您真正的问题似乎是如何处理这样的情况:
#include <string.h>
#include <libfoo.h>
extern void foo(void);
extern void bar(void);
void pick_foo_or_bar(const char *s)
{
size_t slen = strlen(s);
int value = libfoo_api_returning_an_int();
if (slen > value) // -Wconversion warning on this line
foo();
else
bar();
}
之所以存在静态断言
,是因为如果我没记错的话,C标准不能保证大小t
至少与无符号整数
一样大。例如,我可以想象80286的ABI,其中int
是四个字节宽的b
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <libfoo.h>
extern void foo(void);
extern void bar(void);
// Code below is correct only if size_t is at least as large as int.
static_assert(SIZE_MAX >= INT_MAX);
void pick_foo_or_bar(const char *s)
{
size_t slen = strlen(s);
int value = libfoo_api_returning_an_int();
if (value < 0 || (size_t)value < slen)
foo();
else
bar();
}
void pick_foo_or_bar(unsigned short a, long b)
{
if (b < 0 || b < (long)a)
foo();
else
bar();
}
void pick_foo_or_bar(uid_t a, gid_t b)
{
if (a < 0 && b < 0) {
if ((intmax_t)a < (intmax_t)b)
bar();
else
foo();
} else if (a < 0) {
bar();
} else if (b < 0) {
foo();
} else {
if ((uintmax_t)a < (uintmax_t)b)
bar();
else
foo();
}
}