http://www.programmerinterview.com/index.php/c-cplusplus/c-declarations/
Begin looking at the variable name. 1) without skipping a right parenthesis, look right and say what you see. 2) Without skipping a left parenthesis, look left and say what you see. 3) If you are inside a parenthesis, move out of it move to the right to see what you see. 4) Look left and see what you see. Start again from 1 if need be.
int (*a)[3];
Begin by looking at a. 1) Go right and a and hit a right parenthesis. Do not say anything. 2) Go left of a and say what you see. Do not pass a left parenthesis. A pointer. 3) Go outside the parenthesis and see an array of size 3. 4) Go left and see an int.
SO, a is a pointer to an array of 3 ints.
~char *i[2][8];~ 1) Move right of i and say array of size 2 and an array of size 8. 2) move let of i and say pointer 3) a char
i is an array composed of 2 arrays of 8 pointers to chars.
char *(*a[ 3 ])();
a is an array of size 3 pointers to functions, returning an char pointer
int (*t[])();
t
t is an array of points to function returning an int.
while (c == getchar())
putchar (c);
Most variables are local to the function that calls them. That is, any variables declared in a function die when the function exits. For example, the following function add
, creates the variables a and b in the main function. BUT they disappear after the function ends.
int
add (int a, int b) {
return a + b;
}
int
main () {
printf ("the sum is %s", add (3, 4));
printf ("a is %s, b is %s", a, b); /* results in error,
because main can't
access a or b. */
return 0;
}
There are also static variables that are static, which keep their values each time they are called. If you are trying to write functional code, then only use these variables.
#include <stdio.h>
int count () {
static int b = 0;
return b++;
}
int
main () {
printf ("b is %s\n", count());
printf ("b is %s\n", count());
printf ("b is %s\n", count());
printf ("b is %s\n", count());
return 0;
}
The output of the above would be
"b is 1"
"b is 2"
"b is 3"
"b is 4"
External variables are variables that are accessible to any function. They can be thought of as global variables, because any function has access to these global variables. Never use this functionality. This is NOT functional programming. Using global variables usually means that your program will have to run synchrously and not use any threads. It can also lead to some odd errors.
#include <stdio.h>
//this is an external variable. It exists outside all the other functions that call it.
int count = 5;
int add (int a) {
extern int count;
return count + a;
}
int
main () {
extern int count;
printf ("count == %d\n", count);
printf ("add (1) == %d \n", add(1));
}
a singly byte capable of holding 1 character. A character is any character in ASCII. It's the english alphabet plus some other characters like "@", "!", "#", "$", "%", etc.
#+BEGIN_SRC C /* Is the ASCII number representing x. char number = 'x'; is the char array "x\0" */ char x [] = "x"; #+END_SRC
A whole number that can be negative or positive. One can also use octal or hexidecimal to define a number #+BEGIN_SRC C int x = 31; /* the same value in octal int x = 037; int the same value in hexidecimal. */ int x = 0x1f; int x = 0X1F; #+END_SRC
I believe that this is a constant too.
#define NEWLINE '\n'
The Enumeration constant is a list of constant integer values. It can often be used for boolean values:
enum boolean { NO, YES };
By default the first element in the list has a value of 0, the next 1, and so on.
You can enumerate the months like so,
enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
printf ("%s", "Hello World\n");
Hello World
A variable must be defined, before it can be used. The following two snippets are identical:
char my, how, why;
float a, x[1000];
char my;
char how;
char why;
float a;
float x[1000];
You can also declare variables with a value:
char a, b, c = 5;
int o, y, z = 8;
switch (expression) { case const-expr: statements case const-expr: statements default: statements }
The switch statement is a cool way have multiple if else statements in a better fashion.
I normally use it like so:
switch (opt)
{
// if this parser function is called on an option that it doesn't recognize, then don't do anything.
default:
return ARGP_ERR_UNKNOWN;
case 'j':
{
printf ("What do you call a box full of ducks?\n");
printf ("A bunch of quackers.\n");
break;
}
case 'm':
{
//some code
break;
}
}
BUT there are cooler ways to use the switch statement!
switch (digit) {
case: 'A' case: 'B' case 'C':
{
//some code
}
case: 5 case: 7 case: 9
{
//some code
break;
}
default:
//some code
break;
}
initialize i to be equal to 0, while i is less than 5, do some code.
for (int i = 0; i < 5; i++) {
//code
}
isdigit ('c'); //returns false aka non-0.
tolower ('Y'); // returns y
toupper ('z');; // returns z
#define max(A,B) ((A) > (B) ? (A) : (B))
You can also undefine macros. You might do this to make sure that you are using a function and not a macro:
#undef max
max (a, b);
A common method of managing memory is by using virtual memory. Virtual memory is memory that is mapped to physical memory, but usually there is more virtual memory than there is physical memory. A computer may have 5 GB of real memory, but 6 GB of virtual memory.
Virtual memory is split up into pages, which are normally 4KB each. A virtual memory page references a real memory page, which is called a frame. So frames are real memory and pages are virtual memory.
It's like a mormon marriage. You're supposed to have 1 wife, but the husband gets multiple women.
A process has a page associated with it, but sometimes memory is short and the process' page is not connected to a frame. When the process tries to use the virtual page, and the virtual page tries to access the frame, this is called a page fault. When this happens the kernel suspends the process and connects the page to a frame. Then the kernel starts the process again, and the process thinks that the page was connected to a frame.
It's actually possible to lock pages. Suppose you have a realtime application that cannot accept page faults, then you can lock that page. You could also do the same for security sensitive information. If a process has stored your password, you want that memory only in real memory. You never want it to get sent to swap... But locking pages can cause a performance penalty. If all programs lock pages, then no programs can run.
Many C command line programs accept arguments. Just type git --help
in a command line to see what I mean. argp is GNU's standard for dealing with arguments passed to C programs. Most people will probably only need to call argp_parse in the main function to start using it.
It's a good idea to set some default variables:
const char * argp_program_version
"VERSION_NUMBER";=
=const char * argp_program_bug_address = "EMAIL_ADDRESS";=
An argument parser is a struct. You probably will need to define options, parser, args_doc, and doc.
struct argp argp;
The options is just a list of options that this program understands. Options can be -CHAR or -NAME.
-CHAR is of the form "-g" or "-h" or "-i".
-NAME is of the form "--get" or "--help" or "--i"
For example, one can create an arg_options struct like so:
struct argp_option argp_options_joke;
Let's suppose you want to make an option that prints a silly joke. To make the long option be "--joke" you need:
argp_options_joke.name = "joke";
To have the short option be "-j" :
argp_options_joke.key = 'j';
This field needs a name so that argp can associate the option with a parser.
argp_options_joke.arg = "joke";
And a doc string
argp_options_joke.doc = "Print a funny joke.";
You can also make the option NOT need an argument. For example the "--help" does not have an argument, but the "rm -r" does require an argument. In this case "rm -r" requires the file/directory to delete.
argp_options_joke.flags = OPTION_ARG_OPTIONAL; // this option does not need an argument.
Now you need to turn this option into an array that can be passed to your argp.options variable.
Notice that the "{ 0 }". struct argp_option options [2] needs to be a list with the last element in the list having 0 in all of its fields. "{ 0 }" is the C shortcut for that.
struct argp_option options [2] = { argp_options_joke, { 0 } };
argp.options = options.
This is the usage string that you print when someone calls your program with PROGRAMNAME --help.
argp.args_doc = "argp [options]";
This is the documentation paragraph that explains what your program does.
argp.doc = "Just a simple test argp program!";
argp_parse parses the arguments via an argument parser. The argument parser could be a null pointer.
The easiest way to use argp to parse options is to use one function to parse all options. This function needs to look like this:
error_t PARSER (int KEY, char *ARG, struct argp_state *STATE)
The options field in a struct argp points to a function. Every time this parsing function is called, it parses a command line option. If the user typed in -j, then KEY equals 'j'. If the user typed in -g, then the key field equals 'k'. So you could implement a basic parser function to parse each argument based on what KEY equals. ie:
error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case 'j':
//some ACTION code here
break;
case 'g':
//some different ACTION code here.
Daisy theme documentation: [[gnus:nnimap+imap.fastmail.com:INBOX#CAHD1g8WjE_jHcX211TYbjZvZWoZdcQF_+2u5s6yq+eaKoDE4XQ@mail.gmail.com][Email from Lindsay V.: Re: Doing some updates]]
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
[2018-10-30 Tue] I took this test and got a 71%
:answer: It is a way to abnormally terminate a program.
It does not allow cleanup functions registered with atexit or on_exit.
This function actually terminates with the SIGABRT signal. My program can include a handler to intercept this signal. :END:
What's the differance between a double, float, short, int, long, char, etc.
Write some examples of floating numbers, etc.
ie: 9f
Write some hex numbers...
:ANSWER: #+HEADERS :includes #+BEGIN_SRC C int a = 500L;
int b = 500l; #+END_SRC :END: :ANSWER: #+HEADERS :includes #+BEGIN_SRC C int a = 240UL;
int b = 212ul; #+END_SRC :END: #+HEADERS :includes #+BEGIN_SRC C short int a = 240UL; #+END_SRC
:ANSWER: The declaration (aka "short int a"), implies that a is a short integer. But the definition (240UL), implies that A is an unsigned long. The compiler will probably complain that our declaration and definition do not match. :END: #+HEADERS :includes #+BEGIN_SRC C short int a = 240f; #+END_SRC
:ANSWER: The declaration (aka "short int a"), implies that a is a short integer. But the definition (240f), implies that A is a floating integer. The compiler will probably complain that our declaration and definition do not match. :END:
Because computers only understand 1s and 0s. There is a conversion penalty every time the computer has to convert back and forth between binary numbers and decimal digits.
Using Hex numbers can be useful when printing pointer addresses. A
program pointer points to a region of memory. Suppose that a pointer
address is at the 10,995 byte. One can write this is binary like
0b0010101011110011
or in hex 0x2AF3
every 4 bits (a nibble), can be represented by one digit in Hex. This saves space.
I still don't know why pointer address's aren't just printed in decimal form though.
When I read about string literals on page 194 of the C book, it implies that the below code should work...
#+HEADERS: :includes #+BEGIN_SRC C printf ("%s", 'a''b''c'); #+END_SRC
#+RESULTS:
Perhaps it was talking about this.
#+HEADERS: :includes #+BEGIN_SRC C printf ("%s", "abc" "defg" "hijk"); #+END_SRC
#+RESULTS:
abcdefghijk
#+HEADERS: :includes #+BEGIN_SRC C char * x = "abc"; char * y = "def"; char * z = "g"; printf ("%s", x y z); #+END_SRC
#+RESULTS:
:PROPERTIES: :ID: 9ac4e026-d625-43cc-acec-ba39de698537 :END:
why don't
I found these code snippets in the C coding book #+BEGIN_SRC C #define tempfile(dir) #dir "/%s"
#define cat(x,y) x ## y #+END_SRC
:ANSWER: C does not allow one to extend the language by creating unique new definitions. Rather, it allows one to extend existing types: int, long, double, etc.
This is useful for aesthetic and portability reasons. Consider the following:
#+BEGIN_SRC C typedef struct complicatedStruct { char ** bread; int toppings [5]; double *weight; float *size; } burger;
// now we can create as many burgers as we want
burger quarterPounder, halfPound, heavyBurger;
#+END_SRC
This can be helpful for portability reasons as well. Consider a machine that does not have the "float" value. Then to port the program, all we need to change would be the various typedefs. Typedefs can also be useful with complicated structures and function pointers like my files shows.
:END: :ANSWER:
typedef int (*functionPointer) (int *, int);
:END:
typedef struct {
char *word;
char **string;
char array [];
} tnode;
:answer: A multibyte character is a character that takes more than 1 byte to encode. Unicode for example, uses numerous bytes to encode '✯' or 'ϖ' for example. :END:
:answer: This is a string that is composed of entirely multibyte strings. :END:
:answer: L"✡" :END:
:answer: A wide string is a string that is composed of wchar_t objects. A wide string is usually declared like so: wchar_t * Also most unicode strings are going to be wide strings. :END:
:answer: 'WEOF' :END:
This program should not be executing! Malloc is not allocating enough memory to hold the string... #+HEADERS: :includes #+BEGIN_SRC C :results output const char * create_hello_string (const char * string) { char * local_string = (char *) malloc (sizeof (char)); strcpy (local_string, string); return local_string; }
int main () { char * hello_string = create_hello_string ("hello this string is long."); printf("%s\n", hello_string); return 0; } #+END_SRC
#+RESULTS:
hello this string is lon
#+HEADERS: :includes #+BEGIN_SRC C if (1) { int i = 5; }
printf ("i is %d\n", i); #+END_SRC
#+RESULTS:
:answer: i is defined in the if statement scope. It is not defined in the print statement. :END:
#+HEADERS: :includes #+BEGIN_SRC C for (int i = 0; i < 3; i++) ; printf ("i is %d\n", i); #+END_SRC
#+RESULTS:
:answer: 'i' is not defined. 'i' is defined inside the scope of the for block. Outside of that block, 'i' does not exist. :END:
#+HEADERS: :includes #+BEGIN_SRC C :results output char * copy_string (char * to, char * from) { while (*to++ = *from++) ; }
int main () { char hello [1]; hello [0] = 'h'; hello [1] = 'e'; hello [2] = 'l'; hello [3] = 'l'; hello [4] = 'o'; hello [1000] = '8'; //copy_string (hello, "hello"); printf ("hello[] is %s\n", hello); putchar (hello [1000]); putchar (hello [1001]); return 0; } #+END_SRC
#+RESULTS:
hello[] is hello 8
#+BEGIN_SRC C int strlen (const char[]); #+END_SRC
:answer: This means that the function strlen, will not modify the string that is passed to it. :END:
The stack is what you get your automatic variables. AKA variable that you don't have to allocate space for via malloc.
The heap contains all of the variables you have got via malloc calls.
The stack is automatic variables, but the heap is global variables...
The heap are variables that you get via calls to malloc.
The stack are variables you don't have have to use malloc, aka normal or automatic variables.
:ANSWER: Both a union and a struct are an easy way of collecting variables under one variable name. The difference is a struct's collection can define all values simultaneously. A union's collection is only allowed to define one variable at a time. :END:
:ANSWER: A declaration is a promise to the compiler that a function or variable exists.
A definition is the section of code that allocates a region of memory for the variable or function.
#+BEGIN_SRC C #include int a; // declaration int add (int a, int b);
int main () { a = 5; //this is the assignment statement int b = 10; //I am also an assignment statement
int c = add (a, b); printf("%d\n", c); return 0; }
//definition int add (int a, int b) { return a + b; } #+END_SRC
#+RESULTS:
15
:END: :ANSWER: Your program tried to access memory to which it did not have access. :END:
# retrieved from https://www.cprogramming.com/debugging/segfaults.html
:ANSWER: Your recursive function used up all of the stack space. You have no more memory to continue recursing. :END:
:ANSWER: The parameters are the local variables that are shown in the function definition. :END:
:ANSWER: An argument is the value that is passed to the function. :END:
Functions are made up of statements, which specify computing operations to be done. Statements are usually one line long and end in ";".
:answer: It is a place to store various information about the system so that applications work smoothly together.
/etc/hostname stores the computer's hostname. That's how the C library and everything else know the computer's hostname.
/etc/nsswitch.conf configures other things. :END:
:answer: malloc lets you explicitly allocate memory, and you are responsible for destroying that memory.
With alloc you can get memory for yourself, and when you leave the function that alloc is called from, the memory is freed automatically! So it's really easy to use, and maybe better! :END:
A pipe has no name. Only the parent and it's children can communicate with the pipe.
A FIFO is a communication that names a name. Anyone can open it and communicate to it. http://valgrind.org/docs/manual/quick-start.html#quick-start.mcrun
If run your program with arguments like: main arg1 arg2,
Then you can run valgrind to test for memory errors like this:
valgrind --leak-check=yes myprog arg1 arg2
memcheck is the default tool. --leak-check=yes turns on the detailed memory checker.
They are read right to left.
:answer: Signals are ways for your programs to declare certain events to have happened. :END: :answer: This generally means that the program must stop executing. Some massive problem has broken significant program logic, exposed a security vulnerability, etc. Programs can at this time write a core dump file and then return control to the OS to end the program. This dump file is useful for investigating what caused the crash. :END:
Suppose you wish to add an int and a float. C does a conversion for you. Generally, the automatic conversions convert a small type to a larger type, so you won't lose information. IE: C will convert an int into a float to add an int and a float.
int i = 2;
float f = 3.0;
printf("%f\n", i + f);
5.0
:ANSWER: =#include = is for standard libraries.
#include "filename"
is for libraries that I write.
:END:
#+BEGIN_SRC C #if !defined (HDR) #if SYSTEM == BSD #define HDR "bsd.h" #elif SYSTEM == LINUX #define HDR == "linux.h" #else #define HDR "msdos.h" #endif
#include HDR #+END_SRC
#+HEADERS: :includes #+BEGIN_SRC C float f = 39403.29304; printf ("%%f %f\n", f); printf ("%%2f %2f\n", f); printf ("%%2.0f %2.0f\n", f); printf ("%%100.100f %100.100f\n", f); #+END_SRC
#+RESULTS: | %f | 39403.292969 | | %2f | 39403.292969 | | %2.0f | 39403 | | %100.100f | 39403.29296875 |
:ANSWER: %d is for decimal %6d is a decimal integer at least 6 characters wide %f floating point %6f is a floating point at least 6 characters wide %.2f print as a floating point and add two characters after the decimal point %6.2f print as a floating point. Print 6 characters before the decimal and 2 after %o is for octal %x for hexadecimal %c for character %% is for the "%" character. :END:
"Hello\n"
:ANSWER:
byte | ||||||
---|---|---|---|---|---|---|
H | e | l | l | o | \n | \0 |
END |
:ANSWER: external
extern int n;
:END:
:ANSWER: You can't.
External variables must be declared outside any function, and they must be declared inside any function that wants to use them.
You can do this though:
#include <stdio.h>
int n;
int main () {
extern int n;
n = 10;
return n;
}
:END:
:ANSWER: This is a string array.
char string [] = "hello";
printf("%s\n", string);
hello
It is stored in continuous, read/write region of memory like this:
h | e | l | l | o | \0 |
I am allowed to alter any character in the string. So
char string[] = "hello";
string[2] = 'w';
printf ("%s\n", string);
hewlo
This is a string literal
char * string = "hello";
It is stored in a continuous, readonly section of memory like this:
hello\0 |
So trying to modify the string results in an error
//char * string = "hello";
string[2] = 'w';
printf ("%s\n", string);
:END:
:answer: strtok :END:
:ANSWER: Highest presidence to lowest. The arithmatic rules are PEMDAS. So C does not need parenthesis when evaluating basic arithmetic.
A void function, can be called by any bit of code in your project. A static void function, can only be used in the source code file it is in. This is useful for large projects. Many drivers in the linux kernel are named static void, so that they do not conflict with any other functions in the linux kernel.
:answer: In POSIX safety terms these refer to if it is safe to call various functions.
MT-safe means that it is safe to call this function inside a thread. This does not mean that the function is atomic. :END:
:answer: 'a' is a character. "a" is a string. "a" is internally represented as {'a','\0'}. :END:
:answer: libnetfs
This is the library that NFS is built on. :END:
#include <stdio.h>
int main () {
int *p = 15;
printf("%d",*p);
return 0;
}
:answer: A runtime error. The pointer is not pointing to a proper location in memory. Trying to read from an undefined point in memory, will cause a segmentation fault. :END:
#+HEADERS: :includes #+BEGIN_SRC C printf ("%d\n", 5/9); printf ("%d\n", 5.0/9.0); printf ("%f\n", 5.0/9.0); #+END_SRC
:answer: #+RESULTS: | 0 | | 4202507 | | 0.555556 | :END:
Why do they have different output?
:answer: The integers 5 and 9 are integers. However 5.0 and 9.0 are considered floating point numbers. Floating point numbers may have information after the decimal point. :END:
Input is reading data. Output is writing data. Glibc provides several functions for doing both!
I can read/write to a file by using a stream or a file descriptor. The stream is supposed to be easier to use. The file descriptor method is very low level, and streams are built a-top it. Streams allow 3 different types of buffering.
Streams allow for getting in character by character, or by line by line.
Apparently I should focus on formatted input and formatted output programs...
I will also have file positions. Whenever I am reading a file, some integer keeps track of where I am in the file. If I read a byte forward, then that integer increases by 1.
Streams use file pointers. This is stuff in stdio.h. I can check to see if I have found the end of the file by calling:
int feof (FILE * STREAM) it returns non-0 if the end of file is found.
When I call my main function, three streams are defined: stdin, stdout, and stderr. cool eh?
I can even re-direct stderr to a file:
fclose (stdout);
stdout = fopen ("standard-output-file", "w");
file * fopen (const char * FILE, const char * OPENTYPE)
Opentype can be: "r", "w", "a", "r+", "w+", "a+", "m".
"r" is just for reading a file.
"w" is just for writing a file and the previous file contents are discarded.
"a" is for appending at the end of the file.
"r+" is for reading and writing to a file. This is probably the most useful.
"m" is for opening files via mmap. It is only used for reading. This is the function that the Hurd program uses. int fclose (FILE * stream)
These are how to write one character. Pretty easy.
put c (int C, FILE * STREAM)
This writes a string to a FILE *.
puts (const char S, FILE STREAM)
These functions get one character from a stream. It's normally best to use getc, because it's faster.
fseek (FILE * STREAM, long int OFFSET, int WHENCE)
WHENCE can be SEEK_SET, SEEK_CUR, SEEK_END to indicate if the offset is the relative to current file pointer position, the end of the file, or the beginning of the file. is a function that lets you write an error message to the stderr stream. info:libc#Regular Expressions
This is all stored in regex.h
One first needs to compile a regexp via regcomp (), then one needs to search for matches via regexec (). Regexec will store the matches in an array that you pass into it.
compiled regular expressions are stored in the data structure regex_t. Every regex_t has one field that I need: a re_nsub, which holds the compiled regular expressions.
The array has elements of type regmatch_t. It has two fields:
After you have found your matches, be sure to free up the space your compiled regex was using via regfree
regfree (regex);
grep shows the proper matches in the white-space.txt file:
grep -E '[^ ] +$' white-space.txt
This line has extra white space this one does bro This line definitely has some white space.
BUT this regex doesn't match when I use the C version. But it does match when I remove the "$".
#+HEADERS: :includes #+BEGIN_SRC C char hello [32] = "Hello World!"; char * string; string = memchr (hello, '!', strlen(hello)); printf ("%s\n", string); #+END_SRC
#+RESULTS:
!
:answer: tsearch :END:
https://www.youtube.com/user/jstrosch/videos?sort=dd&view=0&shelf_id=1 These data types do have some qualifiers that can be applied to them.
short int n;
long int m;
The above is the same as:
short n;
long m;
You can think of this like sql data types. a short may have a value between -128-127. "int" is no smaller than a short, and no larger than a long. The compiler is free to determine these sizes, based on the hardware.
unsigned or signed may be used for chars and any integer. An unsigned variable's value can never be negative. A signed variable's value can be negative or positive.
signed int n;
unsigned char c;
signed float f;
long unsigned double d;
The qualifier long applied to a double means to make the variable extra precise.
I can specify that a value in C will not change. If this value is changed, the program will probably abort.
const int n = 5;
int n = 101e2;
printf ("%d\n", n);
10100
float f = 1.01e2;
printf ("%f\n", f);
101.0
int n = 0b11;
printf ("%d\n", n);
3
A struct is a collection of data grouped under one variable name. This is convenient for large programs with lots of data. Consider a registration program that is responsible for registering many users. Each user has a name, address, phone number, etc. A convenient method for handling this kind of problem is to use a struct.
struct human {
char * phone_number;
char * name;
char * address;
};
Then to declare variables of this type one would do the following:
struct human phil, john, james;
Now we have three variables "phil", "john", and "james". We could now start filling in their information:
phil.name = "Phil";
john.name = "John";
james.name = "James";
We could also do all of the above like this:
struct {
char * name;
char * phone_number;
char * address;
} james, john, phil;
phil.name = "Phil";
john.name = "John";
james.name = "James";
But it's more convenient to give the struct a tag. The tag in this case is "human".
Probably the easier way to do all of the above is to do the following:
struct human {
char * name;
char * phone_number;
char * address;
};
struct human james = { "James" , "7652834019", "1128 Liby Way New York" };
struct human john = { "James" , "7642824513", "1128 Liby Way New Jersey" };
struct human phil = { "Phil" , "7652434074", "1128 Liby Way New York" };
An even easier way would probably be to use a typedef.
typedef struct shuman {
char * name;
char * phone_number;
char * address;
} human_t; //the "_t" is a hint that this is a typedef
human james = { "James" , "7652834019", "1128 Liby Way New York" };
human john = { "James" , "7642824513", "1128 Liby Way New Jersey" };
human phil = { "Phil" , "7652434074", "1128 Liby Way New York" };
Here's we've created a structure, and we have given it the typedef "human". Now we can use this as a way to create new struct "shuman".
We can also nest structures. Suppose we wanted to create a structure that is a family! We can do that pretty easily too!
The way I had thought about doing it at first was to use the libc function strtok, which takes a string, and returns many substrings based on a set of string of characters.
In other words, strtok removes special characters and only returns the strings between those special characters.
So if the string is " and ", and the delimiters are "<" and ">", then multiple calls to strtok returns
strtok () --> Hello strtok () --> and strtok () --> Hello
This method worked when I was testing my logic. Instead of specifying an html file, I hardcoded an html string in the file:
#+BEGIN_SRC C const char * string = "real simple"; #+END_SRC
BUT now that I want to parse an html file, I may have found a better function: getdelim. getdelim let you read a token from a file. So I probably won't have to use strtok anymore! I can just read the file via getdelim and specify that "<>" are my delimiters. The only problem is the getdelim is get delimiter not get "delimeters". So getdelimiter only supports setting a char delimeter. Not a string of delimeters.
I have three possible solutions:
The main problem with this technique is that the function has a hard time processing elements with contents.
ie:
Hello World
In the nested while loop, getdelim("<") will return the opening p element, but may forget about the p's content. I could use static variables to get around this.
#+HEADERS: :includes #+BEGIN_SRC C :dir ~/programming/c/ FILE * file = fopen ("simple.html", "r"); char ** token;
const char * getdelimeters (FILE * file, char ** token) { while ((token = getdelim (token, 128, "<", file)) != NULL) { //if token does not contain ">" return token; while ((token = getdelim (token, 128, ">", file)) != NULL) { //I'll use a static variable here to store the content... return token; } } return NULL; }
while ((token = getdelimeters (file, token)) != NULL) { printf ("Hello%s\n", token); }
fclose (file); //getdelim (char ** lineptr, size_t n, int delimiter, FILE stream);
#+END_SRC
#+RESULTS:
The reference in the back of the C book has some tips about how I can compile C.
An expression is what is contained inside of parenthesis (also can be found inside a printf statement). Can be of a few types #+BEGIN_SRC C if (1 < 5) ; else if (3 == 3) ; else if (2 != 6 ) ; #+END_SRC
#+RESULTS:
#+BEGIN_SRC C if (x = 1) ; else if (z = 3 != EOF) ; else if (2 + 6 == 8) ; #+END_SRC
#+BEGIN_SRC C
if (x + 1)
;
else if (z = 1)
;
else if (y+)
;
#+END_SRC
#+BEGIN_SRC C if (isdigit (1)) ; else if (isupper('a')) ; else if (islower ('b')) ; #+END_SRC A statement is any bit of code that ends in a semicolon. These are all statements. #+BEGIN_SRC C int x = 5; x++; int b = x - 2; int c = x % b; #+END_SRC
Any region of code that is contained between two braces {}, is considered a compound statement or a block. C considers a block and a statement as syntactically equivalent. The braces around the main function is one block. An if else statement contains two or more blocks.
#+BEGIN_SRC C if (1) { //first block } else if (2) { //second block } else { //third block } #+END_SRC #+BEGIN_SRC C #define name replacement text #+END_SRC |----+-----------------+------+--------------------| | \a | alert bell | \\ | backslash | | \b | backspace | \? | question mark | | \f | formfeed | \' | single quote | | \n | newline | \" | double quote | | \r | carriage return | \ooo | octal number | | \v | vertical tab | \xhh | hexadecimal number | |----+-----------------+------+--------------------| |----------+--------+----------+----------| | auto | double | int | struct | | break | else | long | switch | | case | enum | register | typedef | | char | extern | return | union | | const | float | short | unsigned | | continue | for | signed | void | | default | goto | sizeof | volatile | | do | if | static | while | |----------+--------+----------+----------|
|--------+---------| | void | char | | short | int | | long | float | | double | signed | | struct | union | | enum | typedef | |--------+---------|
|----------+----------| | register | volatile | |----------+----------|
| auto | register | | static | extern | | typedef | |
#+HEADERS: :includes #+BEGIN_SRC C :dir ~/programming/c/
char string [16] = "hello World\0"; char other_string [16];
memcpy (other_string, string, 7);
fwrite (other_string, 1, 7, stdout);
#+END_SRC
#+RESULTS:
hello W
https://www.cprogramming.com/how_to_learn_to_program.html
#+HEADERS :includes #+BEGIN_SRC C int main () { printf ("Hello World\n"); return 0; } #+END_SRC
#+RESULTS:
Hello World
#+HEADERS :includes #+BEGIN_SRC C printf ("Hello World\n") #+END_SRC
#+RESULTS:
#+BEGIN_SRC C #include
main () { printf ("Hello World\n"); } #+END_SRC
#+RESULTS:
#+BEGIN_SRC C #include
int main () { printf ("Hello World\n"); } #+END_SRC
#+RESULTS:
Hello World
#+BEGIN_SRC C #include
void main () { printf ("Hello World\n"); } #+END_SRC
#+RESULTS:
#+BEGIN_SRC C include
int main () { printf ("hello World\n"); return 0; } #+END_SRC
#+RESULTS:
#+BEGIN_SRC C #include
int main () { printf ("hello World\n"); return 0; } #+END_SRC
#+RESULTS:
#+BEGIN_SRC C #include
int main () { printf ("hello \e \a \f \< \( < \@ \5 World\n"); return 0; } #+END_SRC
#+RESULTS:
hello < ( < @ World
#+HEADERS: :includes #+BEGIN_SRC C char * reverse (char * to, char * from) { int i, j; for (j = 0, i = strlen (from) - 1; (*(to + j) = *(from + i)) && i > 0; i--, j++) ; }
int main () { char * str = (char *) malloc (sizeof("hello")); reverse (str, "hello"); printf ("%s\n", str); putchar (*(str + 10)); //why does this not cause an error? return 0; } #+END_SRC
#+RESULTS: | olleh | | |
#+HEADERS: :includes #+BEGIN_SRC C printf ("strlen is %d\n", strlen("ab")); #+END_SRC
#+RESULTS:
strlen is 2
#+HEADERS: :includes #+BEGIN_SRC C printf ("'c' - 'a' = %d\n", 'c' - 'a'); #+END_SRC
#+RESULTS:
'c' - 'a' = 2
#+BEGIN_SRC C #include
int main() { char a [] = "abcdefghijklmnopqrstuvwxyz"; char A [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < 26; i++) { printf ("%c %d %c %d %d %d\n", a[i], a[i], A[i], A[i], i < 10 ? i : 0, i < 10 ? (int) (i+48) : ' '); } return 0; }
#+END_SRC
#+RESULTS: | a | 97 | A | 65 | 0 | 48 | | 48 | 49 | | | | | | b | 98 | B | 66 | 1 | 49 | | 48 | 49 | | | | | | c | 99 | C | 67 | 2 | 50 | | 48 | 49 | | | | | | d | 100 | D | 68 | 3 | 51 | | 48 | 49 | | | | | | e | 101 | E | 69 | 4 | 52 | | 48 | 49 | | | | | | f | 102 | F | 70 | 5 | 53 | | 48 | 49 | | | | | | g | 103 | G | 71 | 6 | 54 | | 48 | 49 | | | | | | h | 104 | H | 72 | 7 | 55 | | 48 | 49 | | | | | | i | 105 | I | 73 | 8 | 56 | | 48 | 49 | | | | | | j | 106 | J | 74 | 9 | 57 | | 48 | 49 | | | | | | k | 107 | K | 75 | 0 | 32 | | 48 | 49 | | | | | | l | 108 | L | 76 | 0 | 32 | | 48 | 49 | | | | | | m | 109 | M | 77 | 0 | 32 | | 48 | 49 | | | | | | n | 110 | N | 78 | 0 | 32 | | 48 | 49 | | | | | | o | 111 | O | 79 | 0 | 32 | | 48 | 49 | | | | | | p | 112 | P | 80 | 0 | 32 | | 48 | 49 | | | | | | q | 113 | Q | 81 | 0 | 32 | | 48 | 49 | | | | | | r | 114 | R | 82 | 0 | 32 | | 48 | 49 | | | | | | s | 115 | S | 83 | 0 | 32 | | 48 | 49 | | | | | | t | 116 | T | 84 | 0 | 32 | | 48 | 49 | | | | | | u | 117 | U | 85 | 0 | 32 | | 48 | 49 | | | | | | v | 118 | V | 86 | 0 | 32 | | 48 | 49 | | | | | | w | 119 | W | 87 | 0 | 32 | | 48 | 49 | | | | | | x | 120 | X | 88 | 0 | 32 | | 48 | 49 | | | | | | y | 121 | Y | 89 | 0 | 32 | | 48 | 49 | | | | | | z | 122 | Z | 90 | 0 | 32 | | 48 | 49 | | | | |
#+HEADERS: :include #+BEGIN_SRC C #include
int main () { printf ("%d", (26 % 26)); return 0; } #+END_SRC
#+RESULTS:
0
This simple function will try to expand strings like "a-d" into "abcd". Eventually try to handle "0-9" and even "a-z0-9"
!*p is how you can test if your pointer currently points at the '\0' character. #+HEADERS: :includes #+BEGIN_SRC C // sequence_t will store the information from an encoded string the // encoded strings looks like "[a-zA-Z0-9]-[a-zA-Z0-9]". So an // encoded string of "a-z", represents the whole alphabet.
A struct of //sequence_t = {beginning_char = 'a', end_char = 'z', next = sequence_t { beginning_char = '0', end_char = '9', next = 0 }} // represents a string that contains the alphabet followed by the // numbers 1-9. The original string would have been "a-z0-9". struct sequence_t { char beginning_char, end_char; unsigned int sequence_length; struct sequence_t *next; };
struct sequence_t * allocate_sequence () { struct sequence_t * sequence = (struct sequence_t *) malloc (sizeof (struct sequence_t)); return sequence; }
struct sequence_t * parse_string (char * str) { struct sequence_t * sequence = allocate_sequence(); sequence->beginning_char = *str; sequence->end_char = *(str + 2); }
int main () { char * string = expand ("a-z"); printf ("%s\n", string); return 0; } #+END_SRC
#+RESULTS:
#+HEADERS: :includes #+BEGIN_SRC C int main () { int fahr, celsius; int lower, upper, step;
lower = 0; * lower limit of temperature table upper = 300; upper limit step = 20; step size *
fahr = lower; printf ("Fahrenheit Celsius\n"); while (fahr <= upper) { celsius = 5 * (fahr - 30) / 9; celsius = (fahr - 30) * (5/9); //this is wrong //in C integer division, truncates any remainder aka 5 / 9 = .55555, but in C 5/9 == 0 printf ("%d %d\n", fahr, celsius); fahr = fahr + step; } return 0; } #+END_SRC
#+RESULTS: | Fahrenheit | Celsius | | 0 | -16 | | 20 | -5 | | 40 | 5 | | 60 | 16 | | 80 | 27 | | 100 | 38 | | 120 | 50 | | 140 | 61 | | 160 | 72 | | 180 | 83 | | 200 | 94 | | 220 | 105 | | 240 | 116 | | 260 | 127 | | 280 | 138 | | 300 | 150 |
int main ()
{
float fahr, celsius;
int lower, upper, step;
lower = 0;
upper = 300;
step = 10;
fahr = lower;
printf ("Fahrenheit Celsius\n");
while (fahr <= upper)
{
/* 5.0 / 9.0 is not truncated to 0, because 5.0 is a floating number not an int */
celsius = (5.0 / 9.0) * (fahr - 32.0);
/* 3.0, means print at least 3 characters wide with no decimal digit */
/* 6.1 means print at least 8 characters wide with 3 decimal digits */
printf ("%3.0f %8.3f\n", fahr, celsius);
fahr = fahr + step;
}
return 0;
}
Fahrenheit | Celsius |
0 | -17.778 |
10 | -12.222 |
20 | -6.667 |
30 | -1.111 |
40 | 4.444 |
50 | 10.0 |
60 | 15.556 |
70 | 21.111 |
80 | 26.667 |
90 | 32.222 |
100 | 37.778 |
110 | 43.333 |
120 | 48.889 |
130 | 54.444 |
140 | 60.0 |
150 | 65.556 |
160 | 71.111 |
170 | 76.667 |
180 | 82.222 |
190 | 87.778 |
200 | 93.333 |
210 | 98.889 |
220 | 104.444 |
230 | 110.0 |
240 | 115.556 |
250 | 121.111 |
260 | 126.667 |
270 | 132.222 |
280 | 137.778 |
290 | 143.333 |
300 | 148.889 |
int main ()
{
float fahr, celsius;
int lower, upper, step;
lower = 0;
upper = 300;
step = 10;
celsius = lower;
printf ("Celsius Fahrenheit\n");
while (celsius <= upper)
{
/* 5.0 / 9.0 is not truncated to 0, because 5.0 is a floating number not an int */
fahr = (5.0 / 9.0) * celsius + 32;
/* 3.0, means print at least 3 characters wide with no decimal digit */
/* 6.1 means print at least 8 characters wide with 3 decimal digits */
printf ("%3.0f %5.1f\n", celsius, fahr);
celsius = celsius + step;
}
return 0;
}
Celsius | Fahrenheit |
0 | 32.0 |
10 | 37.6 |
20 | 43.1 |
30 | 48.7 |
40 | 54.2 |
50 | 59.8 |
60 | 65.3 |
70 | 70.9 |
80 | 76.4 |
90 | 82.0 |
100 | 87.6 |
110 | 93.1 |
120 | 98.7 |
130 | 104.2 |
140 | 109.8 |
150 | 115.3 |
160 | 120.9 |
170 | 126.4 |
180 | 132.0 |
190 | 137.6 |
200 | 143.1 |
210 | 148.7 |
220 | 154.2 |
230 | 159.8 |
240 | 165.3 |
250 | 170.9 |
260 | 176.4 |
270 | 182.0 |
280 | 187.6 |
290 | 193.1 |
300 | 198.7 |
#include <stdio.h>
int main ()
{
int fahr;
for (fahr = 0; fahr <= 300; fahr = fahr + 20)
{
printf ("%d %6.1f\n", fahr, (5.0/9.0) * (fahr - 32));
}
return 0;
}
0 | -17.8 |
20 | -6.7 |
40 | 4.4 |
60 | 15.6 |
80 | 26.7 |
100 | 37.8 |
120 | 48.9 |
140 | 60.0 |
160 | 71.1 |
180 | 82.2 |
200 | 93.3 |
220 | 104.4 |
240 | 115.6 |
260 | 126.7 |
280 | 137.8 |
300 | 148.9 |
#include <stdio.h>
#define LOWER 0
#define UPPER 300
#define STEP 20
int main ()
{
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
{
printf ("%d %6.1f\n", fahr, (5.0/9.0) * (fahr - 32));
}
return 0;
}
0 | -17.8 |
20 | -6.7 |
40 | 4.4 |
60 | 15.6 |
80 | 26.7 |
100 | 37.8 |
120 | 48.9 |
140 | 60.0 |
160 | 71.1 |
180 | 82.2 |
200 | 93.3 |
220 | 104.4 |
240 | 115.6 |
260 | 126.7 |
280 | 137.8 |
300 | 148.9 |
A program that outputs it's input
char c;
c = getchar ();
while (c != EOF)
{
putchar (c);
c = getchar ();
}
char c; That's the problem. char c can only hold 128 characters. It is not large enough to hold the EOF character. So c must be declared in int.
#include <stdio.h>
int main ()
{
int c;
while ((c = getchar()) != EOF)
putchar (c);
return 0;
}
#include <stdio.h>
int main ()
{
printf("%d\n", EOF);
return 0;
}
-1
#include <stdio.h>
int main ()
{
char string [16] = "silly.txt";
FILE * stream = fopen (string, "r");
int c, nl;
nl = 0;
while ((c = fgetc(stream)) != EOF)
if (c == '\n')
++nl;
printf ("number of lines in %s is %d\n", string, nl);
return 0;
}
number of lines in silly.txt is 9
#include <stdio.h>
int main ()
{
char string [16] = "silly.txt";
FILE * stream = fopen (string, "r");
int c, nl, tabs, blanks = 0;
while ((c = fgetc(stream)) != EOF)
switch (c)
{
case '\n':
++nl;
break;
case '\t':
++tabs;
break;
case ' ':
++blanks;
break;
}
printf ("number of lines in %s is %d\n", string, nl);
printf ("number of blanks in %s is %d\n", string, blanks);
printf ("number of tabs in %s is %d\n", string, tabs);
return 0;
}
number | of | lines | in | silly.txt | is | 9 |
number | of | blanks | in | silly.txt | is | 16 |
number | of | tabs | in | silly.txt | is | 0 |
#include <stdio.h>
#define IN 1
#define OUT 0
int main ()
{
char string [16] = "silly.txt";
FILE * stream = fopen (string, "r");
int c, nc, nl, nw, state = 0;
while ((c = fgetc (stream)) != EOF)
{
++nc;
if (c == '\n')
++nl;
if (c == '\n' || c == ' ' || c == '\t')
state = OUT;
else
{
if (state == OUT)
state = IN;
++nw;
}
}
printf ("%s has %d lines, %d words, and %d characters\n", string, nl, nw, nc);
return 0;
}
silly.txt has 9 lines | 32934 words | and 193 characters |
char string [16] = "silly.txt";
FILE * stream = fopen (string, "r");
int c, nc, nl, nw, state = 0;
while ((c = fgetc (stream)) != EOF)
{
if (c == ' ')
{
state = OUT;
printf("\n");
}
else
{
if (state == OUT)
state = IN;
fputc (c, stdout);
state = IN;
++nw;
}
}
#+AUTHOR:Joshua |
Branson |
#+TITLE: |
#+LATEX_HEADER: |
\usepackage{lmodern} |
#+LATEX_HEADER: |
\usepackage[QX]{fontenc} |
#+OPTIONS: |
H:10 |
toc:nil |
* |
This |
is |
a |
silly |
Text |
File |
I'm |
using |
it |
to |
count |
lines |
to |
to |
to |
#include <stdio.h>
#define IN 1
#define OUT 0
#define MAX_WORD_LENGTH 32
int main ()
{
char string [16] = "silly.txt";
/* word_length[5] = 7, means that there were 7 words of length 5; */
int word_lengths [MAX_WORD_LENGTH];
/* initialize word_lengths to 0 */
for (int i = 0; i < MAX_WORD_LENGTH; i++)
word_lengths[i] = 0;
FILE * stream = fopen (string, "r");
/* nw == new word */
/* wl == word length */
int c, nw, wl, state = 0;
while ((c = fgetc (stream)) != EOF)
{
/* if this is NOT a word, state is now OUT of word */
if (c == '\n' || c == ' ' || c == '\t')
{
state = OUT;
if (wl > 0)
{
word_lengths[wl] = word_lengths[wl] + 1;
}
wl = 0;
}
else //state is now IN a word
{
if (state == OUT)
{
state = IN;
++nw;
}
++wl;
}
}
printf ("%s has %d words\n", string, nw);
//print the histogram of word lengths
//ie:
/* word_lengths = {0, 1, 4, 5}
output is :
1 -
2 ----
3 -----
,*/
for (int i = 1; i < MAX_WORD_LENGTH; i++)
{
if (word_lengths[i])
{
printf("%d ", i);
for (int j = 0; j < word_lengths[i]; j++)
fputc ('-', stdout);
printf("\n");
}
}
return 0;
}
The headers and should be helpful to do this.
int b = 0b111111111111;
printf("%d %d %d\n", b, 0177, b & 0177);
int c = 0b111110000000;
printf("%d %u\n", c, c);
4095 | 127 | 127 |
3968 | 3968 |
/* This function takes an int and prints its binary representation */
int return_highest_power_of_2 (int i)
{
/* find the highest power of 2 <= i */
short int n = 0;
for (; pow(2 , n) <= i; ++n)
{
}
return --n;
}
int * return_b_number (int n)
{
if (n == 0)
{
return 0;
}
if (n == 1)
{
return 1;
}
short highest_power_of_2 = return_highest_power_of_2 (n);
//this needs to be turned into something interesting...
return return_b_number (n - pow(2, highest_power_of_2)) + pow (2, highest_power_of_2);
}
print_b_number (int n)
{
//printf("%d\n", return_b_number (n));
}
int main ()
{
//print_b_number (2);
//printf ("%d\n", return_highest_power_of_2 (32));
printf ("%3.0f\n", return_b_number (2));
printf ("%d\n", (int) return_b_number (2));
return 0;
}
#+HEADERS: :includes #+BEGIN_SRC C for (int i = 0; i < 3; i++) printf ("You have %d item%s\n", i, i==1 ? "" : "s"); #+END_SRC
#+RESULTS: | You | have | 0 | items | | You | have | 1 | item | | You | have | 2 | items |
:ANSWER: strcat concatenates two strings. It is a bad idea, but strcat is a slow method of concatenating two strings. C does not store the length of strings. Instead, it has to calculate the length of the strings each time, one attempts to copy a string.
It may be a better idea to use mempcpy. :END:
Ok, so org-babel should be throwing an error here, but it is not...
int a [8];
a[7] = 3;
a[6] = 4;
a[55] = 1;
a[0] = 2;
printf ("%d %d %d %d\n", a[7], a[6], a[8], a[0]);
3 4 4198752 2
int return_highest_power_of_2 (int i)
{
/* find the highest power of 2 <= i */
short int n = 0;
for (; pow(2 , n) <= i; ++n)
{
}
return --n;
}
int main ()
{
short a = return_highest_power_of_2 (0);
short b = return_highest_power_of_2 (1);
short c = return_highest_power_of_2 (2);
short d = return_highest_power_of_2 (3);
short e = return_highest_power_of_2 (4);
short f = return_highest_power_of_2 (5);
short g = return_highest_power_of_2 (6);
short h = return_highest_power_of_2 (8);
short i = return_highest_power_of_2 (9);
short j = return_highest_power_of_2 (10);
short k = return_highest_power_of_2 (11);
short l = return_highest_power_of_2 (16);
printf ("0 %d\n", a);
printf ("1 %d\n", b);
printf ("2 %d\n", c);
printf ("3 %d\n", d);
printf ("4 %d\n", e);
printf ("5 %d\n", f);
printf ("6 %d\n", g);
printf ("8 %d\n", h);
printf ("9 %d\n", i);
printf ("10 %d\n", j);
printf ("11 %d\n", k);
printf ("16 %d\n", l);
return 0;
}
0 | -1 |
1 | 0 |
2 | 1 |
3 | 1 |
4 | 2 |
5 | 2 |
6 | 2 |
8 | 3 |
9 | 3 |
10 | 3 |
11 | 3 |
16 | 4 |
ll of these things are discussed in the libc manual |
#+HEADERS: :include #+BEGIN_SRC C unsigned int c = 'z';
printf ("%d", c + 7); #+END_SRC
#+RESULTS:
129
| a | 97 | A | 65 |
#+HEADERS: :include #+BEGIN_SRC C enum lower_letters { a = 97, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z };
enum upper_letters { A = 65, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z };
enum upper_letters letter = Z;
putchar ((int)'z' + 7); #+END_SRC
#+RESULTS:
a
echo "Probably the simplest case is to decrypt a short sentence." | ./caesar -s 1 | ./caesar -s 25
Probably the simplest case is to decrypt a short sentence.
echo "GNU Emacs is Free" | ./caesar -s 1
HOV Fnbdt jt Gsff
echo "GNU Emacs is Free" | ./caesar -s 1 | ./decrypt
GNU Emacs is Free
The & operator takes two integers, and outputs the bits that are both 1.
13 | & | 11 |
1111 | 1100 |
Now the bitwise & operation
13 | 1101 |
11 | 1011 |
& | & |
9 | 1001 |
int main ()
{
int a, b;
a = 13;
b = 11;
printf("%d\n", a & b);
a = 0b1101; //binary 13
b = 0b1101; //binary 11
return 0;
}
9
Bitwise OR is like the propositional logic "\/".
For two binary numbers, the if one bit is a 1, then the answer will have a 1.
15 | OR | 3 |
1111 | 11 |
15 | 1111 |
13 | 0011 |
OR | OR |
15 | 1111 |
int main ()
{
int a = 15;
int b = 13;
printf("%d\n", a|b);
a = 0b1111;
b = 0b1101;
printf("%d\n", a|b);
return 0;
}
15 |
15 |
17 | OR | 9 |
1111 | 1001 |
17 | 10001 |
9 | 01001 |
^ | ^ |
25 | 11000 |
int main ()
{
int a = 17;
int b = 9;
printf("%d\n", a|b);
a = 0b10001;
b = 0b1001;
printf("%d\n", a|b);
return 0;
}
25 |
25 |
I don't understand this one. I thought ~13 = 2.
It only works on one operand. It inverts all bits of one number to the opposite bit.
13 | 1101 | |
~ | ~ | |
-14 | 0010 | ???? |
int main ()
{
int i = 13;
printf("%d\n", ~i);
i = 0b1101;
printf("%d\n", ~i);
return 0;
}
-14 |
-14 |
1 | <<2 | 1 | <<2 |
---|---|---|---|
100 | 4 |
The left shift operator moves bits in a number to the left.
int main ()
{
int a = 1;
int b = 0b1;
printf("%d %d\n", a<<2, b<<2);
return 0;
}
4 4
info:autoconf#Portable C and C++
#+HEADERS: :include #+BEGIN_SRC C printf("%c", (char) ((int) 'z' + 1)); #+END_SRC
#+RESULTS:
{
http://0pointer.de/blog/projects/libabc.html
https://git.kernel.org/pub/scm/linux/kernel/git/kay/libabc.git/plain/README