Are there any significant differences between the following two methods of printing text using subscripts? Are there any pros/cons of using one method over the other?
#include <stdio.h>
int main(void)
{
int i;
char *text;
/* method 1 */
text = "abc";
for (i = 0; i < 3; ++i) {
printf("%c\n", text[i]);
}
printf("\n");
/* method 2 */
for (i = 0; i < 3; ++i) {
printf("%c\n", "abc"[i]);
}
return 0;
}
Both methods are basically the same. The 2nd method could be slightly faster since your print function calls a static value ("abc") instead of a reference to "abc".
I wouldn't be surprised if the compiler would make those 2 methods similar in the end.
This being said, the first method should be better in most situations since you'll probably want to reuse the 'text' variable or load it from elsewhere.
Related
Just wondering if these variations of for loops are more efficient and practical.
By messing with the c for loop syntax i can embedd statements that would go in the loop-body into the loop-head like so:
Example 1:
#include <stdio.h>
int main(int argc, char ** argv)
{
// Simple program that prints out the command line arguments passed in
if (argc > 1)
{
for(int i = 1; puts(argv[i++]), i < argc;);
// This does the same as this:
// for(int i = 1; i < argc; i++)
// {
// puts(argv[i]);
// }
}
return 0;
}
I understand how the commas work in the for loop it goes through each statement in order, evaluates them then disregards all but the last one which is why it is able to iterate using the "i < argc"condition. There is no need for the final segment to increment the i variable as i did that in the middle segment of the loop head (in the puts(argv[i++]) bit).
Is this more efficient or is just just cleaner to seperate it into the loop body rather than combine it all into one line?
Example 2:
int stringLength(const char * string)
{
// Function that counts characters up until null terminator character and returns the total
int counter = 0;
for(counter; string[counter] != '\0'; counter++);
return counter;
// Same as:
//int counter = 0;
// for(int i = 0; string[i] != '\0'; i++)
//{
// counter++;
//}
//return counter;
}
This one seems more efficient than the version with the loop body as no local variable for the for-loop is initialised. Is it conventional to do these sorts of loops with no bodies?
Step 1: Correctness
Make sure code is correct.
Consider OP's code below. Does it attempt to print argv[argc] which would be bad?
if (argc > 1) {
for(int i = 1; puts(argv[i++]), i < argc;);
I initially thought it did. So did another user. Yet it OK.
… and this is exactly why code is weak.
Code not only should be correct, better code looks correct too. Using an anti-pattern as suggested by OP is rarely1 as good thing.
Step 2: Since code variations have the same big O, focus on understandably.
Sculpt your code – remove what is not needed.
for (int i = 1; i < argc; i++) {
puts(argv[i]);
}
What OP is doing is a trivial optimization concern.
Is premature optimization really the root of all evil?
Is it conventional to do these sorts of loops with no bodies?
Not really.
The key to the style of coding is to follow your group's style guide. Great software is often a team effort. If your group's likes to minimize bodies, go ahead. I have seen the opposite more common, explicit { some_code } bodies.
Note: int stringLength(const char * string) fails for strings longer than INT_MAX. Better to use size_t as the return type – thus an example of step 1 faltering.
1 All coding style rules, except this rule, have exceptions.
I am trying to write a function(findString) to find out if character strings are present inside another string. For my function, the first argument is the searched character string and the second is the one trying to be found.
If the string is found, then the location of the source string is returned.
My written code is below:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
int findstring(char source[], char lookup[]){
int lensource, lenlookup;
lensource= strlen(source);
lenlookup = strlen(lookup);
int i;int j;
for(i=0; i>=lensource; ++i)
for (j=0; j>=lenlookup; ++j)
if (source[i]==lookup[j])
return i;
}
int main(){
findstring("Heyman","ey");
}
If the function worked properly, then the index 2 should be returned.
However, when I run it, nothing is returned. I suppose the problem it that there is something wrong with my approach with the for loop or if statement.
I'm doing this without using strstr
First, there is a function that does this already, called strstr.
Second, your loop is written incorrectly. It should be:
for(i=0; i < lensource - lenlookup + 1; ++i) {
for (j=0; j<lenlookup; ++j)
if (source[i + j]!=lookup[j])
break;
if (j == lenlookup) return i + 1; // edit: had error
// note that return i feels more right, but
// op's spec seems to want i + 1
}
return -1; // no spec on return value for failure, but -1 seems reasonable
Edit: had typo.
Assuming both source and lookup are non-empty strings, then both lenlookup and lensource are strictly positive.
And your for loops are never executed, because
for(i=0; i>=lensource; ++i) {
// do something
}
is understood as (and translated by the compiler to):
i=0;
while(i>=lensource) {
// do something;
// at last
++i;
}
so you understand the initial test i>=lensource is false (at start i==0 but lensource>0) so the loop is never executed
BTW I strongly suggest to compile your code with all warnings and debugging info (e.g. gcc -Wall -g) and to use a debugger (e.g. gdb) to run it step by step and understanding what is happening.
You missed basic input check (what if either source or lookup is NULL, what if lookup is an empty string, what if lookup is longer than source, etc)
The comparison is not performed correctly
Your function doesn't always return a value (what does it return if lookup is not found in source?).
int findstring(char source[], char lookup[]){
// when either input is NULL
if(source==NULL||lookup==NULL)return -1;
int lensource, lenlookup;
lensource= strlen(source);
lenlookup = strlen(lookup);
// when lookup is an empty string
if(lenlookup==0)return 0;
// when lookup is longer than source
if(lenlookup>lensource)return -1;
int i;int j;
for(i=0; i<=lensource-lenlookup; ++i){
bool success = true;
for (j=0; j<=lenlookup; ++j){
if(lenlookup[j]!=lenlookup[i+j]){
success = false;
break;
}
}
if(success)return i;
}
return -1;
}
You may also want to check out other more efficient algorithms like KMP, boyer-moore and rabin-karp.
so i've looked through here and on google and tried various forms to try and accomplish this. it doesn't seem like it should be hard. i've tried getting a value from the char, tried just using math on it since i've read that a char in C is a number to the compiler anyway. what i have is an array of 4 strings. each element is another array of 20 + 1 characters (to include the null \0) what i'm trying to do is shift the value of each character in each string by a predefined amount using a variable "decryption_shift". what i thought i was doing is using 2 for loops, one to do one string at a time, the other to change each character in the strings. i've tried using pointers, tmp variables. yes this is a homework assignment, problem is it's a higher level class and they aren't teaching us methods/functions/syntax, they want us to research and learn on our own how to do it. i've already spent 2 hours trying to figure out this one snippet and don't know where else to turn. any help is greatly appreciated.
~justin
void decrypt_chunks()
{
for (m = 0; m < 0; m++)
{
for (n = 0; n < 20; n++)
{
// int *chunksp = &chunks[m][n];
chunks[m][n] = chunks[m][n] - DECRYPTION_SHIFT;
// *chunksp[m][n]=tmp;
// chunks[m][n]=tmp;
}
}
}
Your problem is here:
for (m = 0; m < 0; m++)
The loop will never execute because the termination condition is met on initialization. Try
for (m = 0; m < 4; m++)
I can't see where DECRYPTION_SHIFT or chunks is defined (and initialized), so make sure you're actually define it globally or in the decrpyt_chunks() function (note: usually you write variables lowercase and macros uppercase, and if DECRYPTION_SHIFT is a variable you should write it in lowercase letters)
for (m = 0; m < 0; m++) while never run, this statement in words would be something like: set m to ziro (btw where did you defined m?) and do the following things as long as m is less than ziro (never the case, as you set it to ziro)
As this seems like a very basic problem, make sure you actually understand what a programming language is and how it works and consider reading one or two books about c (or almost any other programming language, as this homework would be in most modern languages pretty much the same).
To really make this thing interresting, what you basically do is encrypting like Caesar, so to implement this, the code could look similar to this one:
#include <stdio.h>
#include <string.h>
void decrypt_chunks(int decryption_shift);
char chunks[4][21];
int main(int stdr, char *stdv[])
{
strcpy(chunks[0],"Hello World! And Bye");
printf("message string: %s\n", chunks[0]);
decrypt_chunks(1);
printf("encrypted string: %s\n", chunks[0]);
decrypt_chunks(-1);
printf("decrypted sring: %s\n", chunks[0]);
}
void decrypt_chunks(int decryption_shift)
{
for (int m = 0; m < 4; m++)
{
for (int n = 0; n < 20; n++)
{
chunks[m][n] = chunks[m][n] - decryption_shift;
}
}
}
I'm writing a function for my homework which is supposed to tell if a given string is a palindrome or not.
Although I even tried it on paper with the word "otto", my program always returns 1.
Although this is a quite common question, I'd really like to know what I'm doing wrong instead of just copying a solution from here.
int is_palindrom(const char* palin)
{
int size = strlen(palin), i=0;
for (i=0;i<=(size/2); ++i)
{
if(palin[i] != palin[(size - i -1)])
{
return 1;
}
}
return 0;
}
Your code is correct, however please note that you may have an inverted logical expression. You are returning 1 in case of not equal, and 0 when it is. This means your function is working the opposite of "standard" C functions, where 1 evaluates to true.
Obviously, you are free to use whichever value you like to represent whatever you want. However, this can easily lead to confusion if someone else is reading your code. If bool is available, you should be using that; otherwise, you should always assume 1 is true and 0 is false.
Also, make sure to note is_palindrome takes a string and not an integer.
i.e. you must call it as is_palindrome("767") and not is_palindrome(767)
Your code does return 0 when it should. I am guessing when you read the string you pass as argument to your function, there are extra characters appended to the string, most probably a new line character. Try debugging the application or adding debug output in the function. For instance print the length of the string and the ascii codes of the characters in it.
Here is the code I used to verify it:
#include <stdio.h>
#include <string.h>
int is_palindrom(const char* palin)
{
int size = strlen(palin), i=0;
for (i=0;i<=(size/2); ++i)
{
if(palin[i] != palin[(size - i -1)])
{
return 1;
}
}
return 0;
}
int main(void) {
printf("%d", is_palindrom("otto"));
return 0;
}
Make sure your (const char *) has a "\0" at the end when you call this function.
#include<stdio.h>
#include<conio.h>
int is_palindrom(const char* jj);
int main(char *args){
int rr = is_palindrom("otto");
printf("rsult is %d", rr);
getch();
}
int is_palindrom(const char* palin)
{
int size = strlen(palin), i=0;
for (i=0;i<=(size/2); ++i)
{
if(palin[i] != palin[(size - i -1)])
{
return 1;
}
}
return 0;
}
I ran you code using above code snippet and it work fine for me.it returns 0 if palindrome is entered and 1 if entered value is not palindrome. the main part of the function is the loop
for (i=0;i<=(size/2); ++i) and the comparison if(palin[i] != palin[(size - i -1)]) the loop starts from 0 and then in condition palin[0] element and palin[4-0-1] i.e palin[3] element first o and last o in this case are mapped then the increement ++i takes place and then nest mapping of palin[second] and palin[second-last] elements happen so you can you either `++i' or 'i++'
So, I have a task to find number of substrings in given string. I can't use any C libraries for doing this task. stringExist can only have 2 strings as a parameters.
My solution is working, but I have a feeling that there should be a more elegant way to do this task.
Solution 1: as it turns out, it doesn't work correctly
#include <stdio.h>
int stringExist(char string[], char s2[]);
int main(void){
char string[] = "strstrASDstrSTRst";
char s2[] = "str";
printf("Final result: %i\n",stringExist(string,s2));
return 0;
}
int stringExist(char string[], char s2[]){
/* I am aware that I can init all this values in one row */
int count = 0;
int size = 0;
int i = 0;
int temp = 0;
int result = 0;
while(s2[size]!='\0'){
size++;
}
while(string[i]!='\0')
{
if(string[i]==s2[0])
{
printf("Found first occurrence\n");
count=0;
while((temp=(string[i]==s2[count]))!=0)
{
count++;
if(size==count){
printf("Match\n");
result++;
break;
}
i++;
}
}
i++;
}
return result;
}
Solution number 2:
So far no errors found.
Did a little bit different string traversal, now I don't increment i in the compare chars loop.
#include <stdio.h>
int stringExist(char string[], char s2[]);
int main(void){
char string[] = "bobobobojkhhkjjkhbo;klkl;bobo";
char s2[] = "bobo";
printf("Final result: %i\n",stringExist(string,s2));
return 0;
}
int stringExist(char string[], char s2[]){
int count = 0;
int size = 0;
int i = 0;
int c = 0;
int temp = 0;
int result = 0;
while(s2[size]!='\0'){
size++;
}
for(i=0;string[i]!='\0';i++){
if(string[i]==s2[0])
{
printf("Found first occurence at %i\n",i);
count = 0;
c = i;
while((temp=(string[c]==s2[count]))!=0)
{
printf("Count %i, I %i, current char: %c\n",count, c,string[c]);
count++;
if(size==count){
printf("Match\n");
result++;
break;
}
c++;
}
}
}
return result;
}
Thanks for you suggestions,
Vitaly
beat it: (also works for the extra condition)
int stringExist( char *string, char *sub )
{
int count = 0;
while( *string )
{
char *a = string, *b = sub;
while( *a && *a == *b ) {a++;b++;}
count += !*b;
++string;
}
return count;
}
I suggest writing it the way you would if you were allowed to use library functions. Then go back and write your own versions of those library functions that you used. While writing highly optimized versions of the string.h functions may be difficult, writing decent versions of most of them them in C is pretty easy..
Using subroutines (functions) to preform sub-tasks of this problem will help you to keep your code clear and also avoid certain types of problems, such as if you called:
x = stringExist("aaaaa", "aa");
There are 4 occurances of the string "aa" within "aaaaa", but I don't think that your function will find all of them. The reason for this is that as you search through the larger string for occurances of the second you are using the same index for both the beginning of the string and within the string. In fact, it looks like you would get the wrong results for:
x = stringExist("tBatBath", "tBath");
Unless of course, I've misunderstood what the function was supposed to do.
If you were to write your own version of a string prefix comparing function (essentially memcmp or strncmp) then you would have separated the job of matching the length of the string from looking deeper into the string and probably would not have made such a mistake.
If you are worried about squeezing efficiency out of your functions and the overhead of calling functions, don't. First, it's not that bad. Second, just declare them inline or static inline and if you compile with optimization turned on the compiler will most likely generate code as good as it would have without the use of multiple functions.
This feels like a homework question - in which case you should definitely just do it yourself. But, something that you'll probably want to check for that I don't think your code is handling correctly now is this:
How many times does "bobo" appear in the string "bobobo". It should probably be twice and I think your code as is will only count one.
Good luck,
Mark.
Well, from an algorithmic point of view, it's not bad. You can make optimizations, but I don't think that's the point (looks like homework!).
You may have a slight issue: in a string like "hahahaha", how many times should "haha" be detected? Twice? Thrice? Your code would see it twice.
From a stylistic point of view, there's certainly room for improvement, but you'll learn that over time, from coding and reading other's code =). Keep at it!